]> git.proxmox.com Git - qemu.git/blame - target-mips/translate.c
target-mips: implement movn/movz using movcond
[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. */
e7139c44 1487#ifdef CONFIG_USER_ONLY
d9bea114 1488#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1489static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1490{ \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1496 tcg_temp_free(t0); \
aaa9128a 1497}
e7139c44
AJ
1498#else
1499#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1500static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1501{ \
895c2d04 1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1503}
1504#endif
aaa9128a
TS
1505OP_LD_ATOMIC(ll,ld32s);
1506#if defined(TARGET_MIPS64)
1507OP_LD_ATOMIC(lld,ld64);
1508#endif
1509#undef OP_LD_ATOMIC
1510
590bc601
PB
1511#ifdef CONFIG_USER_ONLY
1512#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1513static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1514{ \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1518 \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
7db13fae 1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1534}
1535#else
1536#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1537static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1538{ \
1539 TCGv t0 = tcg_temp_new(); \
895c2d04 1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1541 gen_store_gpr(t0, rt); \
590bc601
PB
1542 tcg_temp_free(t0); \
1543}
1544#endif
590bc601 1545OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1546#if defined(TARGET_MIPS64)
590bc601 1547OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1548#endif
1549#undef OP_ST_ATOMIC
1550
662d7485
NF
1551static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1553{
1554 if (base == 0) {
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1558 } else {
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1561 }
1562}
1563
364d4831
NF
1564static target_ulong pc_relative_pc (DisasContext *ctx)
1565{
1566 target_ulong pc = ctx->pc;
1567
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1570
1571 pc -= branch_bytes;
1572 }
1573
1574 pc &= ~(target_ulong)3;
1575 return pc;
1576}
1577
5c13fdfd 1578/* Load */
7db13fae 1579static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
afa88c3a 1580 int rt, int base, int16_t offset)
6af0bf9c 1581{
5c13fdfd 1582 const char *opn = "ld";
fc40787a 1583 TCGv t0, t1, t2;
afa88c3a
AJ
1584
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1589 MIPS_DEBUG("NOP");
1590 return;
1591 }
6af0bf9c 1592
afa88c3a 1593 t0 = tcg_temp_new();
662d7485 1594 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1595
6af0bf9c 1596 switch (opc) {
d26bc211 1597#if defined(TARGET_MIPS64)
6e473128 1598 case OPC_LWU:
2910c6cb 1599 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
78723684 1600 gen_store_gpr(t0, rt);
6e473128
TS
1601 opn = "lwu";
1602 break;
6af0bf9c 1603 case OPC_LD:
2910c6cb 1604 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
78723684 1605 gen_store_gpr(t0, rt);
6af0bf9c
FB
1606 opn = "ld";
1607 break;
7a387fff 1608 case OPC_LLD:
b835e919 1609 save_cpu_state(ctx, 1);
5c13fdfd 1610 op_ld_lld(t0, t0, ctx);
78723684 1611 gen_store_gpr(t0, rt);
7a387fff
TS
1612 opn = "lld";
1613 break;
6af0bf9c 1614 case OPC_LDL:
3cee3050 1615 t1 = tcg_temp_new();
fc40787a
AJ
1616 tcg_gen_andi_tl(t1, t0, 7);
1617#ifndef TARGET_WORDS_BIGENDIAN
1618 tcg_gen_xori_tl(t1, t1, 7);
1619#endif
1620 tcg_gen_shli_tl(t1, t1, 3);
1621 tcg_gen_andi_tl(t0, t0, ~7);
1622 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1623 tcg_gen_shl_tl(t0, t0, t1);
1624 tcg_gen_xori_tl(t1, t1, 63);
1625 t2 = tcg_const_tl(0x7fffffffffffffffull);
1626 tcg_gen_shr_tl(t2, t2, t1);
78723684 1627 gen_load_gpr(t1, rt);
fc40787a
AJ
1628 tcg_gen_and_tl(t1, t1, t2);
1629 tcg_temp_free(t2);
1630 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1631 tcg_temp_free(t1);
fc40787a 1632 gen_store_gpr(t0, rt);
6af0bf9c
FB
1633 opn = "ldl";
1634 break;
6af0bf9c 1635 case OPC_LDR:
3cee3050 1636 t1 = tcg_temp_new();
fc40787a
AJ
1637 tcg_gen_andi_tl(t1, t0, 7);
1638#ifdef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1, t1, 7);
1640#endif
1641 tcg_gen_shli_tl(t1, t1, 3);
1642 tcg_gen_andi_tl(t0, t0, ~7);
1643 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1644 tcg_gen_shr_tl(t0, t0, t1);
1645 tcg_gen_xori_tl(t1, t1, 63);
1646 t2 = tcg_const_tl(0xfffffffffffffffeull);
1647 tcg_gen_shl_tl(t2, t2, t1);
78723684 1648 gen_load_gpr(t1, rt);
fc40787a
AJ
1649 tcg_gen_and_tl(t1, t1, t2);
1650 tcg_temp_free(t2);
1651 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1652 tcg_temp_free(t1);
fc40787a 1653 gen_store_gpr(t0, rt);
6af0bf9c
FB
1654 opn = "ldr";
1655 break;
364d4831 1656 case OPC_LDPC:
3cee3050 1657 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1658 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1659 tcg_temp_free(t1);
2910c6cb 1660 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
364d4831 1661 gen_store_gpr(t0, rt);
5c13fdfd 1662 opn = "ldpc";
364d4831 1663 break;
6af0bf9c 1664#endif
364d4831 1665 case OPC_LWPC:
3cee3050 1666 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1667 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1668 tcg_temp_free(t1);
2910c6cb 1669 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
364d4831 1670 gen_store_gpr(t0, rt);
5c13fdfd 1671 opn = "lwpc";
364d4831 1672 break;
6af0bf9c 1673 case OPC_LW:
2910c6cb 1674 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
78723684 1675 gen_store_gpr(t0, rt);
6af0bf9c
FB
1676 opn = "lw";
1677 break;
6af0bf9c 1678 case OPC_LH:
2910c6cb 1679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
78723684 1680 gen_store_gpr(t0, rt);
6af0bf9c
FB
1681 opn = "lh";
1682 break;
6af0bf9c 1683 case OPC_LHU:
2910c6cb 1684 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
78723684 1685 gen_store_gpr(t0, rt);
6af0bf9c
FB
1686 opn = "lhu";
1687 break;
1688 case OPC_LB:
2910c6cb 1689 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
78723684 1690 gen_store_gpr(t0, rt);
6af0bf9c
FB
1691 opn = "lb";
1692 break;
6af0bf9c 1693 case OPC_LBU:
2910c6cb 1694 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
78723684 1695 gen_store_gpr(t0, rt);
6af0bf9c
FB
1696 opn = "lbu";
1697 break;
1698 case OPC_LWL:
3cee3050 1699 t1 = tcg_temp_new();
fc40787a
AJ
1700 tcg_gen_andi_tl(t1, t0, 3);
1701#ifndef TARGET_WORDS_BIGENDIAN
1702 tcg_gen_xori_tl(t1, t1, 3);
1703#endif
1704 tcg_gen_shli_tl(t1, t1, 3);
1705 tcg_gen_andi_tl(t0, t0, ~3);
1706 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1707 tcg_gen_shl_tl(t0, t0, t1);
1708 tcg_gen_xori_tl(t1, t1, 31);
1709 t2 = tcg_const_tl(0x7fffffffull);
1710 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1711 gen_load_gpr(t1, rt);
fc40787a
AJ
1712 tcg_gen_and_tl(t1, t1, t2);
1713 tcg_temp_free(t2);
1714 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1715 tcg_temp_free(t1);
fc40787a
AJ
1716 tcg_gen_ext32s_tl(t0, t0);
1717 gen_store_gpr(t0, rt);
6af0bf9c
FB
1718 opn = "lwl";
1719 break;
6af0bf9c 1720 case OPC_LWR:
3cee3050 1721 t1 = tcg_temp_new();
fc40787a
AJ
1722 tcg_gen_andi_tl(t1, t0, 3);
1723#ifdef TARGET_WORDS_BIGENDIAN
1724 tcg_gen_xori_tl(t1, t1, 3);
1725#endif
1726 tcg_gen_shli_tl(t1, t1, 3);
1727 tcg_gen_andi_tl(t0, t0, ~3);
1728 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1729 tcg_gen_shr_tl(t0, t0, t1);
1730 tcg_gen_xori_tl(t1, t1, 31);
1731 t2 = tcg_const_tl(0xfffffffeull);
1732 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1733 gen_load_gpr(t1, rt);
fc40787a
AJ
1734 tcg_gen_and_tl(t1, t1, t2);
1735 tcg_temp_free(t2);
1736 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1737 tcg_temp_free(t1);
fc40787a 1738 gen_store_gpr(t0, rt);
6af0bf9c
FB
1739 opn = "lwr";
1740 break;
6af0bf9c 1741 case OPC_LL:
e7139c44 1742 save_cpu_state(ctx, 1);
5c13fdfd 1743 op_ld_ll(t0, t0, ctx);
78723684 1744 gen_store_gpr(t0, rt);
6af0bf9c
FB
1745 opn = "ll";
1746 break;
d66c7132 1747 }
2abf314d 1748 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1749 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1750 tcg_temp_free(t0);
d66c7132
AJ
1751}
1752
5c13fdfd
AJ
1753/* Store */
1754static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1755 int base, int16_t offset)
1756{
1757 const char *opn = "st";
1758 TCGv t0 = tcg_temp_new();
1759 TCGv t1 = tcg_temp_new();
1760
1761 gen_base_offset_addr(ctx, t0, base, offset);
1762 gen_load_gpr(t1, rt);
1763 switch (opc) {
1764#if defined(TARGET_MIPS64)
1765 case OPC_SD:
2910c6cb 1766 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1767 opn = "sd";
1768 break;
1769 case OPC_SDL:
1770 save_cpu_state(ctx, 1);
895c2d04 1771 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1772 opn = "sdl";
1773 break;
1774 case OPC_SDR:
1775 save_cpu_state(ctx, 1);
895c2d04 1776 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1777 opn = "sdr";
1778 break;
1779#endif
1780 case OPC_SW:
2910c6cb 1781 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1782 opn = "sw";
1783 break;
1784 case OPC_SH:
2910c6cb 1785 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1786 opn = "sh";
1787 break;
1788 case OPC_SB:
2910c6cb 1789 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1790 opn = "sb";
1791 break;
1792 case OPC_SWL:
1793 save_cpu_state(ctx, 1);
895c2d04 1794 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1795 opn = "swl";
1796 break;
1797 case OPC_SWR:
1798 save_cpu_state(ctx, 1);
895c2d04 1799 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1800 opn = "swr";
1801 break;
1802 }
2abf314d 1803 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1804 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1805 tcg_temp_free(t0);
1806 tcg_temp_free(t1);
1807}
1808
1809
d66c7132
AJ
1810/* Store conditional */
1811static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1812 int base, int16_t offset)
1813{
1814 const char *opn = "st_cond";
1815 TCGv t0, t1;
1816
2d2826b9 1817#ifdef CONFIG_USER_ONLY
d66c7132 1818 t0 = tcg_temp_local_new();
d66c7132 1819 t1 = tcg_temp_local_new();
2d2826b9
AJ
1820#else
1821 t0 = tcg_temp_new();
1822 t1 = tcg_temp_new();
1823#endif
1824 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1825 gen_load_gpr(t1, rt);
1826 switch (opc) {
1827#if defined(TARGET_MIPS64)
1828 case OPC_SCD:
b835e919 1829 save_cpu_state(ctx, 1);
5c13fdfd 1830 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1831 opn = "scd";
1832 break;
1833#endif
6af0bf9c 1834 case OPC_SC:
e7139c44 1835 save_cpu_state(ctx, 1);
5c13fdfd 1836 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1837 opn = "sc";
1838 break;
6af0bf9c 1839 }
2abf314d 1840 (void)opn; /* avoid a compiler warning */
6af0bf9c 1841 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1842 tcg_temp_free(t1);
d66c7132 1843 tcg_temp_free(t0);
6af0bf9c
FB
1844}
1845
6ea83fed 1846/* Load and store */
7a387fff 1847static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1848 int base, int16_t offset)
6ea83fed 1849{
923617a3 1850 const char *opn = "flt_ldst";
4e2474d6 1851 TCGv t0 = tcg_temp_new();
6ea83fed 1852
662d7485 1853 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1854 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1855 memory access. */
6ea83fed
FB
1856 switch (opc) {
1857 case OPC_LWC1:
b6d96bed 1858 {
a7812ae4 1859 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1860
c407df81
AJ
1861 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1862 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 1863 gen_store_fpr32(fp0, ft);
a7812ae4 1864 tcg_temp_free_i32(fp0);
b6d96bed 1865 }
6ea83fed
FB
1866 opn = "lwc1";
1867 break;
1868 case OPC_SWC1:
b6d96bed 1869 {
a7812ae4
PB
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 TCGv t1 = tcg_temp_new();
b6d96bed
TS
1872
1873 gen_load_fpr32(fp0, ft);
a7812ae4
PB
1874 tcg_gen_extu_i32_tl(t1, fp0);
1875 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1876 tcg_temp_free(t1);
1877 tcg_temp_free_i32(fp0);
b6d96bed 1878 }
6ea83fed
FB
1879 opn = "swc1";
1880 break;
1881 case OPC_LDC1:
b6d96bed 1882 {
a7812ae4 1883 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1884
1885 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1886 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1887 tcg_temp_free_i64(fp0);
b6d96bed 1888 }
6ea83fed
FB
1889 opn = "ldc1";
1890 break;
1891 case OPC_SDC1:
b6d96bed 1892 {
a7812ae4 1893 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1894
1895 gen_load_fpr64(ctx, fp0, ft);
1896 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 1897 tcg_temp_free_i64(fp0);
b6d96bed 1898 }
6ea83fed
FB
1899 opn = "sdc1";
1900 break;
1901 default:
923617a3 1902 MIPS_INVAL(opn);
e397ee33 1903 generate_exception(ctx, EXCP_RI);
78723684 1904 goto out;
6ea83fed 1905 }
2abf314d 1906 (void)opn; /* avoid a compiler warning */
6ea83fed 1907 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1908 out:
1909 tcg_temp_free(t0);
6ea83fed 1910}
6ea83fed 1911
7db13fae 1912static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1913 uint32_t op, int rt, int rs, int16_t imm)
1914{
1915 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1916 check_cp1_enabled(ctx);
1917 gen_flt_ldst(ctx, op, rt, rs, imm);
1918 } else {
1919 generate_exception_err(ctx, EXCP_CpU, 1);
1920 }
1921}
1922
6af0bf9c 1923/* Arithmetic with immediate operand */
7db13fae 1924static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
e189e748 1925 int rt, int rs, int16_t imm)
6af0bf9c 1926{
324d9e32 1927 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1928 const char *opn = "imm arith";
6af0bf9c 1929
7a387fff 1930 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1931 /* If no destination, treat it as a NOP.
1932 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1933 MIPS_DEBUG("NOP");
324d9e32 1934 return;
6af0bf9c
FB
1935 }
1936 switch (opc) {
1937 case OPC_ADDI:
48d38ca5 1938 {
324d9e32
AJ
1939 TCGv t0 = tcg_temp_local_new();
1940 TCGv t1 = tcg_temp_new();
1941 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1942 int l1 = gen_new_label();
1943
324d9e32
AJ
1944 gen_load_gpr(t1, rs);
1945 tcg_gen_addi_tl(t0, t1, uimm);
1946 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1947
324d9e32
AJ
1948 tcg_gen_xori_tl(t1, t1, ~uimm);
1949 tcg_gen_xori_tl(t2, t0, uimm);
1950 tcg_gen_and_tl(t1, t1, t2);
1951 tcg_temp_free(t2);
1952 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1953 tcg_temp_free(t1);
48d38ca5
TS
1954 /* operands of same sign, result different sign */
1955 generate_exception(ctx, EXCP_OVERFLOW);
1956 gen_set_label(l1);
78723684 1957 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1958 gen_store_gpr(t0, rt);
1959 tcg_temp_free(t0);
48d38ca5 1960 }
6af0bf9c
FB
1961 opn = "addi";
1962 break;
1963 case OPC_ADDIU:
324d9e32
AJ
1964 if (rs != 0) {
1965 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1966 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1967 } else {
1968 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1969 }
6af0bf9c
FB
1970 opn = "addiu";
1971 break;
d26bc211 1972#if defined(TARGET_MIPS64)
7a387fff 1973 case OPC_DADDI:
48d38ca5 1974 {
324d9e32
AJ
1975 TCGv t0 = tcg_temp_local_new();
1976 TCGv t1 = tcg_temp_new();
1977 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1978 int l1 = gen_new_label();
1979
324d9e32
AJ
1980 gen_load_gpr(t1, rs);
1981 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1982
324d9e32
AJ
1983 tcg_gen_xori_tl(t1, t1, ~uimm);
1984 tcg_gen_xori_tl(t2, t0, uimm);
1985 tcg_gen_and_tl(t1, t1, t2);
1986 tcg_temp_free(t2);
1987 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1988 tcg_temp_free(t1);
48d38ca5
TS
1989 /* operands of same sign, result different sign */
1990 generate_exception(ctx, EXCP_OVERFLOW);
1991 gen_set_label(l1);
324d9e32
AJ
1992 gen_store_gpr(t0, rt);
1993 tcg_temp_free(t0);
48d38ca5 1994 }
7a387fff
TS
1995 opn = "daddi";
1996 break;
1997 case OPC_DADDIU:
324d9e32
AJ
1998 if (rs != 0) {
1999 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2000 } else {
2001 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2002 }
7a387fff
TS
2003 opn = "daddiu";
2004 break;
2005#endif
324d9e32 2006 }
2abf314d 2007 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2008 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2009}
2010
2011/* Logic with immediate operand */
9fa77488
RH
2012static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2013 int rt, int rs, int16_t imm)
324d9e32
AJ
2014{
2015 target_ulong uimm;
2016 const char *opn = "imm logic";
2017
2018 if (rt == 0) {
2019 /* If no destination, treat it as a NOP. */
2020 MIPS_DEBUG("NOP");
2021 return;
2022 }
2023 uimm = (uint16_t)imm;
2024 switch (opc) {
6af0bf9c 2025 case OPC_ANDI:
324d9e32
AJ
2026 if (likely(rs != 0))
2027 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2028 else
2029 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2030 opn = "andi";
2031 break;
2032 case OPC_ORI:
324d9e32
AJ
2033 if (rs != 0)
2034 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2035 else
2036 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2037 opn = "ori";
2038 break;
2039 case OPC_XORI:
324d9e32
AJ
2040 if (likely(rs != 0))
2041 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2042 else
2043 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2044 opn = "xori";
2045 break;
2046 case OPC_LUI:
324d9e32 2047 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
6af0bf9c
FB
2048 opn = "lui";
2049 break;
324d9e32 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}
2054
2055/* Set on less than with immediate operand */
9fa77488
RH
2056static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2057 int rt, int rs, int16_t imm)
324d9e32
AJ
2058{
2059 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2060 const char *opn = "imm arith";
2061 TCGv t0;
2062
2063 if (rt == 0) {
2064 /* If no destination, treat it as a NOP. */
2065 MIPS_DEBUG("NOP");
2066 return;
2067 }
2068 t0 = tcg_temp_new();
2069 gen_load_gpr(t0, rs);
2070 switch (opc) {
2071 case OPC_SLTI:
e68dd28f 2072 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2073 opn = "slti";
2074 break;
2075 case OPC_SLTIU:
e68dd28f 2076 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2077 opn = "sltiu";
2078 break;
2079 }
2abf314d 2080 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2081 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2082 tcg_temp_free(t0);
2083}
2084
2085/* Shifts with immediate operand */
7db13fae 2086static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2087 int rt, int rs, int16_t imm)
2088{
2089 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2090 const char *opn = "imm shift";
2091 TCGv t0;
2092
2093 if (rt == 0) {
2094 /* If no destination, treat it as a NOP. */
2095 MIPS_DEBUG("NOP");
2096 return;
2097 }
2098
2099 t0 = tcg_temp_new();
2100 gen_load_gpr(t0, rs);
2101 switch (opc) {
6af0bf9c 2102 case OPC_SLL:
78723684 2103 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2104 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2105 opn = "sll";
2106 break;
2107 case OPC_SRA:
324d9e32 2108 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2109 opn = "sra";
2110 break;
2111 case OPC_SRL:
ea63e2c3
NF
2112 if (uimm != 0) {
2113 tcg_gen_ext32u_tl(t0, t0);
2114 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2115 } else {
2116 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2117 }
ea63e2c3
NF
2118 opn = "srl";
2119 break;
2120 case OPC_ROTR:
2121 if (uimm != 0) {
2122 TCGv_i32 t1 = tcg_temp_new_i32();
2123
2124 tcg_gen_trunc_tl_i32(t1, t0);
2125 tcg_gen_rotri_i32(t1, t1, uimm);
2126 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2127 tcg_temp_free_i32(t1);
3399e30f
NF
2128 } else {
2129 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2130 }
2131 opn = "rotr";
7a387fff 2132 break;
d26bc211 2133#if defined(TARGET_MIPS64)
7a387fff 2134 case OPC_DSLL:
324d9e32 2135 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2136 opn = "dsll";
2137 break;
2138 case OPC_DSRA:
324d9e32 2139 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2140 opn = "dsra";
2141 break;
2142 case OPC_DSRL:
ea63e2c3
NF
2143 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2144 opn = "dsrl";
2145 break;
2146 case OPC_DROTR:
2147 if (uimm != 0) {
2148 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2149 } else {
2150 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2151 }
ea63e2c3 2152 opn = "drotr";
7a387fff
TS
2153 break;
2154 case OPC_DSLL32:
324d9e32 2155 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2156 opn = "dsll32";
2157 break;
2158 case OPC_DSRA32:
324d9e32 2159 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2160 opn = "dsra32";
2161 break;
2162 case OPC_DSRL32:
ea63e2c3
NF
2163 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2164 opn = "dsrl32";
2165 break;
2166 case OPC_DROTR32:
2167 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2168 opn = "drotr32";
6af0bf9c 2169 break;
7a387fff 2170#endif
6af0bf9c 2171 }
2abf314d 2172 (void)opn; /* avoid a compiler warning */
93b12ccc 2173 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2174 tcg_temp_free(t0);
6af0bf9c
FB
2175}
2176
2177/* Arithmetic */
7db13fae 2178static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2179 int rd, int rs, int rt)
2180{
923617a3 2181 const char *opn = "arith";
6af0bf9c 2182
7a387fff
TS
2183 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2184 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2185 /* If no destination, treat it as a NOP.
2186 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2187 MIPS_DEBUG("NOP");
460f00c4 2188 return;
185f0762 2189 }
460f00c4 2190
6af0bf9c
FB
2191 switch (opc) {
2192 case OPC_ADD:
48d38ca5 2193 {
460f00c4
AJ
2194 TCGv t0 = tcg_temp_local_new();
2195 TCGv t1 = tcg_temp_new();
2196 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2197 int l1 = gen_new_label();
2198
460f00c4
AJ
2199 gen_load_gpr(t1, rs);
2200 gen_load_gpr(t2, rt);
2201 tcg_gen_add_tl(t0, t1, t2);
2202 tcg_gen_ext32s_tl(t0, t0);
2203 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2204 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2205 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2206 tcg_temp_free(t2);
2207 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2208 tcg_temp_free(t1);
48d38ca5
TS
2209 /* operands of same sign, result different sign */
2210 generate_exception(ctx, EXCP_OVERFLOW);
2211 gen_set_label(l1);
460f00c4
AJ
2212 gen_store_gpr(t0, rd);
2213 tcg_temp_free(t0);
48d38ca5 2214 }
6af0bf9c
FB
2215 opn = "add";
2216 break;
2217 case OPC_ADDU:
460f00c4
AJ
2218 if (rs != 0 && rt != 0) {
2219 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2220 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2221 } else if (rs == 0 && rt != 0) {
2222 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2223 } else if (rs != 0 && rt == 0) {
2224 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2225 } else {
2226 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2227 }
6af0bf9c
FB
2228 opn = "addu";
2229 break;
2230 case OPC_SUB:
48d38ca5 2231 {
460f00c4
AJ
2232 TCGv t0 = tcg_temp_local_new();
2233 TCGv t1 = tcg_temp_new();
2234 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2235 int l1 = gen_new_label();
2236
460f00c4
AJ
2237 gen_load_gpr(t1, rs);
2238 gen_load_gpr(t2, rt);
2239 tcg_gen_sub_tl(t0, t1, t2);
2240 tcg_gen_ext32s_tl(t0, t0);
2241 tcg_gen_xor_tl(t2, t1, t2);
2242 tcg_gen_xor_tl(t1, t0, t1);
2243 tcg_gen_and_tl(t1, t1, t2);
2244 tcg_temp_free(t2);
2245 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2246 tcg_temp_free(t1);
31e3104f 2247 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2248 generate_exception(ctx, EXCP_OVERFLOW);
2249 gen_set_label(l1);
460f00c4
AJ
2250 gen_store_gpr(t0, rd);
2251 tcg_temp_free(t0);
48d38ca5 2252 }
6af0bf9c
FB
2253 opn = "sub";
2254 break;
2255 case OPC_SUBU:
460f00c4
AJ
2256 if (rs != 0 && rt != 0) {
2257 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2258 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2259 } else if (rs == 0 && rt != 0) {
2260 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2261 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2262 } else if (rs != 0 && rt == 0) {
2263 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2264 } else {
2265 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2266 }
6af0bf9c
FB
2267 opn = "subu";
2268 break;
d26bc211 2269#if defined(TARGET_MIPS64)
7a387fff 2270 case OPC_DADD:
48d38ca5 2271 {
460f00c4
AJ
2272 TCGv t0 = tcg_temp_local_new();
2273 TCGv t1 = tcg_temp_new();
2274 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2275 int l1 = gen_new_label();
2276
460f00c4
AJ
2277 gen_load_gpr(t1, rs);
2278 gen_load_gpr(t2, rt);
2279 tcg_gen_add_tl(t0, t1, t2);
2280 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2281 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2282 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2283 tcg_temp_free(t2);
2284 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2285 tcg_temp_free(t1);
48d38ca5
TS
2286 /* operands of same sign, result different sign */
2287 generate_exception(ctx, EXCP_OVERFLOW);
2288 gen_set_label(l1);
460f00c4
AJ
2289 gen_store_gpr(t0, rd);
2290 tcg_temp_free(t0);
48d38ca5 2291 }
7a387fff
TS
2292 opn = "dadd";
2293 break;
2294 case OPC_DADDU:
460f00c4
AJ
2295 if (rs != 0 && rt != 0) {
2296 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2297 } else if (rs == 0 && rt != 0) {
2298 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2299 } else if (rs != 0 && rt == 0) {
2300 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2301 } else {
2302 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2303 }
7a387fff
TS
2304 opn = "daddu";
2305 break;
2306 case OPC_DSUB:
48d38ca5 2307 {
460f00c4
AJ
2308 TCGv t0 = tcg_temp_local_new();
2309 TCGv t1 = tcg_temp_new();
2310 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2311 int l1 = gen_new_label();
2312
460f00c4
AJ
2313 gen_load_gpr(t1, rs);
2314 gen_load_gpr(t2, rt);
2315 tcg_gen_sub_tl(t0, t1, t2);
2316 tcg_gen_xor_tl(t2, t1, t2);
2317 tcg_gen_xor_tl(t1, t0, t1);
2318 tcg_gen_and_tl(t1, t1, t2);
2319 tcg_temp_free(t2);
2320 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2321 tcg_temp_free(t1);
31e3104f 2322 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2323 generate_exception(ctx, EXCP_OVERFLOW);
2324 gen_set_label(l1);
460f00c4
AJ
2325 gen_store_gpr(t0, rd);
2326 tcg_temp_free(t0);
48d38ca5 2327 }
7a387fff
TS
2328 opn = "dsub";
2329 break;
2330 case OPC_DSUBU:
460f00c4
AJ
2331 if (rs != 0 && rt != 0) {
2332 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2333 } else if (rs == 0 && rt != 0) {
2334 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2335 } else if (rs != 0 && rt == 0) {
2336 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2337 } else {
2338 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2339 }
7a387fff
TS
2340 opn = "dsubu";
2341 break;
2342#endif
460f00c4
AJ
2343 case OPC_MUL:
2344 if (likely(rs != 0 && rt != 0)) {
2345 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2346 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2347 } else {
2348 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2349 }
2350 opn = "mul";
6af0bf9c 2351 break;
460f00c4 2352 }
2abf314d 2353 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2354 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2355}
2356
2357/* Conditional move */
9fa77488
RH
2358static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2359 int rd, int rs, int rt)
460f00c4
AJ
2360{
2361 const char *opn = "cond move";
acf12465 2362 TCGv t0, t1, t2;
460f00c4
AJ
2363
2364 if (rd == 0) {
acf12465 2365 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2366 MIPS_DEBUG("NOP");
2367 return;
2368 }
2369
acf12465
AJ
2370 t0 = tcg_temp_new();
2371 gen_load_gpr(t0, rt);
2372 t1 = tcg_const_tl(0);
2373 t2 = tcg_temp_new();
2374 gen_load_gpr(t2, rs);
460f00c4
AJ
2375 switch (opc) {
2376 case OPC_MOVN:
acf12465 2377 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2378 opn = "movn";
6af0bf9c 2379 break;
460f00c4 2380 case OPC_MOVZ:
acf12465 2381 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2382 opn = "movz";
2383 break;
2384 }
acf12465
AJ
2385 tcg_temp_free(t2);
2386 tcg_temp_free(t1);
2387 tcg_temp_free(t0);
460f00c4 2388
2abf314d 2389 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2390 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2391}
2392
2393/* Logic */
9fa77488
RH
2394static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2395 int rd, int rs, int rt)
460f00c4
AJ
2396{
2397 const char *opn = "logic";
2398
2399 if (rd == 0) {
2400 /* If no destination, treat it as a NOP. */
2401 MIPS_DEBUG("NOP");
2402 return;
2403 }
2404
2405 switch (opc) {
6af0bf9c 2406 case OPC_AND:
460f00c4
AJ
2407 if (likely(rs != 0 && rt != 0)) {
2408 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2409 } else {
2410 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2411 }
6af0bf9c
FB
2412 opn = "and";
2413 break;
2414 case OPC_NOR:
460f00c4
AJ
2415 if (rs != 0 && rt != 0) {
2416 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2417 } else if (rs == 0 && rt != 0) {
2418 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2419 } else if (rs != 0 && rt == 0) {
2420 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2421 } else {
2422 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2423 }
6af0bf9c
FB
2424 opn = "nor";
2425 break;
2426 case OPC_OR:
460f00c4
AJ
2427 if (likely(rs != 0 && rt != 0)) {
2428 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2429 } else if (rs == 0 && rt != 0) {
2430 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2431 } else if (rs != 0 && rt == 0) {
2432 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2433 } else {
2434 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2435 }
6af0bf9c
FB
2436 opn = "or";
2437 break;
2438 case OPC_XOR:
460f00c4
AJ
2439 if (likely(rs != 0 && rt != 0)) {
2440 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2441 } else if (rs == 0 && rt != 0) {
2442 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2443 } else if (rs != 0 && rt == 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2445 } else {
2446 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2447 }
6af0bf9c
FB
2448 opn = "xor";
2449 break;
460f00c4 2450 }
2abf314d 2451 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2452 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2453}
2454
2455/* Set on lower than */
9fa77488
RH
2456static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2457 int rd, int rs, int rt)
460f00c4
AJ
2458{
2459 const char *opn = "slt";
2460 TCGv t0, t1;
2461
2462 if (rd == 0) {
2463 /* If no destination, treat it as a NOP. */
2464 MIPS_DEBUG("NOP");
2465 return;
2466 }
2467
2468 t0 = tcg_temp_new();
2469 t1 = tcg_temp_new();
2470 gen_load_gpr(t0, rs);
2471 gen_load_gpr(t1, rt);
2472 switch (opc) {
2473 case OPC_SLT:
e68dd28f 2474 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2475 opn = "slt";
6af0bf9c 2476 break;
460f00c4 2477 case OPC_SLTU:
e68dd28f 2478 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2479 opn = "sltu";
2480 break;
2481 }
2abf314d 2482 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2483 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2484 tcg_temp_free(t0);
2485 tcg_temp_free(t1);
2486}
20c4c97c 2487
460f00c4 2488/* Shifts */
7db13fae 2489static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
460f00c4
AJ
2490 int rd, int rs, int rt)
2491{
2492 const char *opn = "shifts";
2493 TCGv t0, t1;
20c4c97c 2494
460f00c4
AJ
2495 if (rd == 0) {
2496 /* If no destination, treat it as a NOP.
2497 For add & sub, we must generate the overflow exception when needed. */
2498 MIPS_DEBUG("NOP");
2499 return;
2500 }
2501
2502 t0 = tcg_temp_new();
2503 t1 = tcg_temp_new();
2504 gen_load_gpr(t0, rs);
2505 gen_load_gpr(t1, rt);
2506 switch (opc) {
6af0bf9c 2507 case OPC_SLLV:
78723684
TS
2508 tcg_gen_andi_tl(t0, t0, 0x1f);
2509 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2510 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2511 opn = "sllv";
2512 break;
2513 case OPC_SRAV:
78723684 2514 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2515 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2516 opn = "srav";
2517 break;
2518 case OPC_SRLV:
ea63e2c3
NF
2519 tcg_gen_ext32u_tl(t1, t1);
2520 tcg_gen_andi_tl(t0, t0, 0x1f);
2521 tcg_gen_shr_tl(t0, t1, t0);
2522 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2523 opn = "srlv";
2524 break;
2525 case OPC_ROTRV:
2526 {
2527 TCGv_i32 t2 = tcg_temp_new_i32();
2528 TCGv_i32 t3 = tcg_temp_new_i32();
2529
2530 tcg_gen_trunc_tl_i32(t2, t0);
2531 tcg_gen_trunc_tl_i32(t3, t1);
2532 tcg_gen_andi_i32(t2, t2, 0x1f);
2533 tcg_gen_rotr_i32(t2, t3, t2);
2534 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2535 tcg_temp_free_i32(t2);
2536 tcg_temp_free_i32(t3);
2537 opn = "rotrv";
5a63bcb2 2538 }
7a387fff 2539 break;
d26bc211 2540#if defined(TARGET_MIPS64)
7a387fff 2541 case OPC_DSLLV:
78723684 2542 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2543 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2544 opn = "dsllv";
2545 break;
2546 case OPC_DSRAV:
78723684 2547 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2548 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2549 opn = "dsrav";
2550 break;
2551 case OPC_DSRLV:
ea63e2c3
NF
2552 tcg_gen_andi_tl(t0, t0, 0x3f);
2553 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2554 opn = "dsrlv";
2555 break;
2556 case OPC_DROTRV:
2557 tcg_gen_andi_tl(t0, t0, 0x3f);
2558 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2559 opn = "drotrv";
6af0bf9c 2560 break;
7a387fff 2561#endif
6af0bf9c 2562 }
2abf314d 2563 (void)opn; /* avoid a compiler warning */
6af0bf9c 2564 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2565 tcg_temp_free(t0);
2566 tcg_temp_free(t1);
6af0bf9c
FB
2567}
2568
2569/* Arithmetic on HI/LO registers */
7a387fff 2570static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
6af0bf9c 2571{
923617a3 2572 const char *opn = "hilo";
4133498f 2573 unsigned int acc;
6af0bf9c
FB
2574
2575 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2576 /* Treat as NOP. */
6af0bf9c 2577 MIPS_DEBUG("NOP");
a1f6684d 2578 return;
6af0bf9c 2579 }
4133498f
JL
2580
2581 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2582 acc = ((ctx->opcode) >> 21) & 0x03;
2583 } else {
2584 acc = ((ctx->opcode) >> 11) & 0x03;
2585 }
2586
2587 if (acc != 0) {
2588 check_dsp(ctx);
2589 }
2590
6af0bf9c
FB
2591 switch (opc) {
2592 case OPC_MFHI:
4133498f
JL
2593#if defined(TARGET_MIPS64)
2594 if (acc != 0) {
2595 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2596 } else
2597#endif
2598 {
2599 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2600 }
6af0bf9c
FB
2601 opn = "mfhi";
2602 break;
2603 case OPC_MFLO:
4133498f
JL
2604#if defined(TARGET_MIPS64)
2605 if (acc != 0) {
2606 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2607 } else
2608#endif
2609 {
2610 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2611 }
6af0bf9c
FB
2612 opn = "mflo";
2613 break;
2614 case OPC_MTHI:
4133498f
JL
2615 if (reg != 0) {
2616#if defined(TARGET_MIPS64)
2617 if (acc != 0) {
2618 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2619 } else
2620#endif
2621 {
2622 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2623 }
2624 } else {
2625 tcg_gen_movi_tl(cpu_HI[acc], 0);
2626 }
6af0bf9c
FB
2627 opn = "mthi";
2628 break;
2629 case OPC_MTLO:
4133498f
JL
2630 if (reg != 0) {
2631#if defined(TARGET_MIPS64)
2632 if (acc != 0) {
2633 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2634 } else
2635#endif
2636 {
2637 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2638 }
2639 } else {
2640 tcg_gen_movi_tl(cpu_LO[acc], 0);
2641 }
6af0bf9c
FB
2642 opn = "mtlo";
2643 break;
6af0bf9c 2644 }
2abf314d 2645 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2646 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2647}
2648
7a387fff 2649static void gen_muldiv (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2650 int rs, int rt)
2651{
923617a3 2652 const char *opn = "mul/div";
d45f89f4 2653 TCGv t0, t1;
4133498f 2654 unsigned int acc;
d45f89f4
AJ
2655
2656 switch (opc) {
2657 case OPC_DIV:
2658 case OPC_DIVU:
2659#if defined(TARGET_MIPS64)
2660 case OPC_DDIV:
2661 case OPC_DDIVU:
2662#endif
2663 t0 = tcg_temp_local_new();
2664 t1 = tcg_temp_local_new();
2665 break;
2666 default:
2667 t0 = tcg_temp_new();
2668 t1 = tcg_temp_new();
2669 break;
2670 }
6af0bf9c 2671
78723684
TS
2672 gen_load_gpr(t0, rs);
2673 gen_load_gpr(t1, rt);
6af0bf9c
FB
2674 switch (opc) {
2675 case OPC_DIV:
48d38ca5
TS
2676 {
2677 int l1 = gen_new_label();
d45f89f4 2678 int l2 = gen_new_label();
48d38ca5 2679
d45f89f4
AJ
2680 tcg_gen_ext32s_tl(t0, t0);
2681 tcg_gen_ext32s_tl(t1, t1);
78723684 2682 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
d45f89f4
AJ
2683 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2684 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2685
2686 tcg_gen_mov_tl(cpu_LO[0], t0);
2687 tcg_gen_movi_tl(cpu_HI[0], 0);
2688 tcg_gen_br(l1);
2689 gen_set_label(l2);
2690 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2691 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2692 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2693 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
48d38ca5
TS
2694 gen_set_label(l1);
2695 }
6af0bf9c
FB
2696 opn = "div";
2697 break;
2698 case OPC_DIVU:
48d38ca5
TS
2699 {
2700 int l1 = gen_new_label();
2701
0c0ed03b
AJ
2702 tcg_gen_ext32u_tl(t0, t0);
2703 tcg_gen_ext32u_tl(t1, t1);
78723684 2704 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
d45f89f4
AJ
2705 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2706 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2707 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2708 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
48d38ca5
TS
2709 gen_set_label(l1);
2710 }
6af0bf9c
FB
2711 opn = "divu";
2712 break;
2713 case OPC_MULT:
214c465f 2714 {
d45f89f4
AJ
2715 TCGv_i64 t2 = tcg_temp_new_i64();
2716 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2717 acc = ((ctx->opcode) >> 11) & 0x03;
2718 if (acc != 0) {
2719 check_dsp(ctx);
2720 }
d45f89f4
AJ
2721
2722 tcg_gen_ext_tl_i64(t2, t0);
2723 tcg_gen_ext_tl_i64(t3, t1);
2724 tcg_gen_mul_i64(t2, t2, t3);
2725 tcg_temp_free_i64(t3);
2726 tcg_gen_trunc_i64_tl(t0, t2);
2727 tcg_gen_shri_i64(t2, t2, 32);
2728 tcg_gen_trunc_i64_tl(t1, t2);
2729 tcg_temp_free_i64(t2);
4133498f
JL
2730 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2731 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2732 }
6af0bf9c
FB
2733 opn = "mult";
2734 break;
2735 case OPC_MULTU:
214c465f 2736 {
d45f89f4
AJ
2737 TCGv_i64 t2 = tcg_temp_new_i64();
2738 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2739 acc = ((ctx->opcode) >> 11) & 0x03;
2740 if (acc != 0) {
2741 check_dsp(ctx);
2742 }
214c465f 2743
78723684
TS
2744 tcg_gen_ext32u_tl(t0, t0);
2745 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2746 tcg_gen_extu_tl_i64(t2, t0);
2747 tcg_gen_extu_tl_i64(t3, t1);
2748 tcg_gen_mul_i64(t2, t2, t3);
2749 tcg_temp_free_i64(t3);
2750 tcg_gen_trunc_i64_tl(t0, t2);
2751 tcg_gen_shri_i64(t2, t2, 32);
2752 tcg_gen_trunc_i64_tl(t1, t2);
2753 tcg_temp_free_i64(t2);
4133498f
JL
2754 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2755 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2756 }
6af0bf9c
FB
2757 opn = "multu";
2758 break;
d26bc211 2759#if defined(TARGET_MIPS64)
7a387fff 2760 case OPC_DDIV:
48d38ca5
TS
2761 {
2762 int l1 = gen_new_label();
d45f89f4 2763 int l2 = gen_new_label();
48d38ca5 2764
78723684 2765 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
d45f89f4
AJ
2766 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2767 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2768 tcg_gen_mov_tl(cpu_LO[0], t0);
2769 tcg_gen_movi_tl(cpu_HI[0], 0);
2770 tcg_gen_br(l1);
2771 gen_set_label(l2);
2772 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2773 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
48d38ca5
TS
2774 gen_set_label(l1);
2775 }
7a387fff
TS
2776 opn = "ddiv";
2777 break;
2778 case OPC_DDIVU:
48d38ca5
TS
2779 {
2780 int l1 = gen_new_label();
2781
78723684 2782 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
b10fa3c9
AJ
2783 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2784 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
48d38ca5
TS
2785 gen_set_label(l1);
2786 }
7a387fff
TS
2787 opn = "ddivu";
2788 break;
2789 case OPC_DMULT:
895c2d04 2790 gen_helper_dmult(cpu_env, t0, t1);
7a387fff
TS
2791 opn = "dmult";
2792 break;
2793 case OPC_DMULTU:
895c2d04 2794 gen_helper_dmultu(cpu_env, t0, t1);
7a387fff
TS
2795 opn = "dmultu";
2796 break;
2797#endif
6af0bf9c 2798 case OPC_MADD:
214c465f 2799 {
d45f89f4
AJ
2800 TCGv_i64 t2 = tcg_temp_new_i64();
2801 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2802 acc = ((ctx->opcode) >> 11) & 0x03;
2803 if (acc != 0) {
2804 check_dsp(ctx);
2805 }
d45f89f4
AJ
2806
2807 tcg_gen_ext_tl_i64(t2, t0);
2808 tcg_gen_ext_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 = "madd";
2821 break;
2822 case OPC_MADDU:
4133498f 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 }
214c465f 2830
78723684
TS
2831 tcg_gen_ext32u_tl(t0, t0);
2832 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2833 tcg_gen_extu_tl_i64(t2, t0);
2834 tcg_gen_extu_tl_i64(t3, t1);
2835 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2836 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2837 tcg_gen_add_i64(t2, t2, t3);
2838 tcg_temp_free_i64(t3);
2839 tcg_gen_trunc_i64_tl(t0, t2);
2840 tcg_gen_shri_i64(t2, t2, 32);
2841 tcg_gen_trunc_i64_tl(t1, t2);
2842 tcg_temp_free_i64(t2);
4133498f
JL
2843 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2844 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2845 }
6af0bf9c
FB
2846 opn = "maddu";
2847 break;
2848 case OPC_MSUB:
214c465f 2849 {
d45f89f4
AJ
2850 TCGv_i64 t2 = tcg_temp_new_i64();
2851 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2852 acc = ((ctx->opcode) >> 11) & 0x03;
2853 if (acc != 0) {
2854 check_dsp(ctx);
2855 }
d45f89f4
AJ
2856
2857 tcg_gen_ext_tl_i64(t2, t0);
2858 tcg_gen_ext_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 = "msub";
2871 break;
2872 case OPC_MSUBU:
214c465f 2873 {
d45f89f4
AJ
2874 TCGv_i64 t2 = tcg_temp_new_i64();
2875 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2876 acc = ((ctx->opcode) >> 11) & 0x03;
2877 if (acc != 0) {
2878 check_dsp(ctx);
2879 }
214c465f 2880
78723684
TS
2881 tcg_gen_ext32u_tl(t0, t0);
2882 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2883 tcg_gen_extu_tl_i64(t2, t0);
2884 tcg_gen_extu_tl_i64(t3, t1);
2885 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2886 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2887 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2888 tcg_temp_free_i64(t3);
2889 tcg_gen_trunc_i64_tl(t0, t2);
2890 tcg_gen_shri_i64(t2, t2, 32);
2891 tcg_gen_trunc_i64_tl(t1, t2);
2892 tcg_temp_free_i64(t2);
4133498f
JL
2893 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2894 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2895 }
6af0bf9c
FB
2896 opn = "msubu";
2897 break;
2898 default:
923617a3 2899 MIPS_INVAL(opn);
6af0bf9c 2900 generate_exception(ctx, EXCP_RI);
78723684 2901 goto out;
6af0bf9c 2902 }
2abf314d 2903 (void)opn; /* avoid a compiler warning */
6af0bf9c 2904 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2905 out:
2906 tcg_temp_free(t0);
2907 tcg_temp_free(t1);
6af0bf9c
FB
2908}
2909
e9c71dd1
TS
2910static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2911 int rd, int rs, int rt)
2912{
2913 const char *opn = "mul vr54xx";
f157bfe1
AJ
2914 TCGv t0 = tcg_temp_new();
2915 TCGv t1 = tcg_temp_new();
e9c71dd1 2916
6c5c1e20
TS
2917 gen_load_gpr(t0, rs);
2918 gen_load_gpr(t1, rt);
e9c71dd1
TS
2919
2920 switch (opc) {
2921 case OPC_VR54XX_MULS:
895c2d04 2922 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2923 opn = "muls";
6958549d 2924 break;
e9c71dd1 2925 case OPC_VR54XX_MULSU:
895c2d04 2926 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2927 opn = "mulsu";
6958549d 2928 break;
e9c71dd1 2929 case OPC_VR54XX_MACC:
895c2d04 2930 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2931 opn = "macc";
6958549d 2932 break;
e9c71dd1 2933 case OPC_VR54XX_MACCU:
895c2d04 2934 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2935 opn = "maccu";
6958549d 2936 break;
e9c71dd1 2937 case OPC_VR54XX_MSAC:
895c2d04 2938 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2939 opn = "msac";
6958549d 2940 break;
e9c71dd1 2941 case OPC_VR54XX_MSACU:
895c2d04 2942 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2943 opn = "msacu";
6958549d 2944 break;
e9c71dd1 2945 case OPC_VR54XX_MULHI:
895c2d04 2946 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2947 opn = "mulhi";
6958549d 2948 break;
e9c71dd1 2949 case OPC_VR54XX_MULHIU:
895c2d04 2950 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2951 opn = "mulhiu";
6958549d 2952 break;
e9c71dd1 2953 case OPC_VR54XX_MULSHI:
895c2d04 2954 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2955 opn = "mulshi";
6958549d 2956 break;
e9c71dd1 2957 case OPC_VR54XX_MULSHIU:
895c2d04 2958 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2959 opn = "mulshiu";
6958549d 2960 break;
e9c71dd1 2961 case OPC_VR54XX_MACCHI:
895c2d04 2962 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2963 opn = "macchi";
6958549d 2964 break;
e9c71dd1 2965 case OPC_VR54XX_MACCHIU:
895c2d04 2966 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2967 opn = "macchiu";
6958549d 2968 break;
e9c71dd1 2969 case OPC_VR54XX_MSACHI:
895c2d04 2970 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2971 opn = "msachi";
6958549d 2972 break;
e9c71dd1 2973 case OPC_VR54XX_MSACHIU:
895c2d04 2974 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2975 opn = "msachiu";
6958549d 2976 break;
e9c71dd1
TS
2977 default:
2978 MIPS_INVAL("mul vr54xx");
2979 generate_exception(ctx, EXCP_RI);
6c5c1e20 2980 goto out;
e9c71dd1 2981 }
6c5c1e20 2982 gen_store_gpr(t0, rd);
2abf314d 2983 (void)opn; /* avoid a compiler warning */
e9c71dd1 2984 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2985
2986 out:
2987 tcg_temp_free(t0);
2988 tcg_temp_free(t1);
e9c71dd1
TS
2989}
2990
7a387fff 2991static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2992 int rd, int rs)
2993{
923617a3 2994 const char *opn = "CLx";
20e1fb52 2995 TCGv t0;
6c5c1e20 2996
6af0bf9c 2997 if (rd == 0) {
ead9360e 2998 /* Treat as NOP. */
6af0bf9c 2999 MIPS_DEBUG("NOP");
20e1fb52 3000 return;
6af0bf9c 3001 }
20e1fb52 3002 t0 = tcg_temp_new();
6c5c1e20 3003 gen_load_gpr(t0, rs);
6af0bf9c
FB
3004 switch (opc) {
3005 case OPC_CLO:
20e1fb52 3006 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3007 opn = "clo";
3008 break;
3009 case OPC_CLZ:
20e1fb52 3010 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3011 opn = "clz";
3012 break;
d26bc211 3013#if defined(TARGET_MIPS64)
7a387fff 3014 case OPC_DCLO:
20e1fb52 3015 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3016 opn = "dclo";
3017 break;
3018 case OPC_DCLZ:
20e1fb52 3019 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3020 opn = "dclz";
3021 break;
3022#endif
6af0bf9c 3023 }
2abf314d 3024 (void)opn; /* avoid a compiler warning */
6af0bf9c 3025 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3026 tcg_temp_free(t0);
6af0bf9c
FB
3027}
3028
161f85e6 3029/* Godson integer instructions */
bd277fa1
RH
3030static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3031 int rd, int rs, int rt)
161f85e6
AJ
3032{
3033 const char *opn = "loongson";
3034 TCGv t0, t1;
3035
3036 if (rd == 0) {
3037 /* Treat as NOP. */
3038 MIPS_DEBUG("NOP");
3039 return;
3040 }
3041
3042 switch (opc) {
3043 case OPC_MULT_G_2E:
3044 case OPC_MULT_G_2F:
3045 case OPC_MULTU_G_2E:
3046 case OPC_MULTU_G_2F:
3047#if defined(TARGET_MIPS64)
3048 case OPC_DMULT_G_2E:
3049 case OPC_DMULT_G_2F:
3050 case OPC_DMULTU_G_2E:
3051 case OPC_DMULTU_G_2F:
3052#endif
3053 t0 = tcg_temp_new();
3054 t1 = tcg_temp_new();
3055 break;
3056 default:
3057 t0 = tcg_temp_local_new();
3058 t1 = tcg_temp_local_new();
3059 break;
3060 }
3061
3062 gen_load_gpr(t0, rs);
3063 gen_load_gpr(t1, rt);
3064
3065 switch (opc) {
3066 case OPC_MULT_G_2E:
3067 case OPC_MULT_G_2F:
3068 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3069 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3070 opn = "mult.g";
3071 break;
3072 case OPC_MULTU_G_2E:
3073 case OPC_MULTU_G_2F:
3074 tcg_gen_ext32u_tl(t0, t0);
3075 tcg_gen_ext32u_tl(t1, t1);
3076 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3077 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3078 opn = "multu.g";
3079 break;
3080 case OPC_DIV_G_2E:
3081 case OPC_DIV_G_2F:
3082 {
3083 int l1 = gen_new_label();
3084 int l2 = gen_new_label();
3085 int l3 = gen_new_label();
3086 tcg_gen_ext32s_tl(t0, t0);
3087 tcg_gen_ext32s_tl(t1, t1);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3089 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3090 tcg_gen_br(l3);
3091 gen_set_label(l1);
3092 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3093 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3094 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3095 tcg_gen_br(l3);
3096 gen_set_label(l2);
3097 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3098 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3099 gen_set_label(l3);
3100 }
3101 opn = "div.g";
3102 break;
3103 case OPC_DIVU_G_2E:
3104 case OPC_DIVU_G_2F:
3105 {
3106 int l1 = gen_new_label();
3107 int l2 = gen_new_label();
3108 tcg_gen_ext32u_tl(t0, t0);
3109 tcg_gen_ext32u_tl(t1, t1);
3110 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3111 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3112 tcg_gen_br(l2);
3113 gen_set_label(l1);
3114 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3115 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3116 gen_set_label(l2);
3117 }
3118 opn = "divu.g";
3119 break;
3120 case OPC_MOD_G_2E:
3121 case OPC_MOD_G_2F:
3122 {
3123 int l1 = gen_new_label();
3124 int l2 = gen_new_label();
3125 int l3 = gen_new_label();
3126 tcg_gen_ext32u_tl(t0, t0);
3127 tcg_gen_ext32u_tl(t1, t1);
3128 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3129 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3130 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3131 gen_set_label(l1);
3132 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3133 tcg_gen_br(l3);
3134 gen_set_label(l2);
3135 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3136 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3137 gen_set_label(l3);
3138 }
3139 opn = "mod.g";
3140 break;
3141 case OPC_MODU_G_2E:
3142 case OPC_MODU_G_2F:
3143 {
3144 int l1 = gen_new_label();
3145 int l2 = gen_new_label();
3146 tcg_gen_ext32u_tl(t0, t0);
3147 tcg_gen_ext32u_tl(t1, t1);
3148 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3149 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3150 tcg_gen_br(l2);
3151 gen_set_label(l1);
3152 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3153 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3154 gen_set_label(l2);
3155 }
3156 opn = "modu.g";
3157 break;
3158#if defined(TARGET_MIPS64)
3159 case OPC_DMULT_G_2E:
3160 case OPC_DMULT_G_2F:
3161 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3162 opn = "dmult.g";
3163 break;
3164 case OPC_DMULTU_G_2E:
3165 case OPC_DMULTU_G_2F:
3166 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3167 opn = "dmultu.g";
3168 break;
3169 case OPC_DDIV_G_2E:
3170 case OPC_DDIV_G_2F:
3171 {
3172 int l1 = gen_new_label();
3173 int l2 = gen_new_label();
3174 int l3 = gen_new_label();
3175 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3176 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3177 tcg_gen_br(l3);
3178 gen_set_label(l1);
3179 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3180 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3181 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3182 tcg_gen_br(l3);
3183 gen_set_label(l2);
3184 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3185 gen_set_label(l3);
3186 }
3187 opn = "ddiv.g";
3188 break;
3189 case OPC_DDIVU_G_2E:
3190 case OPC_DDIVU_G_2F:
3191 {
3192 int l1 = gen_new_label();
3193 int l2 = gen_new_label();
3194 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3195 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3196 tcg_gen_br(l2);
3197 gen_set_label(l1);
3198 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3199 gen_set_label(l2);
3200 }
3201 opn = "ddivu.g";
3202 break;
3203 case OPC_DMOD_G_2E:
3204 case OPC_DMOD_G_2F:
3205 {
3206 int l1 = gen_new_label();
3207 int l2 = gen_new_label();
3208 int l3 = gen_new_label();
3209 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3210 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3211 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3212 gen_set_label(l1);
3213 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3214 tcg_gen_br(l3);
3215 gen_set_label(l2);
3216 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3217 gen_set_label(l3);
3218 }
3219 opn = "dmod.g";
3220 break;
3221 case OPC_DMODU_G_2E:
3222 case OPC_DMODU_G_2F:
3223 {
3224 int l1 = gen_new_label();
3225 int l2 = gen_new_label();
3226 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3227 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3228 tcg_gen_br(l2);
3229 gen_set_label(l1);
3230 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3231 gen_set_label(l2);
3232 }
3233 opn = "dmodu.g";
3234 break;
3235#endif
3236 }
3237
2abf314d 3238 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3239 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3240 tcg_temp_free(t0);
3241 tcg_temp_free(t1);
3242}
3243
bd277fa1
RH
3244/* Loongson multimedia instructions */
3245static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3246{
3247 const char *opn = "loongson_cp2";
3248 uint32_t opc, shift_max;
3249 TCGv_i64 t0, t1;
3250
3251 opc = MASK_LMI(ctx->opcode);
3252 switch (opc) {
3253 case OPC_ADD_CP2:
3254 case OPC_SUB_CP2:
3255 case OPC_DADD_CP2:
3256 case OPC_DSUB_CP2:
3257 t0 = tcg_temp_local_new_i64();
3258 t1 = tcg_temp_local_new_i64();
3259 break;
3260 default:
3261 t0 = tcg_temp_new_i64();
3262 t1 = tcg_temp_new_i64();
3263 break;
3264 }
3265
3266 gen_load_fpr64(ctx, t0, rs);
3267 gen_load_fpr64(ctx, t1, rt);
3268
3269#define LMI_HELPER(UP, LO) \
3270 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3271#define LMI_HELPER_1(UP, LO) \
3272 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3273#define LMI_DIRECT(UP, LO, OP) \
3274 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3275
3276 switch (opc) {
3277 LMI_HELPER(PADDSH, paddsh);
3278 LMI_HELPER(PADDUSH, paddush);
3279 LMI_HELPER(PADDH, paddh);
3280 LMI_HELPER(PADDW, paddw);
3281 LMI_HELPER(PADDSB, paddsb);
3282 LMI_HELPER(PADDUSB, paddusb);
3283 LMI_HELPER(PADDB, paddb);
3284
3285 LMI_HELPER(PSUBSH, psubsh);
3286 LMI_HELPER(PSUBUSH, psubush);
3287 LMI_HELPER(PSUBH, psubh);
3288 LMI_HELPER(PSUBW, psubw);
3289 LMI_HELPER(PSUBSB, psubsb);
3290 LMI_HELPER(PSUBUSB, psubusb);
3291 LMI_HELPER(PSUBB, psubb);
3292
3293 LMI_HELPER(PSHUFH, pshufh);
3294 LMI_HELPER(PACKSSWH, packsswh);
3295 LMI_HELPER(PACKSSHB, packsshb);
3296 LMI_HELPER(PACKUSHB, packushb);
3297
3298 LMI_HELPER(PUNPCKLHW, punpcklhw);
3299 LMI_HELPER(PUNPCKHHW, punpckhhw);
3300 LMI_HELPER(PUNPCKLBH, punpcklbh);
3301 LMI_HELPER(PUNPCKHBH, punpckhbh);
3302 LMI_HELPER(PUNPCKLWD, punpcklwd);
3303 LMI_HELPER(PUNPCKHWD, punpckhwd);
3304
3305 LMI_HELPER(PAVGH, pavgh);
3306 LMI_HELPER(PAVGB, pavgb);
3307 LMI_HELPER(PMAXSH, pmaxsh);
3308 LMI_HELPER(PMINSH, pminsh);
3309 LMI_HELPER(PMAXUB, pmaxub);
3310 LMI_HELPER(PMINUB, pminub);
3311
3312 LMI_HELPER(PCMPEQW, pcmpeqw);
3313 LMI_HELPER(PCMPGTW, pcmpgtw);
3314 LMI_HELPER(PCMPEQH, pcmpeqh);
3315 LMI_HELPER(PCMPGTH, pcmpgth);
3316 LMI_HELPER(PCMPEQB, pcmpeqb);
3317 LMI_HELPER(PCMPGTB, pcmpgtb);
3318
3319 LMI_HELPER(PSLLW, psllw);
3320 LMI_HELPER(PSLLH, psllh);
3321 LMI_HELPER(PSRLW, psrlw);
3322 LMI_HELPER(PSRLH, psrlh);
3323 LMI_HELPER(PSRAW, psraw);
3324 LMI_HELPER(PSRAH, psrah);
3325
3326 LMI_HELPER(PMULLH, pmullh);
3327 LMI_HELPER(PMULHH, pmulhh);
3328 LMI_HELPER(PMULHUH, pmulhuh);
3329 LMI_HELPER(PMADDHW, pmaddhw);
3330
3331 LMI_HELPER(PASUBUB, pasubub);
3332 LMI_HELPER_1(BIADD, biadd);
3333 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3334
3335 LMI_DIRECT(PADDD, paddd, add);
3336 LMI_DIRECT(PSUBD, psubd, sub);
3337 LMI_DIRECT(XOR_CP2, xor, xor);
3338 LMI_DIRECT(NOR_CP2, nor, nor);
3339 LMI_DIRECT(AND_CP2, and, and);
3340 LMI_DIRECT(PANDN, pandn, andc);
3341 LMI_DIRECT(OR, or, or);
3342
3343 case OPC_PINSRH_0:
3344 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3345 opn = "pinsrh_0";
3346 break;
3347 case OPC_PINSRH_1:
3348 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3349 opn = "pinsrh_1";
3350 break;
3351 case OPC_PINSRH_2:
3352 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3353 opn = "pinsrh_2";
3354 break;
3355 case OPC_PINSRH_3:
3356 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3357 opn = "pinsrh_3";
3358 break;
3359
3360 case OPC_PEXTRH:
3361 tcg_gen_andi_i64(t1, t1, 3);
3362 tcg_gen_shli_i64(t1, t1, 4);
3363 tcg_gen_shr_i64(t0, t0, t1);
3364 tcg_gen_ext16u_i64(t0, t0);
3365 opn = "pextrh";
3366 break;
3367
3368 case OPC_ADDU_CP2:
3369 tcg_gen_add_i64(t0, t0, t1);
3370 tcg_gen_ext32s_i64(t0, t0);
3371 opn = "addu";
3372 break;
3373 case OPC_SUBU_CP2:
3374 tcg_gen_sub_i64(t0, t0, t1);
3375 tcg_gen_ext32s_i64(t0, t0);
3376 opn = "addu";
3377 break;
3378
3379 case OPC_SLL_CP2:
3380 opn = "sll";
3381 shift_max = 32;
3382 goto do_shift;
3383 case OPC_SRL_CP2:
3384 opn = "srl";
3385 shift_max = 32;
3386 goto do_shift;
3387 case OPC_SRA_CP2:
3388 opn = "sra";
3389 shift_max = 32;
3390 goto do_shift;
3391 case OPC_DSLL_CP2:
3392 opn = "dsll";
3393 shift_max = 64;
3394 goto do_shift;
3395 case OPC_DSRL_CP2:
3396 opn = "dsrl";
3397 shift_max = 64;
3398 goto do_shift;
3399 case OPC_DSRA_CP2:
3400 opn = "dsra";
3401 shift_max = 64;
3402 goto do_shift;
3403 do_shift:
3404 /* Make sure shift count isn't TCG undefined behaviour. */
3405 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3406
3407 switch (opc) {
3408 case OPC_SLL_CP2:
3409 case OPC_DSLL_CP2:
3410 tcg_gen_shl_i64(t0, t0, t1);
3411 break;
3412 case OPC_SRA_CP2:
3413 case OPC_DSRA_CP2:
3414 /* Since SRA is UndefinedResult without sign-extended inputs,
3415 we can treat SRA and DSRA the same. */
3416 tcg_gen_sar_i64(t0, t0, t1);
3417 break;
3418 case OPC_SRL_CP2:
3419 /* We want to shift in zeros for SRL; zero-extend first. */
3420 tcg_gen_ext32u_i64(t0, t0);
3421 /* FALLTHRU */
3422 case OPC_DSRL_CP2:
3423 tcg_gen_shr_i64(t0, t0, t1);
3424 break;
3425 }
3426
3427 if (shift_max == 32) {
3428 tcg_gen_ext32s_i64(t0, t0);
3429 }
3430
3431 /* Shifts larger than MAX produce zero. */
3432 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3433 tcg_gen_neg_i64(t1, t1);
3434 tcg_gen_and_i64(t0, t0, t1);
3435 break;
3436
3437 case OPC_ADD_CP2:
3438 case OPC_DADD_CP2:
3439 {
3440 TCGv_i64 t2 = tcg_temp_new_i64();
3441 int lab = gen_new_label();
3442
3443 tcg_gen_mov_i64(t2, t0);
3444 tcg_gen_add_i64(t0, t1, t2);
3445 if (opc == OPC_ADD_CP2) {
3446 tcg_gen_ext32s_i64(t0, t0);
3447 }
3448 tcg_gen_xor_i64(t1, t1, t2);
3449 tcg_gen_xor_i64(t2, t2, t0);
3450 tcg_gen_andc_i64(t1, t2, t1);
3451 tcg_temp_free_i64(t2);
3452 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3453 generate_exception(ctx, EXCP_OVERFLOW);
3454 gen_set_label(lab);
3455
3456 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3457 break;
3458 }
3459
3460 case OPC_SUB_CP2:
3461 case OPC_DSUB_CP2:
3462 {
3463 TCGv_i64 t2 = tcg_temp_new_i64();
3464 int lab = gen_new_label();
3465
3466 tcg_gen_mov_i64(t2, t0);
3467 tcg_gen_sub_i64(t0, t1, t2);
3468 if (opc == OPC_SUB_CP2) {
3469 tcg_gen_ext32s_i64(t0, t0);
3470 }
3471 tcg_gen_xor_i64(t1, t1, t2);
3472 tcg_gen_xor_i64(t2, t2, t0);
3473 tcg_gen_and_i64(t1, t1, t2);
3474 tcg_temp_free_i64(t2);
3475 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3476 generate_exception(ctx, EXCP_OVERFLOW);
3477 gen_set_label(lab);
3478
3479 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3480 break;
3481 }
3482
3483 case OPC_PMULUW:
3484 tcg_gen_ext32u_i64(t0, t0);
3485 tcg_gen_ext32u_i64(t1, t1);
3486 tcg_gen_mul_i64(t0, t0, t1);
3487 opn = "pmuluw";
3488 break;
3489
3490 case OPC_SEQU_CP2:
3491 case OPC_SEQ_CP2:
3492 case OPC_SLTU_CP2:
3493 case OPC_SLT_CP2:
3494 case OPC_SLEU_CP2:
3495 case OPC_SLE_CP2:
3496 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3497 FD field is the CC field? */
3498 default:
3499 MIPS_INVAL(opn);
3500 generate_exception(ctx, EXCP_RI);
3501 return;
3502 }
3503
3504#undef LMI_HELPER
3505#undef LMI_DIRECT
3506
3507 gen_store_fpr64(ctx, t0, rd);
3508
3509 (void)opn; /* avoid a compiler warning */
3510 MIPS_DEBUG("%s %s, %s, %s", opn,
3511 fregnames[rd], fregnames[rs], fregnames[rt]);
3512 tcg_temp_free_i64(t0);
3513 tcg_temp_free_i64(t1);
3514}
3515
6af0bf9c 3516/* Traps */
7a387fff 3517static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3518 int rs, int rt, int16_t imm)
3519{
3520 int cond;
cdc0faa6 3521 TCGv t0 = tcg_temp_new();
1ba74fb8 3522 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3523
3524 cond = 0;
3525 /* Load needed operands */
3526 switch (opc) {
3527 case OPC_TEQ:
3528 case OPC_TGE:
3529 case OPC_TGEU:
3530 case OPC_TLT:
3531 case OPC_TLTU:
3532 case OPC_TNE:
3533 /* Compare two registers */
3534 if (rs != rt) {
be24bb4f
TS
3535 gen_load_gpr(t0, rs);
3536 gen_load_gpr(t1, rt);
6af0bf9c
FB
3537 cond = 1;
3538 }
179e32bb 3539 break;
6af0bf9c
FB
3540 case OPC_TEQI:
3541 case OPC_TGEI:
3542 case OPC_TGEIU:
3543 case OPC_TLTI:
3544 case OPC_TLTIU:
3545 case OPC_TNEI:
3546 /* Compare register to immediate */
3547 if (rs != 0 || imm != 0) {
be24bb4f
TS
3548 gen_load_gpr(t0, rs);
3549 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3550 cond = 1;
3551 }
3552 break;
3553 }
3554 if (cond == 0) {
3555 switch (opc) {
3556 case OPC_TEQ: /* rs == rs */
3557 case OPC_TEQI: /* r0 == 0 */
3558 case OPC_TGE: /* rs >= rs */
3559 case OPC_TGEI: /* r0 >= 0 */
3560 case OPC_TGEU: /* rs >= rs unsigned */
3561 case OPC_TGEIU: /* r0 >= 0 unsigned */
3562 /* Always trap */
cdc0faa6 3563 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3564 break;
3565 case OPC_TLT: /* rs < rs */
3566 case OPC_TLTI: /* r0 < 0 */
3567 case OPC_TLTU: /* rs < rs unsigned */
3568 case OPC_TLTIU: /* r0 < 0 unsigned */
3569 case OPC_TNE: /* rs != rs */
3570 case OPC_TNEI: /* r0 != 0 */
ead9360e 3571 /* Never trap: treat as NOP. */
cdc0faa6 3572 break;
6af0bf9c
FB
3573 }
3574 } else {
cdc0faa6
AJ
3575 int l1 = gen_new_label();
3576
6af0bf9c
FB
3577 switch (opc) {
3578 case OPC_TEQ:
3579 case OPC_TEQI:
cdc0faa6 3580 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3581 break;
3582 case OPC_TGE:
3583 case OPC_TGEI:
cdc0faa6 3584 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3585 break;
3586 case OPC_TGEU:
3587 case OPC_TGEIU:
cdc0faa6 3588 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3589 break;
3590 case OPC_TLT:
3591 case OPC_TLTI:
cdc0faa6 3592 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3593 break;
3594 case OPC_TLTU:
3595 case OPC_TLTIU:
cdc0faa6 3596 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3597 break;
3598 case OPC_TNE:
3599 case OPC_TNEI:
cdc0faa6 3600 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3601 break;
6af0bf9c 3602 }
cdc0faa6 3603 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3604 gen_set_label(l1);
3605 }
be24bb4f
TS
3606 tcg_temp_free(t0);
3607 tcg_temp_free(t1);
6af0bf9c
FB
3608}
3609
356265ae 3610static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3611{
6e256c93
FB
3612 TranslationBlock *tb;
3613 tb = ctx->tb;
7b270ef2
NF
3614 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3615 likely(!ctx->singlestep_enabled)) {
57fec1fe 3616 tcg_gen_goto_tb(n);
9b9e4393 3617 gen_save_pc(dest);
4b4a72e5 3618 tcg_gen_exit_tb((tcg_target_long)tb + n);
6e256c93 3619 } else {
9b9e4393 3620 gen_save_pc(dest);
7b270ef2
NF
3621 if (ctx->singlestep_enabled) {
3622 save_cpu_state(ctx, 0);
895c2d04 3623 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3624 }
57fec1fe 3625 tcg_gen_exit_tb(0);
6e256c93 3626 }
c53be334
FB
3627}
3628
6af0bf9c 3629/* Branches (before delay slot) */
7a387fff 3630static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3631 int insn_bytes,
6af0bf9c
FB
3632 int rs, int rt, int32_t offset)
3633{
d077b6f7 3634 target_ulong btgt = -1;
3ad4bb2d 3635 int blink = 0;
2fdbad25 3636 int bcond_compute = 0;
1ba74fb8
AJ
3637 TCGv t0 = tcg_temp_new();
3638 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3639
3640 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3641#ifdef MIPS_DEBUG_DISAS
d12d51d5 3642 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3643#endif
3ad4bb2d 3644 generate_exception(ctx, EXCP_RI);
6c5c1e20 3645 goto out;
3ad4bb2d 3646 }
6af0bf9c 3647
6af0bf9c
FB
3648 /* Load needed operands */
3649 switch (opc) {
3650 case OPC_BEQ:
3651 case OPC_BEQL:
3652 case OPC_BNE:
3653 case OPC_BNEL:
3654 /* Compare two registers */
3655 if (rs != rt) {
6c5c1e20
TS
3656 gen_load_gpr(t0, rs);
3657 gen_load_gpr(t1, rt);
2fdbad25 3658 bcond_compute = 1;
6af0bf9c 3659 }
7dca4ad0 3660 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3661 break;
3662 case OPC_BGEZ:
3663 case OPC_BGEZAL:
3c824109 3664 case OPC_BGEZALS:
6af0bf9c
FB
3665 case OPC_BGEZALL:
3666 case OPC_BGEZL:
3667 case OPC_BGTZ:
3668 case OPC_BGTZL:
3669 case OPC_BLEZ:
3670 case OPC_BLEZL:
3671 case OPC_BLTZ:
3672 case OPC_BLTZAL:
3c824109 3673 case OPC_BLTZALS:
6af0bf9c
FB
3674 case OPC_BLTZALL:
3675 case OPC_BLTZL:
3676 /* Compare to zero */
3677 if (rs != 0) {
6c5c1e20 3678 gen_load_gpr(t0, rs);
2fdbad25 3679 bcond_compute = 1;
6af0bf9c 3680 }
7dca4ad0 3681 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3682 break;
e45a93e2
JL
3683 case OPC_BPOSGE32:
3684#if defined(TARGET_MIPS64)
3685 case OPC_BPOSGE64:
3686 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3687#else
3688 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3689#endif
3690 bcond_compute = 1;
3691 btgt = ctx->pc + insn_bytes + offset;
3692 break;
6af0bf9c
FB
3693 case OPC_J:
3694 case OPC_JAL:
364d4831 3695 case OPC_JALX:
620e48f6
NF
3696 case OPC_JALS:
3697 case OPC_JALXS:
6af0bf9c 3698 /* Jump to immediate */
7dca4ad0 3699 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3700 break;
3701 case OPC_JR:
3702 case OPC_JALR:
364d4831 3703 case OPC_JALRC:
620e48f6 3704 case OPC_JALRS:
6af0bf9c 3705 /* Jump to register */
7a387fff
TS
3706 if (offset != 0 && offset != 16) {
3707 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3708 others are reserved. */
923617a3 3709 MIPS_INVAL("jump hint");
6af0bf9c 3710 generate_exception(ctx, EXCP_RI);
6c5c1e20 3711 goto out;
6af0bf9c 3712 }
d077b6f7 3713 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3714 break;
3715 default:
3716 MIPS_INVAL("branch/jump");
3717 generate_exception(ctx, EXCP_RI);
6c5c1e20 3718 goto out;
6af0bf9c 3719 }
2fdbad25 3720 if (bcond_compute == 0) {
6af0bf9c
FB
3721 /* No condition to be computed */
3722 switch (opc) {
3723 case OPC_BEQ: /* rx == rx */
3724 case OPC_BEQL: /* rx == rx likely */
3725 case OPC_BGEZ: /* 0 >= 0 */
3726 case OPC_BGEZL: /* 0 >= 0 likely */
3727 case OPC_BLEZ: /* 0 <= 0 */
3728 case OPC_BLEZL: /* 0 <= 0 likely */
3729 /* Always take */
4ad40f36 3730 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3731 MIPS_DEBUG("balways");
3732 break;
3c824109 3733 case OPC_BGEZALS:
6af0bf9c
FB
3734 case OPC_BGEZAL: /* 0 >= 0 */
3735 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3736 ctx->hflags |= (opc == OPC_BGEZALS
3737 ? MIPS_HFLAG_BDS16
3738 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3739 /* Always take and link */
3740 blink = 31;
4ad40f36 3741 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3742 MIPS_DEBUG("balways and link");
3743 break;
3744 case OPC_BNE: /* rx != rx */
3745 case OPC_BGTZ: /* 0 > 0 */
3746 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3747 /* Treat as NOP. */
6af0bf9c 3748 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3749 goto out;
3c824109 3750 case OPC_BLTZALS:
eeef26cd 3751 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3752 ctx->hflags |= (opc == OPC_BLTZALS
3753 ? MIPS_HFLAG_BDS16
3754 : MIPS_HFLAG_BDS32);
3755 /* Handle as an unconditional branch to get correct delay
3756 slot checking. */
3757 blink = 31;
3758 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3759 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3760 MIPS_DEBUG("bnever and link");
3c824109 3761 break;
eeef26cd 3762 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3763 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3764 /* Skip the instruction in the delay slot */
3765 MIPS_DEBUG("bnever, link and skip");
3766 ctx->pc += 4;
6c5c1e20 3767 goto out;
6af0bf9c
FB
3768 case OPC_BNEL: /* rx != rx likely */
3769 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3770 case OPC_BLTZL: /* 0 < 0 likely */
3771 /* Skip the instruction in the delay slot */
3772 MIPS_DEBUG("bnever and skip");
9898128f 3773 ctx->pc += 4;
6c5c1e20 3774 goto out;
6af0bf9c 3775 case OPC_J:
4ad40f36 3776 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3777 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3778 break;
620e48f6 3779 case OPC_JALXS:
364d4831
NF
3780 case OPC_JALX:
3781 ctx->hflags |= MIPS_HFLAG_BX;
3782 /* Fallthrough */
620e48f6 3783 case OPC_JALS:
6af0bf9c
FB
3784 case OPC_JAL:
3785 blink = 31;
4ad40f36 3786 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3787 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3788 ? MIPS_HFLAG_BDS16
3789 : MIPS_HFLAG_BDS32);
d077b6f7 3790 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3791 break;
3792 case OPC_JR:
4ad40f36 3793 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3794 if (insn_bytes == 4)
3795 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3796 MIPS_DEBUG("jr %s", regnames[rs]);
3797 break;
620e48f6 3798 case OPC_JALRS:
6af0bf9c 3799 case OPC_JALR:
364d4831 3800 case OPC_JALRC:
6af0bf9c 3801 blink = rt;
4ad40f36 3802 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3803 ctx->hflags |= (opc == OPC_JALRS
3804 ? MIPS_HFLAG_BDS16
3805 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3806 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3807 break;
3808 default:
3809 MIPS_INVAL("branch/jump");
3810 generate_exception(ctx, EXCP_RI);
6c5c1e20 3811 goto out;
6af0bf9c
FB
3812 }
3813 } else {
3814 switch (opc) {
3815 case OPC_BEQ:
e68dd28f 3816 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3817 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3818 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3819 goto not_likely;
3820 case OPC_BEQL:
e68dd28f 3821 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3822 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3823 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3824 goto likely;
3825 case OPC_BNE:
e68dd28f 3826 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3827 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3828 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3829 goto not_likely;
3830 case OPC_BNEL:
e68dd28f 3831 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3832 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3833 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3834 goto likely;
3835 case OPC_BGEZ:
e68dd28f 3836 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3837 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3838 goto not_likely;
3839 case OPC_BGEZL:
e68dd28f 3840 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3841 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3842 goto likely;
3c824109 3843 case OPC_BGEZALS:
6af0bf9c 3844 case OPC_BGEZAL:
3c824109
NF
3845 ctx->hflags |= (opc == OPC_BGEZALS
3846 ? MIPS_HFLAG_BDS16
3847 : MIPS_HFLAG_BDS32);
e68dd28f 3848 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3849 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3850 blink = 31;
3851 goto not_likely;
3852 case OPC_BGEZALL:
e68dd28f 3853 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3854 blink = 31;
d077b6f7 3855 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3856 goto likely;
3857 case OPC_BGTZ:
e68dd28f 3858 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3859 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3860 goto not_likely;
3861 case OPC_BGTZL:
e68dd28f 3862 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3863 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3864 goto likely;
3865 case OPC_BLEZ:
e68dd28f 3866 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3867 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3868 goto not_likely;
3869 case OPC_BLEZL:
e68dd28f 3870 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3871 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3872 goto likely;
3873 case OPC_BLTZ:
e68dd28f 3874 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3875 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3876 goto not_likely;
3877 case OPC_BLTZL:
e68dd28f 3878 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3879 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3880 goto likely;
e45a93e2
JL
3881 case OPC_BPOSGE32:
3882 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3883 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3884 goto not_likely;
3885#if defined(TARGET_MIPS64)
3886 case OPC_BPOSGE64:
3887 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3888 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3889 goto not_likely;
3890#endif
3c824109 3891 case OPC_BLTZALS:
6af0bf9c 3892 case OPC_BLTZAL:
3c824109
NF
3893 ctx->hflags |= (opc == OPC_BLTZALS
3894 ? MIPS_HFLAG_BDS16
3895 : MIPS_HFLAG_BDS32);
e68dd28f 3896 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3897 blink = 31;
d077b6f7 3898 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3899 not_likely:
4ad40f36 3900 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3901 break;
3902 case OPC_BLTZALL:
e68dd28f 3903 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3904 blink = 31;
d077b6f7 3905 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3906 likely:
4ad40f36 3907 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3908 break;
c53f4a62
TS
3909 default:
3910 MIPS_INVAL("conditional branch/jump");
3911 generate_exception(ctx, EXCP_RI);
6c5c1e20 3912 goto out;
6af0bf9c 3913 }
6af0bf9c 3914 }
923617a3 3915 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3916 blink, ctx->hflags, btgt);
9b9e4393 3917
d077b6f7 3918 ctx->btarget = btgt;
6af0bf9c 3919 if (blink > 0) {
364d4831
NF
3920 int post_delay = insn_bytes;
3921 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3922
3923 if (opc != OPC_JALRC)
3924 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3925
3926 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3927 }
6c5c1e20
TS
3928
3929 out:
364d4831
NF
3930 if (insn_bytes == 2)
3931 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3932 tcg_temp_free(t0);
3933 tcg_temp_free(t1);
6af0bf9c
FB
3934}
3935
7a387fff
TS
3936/* special3 bitfield operations */
3937static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3938 int rs, int lsb, int msb)
7a387fff 3939{
a7812ae4
PB
3940 TCGv t0 = tcg_temp_new();
3941 TCGv t1 = tcg_temp_new();
505ad7c2 3942 target_ulong mask;
6c5c1e20
TS
3943
3944 gen_load_gpr(t1, rs);
7a387fff
TS
3945 switch (opc) {
3946 case OPC_EXT:
3947 if (lsb + msb > 31)
3948 goto fail;
505ad7c2
AJ
3949 tcg_gen_shri_tl(t0, t1, lsb);
3950 if (msb != 31) {
3951 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3952 } else {
3953 tcg_gen_ext32s_tl(t0, t0);
3954 }
7a387fff 3955 break;
c6d6dd7c 3956#if defined(TARGET_MIPS64)
7a387fff 3957 case OPC_DEXTM:
505ad7c2
AJ
3958 tcg_gen_shri_tl(t0, t1, lsb);
3959 if (msb != 31) {
3960 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3961 }
7a387fff
TS
3962 break;
3963 case OPC_DEXTU:
505ad7c2
AJ
3964 tcg_gen_shri_tl(t0, t1, lsb + 32);
3965 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3966 break;
3967 case OPC_DEXT:
505ad7c2
AJ
3968 tcg_gen_shri_tl(t0, t1, lsb);
3969 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3970 break;
c6d6dd7c 3971#endif
7a387fff
TS
3972 case OPC_INS:
3973 if (lsb > msb)
3974 goto fail;
505ad7c2 3975 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
6c5c1e20 3976 gen_load_gpr(t0, rt);
505ad7c2
AJ
3977 tcg_gen_andi_tl(t0, t0, ~mask);
3978 tcg_gen_shli_tl(t1, t1, lsb);
3979 tcg_gen_andi_tl(t1, t1, mask);
3980 tcg_gen_or_tl(t0, t0, t1);
3981 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3982 break;
c6d6dd7c 3983#if defined(TARGET_MIPS64)
7a387fff
TS
3984 case OPC_DINSM:
3985 if (lsb > msb)
3986 goto fail;
505ad7c2 3987 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
6c5c1e20 3988 gen_load_gpr(t0, rt);
505ad7c2
AJ
3989 tcg_gen_andi_tl(t0, t0, ~mask);
3990 tcg_gen_shli_tl(t1, t1, lsb);
3991 tcg_gen_andi_tl(t1, t1, mask);
3992 tcg_gen_or_tl(t0, t0, t1);
7a387fff
TS
3993 break;
3994 case OPC_DINSU:
3995 if (lsb > msb)
3996 goto fail;
6fbab869 3997 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
6c5c1e20 3998 gen_load_gpr(t0, rt);
505ad7c2
AJ
3999 tcg_gen_andi_tl(t0, t0, ~mask);
4000 tcg_gen_shli_tl(t1, t1, lsb + 32);
4001 tcg_gen_andi_tl(t1, t1, mask);
4002 tcg_gen_or_tl(t0, t0, t1);
7a387fff
TS
4003 break;
4004 case OPC_DINS:
4005 if (lsb > msb)
4006 goto fail;
6c5c1e20 4007 gen_load_gpr(t0, rt);
505ad7c2
AJ
4008 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
4009 gen_load_gpr(t0, rt);
4010 tcg_gen_andi_tl(t0, t0, ~mask);
4011 tcg_gen_shli_tl(t1, t1, lsb);
4012 tcg_gen_andi_tl(t1, t1, mask);
4013 tcg_gen_or_tl(t0, t0, t1);
7a387fff 4014 break;
c6d6dd7c 4015#endif
7a387fff
TS
4016 default:
4017fail:
4018 MIPS_INVAL("bitops");
4019 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4020 tcg_temp_free(t0);
4021 tcg_temp_free(t1);
7a387fff
TS
4022 return;
4023 }
6c5c1e20
TS
4024 gen_store_gpr(t0, rt);
4025 tcg_temp_free(t0);
4026 tcg_temp_free(t1);
7a387fff
TS
4027}
4028
49bcf33c
AJ
4029static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4030{
3a55fa47 4031 TCGv t0;
49bcf33c 4032
3a55fa47
AJ
4033 if (rd == 0) {
4034 /* If no destination, treat it as a NOP. */
4035 MIPS_DEBUG("NOP");
4036 return;
4037 }
4038
4039 t0 = tcg_temp_new();
4040 gen_load_gpr(t0, rt);
49bcf33c
AJ
4041 switch (op2) {
4042 case OPC_WSBH:
3a55fa47
AJ
4043 {
4044 TCGv t1 = tcg_temp_new();
4045
4046 tcg_gen_shri_tl(t1, t0, 8);
4047 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4048 tcg_gen_shli_tl(t0, t0, 8);
4049 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4050 tcg_gen_or_tl(t0, t0, t1);
4051 tcg_temp_free(t1);
4052 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4053 }
49bcf33c
AJ
4054 break;
4055 case OPC_SEB:
3a55fa47 4056 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4057 break;
4058 case OPC_SEH:
3a55fa47 4059 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4060 break;
4061#if defined(TARGET_MIPS64)
4062 case OPC_DSBH:
3a55fa47
AJ
4063 {
4064 TCGv t1 = tcg_temp_new();
4065
4066 tcg_gen_shri_tl(t1, t0, 8);
4067 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4068 tcg_gen_shli_tl(t0, t0, 8);
4069 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4070 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4071 tcg_temp_free(t1);
4072 }
49bcf33c
AJ
4073 break;
4074 case OPC_DSHD:
3a55fa47
AJ
4075 {
4076 TCGv t1 = tcg_temp_new();
4077
4078 tcg_gen_shri_tl(t1, t0, 16);
4079 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4080 tcg_gen_shli_tl(t0, t0, 16);
4081 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4082 tcg_gen_or_tl(t0, t0, t1);
4083 tcg_gen_shri_tl(t1, t0, 32);
4084 tcg_gen_shli_tl(t0, t0, 32);
4085 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4086 tcg_temp_free(t1);
4087 }
49bcf33c
AJ
4088 break;
4089#endif
4090 default:
4091 MIPS_INVAL("bsfhl");
4092 generate_exception(ctx, EXCP_RI);
4093 tcg_temp_free(t0);
49bcf33c
AJ
4094 return;
4095 }
49bcf33c 4096 tcg_temp_free(t0);
49bcf33c
AJ
4097}
4098
f1aa6320 4099#ifndef CONFIG_USER_ONLY
0eaef5aa 4100/* CP0 (MMU and control) */
d9bea114 4101static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4102{
d9bea114 4103 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4104
d9bea114
AJ
4105 tcg_gen_ld_i32(t0, cpu_env, off);
4106 tcg_gen_ext_i32_tl(arg, t0);
4107 tcg_temp_free_i32(t0);
4f57689a
TS
4108}
4109
d9bea114 4110static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4111{
d9bea114
AJ
4112 tcg_gen_ld_tl(arg, cpu_env, off);
4113 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4114}
4115
d9bea114 4116static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4117{
d9bea114 4118 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4119
d9bea114
AJ
4120 tcg_gen_trunc_tl_i32(t0, arg);
4121 tcg_gen_st_i32(t0, cpu_env, off);
4122 tcg_temp_free_i32(t0);
f1aa6320
TS
4123}
4124
d9bea114 4125static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4126{
d9bea114
AJ
4127 tcg_gen_ext32s_tl(arg, arg);
4128 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4129}
4130
7db13fae 4131static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4132{
7a387fff 4133 const char *rn = "invalid";
873eb012 4134
e189e748
TS
4135 if (sel != 0)
4136 check_insn(env, ctx, ISA_MIPS32);
4137
873eb012
TS
4138 switch (reg) {
4139 case 0:
7a387fff
TS
4140 switch (sel) {
4141 case 0:
7db13fae 4142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4143 rn = "Index";
4144 break;
4145 case 1:
7385ac0b 4146 check_insn(env, ctx, ASE_MT);
895c2d04 4147 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4148 rn = "MVPControl";
ead9360e 4149 break;
7a387fff 4150 case 2:
7385ac0b 4151 check_insn(env, ctx, ASE_MT);
895c2d04 4152 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4153 rn = "MVPConf0";
ead9360e 4154 break;
7a387fff 4155 case 3:
7385ac0b 4156 check_insn(env, ctx, ASE_MT);
895c2d04 4157 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4158 rn = "MVPConf1";
ead9360e 4159 break;
7a387fff
TS
4160 default:
4161 goto die;
4162 }
873eb012
TS
4163 break;
4164 case 1:
7a387fff
TS
4165 switch (sel) {
4166 case 0:
895c2d04 4167 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4168 rn = "Random";
2423f660 4169 break;
7a387fff 4170 case 1:
7385ac0b 4171 check_insn(env, ctx, ASE_MT);
7db13fae 4172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4173 rn = "VPEControl";
ead9360e 4174 break;
7a387fff 4175 case 2:
7385ac0b 4176 check_insn(env, ctx, ASE_MT);
7db13fae 4177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4178 rn = "VPEConf0";
ead9360e 4179 break;
7a387fff 4180 case 3:
7385ac0b 4181 check_insn(env, ctx, ASE_MT);
7db13fae 4182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4183 rn = "VPEConf1";
ead9360e 4184 break;
7a387fff 4185 case 4:
7385ac0b 4186 check_insn(env, ctx, ASE_MT);
7db13fae 4187 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4188 rn = "YQMask";
ead9360e 4189 break;
7a387fff 4190 case 5:
7385ac0b 4191 check_insn(env, ctx, ASE_MT);
7db13fae 4192 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4193 rn = "VPESchedule";
ead9360e 4194 break;
7a387fff 4195 case 6:
7385ac0b 4196 check_insn(env, ctx, ASE_MT);
7db13fae 4197 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4198 rn = "VPEScheFBack";
ead9360e 4199 break;
7a387fff 4200 case 7:
7385ac0b 4201 check_insn(env, ctx, ASE_MT);
7db13fae 4202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4203 rn = "VPEOpt";
ead9360e 4204 break;
7a387fff
TS
4205 default:
4206 goto die;
4207 }
873eb012
TS
4208 break;
4209 case 2:
7a387fff
TS
4210 switch (sel) {
4211 case 0:
7db13fae 4212 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4213 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4214 rn = "EntryLo0";
4215 break;
7a387fff 4216 case 1:
7385ac0b 4217 check_insn(env, ctx, ASE_MT);
895c2d04 4218 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4219 rn = "TCStatus";
ead9360e 4220 break;
7a387fff 4221 case 2:
7385ac0b 4222 check_insn(env, ctx, ASE_MT);
895c2d04 4223 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4224 rn = "TCBind";
ead9360e 4225 break;
7a387fff 4226 case 3:
7385ac0b 4227 check_insn(env, ctx, ASE_MT);
895c2d04 4228 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4229 rn = "TCRestart";
ead9360e 4230 break;
7a387fff 4231 case 4:
7385ac0b 4232 check_insn(env, ctx, ASE_MT);
895c2d04 4233 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4234 rn = "TCHalt";
ead9360e 4235 break;
7a387fff 4236 case 5:
7385ac0b 4237 check_insn(env, ctx, ASE_MT);
895c2d04 4238 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4239 rn = "TCContext";
ead9360e 4240 break;
7a387fff 4241 case 6:
7385ac0b 4242 check_insn(env, ctx, ASE_MT);
895c2d04 4243 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4244 rn = "TCSchedule";
ead9360e 4245 break;
7a387fff 4246 case 7:
7385ac0b 4247 check_insn(env, ctx, ASE_MT);
895c2d04 4248 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4249 rn = "TCScheFBack";
ead9360e 4250 break;
7a387fff
TS
4251 default:
4252 goto die;
4253 }
873eb012
TS
4254 break;
4255 case 3:
7a387fff
TS
4256 switch (sel) {
4257 case 0:
7db13fae 4258 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4259 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4260 rn = "EntryLo1";
4261 break;
7a387fff
TS
4262 default:
4263 goto die;
1579a72e 4264 }
873eb012
TS
4265 break;
4266 case 4:
7a387fff
TS
4267 switch (sel) {
4268 case 0:
7db13fae 4269 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4270 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4271 rn = "Context";
4272 break;
7a387fff 4273 case 1:
d9bea114 4274// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4275 rn = "ContextConfig";
4276// break;
7a387fff
TS
4277 default:
4278 goto die;
1579a72e 4279 }
873eb012
TS
4280 break;
4281 case 5:
7a387fff
TS
4282 switch (sel) {
4283 case 0:
7db13fae 4284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4285 rn = "PageMask";
4286 break;
7a387fff 4287 case 1:
e189e748 4288 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4289 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4290 rn = "PageGrain";
4291 break;
7a387fff
TS
4292 default:
4293 goto die;
1579a72e 4294 }
873eb012
TS
4295 break;
4296 case 6:
7a387fff
TS
4297 switch (sel) {
4298 case 0:
7db13fae 4299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4300 rn = "Wired";
4301 break;
7a387fff 4302 case 1:
e189e748 4303 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4305 rn = "SRSConf0";
ead9360e 4306 break;
7a387fff 4307 case 2:
e189e748 4308 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4309 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4310 rn = "SRSConf1";
ead9360e 4311 break;
7a387fff 4312 case 3:
e189e748 4313 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4315 rn = "SRSConf2";
ead9360e 4316 break;
7a387fff 4317 case 4:
e189e748 4318 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4319 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4320 rn = "SRSConf3";
ead9360e 4321 break;
7a387fff 4322 case 5:
e189e748 4323 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4325 rn = "SRSConf4";
ead9360e 4326 break;
7a387fff
TS
4327 default:
4328 goto die;
1579a72e 4329 }
873eb012 4330 break;
8c0fdd85 4331 case 7:
7a387fff
TS
4332 switch (sel) {
4333 case 0:
e189e748 4334 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4336 rn = "HWREna";
4337 break;
7a387fff
TS
4338 default:
4339 goto die;
1579a72e 4340 }
8c0fdd85 4341 break;
873eb012 4342 case 8:
7a387fff
TS
4343 switch (sel) {
4344 case 0:
7db13fae 4345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4346 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4347 rn = "BadVAddr";
2423f660 4348 break;
7a387fff
TS
4349 default:
4350 goto die;
4351 }
873eb012
TS
4352 break;
4353 case 9:
7a387fff
TS
4354 switch (sel) {
4355 case 0:
2e70f6ef
PB
4356 /* Mark as an IO operation because we read the time. */
4357 if (use_icount)
4358 gen_io_start();
895c2d04 4359 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4360 if (use_icount) {
4361 gen_io_end();
2e70f6ef 4362 }
55807224
EI
4363 /* Break the TB to be able to take timer interrupts immediately
4364 after reading count. */
4365 ctx->bstate = BS_STOP;
2423f660
TS
4366 rn = "Count";
4367 break;
4368 /* 6,7 are implementation dependent */
7a387fff
TS
4369 default:
4370 goto die;
2423f660 4371 }
873eb012
TS
4372 break;
4373 case 10:
7a387fff
TS
4374 switch (sel) {
4375 case 0:
7db13fae 4376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4377 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4378 rn = "EntryHi";
4379 break;
7a387fff
TS
4380 default:
4381 goto die;
1579a72e 4382 }
873eb012
TS
4383 break;
4384 case 11:
7a387fff
TS
4385 switch (sel) {
4386 case 0:
7db13fae 4387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4388 rn = "Compare";
4389 break;
4390 /* 6,7 are implementation dependent */
7a387fff
TS
4391 default:
4392 goto die;
2423f660 4393 }
873eb012
TS
4394 break;
4395 case 12:
7a387fff
TS
4396 switch (sel) {
4397 case 0:
7db13fae 4398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4399 rn = "Status";
4400 break;
7a387fff 4401 case 1:
e189e748 4402 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4404 rn = "IntCtl";
4405 break;
7a387fff 4406 case 2:
e189e748 4407 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4409 rn = "SRSCtl";
4410 break;
7a387fff 4411 case 3:
e189e748 4412 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4414 rn = "SRSMap";
fd88b6ab 4415 break;
7a387fff
TS
4416 default:
4417 goto die;
4418 }
873eb012
TS
4419 break;
4420 case 13:
7a387fff
TS
4421 switch (sel) {
4422 case 0:
7db13fae 4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4424 rn = "Cause";
4425 break;
7a387fff
TS
4426 default:
4427 goto die;
4428 }
873eb012
TS
4429 break;
4430 case 14:
7a387fff
TS
4431 switch (sel) {
4432 case 0:
7db13fae 4433 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4434 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4435 rn = "EPC";
4436 break;
7a387fff
TS
4437 default:
4438 goto die;
1579a72e 4439 }
873eb012
TS
4440 break;
4441 case 15:
7a387fff
TS
4442 switch (sel) {
4443 case 0:
7db13fae 4444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4445 rn = "PRid";
4446 break;
7a387fff 4447 case 1:
e189e748 4448 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4450 rn = "EBase";
4451 break;
7a387fff
TS
4452 default:
4453 goto die;
4454 }
873eb012
TS
4455 break;
4456 case 16:
4457 switch (sel) {
4458 case 0:
7db13fae 4459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4460 rn = "Config";
4461 break;
4462 case 1:
7db13fae 4463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4464 rn = "Config1";
4465 break;
7a387fff 4466 case 2:
7db13fae 4467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4468 rn = "Config2";
4469 break;
4470 case 3:
7db13fae 4471 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4472 rn = "Config3";
4473 break;
e397ee33
TS
4474 /* 4,5 are reserved */
4475 /* 6,7 are implementation dependent */
4476 case 6:
7db13fae 4477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4478 rn = "Config6";
4479 break;
4480 case 7:
7db13fae 4481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4482 rn = "Config7";
4483 break;
873eb012 4484 default:
873eb012
TS
4485 goto die;
4486 }
4487 break;
4488 case 17:
7a387fff
TS
4489 switch (sel) {
4490 case 0:
895c2d04 4491 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4492 rn = "LLAddr";
4493 break;
7a387fff
TS
4494 default:
4495 goto die;
4496 }
873eb012
TS
4497 break;
4498 case 18:
7a387fff 4499 switch (sel) {
fd88b6ab 4500 case 0 ... 7:
895c2d04 4501 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4502 rn = "WatchLo";
4503 break;
7a387fff
TS
4504 default:
4505 goto die;
4506 }
873eb012
TS
4507 break;
4508 case 19:
7a387fff 4509 switch (sel) {
fd88b6ab 4510 case 0 ...7:
895c2d04 4511 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4512 rn = "WatchHi";
4513 break;
7a387fff
TS
4514 default:
4515 goto die;
4516 }
873eb012 4517 break;
8c0fdd85 4518 case 20:
7a387fff
TS
4519 switch (sel) {
4520 case 0:
d26bc211 4521#if defined(TARGET_MIPS64)
e189e748 4522 check_insn(env, ctx, ISA_MIPS3);
7db13fae 4523 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4524 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4525 rn = "XContext";
4526 break;
703eaf37 4527#endif
7a387fff
TS
4528 default:
4529 goto die;
4530 }
8c0fdd85
TS
4531 break;
4532 case 21:
7a387fff
TS
4533 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4534 switch (sel) {
4535 case 0:
7db13fae 4536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4537 rn = "Framemask";
4538 break;
7a387fff
TS
4539 default:
4540 goto die;
4541 }
8c0fdd85
TS
4542 break;
4543 case 22:
d9bea114 4544 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4545 rn = "'Diagnostic"; /* implementation dependent */
4546 break;
873eb012 4547 case 23:
7a387fff
TS
4548 switch (sel) {
4549 case 0:
895c2d04 4550 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4551 rn = "Debug";
4552 break;
7a387fff 4553 case 1:
d9bea114 4554// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4555 rn = "TraceControl";
4556// break;
7a387fff 4557 case 2:
d9bea114 4558// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4559 rn = "TraceControl2";
4560// break;
7a387fff 4561 case 3:
d9bea114 4562// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4563 rn = "UserTraceData";
4564// break;
7a387fff 4565 case 4:
d9bea114 4566// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4567 rn = "TraceBPC";
4568// break;
7a387fff
TS
4569 default:
4570 goto die;
4571 }
873eb012
TS
4572 break;
4573 case 24:
7a387fff
TS
4574 switch (sel) {
4575 case 0:
f0b3f3ae 4576 /* EJTAG support */
7db13fae 4577 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4578 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4579 rn = "DEPC";
4580 break;
7a387fff
TS
4581 default:
4582 goto die;
4583 }
873eb012 4584 break;
8c0fdd85 4585 case 25:
7a387fff
TS
4586 switch (sel) {
4587 case 0:
7db13fae 4588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4589 rn = "Performance0";
7a387fff
TS
4590 break;
4591 case 1:
d9bea114 4592// gen_helper_mfc0_performance1(arg);
2423f660
TS
4593 rn = "Performance1";
4594// break;
7a387fff 4595 case 2:
d9bea114 4596// gen_helper_mfc0_performance2(arg);
2423f660
TS
4597 rn = "Performance2";
4598// break;
7a387fff 4599 case 3:
d9bea114 4600// gen_helper_mfc0_performance3(arg);
2423f660
TS
4601 rn = "Performance3";
4602// break;
7a387fff 4603 case 4:
d9bea114 4604// gen_helper_mfc0_performance4(arg);
2423f660
TS
4605 rn = "Performance4";
4606// break;
7a387fff 4607 case 5:
d9bea114 4608// gen_helper_mfc0_performance5(arg);
2423f660
TS
4609 rn = "Performance5";
4610// break;
7a387fff 4611 case 6:
d9bea114 4612// gen_helper_mfc0_performance6(arg);
2423f660
TS
4613 rn = "Performance6";
4614// break;
7a387fff 4615 case 7:
d9bea114 4616// gen_helper_mfc0_performance7(arg);
2423f660
TS
4617 rn = "Performance7";
4618// break;
7a387fff
TS
4619 default:
4620 goto die;
4621 }
8c0fdd85
TS
4622 break;
4623 case 26:
d9bea114 4624 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4625 rn = "ECC";
4626 break;
8c0fdd85 4627 case 27:
7a387fff 4628 switch (sel) {
7a387fff 4629 case 0 ... 3:
d9bea114 4630 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4631 rn = "CacheErr";
4632 break;
7a387fff
TS
4633 default:
4634 goto die;
4635 }
8c0fdd85 4636 break;
873eb012
TS
4637 case 28:
4638 switch (sel) {
4639 case 0:
7a387fff
TS
4640 case 2:
4641 case 4:
4642 case 6:
7db13fae 4643 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4644 rn = "TagLo";
4645 break;
4646 case 1:
7a387fff
TS
4647 case 3:
4648 case 5:
4649 case 7:
7db13fae 4650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4651 rn = "DataLo";
4652 break;
4653 default:
873eb012
TS
4654 goto die;
4655 }
4656 break;
8c0fdd85 4657 case 29:
7a387fff
TS
4658 switch (sel) {
4659 case 0:
4660 case 2:
4661 case 4:
4662 case 6:
7db13fae 4663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4664 rn = "TagHi";
4665 break;
4666 case 1:
4667 case 3:
4668 case 5:
4669 case 7:
7db13fae 4670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4671 rn = "DataHi";
4672 break;
4673 default:
4674 goto die;
4675 }
8c0fdd85 4676 break;
873eb012 4677 case 30:
7a387fff
TS
4678 switch (sel) {
4679 case 0:
7db13fae 4680 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4681 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4682 rn = "ErrorEPC";
4683 break;
7a387fff
TS
4684 default:
4685 goto die;
4686 }
873eb012
TS
4687 break;
4688 case 31:
7a387fff
TS
4689 switch (sel) {
4690 case 0:
f0b3f3ae 4691 /* EJTAG support */
7db13fae 4692 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4693 rn = "DESAVE";
4694 break;
7a387fff
TS
4695 default:
4696 goto die;
4697 }
873eb012
TS
4698 break;
4699 default:
873eb012
TS
4700 goto die;
4701 }
2abf314d 4702 (void)rn; /* avoid a compiler warning */
d12d51d5 4703 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4704 return;
4705
4706die:
d12d51d5 4707 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4708 generate_exception(ctx, EXCP_RI);
4709}
4710
7db13fae 4711static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4712{
7a387fff
TS
4713 const char *rn = "invalid";
4714
e189e748
TS
4715 if (sel != 0)
4716 check_insn(env, ctx, ISA_MIPS32);
4717
2e70f6ef
PB
4718 if (use_icount)
4719 gen_io_start();
4720
8c0fdd85
TS
4721 switch (reg) {
4722 case 0:
7a387fff
TS
4723 switch (sel) {
4724 case 0:
895c2d04 4725 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4726 rn = "Index";
4727 break;
4728 case 1:
7385ac0b 4729 check_insn(env, ctx, ASE_MT);
895c2d04 4730 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4731 rn = "MVPControl";
ead9360e 4732 break;
7a387fff 4733 case 2:
7385ac0b 4734 check_insn(env, ctx, ASE_MT);
ead9360e 4735 /* ignored */
7a387fff 4736 rn = "MVPConf0";
ead9360e 4737 break;
7a387fff 4738 case 3:
7385ac0b 4739 check_insn(env, ctx, ASE_MT);
ead9360e 4740 /* ignored */
7a387fff 4741 rn = "MVPConf1";
ead9360e 4742 break;
7a387fff
TS
4743 default:
4744 goto die;
4745 }
8c0fdd85
TS
4746 break;
4747 case 1:
7a387fff
TS
4748 switch (sel) {
4749 case 0:
2423f660 4750 /* ignored */
7a387fff 4751 rn = "Random";
2423f660 4752 break;
7a387fff 4753 case 1:
7385ac0b 4754 check_insn(env, ctx, ASE_MT);
895c2d04 4755 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4756 rn = "VPEControl";
ead9360e 4757 break;
7a387fff 4758 case 2:
7385ac0b 4759 check_insn(env, ctx, ASE_MT);
895c2d04 4760 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4761 rn = "VPEConf0";
ead9360e 4762 break;
7a387fff 4763 case 3:
7385ac0b 4764 check_insn(env, ctx, ASE_MT);
895c2d04 4765 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4766 rn = "VPEConf1";
ead9360e 4767 break;
7a387fff 4768 case 4:
7385ac0b 4769 check_insn(env, ctx, ASE_MT);
895c2d04 4770 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4771 rn = "YQMask";
ead9360e 4772 break;
7a387fff 4773 case 5:
7385ac0b 4774 check_insn(env, ctx, ASE_MT);
7db13fae 4775 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4776 rn = "VPESchedule";
ead9360e 4777 break;
7a387fff 4778 case 6:
7385ac0b 4779 check_insn(env, ctx, ASE_MT);
7db13fae 4780 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4781 rn = "VPEScheFBack";
ead9360e 4782 break;
7a387fff 4783 case 7:
7385ac0b 4784 check_insn(env, ctx, ASE_MT);
895c2d04 4785 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4786 rn = "VPEOpt";
ead9360e 4787 break;
7a387fff
TS
4788 default:
4789 goto die;
4790 }
8c0fdd85
TS
4791 break;
4792 case 2:
7a387fff
TS
4793 switch (sel) {
4794 case 0:
895c2d04 4795 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4796 rn = "EntryLo0";
4797 break;
7a387fff 4798 case 1:
7385ac0b 4799 check_insn(env, ctx, ASE_MT);
895c2d04 4800 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4801 rn = "TCStatus";
ead9360e 4802 break;
7a387fff 4803 case 2:
7385ac0b 4804 check_insn(env, ctx, ASE_MT);
895c2d04 4805 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4806 rn = "TCBind";
ead9360e 4807 break;
7a387fff 4808 case 3:
7385ac0b 4809 check_insn(env, ctx, ASE_MT);
895c2d04 4810 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4811 rn = "TCRestart";
ead9360e 4812 break;
7a387fff 4813 case 4:
7385ac0b 4814 check_insn(env, ctx, ASE_MT);
895c2d04 4815 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4816 rn = "TCHalt";
ead9360e 4817 break;
7a387fff 4818 case 5:
7385ac0b 4819 check_insn(env, ctx, ASE_MT);
895c2d04 4820 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4821 rn = "TCContext";
ead9360e 4822 break;
7a387fff 4823 case 6:
7385ac0b 4824 check_insn(env, ctx, ASE_MT);
895c2d04 4825 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4826 rn = "TCSchedule";
ead9360e 4827 break;
7a387fff 4828 case 7:
7385ac0b 4829 check_insn(env, ctx, ASE_MT);
895c2d04 4830 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4831 rn = "TCScheFBack";
ead9360e 4832 break;
7a387fff
TS
4833 default:
4834 goto die;
4835 }
8c0fdd85
TS
4836 break;
4837 case 3:
7a387fff
TS
4838 switch (sel) {
4839 case 0:
895c2d04 4840 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4841 rn = "EntryLo1";
4842 break;
7a387fff
TS
4843 default:
4844 goto die;
876d4b07 4845 }
8c0fdd85
TS
4846 break;
4847 case 4:
7a387fff
TS
4848 switch (sel) {
4849 case 0:
895c2d04 4850 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4851 rn = "Context";
4852 break;
7a387fff 4853 case 1:
895c2d04 4854// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4855 rn = "ContextConfig";
4856// break;
7a387fff
TS
4857 default:
4858 goto die;
876d4b07 4859 }
8c0fdd85
TS
4860 break;
4861 case 5:
7a387fff
TS
4862 switch (sel) {
4863 case 0:
895c2d04 4864 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4865 rn = "PageMask";
4866 break;
7a387fff 4867 case 1:
e189e748 4868 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4869 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4870 rn = "PageGrain";
4871 break;
7a387fff
TS
4872 default:
4873 goto die;
876d4b07 4874 }
8c0fdd85
TS
4875 break;
4876 case 6:
7a387fff
TS
4877 switch (sel) {
4878 case 0:
895c2d04 4879 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4880 rn = "Wired";
4881 break;
7a387fff 4882 case 1:
e189e748 4883 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4884 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4885 rn = "SRSConf0";
ead9360e 4886 break;
7a387fff 4887 case 2:
e189e748 4888 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4889 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4890 rn = "SRSConf1";
ead9360e 4891 break;
7a387fff 4892 case 3:
e189e748 4893 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4894 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4895 rn = "SRSConf2";
ead9360e 4896 break;
7a387fff 4897 case 4:
e189e748 4898 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4899 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4900 rn = "SRSConf3";
ead9360e 4901 break;
7a387fff 4902 case 5:
e189e748 4903 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4904 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4905 rn = "SRSConf4";
ead9360e 4906 break;
7a387fff
TS
4907 default:
4908 goto die;
876d4b07 4909 }
8c0fdd85
TS
4910 break;
4911 case 7:
7a387fff
TS
4912 switch (sel) {
4913 case 0:
e189e748 4914 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4915 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4916 rn = "HWREna";
4917 break;
7a387fff
TS
4918 default:
4919 goto die;
876d4b07 4920 }
8c0fdd85
TS
4921 break;
4922 case 8:
7a387fff 4923 /* ignored */
f0b3f3ae 4924 rn = "BadVAddr";
8c0fdd85
TS
4925 break;
4926 case 9:
7a387fff
TS
4927 switch (sel) {
4928 case 0:
895c2d04 4929 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4930 rn = "Count";
4931 break;
876d4b07 4932 /* 6,7 are implementation dependent */
7a387fff
TS
4933 default:
4934 goto die;
876d4b07 4935 }
8c0fdd85
TS
4936 break;
4937 case 10:
7a387fff
TS
4938 switch (sel) {
4939 case 0:
895c2d04 4940 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4941 rn = "EntryHi";
4942 break;
7a387fff
TS
4943 default:
4944 goto die;
876d4b07 4945 }
8c0fdd85
TS
4946 break;
4947 case 11:
7a387fff
TS
4948 switch (sel) {
4949 case 0:
895c2d04 4950 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4951 rn = "Compare";
4952 break;
4953 /* 6,7 are implementation dependent */
7a387fff
TS
4954 default:
4955 goto die;
876d4b07 4956 }
8c0fdd85
TS
4957 break;
4958 case 12:
7a387fff
TS
4959 switch (sel) {
4960 case 0:
867abc7e 4961 save_cpu_state(ctx, 1);
895c2d04 4962 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4963 /* BS_STOP isn't good enough here, hflags may have changed. */
4964 gen_save_pc(ctx->pc + 4);
4965 ctx->bstate = BS_EXCP;
2423f660
TS
4966 rn = "Status";
4967 break;
7a387fff 4968 case 1:
e189e748 4969 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4970 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4971 /* Stop translation as we may have switched the execution mode */
4972 ctx->bstate = BS_STOP;
2423f660
TS
4973 rn = "IntCtl";
4974 break;
7a387fff 4975 case 2:
e189e748 4976 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4977 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4978 /* Stop translation as we may have switched the execution mode */
4979 ctx->bstate = BS_STOP;
2423f660
TS
4980 rn = "SRSCtl";
4981 break;
7a387fff 4982 case 3:
e189e748 4983 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4984 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4985 /* Stop translation as we may have switched the execution mode */
4986 ctx->bstate = BS_STOP;
2423f660 4987 rn = "SRSMap";
fd88b6ab 4988 break;
7a387fff
TS
4989 default:
4990 goto die;
876d4b07 4991 }
8c0fdd85
TS
4992 break;
4993 case 13:
7a387fff
TS
4994 switch (sel) {
4995 case 0:
867abc7e 4996 save_cpu_state(ctx, 1);
895c2d04 4997 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4998 rn = "Cause";
4999 break;
7a387fff
TS
5000 default:
5001 goto die;
876d4b07 5002 }
8c0fdd85
TS
5003 break;
5004 case 14:
7a387fff
TS
5005 switch (sel) {
5006 case 0:
7db13fae 5007 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5008 rn = "EPC";
5009 break;
7a387fff
TS
5010 default:
5011 goto die;
876d4b07 5012 }
8c0fdd85
TS
5013 break;
5014 case 15:
7a387fff
TS
5015 switch (sel) {
5016 case 0:
2423f660
TS
5017 /* ignored */
5018 rn = "PRid";
5019 break;
7a387fff 5020 case 1:
e189e748 5021 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 5022 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5023 rn = "EBase";
5024 break;
7a387fff
TS
5025 default:
5026 goto die;
1579a72e 5027 }
8c0fdd85
TS
5028 break;
5029 case 16:
5030 switch (sel) {
5031 case 0:
895c2d04 5032 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5033 rn = "Config";
2423f660
TS
5034 /* Stop translation as we may have switched the execution mode */
5035 ctx->bstate = BS_STOP;
7a387fff
TS
5036 break;
5037 case 1:
e397ee33 5038 /* ignored, read only */
7a387fff
TS
5039 rn = "Config1";
5040 break;
5041 case 2:
895c2d04 5042 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5043 rn = "Config2";
2423f660
TS
5044 /* Stop translation as we may have switched the execution mode */
5045 ctx->bstate = BS_STOP;
8c0fdd85 5046 break;
7a387fff 5047 case 3:
e397ee33 5048 /* ignored, read only */
7a387fff
TS
5049 rn = "Config3";
5050 break;
e397ee33
TS
5051 /* 4,5 are reserved */
5052 /* 6,7 are implementation dependent */
5053 case 6:
5054 /* ignored */
5055 rn = "Config6";
5056 break;
5057 case 7:
5058 /* ignored */
5059 rn = "Config7";
5060 break;
8c0fdd85
TS
5061 default:
5062 rn = "Invalid config selector";
5063 goto die;
5064 }
5065 break;
5066 case 17:
7a387fff
TS
5067 switch (sel) {
5068 case 0:
895c2d04 5069 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5070 rn = "LLAddr";
5071 break;
7a387fff
TS
5072 default:
5073 goto die;
5074 }
8c0fdd85
TS
5075 break;
5076 case 18:
7a387fff 5077 switch (sel) {
fd88b6ab 5078 case 0 ... 7:
895c2d04 5079 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5080 rn = "WatchLo";
5081 break;
7a387fff
TS
5082 default:
5083 goto die;
5084 }
8c0fdd85
TS
5085 break;
5086 case 19:
7a387fff 5087 switch (sel) {
fd88b6ab 5088 case 0 ... 7:
895c2d04 5089 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5090 rn = "WatchHi";
5091 break;
7a387fff
TS
5092 default:
5093 goto die;
5094 }
8c0fdd85
TS
5095 break;
5096 case 20:
7a387fff
TS
5097 switch (sel) {
5098 case 0:
d26bc211 5099#if defined(TARGET_MIPS64)
e189e748 5100 check_insn(env, ctx, ISA_MIPS3);
895c2d04 5101 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5102 rn = "XContext";
5103 break;
703eaf37 5104#endif
7a387fff
TS
5105 default:
5106 goto die;
5107 }
8c0fdd85
TS
5108 break;
5109 case 21:
7a387fff
TS
5110 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5111 switch (sel) {
5112 case 0:
895c2d04 5113 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5114 rn = "Framemask";
5115 break;
7a387fff
TS
5116 default:
5117 goto die;
5118 }
5119 break;
8c0fdd85 5120 case 22:
7a387fff
TS
5121 /* ignored */
5122 rn = "Diagnostic"; /* implementation dependent */
2423f660 5123 break;
8c0fdd85 5124 case 23:
7a387fff
TS
5125 switch (sel) {
5126 case 0:
895c2d04 5127 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5128 /* BS_STOP isn't good enough here, hflags may have changed. */
5129 gen_save_pc(ctx->pc + 4);
5130 ctx->bstate = BS_EXCP;
2423f660
TS
5131 rn = "Debug";
5132 break;
7a387fff 5133 case 1:
895c2d04 5134// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5135 rn = "TraceControl";
8487327a
TS
5136 /* Stop translation as we may have switched the execution mode */
5137 ctx->bstate = BS_STOP;
2423f660 5138// break;
7a387fff 5139 case 2:
895c2d04 5140// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5141 rn = "TraceControl2";
8487327a
TS
5142 /* Stop translation as we may have switched the execution mode */
5143 ctx->bstate = BS_STOP;
2423f660 5144// break;
7a387fff 5145 case 3:
8487327a
TS
5146 /* Stop translation as we may have switched the execution mode */
5147 ctx->bstate = BS_STOP;
895c2d04 5148// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5149 rn = "UserTraceData";
8487327a
TS
5150 /* Stop translation as we may have switched the execution mode */
5151 ctx->bstate = BS_STOP;
2423f660 5152// break;
7a387fff 5153 case 4:
895c2d04 5154// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5155 /* Stop translation as we may have switched the execution mode */
5156 ctx->bstate = BS_STOP;
2423f660
TS
5157 rn = "TraceBPC";
5158// break;
7a387fff
TS
5159 default:
5160 goto die;
5161 }
8c0fdd85
TS
5162 break;
5163 case 24:
7a387fff
TS
5164 switch (sel) {
5165 case 0:
f1aa6320 5166 /* EJTAG support */
7db13fae 5167 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5168 rn = "DEPC";
5169 break;
7a387fff
TS
5170 default:
5171 goto die;
5172 }
8c0fdd85
TS
5173 break;
5174 case 25:
7a387fff
TS
5175 switch (sel) {
5176 case 0:
895c2d04 5177 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5178 rn = "Performance0";
5179 break;
7a387fff 5180 case 1:
d9bea114 5181// gen_helper_mtc0_performance1(arg);
2423f660
TS
5182 rn = "Performance1";
5183// break;
7a387fff 5184 case 2:
d9bea114 5185// gen_helper_mtc0_performance2(arg);
2423f660
TS
5186 rn = "Performance2";
5187// break;
7a387fff 5188 case 3:
d9bea114 5189// gen_helper_mtc0_performance3(arg);
2423f660
TS
5190 rn = "Performance3";
5191// break;
7a387fff 5192 case 4:
d9bea114 5193// gen_helper_mtc0_performance4(arg);
2423f660
TS
5194 rn = "Performance4";
5195// break;
7a387fff 5196 case 5:
d9bea114 5197// gen_helper_mtc0_performance5(arg);
2423f660
TS
5198 rn = "Performance5";
5199// break;
7a387fff 5200 case 6:
d9bea114 5201// gen_helper_mtc0_performance6(arg);
2423f660
TS
5202 rn = "Performance6";
5203// break;
7a387fff 5204 case 7:
d9bea114 5205// gen_helper_mtc0_performance7(arg);
2423f660
TS
5206 rn = "Performance7";
5207// break;
7a387fff
TS
5208 default:
5209 goto die;
5210 }
8c0fdd85
TS
5211 break;
5212 case 26:
2423f660 5213 /* ignored */
8c0fdd85 5214 rn = "ECC";
2423f660 5215 break;
8c0fdd85 5216 case 27:
7a387fff
TS
5217 switch (sel) {
5218 case 0 ... 3:
2423f660
TS
5219 /* ignored */
5220 rn = "CacheErr";
5221 break;
7a387fff
TS
5222 default:
5223 goto die;
5224 }
8c0fdd85
TS
5225 break;
5226 case 28:
5227 switch (sel) {
5228 case 0:
7a387fff
TS
5229 case 2:
5230 case 4:
5231 case 6:
895c2d04 5232 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5233 rn = "TagLo";
5234 break;
7a387fff
TS
5235 case 1:
5236 case 3:
5237 case 5:
5238 case 7:
895c2d04 5239 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5240 rn = "DataLo";
5241 break;
8c0fdd85 5242 default:
8c0fdd85
TS
5243 goto die;
5244 }
5245 break;
5246 case 29:
7a387fff
TS
5247 switch (sel) {
5248 case 0:
5249 case 2:
5250 case 4:
5251 case 6:
895c2d04 5252 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5253 rn = "TagHi";
5254 break;
5255 case 1:
5256 case 3:
5257 case 5:
5258 case 7:
895c2d04 5259 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5260 rn = "DataHi";
5261 break;
5262 default:
5263 rn = "invalid sel";
5264 goto die;
5265 }
8c0fdd85
TS
5266 break;
5267 case 30:
7a387fff
TS
5268 switch (sel) {
5269 case 0:
7db13fae 5270 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5271 rn = "ErrorEPC";
5272 break;
7a387fff
TS
5273 default:
5274 goto die;
5275 }
8c0fdd85
TS
5276 break;
5277 case 31:
7a387fff
TS
5278 switch (sel) {
5279 case 0:
f1aa6320 5280 /* EJTAG support */
7db13fae 5281 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5282 rn = "DESAVE";
5283 break;
7a387fff
TS
5284 default:
5285 goto die;
5286 }
2423f660
TS
5287 /* Stop translation as we may have switched the execution mode */
5288 ctx->bstate = BS_STOP;
8c0fdd85
TS
5289 break;
5290 default:
8c0fdd85
TS
5291 goto die;
5292 }
2abf314d 5293 (void)rn; /* avoid a compiler warning */
d12d51d5 5294 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5295 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5296 if (use_icount) {
5297 gen_io_end();
5298 ctx->bstate = BS_STOP;
5299 }
8c0fdd85
TS
5300 return;
5301
5302die:
d12d51d5 5303 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5304 generate_exception(ctx, EXCP_RI);
5305}
5306
d26bc211 5307#if defined(TARGET_MIPS64)
7db13fae 5308static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5309{
5310 const char *rn = "invalid";
5311
e189e748
TS
5312 if (sel != 0)
5313 check_insn(env, ctx, ISA_MIPS64);
5314
9c2149c8
TS
5315 switch (reg) {
5316 case 0:
5317 switch (sel) {
5318 case 0:
7db13fae 5319 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5320 rn = "Index";
5321 break;
5322 case 1:
7385ac0b 5323 check_insn(env, ctx, ASE_MT);
895c2d04 5324 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5325 rn = "MVPControl";
ead9360e 5326 break;
9c2149c8 5327 case 2:
7385ac0b 5328 check_insn(env, ctx, ASE_MT);
895c2d04 5329 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5330 rn = "MVPConf0";
ead9360e 5331 break;
9c2149c8 5332 case 3:
7385ac0b 5333 check_insn(env, ctx, ASE_MT);
895c2d04 5334 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5335 rn = "MVPConf1";
ead9360e 5336 break;
9c2149c8
TS
5337 default:
5338 goto die;
5339 }
5340 break;
5341 case 1:
5342 switch (sel) {
5343 case 0:
895c2d04 5344 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5345 rn = "Random";
2423f660 5346 break;
9c2149c8 5347 case 1:
7385ac0b 5348 check_insn(env, ctx, ASE_MT);
7db13fae 5349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5350 rn = "VPEControl";
ead9360e 5351 break;
9c2149c8 5352 case 2:
7385ac0b 5353 check_insn(env, ctx, ASE_MT);
7db13fae 5354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5355 rn = "VPEConf0";
ead9360e 5356 break;
9c2149c8 5357 case 3:
7385ac0b 5358 check_insn(env, ctx, ASE_MT);
7db13fae 5359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5360 rn = "VPEConf1";
ead9360e 5361 break;
9c2149c8 5362 case 4:
7385ac0b 5363 check_insn(env, ctx, ASE_MT);
7db13fae 5364 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5365 rn = "YQMask";
ead9360e 5366 break;
9c2149c8 5367 case 5:
7385ac0b 5368 check_insn(env, ctx, ASE_MT);
7db13fae 5369 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5370 rn = "VPESchedule";
ead9360e 5371 break;
9c2149c8 5372 case 6:
7385ac0b 5373 check_insn(env, ctx, ASE_MT);
7db13fae 5374 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5375 rn = "VPEScheFBack";
ead9360e 5376 break;
9c2149c8 5377 case 7:
7385ac0b 5378 check_insn(env, ctx, ASE_MT);
7db13fae 5379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5380 rn = "VPEOpt";
ead9360e 5381 break;
9c2149c8
TS
5382 default:
5383 goto die;
5384 }
5385 break;
5386 case 2:
5387 switch (sel) {
5388 case 0:
7db13fae 5389 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5390 rn = "EntryLo0";
5391 break;
9c2149c8 5392 case 1:
7385ac0b 5393 check_insn(env, ctx, ASE_MT);
895c2d04 5394 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5395 rn = "TCStatus";
ead9360e 5396 break;
9c2149c8 5397 case 2:
7385ac0b 5398 check_insn(env, ctx, ASE_MT);
895c2d04 5399 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5400 rn = "TCBind";
ead9360e 5401 break;
9c2149c8 5402 case 3:
7385ac0b 5403 check_insn(env, ctx, ASE_MT);
895c2d04 5404 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5405 rn = "TCRestart";
ead9360e 5406 break;
9c2149c8 5407 case 4:
7385ac0b 5408 check_insn(env, ctx, ASE_MT);
895c2d04 5409 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5410 rn = "TCHalt";
ead9360e 5411 break;
9c2149c8 5412 case 5:
7385ac0b 5413 check_insn(env, ctx, ASE_MT);
895c2d04 5414 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5415 rn = "TCContext";
ead9360e 5416 break;
9c2149c8 5417 case 6:
7385ac0b 5418 check_insn(env, ctx, ASE_MT);
895c2d04 5419 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5420 rn = "TCSchedule";
ead9360e 5421 break;
9c2149c8 5422 case 7:
7385ac0b 5423 check_insn(env, ctx, ASE_MT);
895c2d04 5424 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5425 rn = "TCScheFBack";
ead9360e 5426 break;
9c2149c8
TS
5427 default:
5428 goto die;
5429 }
5430 break;
5431 case 3:
5432 switch (sel) {
5433 case 0:
7db13fae 5434 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5435 rn = "EntryLo1";
5436 break;
9c2149c8
TS
5437 default:
5438 goto die;
1579a72e 5439 }
9c2149c8
TS
5440 break;
5441 case 4:
5442 switch (sel) {
5443 case 0:
7db13fae 5444 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5445 rn = "Context";
5446 break;
9c2149c8 5447 case 1:
d9bea114 5448// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5449 rn = "ContextConfig";
5450// break;
9c2149c8
TS
5451 default:
5452 goto die;
876d4b07 5453 }
9c2149c8
TS
5454 break;
5455 case 5:
5456 switch (sel) {
5457 case 0:
7db13fae 5458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5459 rn = "PageMask";
5460 break;
9c2149c8 5461 case 1:
e189e748 5462 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5464 rn = "PageGrain";
5465 break;
9c2149c8
TS
5466 default:
5467 goto die;
876d4b07 5468 }
9c2149c8
TS
5469 break;
5470 case 6:
5471 switch (sel) {
5472 case 0:
7db13fae 5473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5474 rn = "Wired";
5475 break;
9c2149c8 5476 case 1:
e189e748 5477 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5479 rn = "SRSConf0";
ead9360e 5480 break;
9c2149c8 5481 case 2:
e189e748 5482 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5484 rn = "SRSConf1";
ead9360e 5485 break;
9c2149c8 5486 case 3:
e189e748 5487 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5489 rn = "SRSConf2";
ead9360e 5490 break;
9c2149c8 5491 case 4:
e189e748 5492 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5494 rn = "SRSConf3";
ead9360e 5495 break;
9c2149c8 5496 case 5:
e189e748 5497 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5499 rn = "SRSConf4";
ead9360e 5500 break;
9c2149c8
TS
5501 default:
5502 goto die;
876d4b07 5503 }
9c2149c8
TS
5504 break;
5505 case 7:
5506 switch (sel) {
5507 case 0:
e189e748 5508 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5510 rn = "HWREna";
5511 break;
9c2149c8
TS
5512 default:
5513 goto die;
876d4b07 5514 }
9c2149c8
TS
5515 break;
5516 case 8:
5517 switch (sel) {
5518 case 0:
7db13fae 5519 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5520 rn = "BadVAddr";
2423f660 5521 break;
9c2149c8
TS
5522 default:
5523 goto die;
876d4b07 5524 }
9c2149c8
TS
5525 break;
5526 case 9:
5527 switch (sel) {
5528 case 0:
2e70f6ef
PB
5529 /* Mark as an IO operation because we read the time. */
5530 if (use_icount)
5531 gen_io_start();
895c2d04 5532 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5533 if (use_icount) {
5534 gen_io_end();
2e70f6ef 5535 }
55807224
EI
5536 /* Break the TB to be able to take timer interrupts immediately
5537 after reading count. */
5538 ctx->bstate = BS_STOP;
2423f660
TS
5539 rn = "Count";
5540 break;
5541 /* 6,7 are implementation dependent */
9c2149c8
TS
5542 default:
5543 goto die;
876d4b07 5544 }
9c2149c8
TS
5545 break;
5546 case 10:
5547 switch (sel) {
5548 case 0:
7db13fae 5549 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5550 rn = "EntryHi";
5551 break;
9c2149c8
TS
5552 default:
5553 goto die;
876d4b07 5554 }
9c2149c8
TS
5555 break;
5556 case 11:
5557 switch (sel) {
5558 case 0:
7db13fae 5559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5560 rn = "Compare";
5561 break;
876d4b07 5562 /* 6,7 are implementation dependent */
9c2149c8
TS
5563 default:
5564 goto die;
876d4b07 5565 }
9c2149c8
TS
5566 break;
5567 case 12:
5568 switch (sel) {
5569 case 0:
7db13fae 5570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5571 rn = "Status";
5572 break;
9c2149c8 5573 case 1:
e189e748 5574 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5576 rn = "IntCtl";
5577 break;
9c2149c8 5578 case 2:
e189e748 5579 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5581 rn = "SRSCtl";
5582 break;
9c2149c8 5583 case 3:
e189e748 5584 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5586 rn = "SRSMap";
5587 break;
9c2149c8
TS
5588 default:
5589 goto die;
876d4b07 5590 }
9c2149c8
TS
5591 break;
5592 case 13:
5593 switch (sel) {
5594 case 0:
7db13fae 5595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5596 rn = "Cause";
5597 break;
9c2149c8
TS
5598 default:
5599 goto die;
876d4b07 5600 }
9c2149c8
TS
5601 break;
5602 case 14:
5603 switch (sel) {
5604 case 0:
7db13fae 5605 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5606 rn = "EPC";
5607 break;
9c2149c8
TS
5608 default:
5609 goto die;
876d4b07 5610 }
9c2149c8
TS
5611 break;
5612 case 15:
5613 switch (sel) {
5614 case 0:
7db13fae 5615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5616 rn = "PRid";
5617 break;
9c2149c8 5618 case 1:
e189e748 5619 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5621 rn = "EBase";
5622 break;
9c2149c8
TS
5623 default:
5624 goto die;
876d4b07 5625 }
9c2149c8
TS
5626 break;
5627 case 16:
5628 switch (sel) {
5629 case 0:
7db13fae 5630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5631 rn = "Config";
5632 break;
5633 case 1:
7db13fae 5634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5635 rn = "Config1";
5636 break;
5637 case 2:
7db13fae 5638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5639 rn = "Config2";
5640 break;
5641 case 3:
7db13fae 5642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5643 rn = "Config3";
5644 break;
5645 /* 6,7 are implementation dependent */
f0b3f3ae 5646 case 6:
7db13fae 5647 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5648 rn = "Config6";
5649 break;
5650 case 7:
7db13fae 5651 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5652 rn = "Config7";
5653 break;
9c2149c8
TS
5654 default:
5655 goto die;
5656 }
5657 break;
5658 case 17:
5659 switch (sel) {
5660 case 0:
895c2d04 5661 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5662 rn = "LLAddr";
5663 break;
9c2149c8
TS
5664 default:
5665 goto die;
5666 }
5667 break;
5668 case 18:
5669 switch (sel) {
fd88b6ab 5670 case 0 ... 7:
895c2d04 5671 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5672 rn = "WatchLo";
5673 break;
9c2149c8
TS
5674 default:
5675 goto die;
5676 }
5677 break;
5678 case 19:
5679 switch (sel) {
fd88b6ab 5680 case 0 ... 7:
895c2d04 5681 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5682 rn = "WatchHi";
5683 break;
9c2149c8
TS
5684 default:
5685 goto die;
5686 }
5687 break;
5688 case 20:
5689 switch (sel) {
5690 case 0:
e189e748 5691 check_insn(env, ctx, ISA_MIPS3);
7db13fae 5692 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5693 rn = "XContext";
5694 break;
9c2149c8
TS
5695 default:
5696 goto die;
5697 }
5698 break;
5699 case 21:
5700 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5701 switch (sel) {
5702 case 0:
7db13fae 5703 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5704 rn = "Framemask";
5705 break;
9c2149c8
TS
5706 default:
5707 goto die;
5708 }
5709 break;
5710 case 22:
d9bea114 5711 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5712 rn = "'Diagnostic"; /* implementation dependent */
5713 break;
9c2149c8
TS
5714 case 23:
5715 switch (sel) {
5716 case 0:
895c2d04 5717 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5718 rn = "Debug";
5719 break;
9c2149c8 5720 case 1:
895c2d04 5721// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5722 rn = "TraceControl";
5723// break;
9c2149c8 5724 case 2:
895c2d04 5725// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5726 rn = "TraceControl2";
5727// break;
9c2149c8 5728 case 3:
895c2d04 5729// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5730 rn = "UserTraceData";
5731// break;
9c2149c8 5732 case 4:
895c2d04 5733// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5734 rn = "TraceBPC";
5735// break;
9c2149c8
TS
5736 default:
5737 goto die;
5738 }
5739 break;
5740 case 24:
5741 switch (sel) {
5742 case 0:
f0b3f3ae 5743 /* EJTAG support */
7db13fae 5744 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5745 rn = "DEPC";
5746 break;
9c2149c8
TS
5747 default:
5748 goto die;
5749 }
5750 break;
5751 case 25:
5752 switch (sel) {
5753 case 0:
7db13fae 5754 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5755 rn = "Performance0";
9c2149c8
TS
5756 break;
5757 case 1:
d9bea114 5758// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5759 rn = "Performance1";
5760// break;
9c2149c8 5761 case 2:
d9bea114 5762// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5763 rn = "Performance2";
5764// break;
9c2149c8 5765 case 3:
d9bea114 5766// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5767 rn = "Performance3";
5768// break;
9c2149c8 5769 case 4:
d9bea114 5770// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5771 rn = "Performance4";
5772// break;
9c2149c8 5773 case 5:
d9bea114 5774// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5775 rn = "Performance5";
5776// break;
9c2149c8 5777 case 6:
d9bea114 5778// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5779 rn = "Performance6";
5780// break;
9c2149c8 5781 case 7:
d9bea114 5782// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5783 rn = "Performance7";
5784// break;
9c2149c8
TS
5785 default:
5786 goto die;
5787 }
5788 break;
5789 case 26:
d9bea114 5790 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5791 rn = "ECC";
5792 break;
9c2149c8
TS
5793 case 27:
5794 switch (sel) {
5795 /* ignored */
5796 case 0 ... 3:
d9bea114 5797 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5798 rn = "CacheErr";
5799 break;
9c2149c8
TS
5800 default:
5801 goto die;
5802 }
5803 break;
5804 case 28:
5805 switch (sel) {
5806 case 0:
5807 case 2:
5808 case 4:
5809 case 6:
7db13fae 5810 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5811 rn = "TagLo";
5812 break;
5813 case 1:
5814 case 3:
5815 case 5:
5816 case 7:
7db13fae 5817 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5818 rn = "DataLo";
5819 break;
5820 default:
5821 goto die;
5822 }
5823 break;
5824 case 29:
5825 switch (sel) {
5826 case 0:
5827 case 2:
5828 case 4:
5829 case 6:
7db13fae 5830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5831 rn = "TagHi";
5832 break;
5833 case 1:
5834 case 3:
5835 case 5:
5836 case 7:
7db13fae 5837 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5838 rn = "DataHi";
5839 break;
5840 default:
5841 goto die;
5842 }
5843 break;
5844 case 30:
5845 switch (sel) {
5846 case 0:
7db13fae 5847 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5848 rn = "ErrorEPC";
5849 break;
9c2149c8
TS
5850 default:
5851 goto die;
5852 }
5853 break;
5854 case 31:
5855 switch (sel) {
5856 case 0:
f0b3f3ae 5857 /* EJTAG support */
7db13fae 5858 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5859 rn = "DESAVE";
5860 break;
9c2149c8
TS
5861 default:
5862 goto die;
5863 }
5864 break;
5865 default:
876d4b07 5866 goto die;
9c2149c8 5867 }
2abf314d 5868 (void)rn; /* avoid a compiler warning */
d12d51d5 5869 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5870 return;
5871
5872die:
d12d51d5 5873 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5874 generate_exception(ctx, EXCP_RI);
5875}
5876
7db13fae 5877static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5878{
5879 const char *rn = "invalid";
5880
e189e748
TS
5881 if (sel != 0)
5882 check_insn(env, ctx, ISA_MIPS64);
5883
2e70f6ef
PB
5884 if (use_icount)
5885 gen_io_start();
5886
9c2149c8
TS
5887 switch (reg) {
5888 case 0:
5889 switch (sel) {
5890 case 0:
895c2d04 5891 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5892 rn = "Index";
5893 break;
5894 case 1:
7385ac0b 5895 check_insn(env, ctx, ASE_MT);
895c2d04 5896 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5897 rn = "MVPControl";
ead9360e 5898 break;
9c2149c8 5899 case 2:
7385ac0b 5900 check_insn(env, ctx, ASE_MT);
ead9360e 5901 /* ignored */
9c2149c8 5902 rn = "MVPConf0";
ead9360e 5903 break;
9c2149c8 5904 case 3:
7385ac0b 5905 check_insn(env, ctx, ASE_MT);
ead9360e 5906 /* ignored */
9c2149c8 5907 rn = "MVPConf1";
ead9360e 5908 break;
9c2149c8
TS
5909 default:
5910 goto die;
5911 }
5912 break;
5913 case 1:
5914 switch (sel) {
5915 case 0:
2423f660 5916 /* ignored */
9c2149c8 5917 rn = "Random";
2423f660 5918 break;
9c2149c8 5919 case 1:
7385ac0b 5920 check_insn(env, ctx, ASE_MT);
895c2d04 5921 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5922 rn = "VPEControl";
ead9360e 5923 break;
9c2149c8 5924 case 2:
7385ac0b 5925 check_insn(env, ctx, ASE_MT);
895c2d04 5926 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5927 rn = "VPEConf0";
ead9360e 5928 break;
9c2149c8 5929 case 3:
7385ac0b 5930 check_insn(env, ctx, ASE_MT);
895c2d04 5931 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5932 rn = "VPEConf1";
ead9360e 5933 break;
9c2149c8 5934 case 4:
7385ac0b 5935 check_insn(env, ctx, ASE_MT);
895c2d04 5936 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5937 rn = "YQMask";
ead9360e 5938 break;
9c2149c8 5939 case 5:
7385ac0b 5940 check_insn(env, ctx, ASE_MT);
7db13fae 5941 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5942 rn = "VPESchedule";
ead9360e 5943 break;
9c2149c8 5944 case 6:
7385ac0b 5945 check_insn(env, ctx, ASE_MT);
7db13fae 5946 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5947 rn = "VPEScheFBack";
ead9360e 5948 break;
9c2149c8 5949 case 7:
7385ac0b 5950 check_insn(env, ctx, ASE_MT);
895c2d04 5951 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5952 rn = "VPEOpt";
ead9360e 5953 break;
9c2149c8
TS
5954 default:
5955 goto die;
5956 }
5957 break;
5958 case 2:
5959 switch (sel) {
5960 case 0:
895c2d04 5961 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5962 rn = "EntryLo0";
5963 break;
9c2149c8 5964 case 1:
7385ac0b 5965 check_insn(env, ctx, ASE_MT);
895c2d04 5966 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5967 rn = "TCStatus";
ead9360e 5968 break;
9c2149c8 5969 case 2:
7385ac0b 5970 check_insn(env, ctx, ASE_MT);
895c2d04 5971 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5972 rn = "TCBind";
ead9360e 5973 break;
9c2149c8 5974 case 3:
7385ac0b 5975 check_insn(env, ctx, ASE_MT);
895c2d04 5976 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5977 rn = "TCRestart";
ead9360e 5978 break;
9c2149c8 5979 case 4:
7385ac0b 5980 check_insn(env, ctx, ASE_MT);
895c2d04 5981 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5982 rn = "TCHalt";
ead9360e 5983 break;
9c2149c8 5984 case 5:
7385ac0b 5985 check_insn(env, ctx, ASE_MT);
895c2d04 5986 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5987 rn = "TCContext";
ead9360e 5988 break;
9c2149c8 5989 case 6:
7385ac0b 5990 check_insn(env, ctx, ASE_MT);
895c2d04 5991 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5992 rn = "TCSchedule";
ead9360e 5993 break;
9c2149c8 5994 case 7:
7385ac0b 5995 check_insn(env, ctx, ASE_MT);
895c2d04 5996 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5997 rn = "TCScheFBack";
ead9360e 5998 break;
9c2149c8
TS
5999 default:
6000 goto die;
6001 }
6002 break;
6003 case 3:
6004 switch (sel) {
6005 case 0:
895c2d04 6006 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
6007 rn = "EntryLo1";
6008 break;
9c2149c8
TS
6009 default:
6010 goto die;
876d4b07 6011 }
9c2149c8
TS
6012 break;
6013 case 4:
6014 switch (sel) {
6015 case 0:
895c2d04 6016 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6017 rn = "Context";
6018 break;
9c2149c8 6019 case 1:
895c2d04 6020// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
6021 rn = "ContextConfig";
6022// break;
9c2149c8
TS
6023 default:
6024 goto die;
876d4b07 6025 }
9c2149c8
TS
6026 break;
6027 case 5:
6028 switch (sel) {
6029 case 0:
895c2d04 6030 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6031 rn = "PageMask";
6032 break;
9c2149c8 6033 case 1:
e189e748 6034 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6035 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6036 rn = "PageGrain";
6037 break;
9c2149c8
TS
6038 default:
6039 goto die;
876d4b07 6040 }
9c2149c8
TS
6041 break;
6042 case 6:
6043 switch (sel) {
6044 case 0:
895c2d04 6045 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6046 rn = "Wired";
6047 break;
9c2149c8 6048 case 1:
e189e748 6049 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6050 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6051 rn = "SRSConf0";
ead9360e 6052 break;
9c2149c8 6053 case 2:
e189e748 6054 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6055 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6056 rn = "SRSConf1";
ead9360e 6057 break;
9c2149c8 6058 case 3:
e189e748 6059 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6060 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6061 rn = "SRSConf2";
ead9360e 6062 break;
9c2149c8 6063 case 4:
e189e748 6064 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6065 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6066 rn = "SRSConf3";
ead9360e 6067 break;
9c2149c8 6068 case 5:
e189e748 6069 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6070 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6071 rn = "SRSConf4";
ead9360e 6072 break;
9c2149c8
TS
6073 default:
6074 goto die;
876d4b07 6075 }
9c2149c8
TS
6076 break;
6077 case 7:
6078 switch (sel) {
6079 case 0:
e189e748 6080 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6081 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6082 rn = "HWREna";
6083 break;
9c2149c8
TS
6084 default:
6085 goto die;
876d4b07 6086 }
9c2149c8
TS
6087 break;
6088 case 8:
6089 /* ignored */
f0b3f3ae 6090 rn = "BadVAddr";
9c2149c8
TS
6091 break;
6092 case 9:
6093 switch (sel) {
6094 case 0:
895c2d04 6095 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6096 rn = "Count";
6097 break;
876d4b07 6098 /* 6,7 are implementation dependent */
9c2149c8
TS
6099 default:
6100 goto die;
876d4b07
TS
6101 }
6102 /* Stop translation as we may have switched the execution mode */
6103 ctx->bstate = BS_STOP;
9c2149c8
TS
6104 break;
6105 case 10:
6106 switch (sel) {
6107 case 0:
895c2d04 6108 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6109 rn = "EntryHi";
6110 break;
9c2149c8
TS
6111 default:
6112 goto die;
876d4b07 6113 }
9c2149c8
TS
6114 break;
6115 case 11:
6116 switch (sel) {
6117 case 0:
895c2d04 6118 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6119 rn = "Compare";
6120 break;
876d4b07 6121 /* 6,7 are implementation dependent */
9c2149c8
TS
6122 default:
6123 goto die;
876d4b07 6124 }
de9a95f0
AJ
6125 /* Stop translation as we may have switched the execution mode */
6126 ctx->bstate = BS_STOP;
9c2149c8
TS
6127 break;
6128 case 12:
6129 switch (sel) {
6130 case 0:
867abc7e 6131 save_cpu_state(ctx, 1);
895c2d04 6132 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6133 /* BS_STOP isn't good enough here, hflags may have changed. */
6134 gen_save_pc(ctx->pc + 4);
6135 ctx->bstate = BS_EXCP;
2423f660
TS
6136 rn = "Status";
6137 break;
9c2149c8 6138 case 1:
e189e748 6139 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6140 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6141 /* Stop translation as we may have switched the execution mode */
6142 ctx->bstate = BS_STOP;
2423f660
TS
6143 rn = "IntCtl";
6144 break;
9c2149c8 6145 case 2:
e189e748 6146 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6147 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6148 /* Stop translation as we may have switched the execution mode */
6149 ctx->bstate = BS_STOP;
2423f660
TS
6150 rn = "SRSCtl";
6151 break;
9c2149c8 6152 case 3:
e189e748 6153 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 6154 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6155 /* Stop translation as we may have switched the execution mode */
6156 ctx->bstate = BS_STOP;
2423f660
TS
6157 rn = "SRSMap";
6158 break;
6159 default:
9c2149c8 6160 goto die;
876d4b07 6161 }
9c2149c8
TS
6162 break;
6163 case 13:
6164 switch (sel) {
6165 case 0:
867abc7e 6166 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6167 /* Mark as an IO operation because we may trigger a software
6168 interrupt. */
6169 if (use_icount) {
6170 gen_io_start();
6171 }
895c2d04 6172 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6173 if (use_icount) {
6174 gen_io_end();
6175 }
6176 /* Stop translation as we may have triggered an intetrupt */
6177 ctx->bstate = BS_STOP;
2423f660
TS
6178 rn = "Cause";
6179 break;
9c2149c8
TS
6180 default:
6181 goto die;
876d4b07 6182 }
9c2149c8
TS
6183 break;
6184 case 14:
6185 switch (sel) {
6186 case 0:
7db13fae 6187 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6188 rn = "EPC";
6189 break;
9c2149c8
TS
6190 default:
6191 goto die;
876d4b07 6192 }
9c2149c8
TS
6193 break;
6194 case 15:
6195 switch (sel) {
6196 case 0:
2423f660
TS
6197 /* ignored */
6198 rn = "PRid";
6199 break;
9c2149c8 6200 case 1:
e189e748 6201 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6202 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6203 rn = "EBase";
6204 break;
9c2149c8
TS
6205 default:
6206 goto die;
876d4b07 6207 }
9c2149c8
TS
6208 break;
6209 case 16:
6210 switch (sel) {
6211 case 0:
895c2d04 6212 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6213 rn = "Config";
2423f660
TS
6214 /* Stop translation as we may have switched the execution mode */
6215 ctx->bstate = BS_STOP;
9c2149c8
TS
6216 break;
6217 case 1:
1fc7bf6e 6218 /* ignored, read only */
9c2149c8
TS
6219 rn = "Config1";
6220 break;
6221 case 2:
895c2d04 6222 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6223 rn = "Config2";
2423f660
TS
6224 /* Stop translation as we may have switched the execution mode */
6225 ctx->bstate = BS_STOP;
9c2149c8
TS
6226 break;
6227 case 3:
2423f660 6228 /* ignored */
9c2149c8
TS
6229 rn = "Config3";
6230 break;
6231 /* 6,7 are implementation dependent */
6232 default:
6233 rn = "Invalid config selector";
6234 goto die;
6235 }
9c2149c8
TS
6236 break;
6237 case 17:
6238 switch (sel) {
6239 case 0:
895c2d04 6240 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6241 rn = "LLAddr";
6242 break;
9c2149c8
TS
6243 default:
6244 goto die;
6245 }
6246 break;
6247 case 18:
6248 switch (sel) {
fd88b6ab 6249 case 0 ... 7:
895c2d04 6250 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6251 rn = "WatchLo";
6252 break;
9c2149c8
TS
6253 default:
6254 goto die;
6255 }
6256 break;
6257 case 19:
6258 switch (sel) {
fd88b6ab 6259 case 0 ... 7:
895c2d04 6260 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6261 rn = "WatchHi";
6262 break;
9c2149c8
TS
6263 default:
6264 goto die;
6265 }
6266 break;
6267 case 20:
6268 switch (sel) {
6269 case 0:
e189e748 6270 check_insn(env, ctx, ISA_MIPS3);
895c2d04 6271 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6272 rn = "XContext";
6273 break;
9c2149c8
TS
6274 default:
6275 goto die;
6276 }
6277 break;
6278 case 21:
6279 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6280 switch (sel) {
6281 case 0:
895c2d04 6282 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6283 rn = "Framemask";
6284 break;
9c2149c8
TS
6285 default:
6286 goto die;
6287 }
6288 break;
6289 case 22:
6290 /* ignored */
6291 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6292 break;
9c2149c8
TS
6293 case 23:
6294 switch (sel) {
6295 case 0:
895c2d04 6296 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6297 /* BS_STOP isn't good enough here, hflags may have changed. */
6298 gen_save_pc(ctx->pc + 4);
6299 ctx->bstate = BS_EXCP;
2423f660
TS
6300 rn = "Debug";
6301 break;
9c2149c8 6302 case 1:
895c2d04 6303// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6304 /* Stop translation as we may have switched the execution mode */
6305 ctx->bstate = BS_STOP;
2423f660
TS
6306 rn = "TraceControl";
6307// break;
9c2149c8 6308 case 2:
895c2d04 6309// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6310 /* Stop translation as we may have switched the execution mode */
6311 ctx->bstate = BS_STOP;
2423f660
TS
6312 rn = "TraceControl2";
6313// break;
9c2149c8 6314 case 3:
895c2d04 6315// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6316 /* Stop translation as we may have switched the execution mode */
6317 ctx->bstate = BS_STOP;
2423f660
TS
6318 rn = "UserTraceData";
6319// break;
9c2149c8 6320 case 4:
895c2d04 6321// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6322 /* Stop translation as we may have switched the execution mode */
6323 ctx->bstate = BS_STOP;
2423f660
TS
6324 rn = "TraceBPC";
6325// break;
9c2149c8
TS
6326 default:
6327 goto die;
6328 }
9c2149c8
TS
6329 break;
6330 case 24:
6331 switch (sel) {
6332 case 0:
f1aa6320 6333 /* EJTAG support */
7db13fae 6334 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6335 rn = "DEPC";
6336 break;
9c2149c8
TS
6337 default:
6338 goto die;
6339 }
6340 break;
6341 case 25:
6342 switch (sel) {
6343 case 0:
895c2d04 6344 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6345 rn = "Performance0";
6346 break;
9c2149c8 6347 case 1:
895c2d04 6348// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6349 rn = "Performance1";
6350// break;
9c2149c8 6351 case 2:
895c2d04 6352// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6353 rn = "Performance2";
6354// break;
9c2149c8 6355 case 3:
895c2d04 6356// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6357 rn = "Performance3";
6358// break;
9c2149c8 6359 case 4:
895c2d04 6360// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6361 rn = "Performance4";
6362// break;
9c2149c8 6363 case 5:
895c2d04 6364// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6365 rn = "Performance5";
6366// break;
9c2149c8 6367 case 6:
895c2d04 6368// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6369 rn = "Performance6";
6370// break;
9c2149c8 6371 case 7:
895c2d04 6372// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6373 rn = "Performance7";
6374// break;
9c2149c8
TS
6375 default:
6376 goto die;
6377 }
876d4b07 6378 break;
9c2149c8 6379 case 26:
876d4b07 6380 /* ignored */
9c2149c8 6381 rn = "ECC";
876d4b07 6382 break;
9c2149c8
TS
6383 case 27:
6384 switch (sel) {
6385 case 0 ... 3:
2423f660
TS
6386 /* ignored */
6387 rn = "CacheErr";
6388 break;
9c2149c8
TS
6389 default:
6390 goto die;
6391 }
876d4b07 6392 break;
9c2149c8
TS
6393 case 28:
6394 switch (sel) {
6395 case 0:
6396 case 2:
6397 case 4:
6398 case 6:
895c2d04 6399 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6400 rn = "TagLo";
6401 break;
6402 case 1:
6403 case 3:
6404 case 5:
6405 case 7:
895c2d04 6406 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6407 rn = "DataLo";
6408 break;
6409 default:
6410 goto die;
6411 }
6412 break;
6413 case 29:
6414 switch (sel) {
6415 case 0:
6416 case 2:
6417 case 4:
6418 case 6:
895c2d04 6419 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6420 rn = "TagHi";
6421 break;
6422 case 1:
6423 case 3:
6424 case 5:
6425 case 7:
895c2d04 6426 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6427 rn = "DataHi";
6428 break;
6429 default:
6430 rn = "invalid sel";
6431 goto die;
6432 }
876d4b07 6433 break;
9c2149c8
TS
6434 case 30:
6435 switch (sel) {
6436 case 0:
7db13fae 6437 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6438 rn = "ErrorEPC";
6439 break;
9c2149c8
TS
6440 default:
6441 goto die;
6442 }
6443 break;
6444 case 31:
6445 switch (sel) {
6446 case 0:
f1aa6320 6447 /* EJTAG support */
7db13fae 6448 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6449 rn = "DESAVE";
6450 break;
9c2149c8
TS
6451 default:
6452 goto die;
6453 }
876d4b07
TS
6454 /* Stop translation as we may have switched the execution mode */
6455 ctx->bstate = BS_STOP;
9c2149c8
TS
6456 break;
6457 default:
876d4b07 6458 goto die;
9c2149c8 6459 }
2abf314d 6460 (void)rn; /* avoid a compiler warning */
d12d51d5 6461 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6462 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6463 if (use_icount) {
6464 gen_io_end();
6465 ctx->bstate = BS_STOP;
6466 }
9c2149c8
TS
6467 return;
6468
6469die:
d12d51d5 6470 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6471 generate_exception(ctx, EXCP_RI);
6472}
d26bc211 6473#endif /* TARGET_MIPS64 */
9c2149c8 6474
7db13fae 6475static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6476 int u, int sel, int h)
6477{
6478 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6479 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6480
6481 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6482 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6483 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6484 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6485 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6486 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6487 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6488 else if (u == 0) {
6489 switch (rt) {
5a25ce94
EI
6490 case 1:
6491 switch (sel) {
6492 case 1:
895c2d04 6493 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6494 break;
6495 case 2:
895c2d04 6496 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6497 break;
6498 default:
6499 goto die;
6500 break;
6501 }
6502 break;
ead9360e
TS
6503 case 2:
6504 switch (sel) {
6505 case 1:
895c2d04 6506 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6507 break;
6508 case 2:
895c2d04 6509 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6510 break;
6511 case 3:
895c2d04 6512 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6513 break;
6514 case 4:
895c2d04 6515 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6516 break;
6517 case 5:
895c2d04 6518 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6519 break;
6520 case 6:
895c2d04 6521 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6522 break;
6523 case 7:
895c2d04 6524 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6525 break;
6526 default:
1a3fd9c3 6527 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6528 break;
6529 }
6530 break;
6531 case 10:
6532 switch (sel) {
6533 case 0:
895c2d04 6534 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6535 break;
6536 default:
1a3fd9c3 6537 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6538 break;
6539 }
6540 case 12:
6541 switch (sel) {
6542 case 0:
895c2d04 6543 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6544 break;
6545 default:
1a3fd9c3 6546 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6547 break;
6548 }
5a25ce94
EI
6549 case 13:
6550 switch (sel) {
6551 case 0:
895c2d04 6552 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6553 break;
6554 default:
6555 goto die;
6556 break;
6557 }
6558 break;
6559 case 14:
6560 switch (sel) {
6561 case 0:
895c2d04 6562 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6563 break;
6564 default:
6565 goto die;
6566 break;
6567 }
6568 break;
6569 case 15:
6570 switch (sel) {
6571 case 1:
895c2d04 6572 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6573 break;
6574 default:
6575 goto die;
6576 break;
6577 }
6578 break;
6579 case 16:
6580 switch (sel) {
6581 case 0 ... 7:
895c2d04 6582 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6583 break;
6584 default:
6585 goto die;
6586 break;
6587 }
6588 break;
ead9360e
TS
6589 case 23:
6590 switch (sel) {
6591 case 0:
895c2d04 6592 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6593 break;
6594 default:
1a3fd9c3 6595 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6596 break;
6597 }
6598 break;
6599 default:
1a3fd9c3 6600 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6601 }
6602 } else switch (sel) {
6603 /* GPR registers. */
6604 case 0:
895c2d04 6605 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6606 break;
6607 /* Auxiliary CPU registers */
6608 case 1:
6609 switch (rt) {
6610 case 0:
895c2d04 6611 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6612 break;
6613 case 1:
895c2d04 6614 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6615 break;
6616 case 2:
895c2d04 6617 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6618 break;
6619 case 4:
895c2d04 6620 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6621 break;
6622 case 5:
895c2d04 6623 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6624 break;
6625 case 6:
895c2d04 6626 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6627 break;
6628 case 8:
895c2d04 6629 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6630 break;
6631 case 9:
895c2d04 6632 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6633 break;
6634 case 10:
895c2d04 6635 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6636 break;
6637 case 12:
895c2d04 6638 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6639 break;
6640 case 13:
895c2d04 6641 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6642 break;
6643 case 14:
895c2d04 6644 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6645 break;
6646 case 16:
895c2d04 6647 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6648 break;
6649 default:
6650 goto die;
6651 }
6652 break;
6653 /* Floating point (COP1). */
6654 case 2:
6655 /* XXX: For now we support only a single FPU context. */
6656 if (h == 0) {
a7812ae4 6657 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6658
6659 gen_load_fpr32(fp0, rt);
6660 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6661 tcg_temp_free_i32(fp0);
ead9360e 6662 } else {
a7812ae4 6663 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6664
6665 gen_load_fpr32h(fp0, rt);
6666 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6667 tcg_temp_free_i32(fp0);
ead9360e
TS
6668 }
6669 break;
6670 case 3:
6671 /* XXX: For now we support only a single FPU context. */
895c2d04 6672 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6673 break;
6674 /* COP2: Not implemented. */
6675 case 4:
6676 case 5:
6677 /* fall through */
6678 default:
6679 goto die;
6680 }
d12d51d5 6681 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6682 gen_store_gpr(t0, rd);
6683 tcg_temp_free(t0);
ead9360e
TS
6684 return;
6685
6686die:
1a3fd9c3 6687 tcg_temp_free(t0);
d12d51d5 6688 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6689 generate_exception(ctx, EXCP_RI);
6690}
6691
7db13fae 6692static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6693 int u, int sel, int h)
6694{
6695 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6696 TCGv t0 = tcg_temp_local_new();
ead9360e 6697
1a3fd9c3 6698 gen_load_gpr(t0, rt);
ead9360e 6699 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6700 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6701 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6702 /* NOP */ ;
6703 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6704 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6705 /* NOP */ ;
6706 else if (u == 0) {
6707 switch (rd) {
5a25ce94
EI
6708 case 1:
6709 switch (sel) {
6710 case 1:
895c2d04 6711 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6712 break;
6713 case 2:
895c2d04 6714 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6715 break;
6716 default:
6717 goto die;
6718 break;
6719 }
6720 break;
ead9360e
TS
6721 case 2:
6722 switch (sel) {
6723 case 1:
895c2d04 6724 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6725 break;
6726 case 2:
895c2d04 6727 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6728 break;
6729 case 3:
895c2d04 6730 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6731 break;
6732 case 4:
895c2d04 6733 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6734 break;
6735 case 5:
895c2d04 6736 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6737 break;
6738 case 6:
895c2d04 6739 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6740 break;
6741 case 7:
895c2d04 6742 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6743 break;
6744 default:
1a3fd9c3 6745 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6746 break;
6747 }
6748 break;
6749 case 10:
6750 switch (sel) {
6751 case 0:
895c2d04 6752 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6753 break;
6754 default:
1a3fd9c3 6755 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6756 break;
6757 }
6758 case 12:
6759 switch (sel) {
6760 case 0:
895c2d04 6761 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6762 break;
6763 default:
1a3fd9c3 6764 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6765 break;
6766 }
5a25ce94
EI
6767 case 13:
6768 switch (sel) {
6769 case 0:
895c2d04 6770 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6771 break;
6772 default:
6773 goto die;
6774 break;
6775 }
6776 break;
6777 case 15:
6778 switch (sel) {
6779 case 1:
895c2d04 6780 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6781 break;
6782 default:
6783 goto die;
6784 break;
6785 }
6786 break;
ead9360e
TS
6787 case 23:
6788 switch (sel) {
6789 case 0:
895c2d04 6790 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6791 break;
6792 default:
1a3fd9c3 6793 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6794 break;
6795 }
6796 break;
6797 default:
1a3fd9c3 6798 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6799 }
6800 } else switch (sel) {
6801 /* GPR registers. */
6802 case 0:
895c2d04 6803 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6804 break;
6805 /* Auxiliary CPU registers */
6806 case 1:
6807 switch (rd) {
6808 case 0:
895c2d04 6809 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6810 break;
6811 case 1:
895c2d04 6812 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6813 break;
6814 case 2:
895c2d04 6815 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6816 break;
6817 case 4:
895c2d04 6818 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6819 break;
6820 case 5:
895c2d04 6821 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6822 break;
6823 case 6:
895c2d04 6824 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6825 break;
6826 case 8:
895c2d04 6827 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6828 break;
6829 case 9:
895c2d04 6830 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6831 break;
6832 case 10:
895c2d04 6833 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6834 break;
6835 case 12:
895c2d04 6836 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6837 break;
6838 case 13:
895c2d04 6839 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6840 break;
6841 case 14:
895c2d04 6842 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6843 break;
6844 case 16:
895c2d04 6845 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6846 break;
6847 default:
6848 goto die;
6849 }
6850 break;
6851 /* Floating point (COP1). */
6852 case 2:
6853 /* XXX: For now we support only a single FPU context. */
6854 if (h == 0) {
a7812ae4 6855 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6856
6857 tcg_gen_trunc_tl_i32(fp0, t0);
6858 gen_store_fpr32(fp0, rd);
a7812ae4 6859 tcg_temp_free_i32(fp0);
ead9360e 6860 } else {
a7812ae4 6861 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6862
6863 tcg_gen_trunc_tl_i32(fp0, t0);
6864 gen_store_fpr32h(fp0, rd);
a7812ae4 6865 tcg_temp_free_i32(fp0);
ead9360e
TS
6866 }
6867 break;
6868 case 3:
6869 /* XXX: For now we support only a single FPU context. */
895c2d04 6870 gen_helper_0e1i(ctc1, t0, rd);
ead9360e
TS
6871 break;
6872 /* COP2: Not implemented. */
6873 case 4:
6874 case 5:
6875 /* fall through */
6876 default:
6877 goto die;
6878 }
d12d51d5 6879 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6880 tcg_temp_free(t0);
ead9360e
TS
6881 return;
6882
6883die:
1a3fd9c3 6884 tcg_temp_free(t0);
d12d51d5 6885 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6886 generate_exception(ctx, EXCP_RI);
6887}
6888
7db13fae 6889static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6890{
287c4b84 6891 const char *opn = "ldst";
6af0bf9c 6892
2e15497c 6893 check_cp0_enabled(ctx);
6af0bf9c
FB
6894 switch (opc) {
6895 case OPC_MFC0:
6896 if (rt == 0) {
ead9360e 6897 /* Treat as NOP. */
6af0bf9c
FB
6898 return;
6899 }
1fc7bf6e 6900 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6901 opn = "mfc0";
6902 break;
6903 case OPC_MTC0:
1a3fd9c3 6904 {
1fc7bf6e 6905 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6906
6907 gen_load_gpr(t0, rt);
1a3fd9c3
TS
6908 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6909 tcg_temp_free(t0);
6910 }
6af0bf9c
FB
6911 opn = "mtc0";
6912 break;
d26bc211 6913#if defined(TARGET_MIPS64)
9c2149c8 6914 case OPC_DMFC0:
e189e748 6915 check_insn(env, ctx, ISA_MIPS3);
9c2149c8 6916 if (rt == 0) {
ead9360e 6917 /* Treat as NOP. */
9c2149c8
TS
6918 return;
6919 }
1fc7bf6e 6920 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6921 opn = "dmfc0";
6922 break;
6923 case OPC_DMTC0:
e189e748 6924 check_insn(env, ctx, ISA_MIPS3);
1a3fd9c3 6925 {
1fc7bf6e 6926 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6927
6928 gen_load_gpr(t0, rt);
1a3fd9c3
TS
6929 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6930 tcg_temp_free(t0);
6931 }
9c2149c8
TS
6932 opn = "dmtc0";
6933 break;
534ce69f 6934#endif
ead9360e 6935 case OPC_MFTR:
7385ac0b 6936 check_insn(env, ctx, ASE_MT);
ead9360e
TS
6937 if (rd == 0) {
6938 /* Treat as NOP. */
6939 return;
6940 }
6c5c1e20 6941 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6942 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6943 opn = "mftr";
6944 break;
6945 case OPC_MTTR:
7385ac0b 6946 check_insn(env, ctx, ASE_MT);
6c5c1e20 6947 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6948 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6949 opn = "mttr";
6950 break;
6af0bf9c 6951 case OPC_TLBWI:
6af0bf9c 6952 opn = "tlbwi";
c01fccd2 6953 if (!env->tlb->helper_tlbwi)
29929e34 6954 goto die;
895c2d04 6955 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6956 break;
6957 case OPC_TLBWR:
6af0bf9c 6958 opn = "tlbwr";
c01fccd2 6959 if (!env->tlb->helper_tlbwr)
29929e34 6960 goto die;
895c2d04 6961 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6962 break;
6963 case OPC_TLBP:
6af0bf9c 6964 opn = "tlbp";
c01fccd2 6965 if (!env->tlb->helper_tlbp)
29929e34 6966 goto die;
895c2d04 6967 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6968 break;
6969 case OPC_TLBR:
6af0bf9c 6970 opn = "tlbr";
c01fccd2 6971 if (!env->tlb->helper_tlbr)
29929e34 6972 goto die;
895c2d04 6973 gen_helper_tlbr(cpu_env);
6af0bf9c 6974 break;
6af0bf9c
FB
6975 case OPC_ERET:
6976 opn = "eret";
e189e748 6977 check_insn(env, ctx, ISA_MIPS2);
895c2d04 6978 gen_helper_eret(cpu_env);
6af0bf9c
FB
6979 ctx->bstate = BS_EXCP;
6980 break;
6981 case OPC_DERET:
6982 opn = "deret";
e189e748 6983 check_insn(env, ctx, ISA_MIPS32);
6af0bf9c 6984 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6985 MIPS_INVAL(opn);
6af0bf9c
FB
6986 generate_exception(ctx, EXCP_RI);
6987 } else {
895c2d04 6988 gen_helper_deret(cpu_env);
6af0bf9c
FB
6989 ctx->bstate = BS_EXCP;
6990 }
6991 break;
4ad40f36
FB
6992 case OPC_WAIT:
6993 opn = "wait";
e189e748 6994 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6995 /* If we get an exception, we want to restart at next instruction */
6996 ctx->pc += 4;
6997 save_cpu_state(ctx, 1);
6998 ctx->pc -= 4;
895c2d04 6999 gen_helper_wait(cpu_env);
4ad40f36
FB
7000 ctx->bstate = BS_EXCP;
7001 break;
6af0bf9c 7002 default:
29929e34 7003 die:
923617a3 7004 MIPS_INVAL(opn);
6af0bf9c
FB
7005 generate_exception(ctx, EXCP_RI);
7006 return;
7007 }
2abf314d 7008 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7009 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7010}
f1aa6320 7011#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7012
6ea83fed 7013/* CP1 Branches (before delay slot) */
7db13fae 7014static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
5a5012ec 7015 int32_t cc, int32_t offset)
6ea83fed
FB
7016{
7017 target_ulong btarget;
923617a3 7018 const char *opn = "cp1 cond branch";
a7812ae4 7019 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7020
e189e748
TS
7021 if (cc != 0)
7022 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7023
6ea83fed
FB
7024 btarget = ctx->pc + 4 + offset;
7025
7a387fff
TS
7026 switch (op) {
7027 case OPC_BC1F:
d94536f4
AJ
7028 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7029 tcg_gen_not_i32(t0, t0);
7030 tcg_gen_andi_i32(t0, t0, 1);
7031 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7032 opn = "bc1f";
6ea83fed 7033 goto not_likely;
7a387fff 7034 case OPC_BC1FL:
d94536f4
AJ
7035 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7036 tcg_gen_not_i32(t0, t0);
7037 tcg_gen_andi_i32(t0, t0, 1);
7038 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7039 opn = "bc1fl";
6ea83fed 7040 goto likely;
7a387fff 7041 case OPC_BC1T:
d94536f4
AJ
7042 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7043 tcg_gen_andi_i32(t0, t0, 1);
7044 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7045 opn = "bc1t";
5a5012ec 7046 goto not_likely;
7a387fff 7047 case OPC_BC1TL:
d94536f4
AJ
7048 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7049 tcg_gen_andi_i32(t0, t0, 1);
7050 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7051 opn = "bc1tl";
6ea83fed
FB
7052 likely:
7053 ctx->hflags |= MIPS_HFLAG_BL;
7054 break;
5a5012ec 7055 case OPC_BC1FANY2:
a16336e4 7056 {
d94536f4
AJ
7057 TCGv_i32 t1 = tcg_temp_new_i32();
7058 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7060 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7061 tcg_temp_free_i32(t1);
d94536f4
AJ
7062 tcg_gen_andi_i32(t0, t0, 1);
7063 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7064 }
fd4a04eb 7065 opn = "bc1any2f";
5a5012ec
TS
7066 goto not_likely;
7067 case OPC_BC1TANY2:
a16336e4 7068 {
d94536f4
AJ
7069 TCGv_i32 t1 = tcg_temp_new_i32();
7070 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7071 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7072 tcg_gen_or_i32(t0, t0, t1);
7073 tcg_temp_free_i32(t1);
7074 tcg_gen_andi_i32(t0, t0, 1);
7075 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7076 }
fd4a04eb 7077 opn = "bc1any2t";
5a5012ec
TS
7078 goto not_likely;
7079 case OPC_BC1FANY4:
a16336e4 7080 {
d94536f4
AJ
7081 TCGv_i32 t1 = tcg_temp_new_i32();
7082 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7083 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7084 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7085 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7086 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7087 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7088 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7089 tcg_temp_free_i32(t1);
d94536f4
AJ
7090 tcg_gen_andi_i32(t0, t0, 1);
7091 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7092 }
fd4a04eb 7093 opn = "bc1any4f";
5a5012ec
TS
7094 goto not_likely;
7095 case OPC_BC1TANY4:
a16336e4 7096 {
d94536f4
AJ
7097 TCGv_i32 t1 = tcg_temp_new_i32();
7098 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7099 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7100 tcg_gen_or_i32(t0, t0, t1);
7101 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7102 tcg_gen_or_i32(t0, t0, t1);
7103 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7104 tcg_gen_or_i32(t0, t0, t1);
7105 tcg_temp_free_i32(t1);
7106 tcg_gen_andi_i32(t0, t0, 1);
7107 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7108 }
fd4a04eb 7109 opn = "bc1any4t";
5a5012ec
TS
7110 not_likely:
7111 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7112 break;
7113 default:
923617a3 7114 MIPS_INVAL(opn);
e397ee33 7115 generate_exception (ctx, EXCP_RI);
6c5c1e20 7116 goto out;
6ea83fed 7117 }
2abf314d 7118 (void)opn; /* avoid a compiler warning */
923617a3 7119 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7120 ctx->hflags, btarget);
7121 ctx->btarget = btarget;
6c5c1e20
TS
7122
7123 out:
a7812ae4 7124 tcg_temp_free_i32(t0);
6ea83fed
FB
7125}
7126
6af0bf9c 7127/* Coprocessor 1 (FPU) */
5a5012ec 7128
5a5012ec
TS
7129#define FOP(func, fmt) (((fmt) << 21) | (func))
7130
bf4120ad
NF
7131enum fopcode {
7132 OPC_ADD_S = FOP(0, FMT_S),
7133 OPC_SUB_S = FOP(1, FMT_S),
7134 OPC_MUL_S = FOP(2, FMT_S),
7135 OPC_DIV_S = FOP(3, FMT_S),
7136 OPC_SQRT_S = FOP(4, FMT_S),
7137 OPC_ABS_S = FOP(5, FMT_S),
7138 OPC_MOV_S = FOP(6, FMT_S),
7139 OPC_NEG_S = FOP(7, FMT_S),
7140 OPC_ROUND_L_S = FOP(8, FMT_S),
7141 OPC_TRUNC_L_S = FOP(9, FMT_S),
7142 OPC_CEIL_L_S = FOP(10, FMT_S),
7143 OPC_FLOOR_L_S = FOP(11, FMT_S),
7144 OPC_ROUND_W_S = FOP(12, FMT_S),
7145 OPC_TRUNC_W_S = FOP(13, FMT_S),
7146 OPC_CEIL_W_S = FOP(14, FMT_S),
7147 OPC_FLOOR_W_S = FOP(15, FMT_S),
7148 OPC_MOVCF_S = FOP(17, FMT_S),
7149 OPC_MOVZ_S = FOP(18, FMT_S),
7150 OPC_MOVN_S = FOP(19, FMT_S),
7151 OPC_RECIP_S = FOP(21, FMT_S),
7152 OPC_RSQRT_S = FOP(22, FMT_S),
7153 OPC_RECIP2_S = FOP(28, FMT_S),
7154 OPC_RECIP1_S = FOP(29, FMT_S),
7155 OPC_RSQRT1_S = FOP(30, FMT_S),
7156 OPC_RSQRT2_S = FOP(31, FMT_S),
7157 OPC_CVT_D_S = FOP(33, FMT_S),
7158 OPC_CVT_W_S = FOP(36, FMT_S),
7159 OPC_CVT_L_S = FOP(37, FMT_S),
7160 OPC_CVT_PS_S = FOP(38, FMT_S),
7161 OPC_CMP_F_S = FOP (48, FMT_S),
7162 OPC_CMP_UN_S = FOP (49, FMT_S),
7163 OPC_CMP_EQ_S = FOP (50, FMT_S),
7164 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7165 OPC_CMP_OLT_S = FOP (52, FMT_S),
7166 OPC_CMP_ULT_S = FOP (53, FMT_S),
7167 OPC_CMP_OLE_S = FOP (54, FMT_S),
7168 OPC_CMP_ULE_S = FOP (55, FMT_S),
7169 OPC_CMP_SF_S = FOP (56, FMT_S),
7170 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7171 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7172 OPC_CMP_NGL_S = FOP (59, FMT_S),
7173 OPC_CMP_LT_S = FOP (60, FMT_S),
7174 OPC_CMP_NGE_S = FOP (61, FMT_S),
7175 OPC_CMP_LE_S = FOP (62, FMT_S),
7176 OPC_CMP_NGT_S = FOP (63, FMT_S),
7177
7178 OPC_ADD_D = FOP(0, FMT_D),
7179 OPC_SUB_D = FOP(1, FMT_D),
7180 OPC_MUL_D = FOP(2, FMT_D),
7181 OPC_DIV_D = FOP(3, FMT_D),
7182 OPC_SQRT_D = FOP(4, FMT_D),
7183 OPC_ABS_D = FOP(5, FMT_D),
7184 OPC_MOV_D = FOP(6, FMT_D),
7185 OPC_NEG_D = FOP(7, FMT_D),
7186 OPC_ROUND_L_D = FOP(8, FMT_D),
7187 OPC_TRUNC_L_D = FOP(9, FMT_D),
7188 OPC_CEIL_L_D = FOP(10, FMT_D),
7189 OPC_FLOOR_L_D = FOP(11, FMT_D),
7190 OPC_ROUND_W_D = FOP(12, FMT_D),
7191 OPC_TRUNC_W_D = FOP(13, FMT_D),
7192 OPC_CEIL_W_D = FOP(14, FMT_D),
7193 OPC_FLOOR_W_D = FOP(15, FMT_D),
7194 OPC_MOVCF_D = FOP(17, FMT_D),
7195 OPC_MOVZ_D = FOP(18, FMT_D),
7196 OPC_MOVN_D = FOP(19, FMT_D),
7197 OPC_RECIP_D = FOP(21, FMT_D),
7198 OPC_RSQRT_D = FOP(22, FMT_D),
7199 OPC_RECIP2_D = FOP(28, FMT_D),
7200 OPC_RECIP1_D = FOP(29, FMT_D),
7201 OPC_RSQRT1_D = FOP(30, FMT_D),
7202 OPC_RSQRT2_D = FOP(31, FMT_D),
7203 OPC_CVT_S_D = FOP(32, FMT_D),
7204 OPC_CVT_W_D = FOP(36, FMT_D),
7205 OPC_CVT_L_D = FOP(37, FMT_D),
7206 OPC_CMP_F_D = FOP (48, FMT_D),
7207 OPC_CMP_UN_D = FOP (49, FMT_D),
7208 OPC_CMP_EQ_D = FOP (50, FMT_D),
7209 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7210 OPC_CMP_OLT_D = FOP (52, FMT_D),
7211 OPC_CMP_ULT_D = FOP (53, FMT_D),
7212 OPC_CMP_OLE_D = FOP (54, FMT_D),
7213 OPC_CMP_ULE_D = FOP (55, FMT_D),
7214 OPC_CMP_SF_D = FOP (56, FMT_D),
7215 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7216 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7217 OPC_CMP_NGL_D = FOP (59, FMT_D),
7218 OPC_CMP_LT_D = FOP (60, FMT_D),
7219 OPC_CMP_NGE_D = FOP (61, FMT_D),
7220 OPC_CMP_LE_D = FOP (62, FMT_D),
7221 OPC_CMP_NGT_D = FOP (63, FMT_D),
7222
7223 OPC_CVT_S_W = FOP(32, FMT_W),
7224 OPC_CVT_D_W = FOP(33, FMT_W),
7225 OPC_CVT_S_L = FOP(32, FMT_L),
7226 OPC_CVT_D_L = FOP(33, FMT_L),
7227 OPC_CVT_PS_PW = FOP(38, FMT_W),
7228
7229 OPC_ADD_PS = FOP(0, FMT_PS),
7230 OPC_SUB_PS = FOP(1, FMT_PS),
7231 OPC_MUL_PS = FOP(2, FMT_PS),
7232 OPC_DIV_PS = FOP(3, FMT_PS),
7233 OPC_ABS_PS = FOP(5, FMT_PS),
7234 OPC_MOV_PS = FOP(6, FMT_PS),
7235 OPC_NEG_PS = FOP(7, FMT_PS),
7236 OPC_MOVCF_PS = FOP(17, FMT_PS),
7237 OPC_MOVZ_PS = FOP(18, FMT_PS),
7238 OPC_MOVN_PS = FOP(19, FMT_PS),
7239 OPC_ADDR_PS = FOP(24, FMT_PS),
7240 OPC_MULR_PS = FOP(26, FMT_PS),
7241 OPC_RECIP2_PS = FOP(28, FMT_PS),
7242 OPC_RECIP1_PS = FOP(29, FMT_PS),
7243 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7244 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7245
7246 OPC_CVT_S_PU = FOP(32, FMT_PS),
7247 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7248 OPC_CVT_S_PL = FOP(40, FMT_PS),
7249 OPC_PLL_PS = FOP(44, FMT_PS),
7250 OPC_PLU_PS = FOP(45, FMT_PS),
7251 OPC_PUL_PS = FOP(46, FMT_PS),
7252 OPC_PUU_PS = FOP(47, FMT_PS),
7253 OPC_CMP_F_PS = FOP (48, FMT_PS),
7254 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7255 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7256 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7257 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7258 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7259 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7260 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7261 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7262 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7263 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7264 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7265 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7266 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7267 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7268 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7269};
7270
7a387fff 7271static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7272{
923617a3 7273 const char *opn = "cp1 move";
72c3a3ee 7274 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7275
7276 switch (opc) {
7277 case OPC_MFC1:
b6d96bed 7278 {
a7812ae4 7279 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7280
7281 gen_load_fpr32(fp0, fs);
7282 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7283 tcg_temp_free_i32(fp0);
6958549d 7284 }
6c5c1e20 7285 gen_store_gpr(t0, rt);
6ea83fed
FB
7286 opn = "mfc1";
7287 break;
7288 case OPC_MTC1:
6c5c1e20 7289 gen_load_gpr(t0, rt);
b6d96bed 7290 {
a7812ae4 7291 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7292
7293 tcg_gen_trunc_tl_i32(fp0, t0);
7294 gen_store_fpr32(fp0, fs);
a7812ae4 7295 tcg_temp_free_i32(fp0);
6958549d 7296 }
6ea83fed
FB
7297 opn = "mtc1";
7298 break;
7299 case OPC_CFC1:
895c2d04 7300 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7301 gen_store_gpr(t0, rt);
6ea83fed
FB
7302 opn = "cfc1";
7303 break;
7304 case OPC_CTC1:
6c5c1e20 7305 gen_load_gpr(t0, rt);
895c2d04 7306 gen_helper_0e1i(ctc1, t0, fs);
6ea83fed
FB
7307 opn = "ctc1";
7308 break;
72c3a3ee 7309#if defined(TARGET_MIPS64)
9c2149c8 7310 case OPC_DMFC1:
72c3a3ee 7311 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7312 gen_store_gpr(t0, rt);
5a5012ec
TS
7313 opn = "dmfc1";
7314 break;
9c2149c8 7315 case OPC_DMTC1:
6c5c1e20 7316 gen_load_gpr(t0, rt);
72c3a3ee 7317 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7318 opn = "dmtc1";
7319 break;
72c3a3ee 7320#endif
5a5012ec 7321 case OPC_MFHC1:
b6d96bed 7322 {
a7812ae4 7323 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7324
7325 gen_load_fpr32h(fp0, fs);
7326 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7327 tcg_temp_free_i32(fp0);
6958549d 7328 }
6c5c1e20 7329 gen_store_gpr(t0, rt);
5a5012ec
TS
7330 opn = "mfhc1";
7331 break;
7332 case OPC_MTHC1:
6c5c1e20 7333 gen_load_gpr(t0, rt);
b6d96bed 7334 {
a7812ae4 7335 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7336
7337 tcg_gen_trunc_tl_i32(fp0, t0);
7338 gen_store_fpr32h(fp0, fs);
a7812ae4 7339 tcg_temp_free_i32(fp0);
6958549d 7340 }
5a5012ec
TS
7341 opn = "mthc1";
7342 break;
6ea83fed 7343 default:
923617a3 7344 MIPS_INVAL(opn);
e397ee33 7345 generate_exception (ctx, EXCP_RI);
6c5c1e20 7346 goto out;
6ea83fed 7347 }
2abf314d 7348 (void)opn; /* avoid a compiler warning */
6ea83fed 7349 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7350
7351 out:
7352 tcg_temp_free(t0);
6ea83fed
FB
7353}
7354
5a5012ec
TS
7355static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7356{
af58f9ca 7357 int l1;
e214b9bb 7358 TCGCond cond;
af58f9ca
AJ
7359 TCGv_i32 t0;
7360
7361 if (rd == 0) {
7362 /* Treat as NOP. */
7363 return;
7364 }
6ea83fed 7365
e214b9bb 7366 if (tf)
e214b9bb 7367 cond = TCG_COND_EQ;
27848470
TS
7368 else
7369 cond = TCG_COND_NE;
7370
af58f9ca
AJ
7371 l1 = gen_new_label();
7372 t0 = tcg_temp_new_i32();
fa31af0e 7373 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7374 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7375 tcg_temp_free_i32(t0);
af58f9ca
AJ
7376 if (rs == 0) {
7377 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7378 } else {
7379 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7380 }
e214b9bb 7381 gen_set_label(l1);
5a5012ec
TS
7382}
7383
b6d96bed 7384static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7385{
a16336e4 7386 int cond;
cbc37b28 7387 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7388 int l1 = gen_new_label();
7389
a16336e4
TS
7390 if (tf)
7391 cond = TCG_COND_EQ;
7392 else
7393 cond = TCG_COND_NE;
7394
fa31af0e 7395 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7396 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7397 gen_load_fpr32(t0, fs);
7398 gen_store_fpr32(t0, fd);
a16336e4 7399 gen_set_label(l1);
cbc37b28 7400 tcg_temp_free_i32(t0);
5a5012ec 7401}
a16336e4 7402
b6d96bed 7403static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7404{
a16336e4 7405 int cond;
cbc37b28
AJ
7406 TCGv_i32 t0 = tcg_temp_new_i32();
7407 TCGv_i64 fp0;
a16336e4
TS
7408 int l1 = gen_new_label();
7409
a16336e4
TS
7410 if (tf)
7411 cond = TCG_COND_EQ;
7412 else
7413 cond = TCG_COND_NE;
7414
fa31af0e 7415 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7416 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7417 tcg_temp_free_i32(t0);
11f94258 7418 fp0 = tcg_temp_new_i64();
9bf3eb2c 7419 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7420 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7421 tcg_temp_free_i64(fp0);
cbc37b28 7422 gen_set_label(l1);
a16336e4
TS
7423}
7424
b6d96bed 7425static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
a16336e4
TS
7426{
7427 int cond;
cbc37b28 7428 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7429 int l1 = gen_new_label();
7430 int l2 = gen_new_label();
7431
7432 if (tf)
7433 cond = TCG_COND_EQ;
7434 else
7435 cond = TCG_COND_NE;
7436
fa31af0e 7437 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7438 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7439 gen_load_fpr32(t0, fs);
7440 gen_store_fpr32(t0, fd);
a16336e4 7441 gen_set_label(l1);
9bf3eb2c 7442
fa31af0e 7443 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28
AJ
7444 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7445 gen_load_fpr32h(t0, fs);
7446 gen_store_fpr32h(t0, fd);
52a0e9eb 7447 tcg_temp_free_i32(t0);
a16336e4 7448 gen_set_label(l2);
a16336e4
TS
7449}
7450
6ea83fed 7451
bf4120ad 7452static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7453 int ft, int fs, int fd, int cc)
6ea83fed 7454{
923617a3 7455 const char *opn = "farith";
6ea83fed
FB
7456 const char *condnames[] = {
7457 "c.f",
7458 "c.un",
7459 "c.eq",
7460 "c.ueq",
7461 "c.olt",
7462 "c.ult",
7463 "c.ole",
7464 "c.ule",
7465 "c.sf",
7466 "c.ngle",
7467 "c.seq",
7468 "c.ngl",
7469 "c.lt",
7470 "c.nge",
7471 "c.le",
7472 "c.ngt",
7473 };
5a1e8ffb
TS
7474 const char *condnames_abs[] = {
7475 "cabs.f",
7476 "cabs.un",
7477 "cabs.eq",
7478 "cabs.ueq",
7479 "cabs.olt",
7480 "cabs.ult",
7481 "cabs.ole",
7482 "cabs.ule",
7483 "cabs.sf",
7484 "cabs.ngle",
7485 "cabs.seq",
7486 "cabs.ngl",
7487 "cabs.lt",
7488 "cabs.nge",
7489 "cabs.le",
7490 "cabs.ngt",
7491 };
7492 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7493 uint32_t func = ctx->opcode & 0x3f;
7494
bf4120ad
NF
7495 switch (op1) {
7496 case OPC_ADD_S:
b6d96bed 7497 {
a7812ae4
PB
7498 TCGv_i32 fp0 = tcg_temp_new_i32();
7499 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7500
7501 gen_load_fpr32(fp0, fs);
7502 gen_load_fpr32(fp1, ft);
895c2d04 7503 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7504 tcg_temp_free_i32(fp1);
b6d96bed 7505 gen_store_fpr32(fp0, fd);
a7812ae4 7506 tcg_temp_free_i32(fp0);
b6d96bed 7507 }
5a5012ec 7508 opn = "add.s";
5a1e8ffb 7509 optype = BINOP;
5a5012ec 7510 break;
bf4120ad 7511 case OPC_SUB_S:
b6d96bed 7512 {
a7812ae4
PB
7513 TCGv_i32 fp0 = tcg_temp_new_i32();
7514 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7515
7516 gen_load_fpr32(fp0, fs);
7517 gen_load_fpr32(fp1, ft);
895c2d04 7518 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7519 tcg_temp_free_i32(fp1);
b6d96bed 7520 gen_store_fpr32(fp0, fd);
a7812ae4 7521 tcg_temp_free_i32(fp0);
b6d96bed 7522 }
5a5012ec 7523 opn = "sub.s";
5a1e8ffb 7524 optype = BINOP;
5a5012ec 7525 break;
bf4120ad 7526 case OPC_MUL_S:
b6d96bed 7527 {
a7812ae4
PB
7528 TCGv_i32 fp0 = tcg_temp_new_i32();
7529 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7530
7531 gen_load_fpr32(fp0, fs);
7532 gen_load_fpr32(fp1, ft);
895c2d04 7533 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7534 tcg_temp_free_i32(fp1);
b6d96bed 7535 gen_store_fpr32(fp0, fd);
a7812ae4 7536 tcg_temp_free_i32(fp0);
b6d96bed 7537 }
5a5012ec 7538 opn = "mul.s";
5a1e8ffb 7539 optype = BINOP;
5a5012ec 7540 break;
bf4120ad 7541 case OPC_DIV_S:
b6d96bed 7542 {
a7812ae4
PB
7543 TCGv_i32 fp0 = tcg_temp_new_i32();
7544 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7545
7546 gen_load_fpr32(fp0, fs);
7547 gen_load_fpr32(fp1, ft);
895c2d04 7548 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7549 tcg_temp_free_i32(fp1);
b6d96bed 7550 gen_store_fpr32(fp0, fd);
a7812ae4 7551 tcg_temp_free_i32(fp0);
b6d96bed 7552 }
5a5012ec 7553 opn = "div.s";
5a1e8ffb 7554 optype = BINOP;
5a5012ec 7555 break;
bf4120ad 7556 case OPC_SQRT_S:
b6d96bed 7557 {
a7812ae4 7558 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7559
7560 gen_load_fpr32(fp0, fs);
895c2d04 7561 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7562 gen_store_fpr32(fp0, fd);
a7812ae4 7563 tcg_temp_free_i32(fp0);
b6d96bed 7564 }
5a5012ec
TS
7565 opn = "sqrt.s";
7566 break;
bf4120ad 7567 case OPC_ABS_S:
b6d96bed 7568 {
a7812ae4 7569 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7570
7571 gen_load_fpr32(fp0, fs);
a7812ae4 7572 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7573 gen_store_fpr32(fp0, fd);
a7812ae4 7574 tcg_temp_free_i32(fp0);
b6d96bed 7575 }
5a5012ec
TS
7576 opn = "abs.s";
7577 break;
bf4120ad 7578 case OPC_MOV_S:
b6d96bed 7579 {
a7812ae4 7580 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7581
7582 gen_load_fpr32(fp0, fs);
7583 gen_store_fpr32(fp0, fd);
a7812ae4 7584 tcg_temp_free_i32(fp0);
b6d96bed 7585 }
5a5012ec
TS
7586 opn = "mov.s";
7587 break;
bf4120ad 7588 case OPC_NEG_S:
b6d96bed 7589 {
a7812ae4 7590 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7591
7592 gen_load_fpr32(fp0, fs);
a7812ae4 7593 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7594 gen_store_fpr32(fp0, fd);
a7812ae4 7595 tcg_temp_free_i32(fp0);
b6d96bed 7596 }
5a5012ec
TS
7597 opn = "neg.s";
7598 break;
bf4120ad 7599 case OPC_ROUND_L_S:
5e755519 7600 check_cp1_64bitmode(ctx);
b6d96bed 7601 {
a7812ae4
PB
7602 TCGv_i32 fp32 = tcg_temp_new_i32();
7603 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7604
7605 gen_load_fpr32(fp32, fs);
895c2d04 7606 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7607 tcg_temp_free_i32(fp32);
b6d96bed 7608 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7609 tcg_temp_free_i64(fp64);
b6d96bed 7610 }
5a5012ec
TS
7611 opn = "round.l.s";
7612 break;
bf4120ad 7613 case OPC_TRUNC_L_S:
5e755519 7614 check_cp1_64bitmode(ctx);
b6d96bed 7615 {
a7812ae4
PB
7616 TCGv_i32 fp32 = tcg_temp_new_i32();
7617 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7618
7619 gen_load_fpr32(fp32, fs);
895c2d04 7620 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7621 tcg_temp_free_i32(fp32);
b6d96bed 7622 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7623 tcg_temp_free_i64(fp64);
b6d96bed 7624 }
5a5012ec
TS
7625 opn = "trunc.l.s";
7626 break;
bf4120ad 7627 case OPC_CEIL_L_S:
5e755519 7628 check_cp1_64bitmode(ctx);
b6d96bed 7629 {
a7812ae4
PB
7630 TCGv_i32 fp32 = tcg_temp_new_i32();
7631 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7632
7633 gen_load_fpr32(fp32, fs);
895c2d04 7634 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7635 tcg_temp_free_i32(fp32);
b6d96bed 7636 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7637 tcg_temp_free_i64(fp64);
b6d96bed 7638 }
5a5012ec
TS
7639 opn = "ceil.l.s";
7640 break;
bf4120ad 7641 case OPC_FLOOR_L_S:
5e755519 7642 check_cp1_64bitmode(ctx);
b6d96bed 7643 {
a7812ae4
PB
7644 TCGv_i32 fp32 = tcg_temp_new_i32();
7645 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7646
7647 gen_load_fpr32(fp32, fs);
895c2d04 7648 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7649 tcg_temp_free_i32(fp32);
b6d96bed 7650 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7651 tcg_temp_free_i64(fp64);
b6d96bed 7652 }
5a5012ec
TS
7653 opn = "floor.l.s";
7654 break;
bf4120ad 7655 case OPC_ROUND_W_S:
b6d96bed 7656 {
a7812ae4 7657 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7658
7659 gen_load_fpr32(fp0, fs);
895c2d04 7660 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7661 gen_store_fpr32(fp0, fd);
a7812ae4 7662 tcg_temp_free_i32(fp0);
b6d96bed 7663 }
5a5012ec
TS
7664 opn = "round.w.s";
7665 break;
bf4120ad 7666 case OPC_TRUNC_W_S:
b6d96bed 7667 {
a7812ae4 7668 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7669
7670 gen_load_fpr32(fp0, fs);
895c2d04 7671 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7672 gen_store_fpr32(fp0, fd);
a7812ae4 7673 tcg_temp_free_i32(fp0);
b6d96bed 7674 }
5a5012ec
TS
7675 opn = "trunc.w.s";
7676 break;
bf4120ad 7677 case OPC_CEIL_W_S:
b6d96bed 7678 {
a7812ae4 7679 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7680
7681 gen_load_fpr32(fp0, fs);
895c2d04 7682 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7683 gen_store_fpr32(fp0, fd);
a7812ae4 7684 tcg_temp_free_i32(fp0);
b6d96bed 7685 }
5a5012ec
TS
7686 opn = "ceil.w.s";
7687 break;
bf4120ad 7688 case OPC_FLOOR_W_S:
b6d96bed 7689 {
a7812ae4 7690 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7691
7692 gen_load_fpr32(fp0, fs);
895c2d04 7693 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7694 gen_store_fpr32(fp0, fd);
a7812ae4 7695 tcg_temp_free_i32(fp0);
b6d96bed 7696 }
5a5012ec
TS
7697 opn = "floor.w.s";
7698 break;
bf4120ad 7699 case OPC_MOVCF_S:
b6d96bed 7700 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7701 opn = "movcf.s";
7702 break;
bf4120ad 7703 case OPC_MOVZ_S:
a16336e4
TS
7704 {
7705 int l1 = gen_new_label();
c9297f4d 7706 TCGv_i32 fp0;
a16336e4 7707
c9297f4d
AJ
7708 if (ft != 0) {
7709 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7710 }
7711 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7712 gen_load_fpr32(fp0, fs);
7713 gen_store_fpr32(fp0, fd);
a7812ae4 7714 tcg_temp_free_i32(fp0);
a16336e4
TS
7715 gen_set_label(l1);
7716 }
5a5012ec
TS
7717 opn = "movz.s";
7718 break;
bf4120ad 7719 case OPC_MOVN_S:
a16336e4
TS
7720 {
7721 int l1 = gen_new_label();
c9297f4d
AJ
7722 TCGv_i32 fp0;
7723
7724 if (ft != 0) {
7725 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7726 fp0 = tcg_temp_new_i32();
7727 gen_load_fpr32(fp0, fs);
7728 gen_store_fpr32(fp0, fd);
7729 tcg_temp_free_i32(fp0);
7730 gen_set_label(l1);
7731 }
a16336e4 7732 }
5a5012ec
TS
7733 opn = "movn.s";
7734 break;
bf4120ad 7735 case OPC_RECIP_S:
b8aa4598 7736 check_cop1x(ctx);
b6d96bed 7737 {
a7812ae4 7738 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7739
7740 gen_load_fpr32(fp0, fs);
895c2d04 7741 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7742 gen_store_fpr32(fp0, fd);
a7812ae4 7743 tcg_temp_free_i32(fp0);
b6d96bed 7744 }
57fa1fb3
TS
7745 opn = "recip.s";
7746 break;
bf4120ad 7747 case OPC_RSQRT_S:
b8aa4598 7748 check_cop1x(ctx);
b6d96bed 7749 {
a7812ae4 7750 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7751
7752 gen_load_fpr32(fp0, fs);
895c2d04 7753 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7754 gen_store_fpr32(fp0, fd);
a7812ae4 7755 tcg_temp_free_i32(fp0);
b6d96bed 7756 }
57fa1fb3
TS
7757 opn = "rsqrt.s";
7758 break;
bf4120ad 7759 case OPC_RECIP2_S:
5e755519 7760 check_cp1_64bitmode(ctx);
b6d96bed 7761 {
a7812ae4
PB
7762 TCGv_i32 fp0 = tcg_temp_new_i32();
7763 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7764
7765 gen_load_fpr32(fp0, fs);
d22d7289 7766 gen_load_fpr32(fp1, ft);
895c2d04 7767 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7768 tcg_temp_free_i32(fp1);
b6d96bed 7769 gen_store_fpr32(fp0, fd);
a7812ae4 7770 tcg_temp_free_i32(fp0);
b6d96bed 7771 }
57fa1fb3
TS
7772 opn = "recip2.s";
7773 break;
bf4120ad 7774 case OPC_RECIP1_S:
5e755519 7775 check_cp1_64bitmode(ctx);
b6d96bed 7776 {
a7812ae4 7777 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7778
7779 gen_load_fpr32(fp0, fs);
895c2d04 7780 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7781 gen_store_fpr32(fp0, fd);
a7812ae4 7782 tcg_temp_free_i32(fp0);
b6d96bed 7783 }
57fa1fb3
TS
7784 opn = "recip1.s";
7785 break;
bf4120ad 7786 case OPC_RSQRT1_S:
5e755519 7787 check_cp1_64bitmode(ctx);
b6d96bed 7788 {
a7812ae4 7789 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7790
7791 gen_load_fpr32(fp0, fs);
895c2d04 7792 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7793 gen_store_fpr32(fp0, fd);
a7812ae4 7794 tcg_temp_free_i32(fp0);
b6d96bed 7795 }
57fa1fb3
TS
7796 opn = "rsqrt1.s";
7797 break;
bf4120ad 7798 case OPC_RSQRT2_S:
5e755519 7799 check_cp1_64bitmode(ctx);
b6d96bed 7800 {
a7812ae4
PB
7801 TCGv_i32 fp0 = tcg_temp_new_i32();
7802 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7803
7804 gen_load_fpr32(fp0, fs);
7805 gen_load_fpr32(fp1, ft);
895c2d04 7806 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7807 tcg_temp_free_i32(fp1);
b6d96bed 7808 gen_store_fpr32(fp0, fd);
a7812ae4 7809 tcg_temp_free_i32(fp0);
b6d96bed 7810 }
57fa1fb3
TS
7811 opn = "rsqrt2.s";
7812 break;
bf4120ad 7813 case OPC_CVT_D_S:
5e755519 7814 check_cp1_registers(ctx, fd);
b6d96bed 7815 {
a7812ae4
PB
7816 TCGv_i32 fp32 = tcg_temp_new_i32();
7817 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7818
7819 gen_load_fpr32(fp32, fs);
895c2d04 7820 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7821 tcg_temp_free_i32(fp32);
b6d96bed 7822 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7823 tcg_temp_free_i64(fp64);
b6d96bed 7824 }
5a5012ec
TS
7825 opn = "cvt.d.s";
7826 break;
bf4120ad 7827 case OPC_CVT_W_S:
b6d96bed 7828 {
a7812ae4 7829 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7830
7831 gen_load_fpr32(fp0, fs);
895c2d04 7832 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7833 gen_store_fpr32(fp0, fd);
a7812ae4 7834 tcg_temp_free_i32(fp0);
b6d96bed 7835 }
5a5012ec
TS
7836 opn = "cvt.w.s";
7837 break;
bf4120ad 7838 case OPC_CVT_L_S:
5e755519 7839 check_cp1_64bitmode(ctx);
b6d96bed 7840 {
a7812ae4
PB
7841 TCGv_i32 fp32 = tcg_temp_new_i32();
7842 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7843
7844 gen_load_fpr32(fp32, fs);
895c2d04 7845 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7846 tcg_temp_free_i32(fp32);
b6d96bed 7847 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7848 tcg_temp_free_i64(fp64);
b6d96bed 7849 }
5a5012ec
TS
7850 opn = "cvt.l.s";
7851 break;
bf4120ad 7852 case OPC_CVT_PS_S:
5e755519 7853 check_cp1_64bitmode(ctx);
b6d96bed 7854 {
a7812ae4
PB
7855 TCGv_i64 fp64 = tcg_temp_new_i64();
7856 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7857 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7858
7859 gen_load_fpr32(fp32_0, fs);
7860 gen_load_fpr32(fp32_1, ft);
13d24f49 7861 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7862 tcg_temp_free_i32(fp32_1);
7863 tcg_temp_free_i32(fp32_0);
36aa55dc 7864 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7865 tcg_temp_free_i64(fp64);
b6d96bed 7866 }
5a5012ec
TS
7867 opn = "cvt.ps.s";
7868 break;
bf4120ad
NF
7869 case OPC_CMP_F_S:
7870 case OPC_CMP_UN_S:
7871 case OPC_CMP_EQ_S:
7872 case OPC_CMP_UEQ_S:
7873 case OPC_CMP_OLT_S:
7874 case OPC_CMP_ULT_S:
7875 case OPC_CMP_OLE_S:
7876 case OPC_CMP_ULE_S:
7877 case OPC_CMP_SF_S:
7878 case OPC_CMP_NGLE_S:
7879 case OPC_CMP_SEQ_S:
7880 case OPC_CMP_NGL_S:
7881 case OPC_CMP_LT_S:
7882 case OPC_CMP_NGE_S:
7883 case OPC_CMP_LE_S:
7884 case OPC_CMP_NGT_S:
8153667c
NF
7885 if (ctx->opcode & (1 << 6)) {
7886 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7887 opn = condnames_abs[func-48];
7888 } else {
7889 gen_cmp_s(ctx, func-48, ft, fs, cc);
7890 opn = condnames[func-48];
5a1e8ffb 7891 }
5a5012ec 7892 break;
bf4120ad 7893 case OPC_ADD_D:
5e755519 7894 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7895 {
a7812ae4
PB
7896 TCGv_i64 fp0 = tcg_temp_new_i64();
7897 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7898
7899 gen_load_fpr64(ctx, fp0, fs);
7900 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7901 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7902 tcg_temp_free_i64(fp1);
b6d96bed 7903 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7904 tcg_temp_free_i64(fp0);
b6d96bed 7905 }
6ea83fed 7906 opn = "add.d";
5a1e8ffb 7907 optype = BINOP;
6ea83fed 7908 break;
bf4120ad 7909 case OPC_SUB_D:
5e755519 7910 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7911 {
a7812ae4
PB
7912 TCGv_i64 fp0 = tcg_temp_new_i64();
7913 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7914
7915 gen_load_fpr64(ctx, fp0, fs);
7916 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7917 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7918 tcg_temp_free_i64(fp1);
b6d96bed 7919 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7920 tcg_temp_free_i64(fp0);
b6d96bed 7921 }
6ea83fed 7922 opn = "sub.d";
5a1e8ffb 7923 optype = BINOP;
6ea83fed 7924 break;
bf4120ad 7925 case OPC_MUL_D:
5e755519 7926 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7927 {
a7812ae4
PB
7928 TCGv_i64 fp0 = tcg_temp_new_i64();
7929 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7930
7931 gen_load_fpr64(ctx, fp0, fs);
7932 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7933 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7934 tcg_temp_free_i64(fp1);
b6d96bed 7935 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7936 tcg_temp_free_i64(fp0);
b6d96bed 7937 }
6ea83fed 7938 opn = "mul.d";
5a1e8ffb 7939 optype = BINOP;
6ea83fed 7940 break;
bf4120ad 7941 case OPC_DIV_D:
5e755519 7942 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7943 {
a7812ae4
PB
7944 TCGv_i64 fp0 = tcg_temp_new_i64();
7945 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7946
7947 gen_load_fpr64(ctx, fp0, fs);
7948 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7949 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7950 tcg_temp_free_i64(fp1);
b6d96bed 7951 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7952 tcg_temp_free_i64(fp0);
b6d96bed 7953 }
6ea83fed 7954 opn = "div.d";
5a1e8ffb 7955 optype = BINOP;
6ea83fed 7956 break;
bf4120ad 7957 case OPC_SQRT_D:
5e755519 7958 check_cp1_registers(ctx, fs | fd);
b6d96bed 7959 {
a7812ae4 7960 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7961
7962 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7963 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7964 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7965 tcg_temp_free_i64(fp0);
b6d96bed 7966 }
6ea83fed
FB
7967 opn = "sqrt.d";
7968 break;
bf4120ad 7969 case OPC_ABS_D:
5e755519 7970 check_cp1_registers(ctx, fs | fd);
b6d96bed 7971 {
a7812ae4 7972 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7973
7974 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7975 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7976 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7977 tcg_temp_free_i64(fp0);
b6d96bed 7978 }
6ea83fed
FB
7979 opn = "abs.d";
7980 break;
bf4120ad 7981 case OPC_MOV_D:
5e755519 7982 check_cp1_registers(ctx, fs | fd);
b6d96bed 7983 {
a7812ae4 7984 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7985
7986 gen_load_fpr64(ctx, fp0, fs);
7987 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7988 tcg_temp_free_i64(fp0);
b6d96bed 7989 }
6ea83fed
FB
7990 opn = "mov.d";
7991 break;
bf4120ad 7992 case OPC_NEG_D:
5e755519 7993 check_cp1_registers(ctx, fs | fd);
b6d96bed 7994 {
a7812ae4 7995 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7996
7997 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7998 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7999 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8000 tcg_temp_free_i64(fp0);
b6d96bed 8001 }
6ea83fed
FB
8002 opn = "neg.d";
8003 break;
bf4120ad 8004 case OPC_ROUND_L_D:
5e755519 8005 check_cp1_64bitmode(ctx);
b6d96bed 8006 {
a7812ae4 8007 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8008
8009 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8010 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 8011 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8012 tcg_temp_free_i64(fp0);
b6d96bed 8013 }
5a5012ec
TS
8014 opn = "round.l.d";
8015 break;
bf4120ad 8016 case OPC_TRUNC_L_D:
5e755519 8017 check_cp1_64bitmode(ctx);
b6d96bed 8018 {
a7812ae4 8019 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8020
8021 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8022 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 8023 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8024 tcg_temp_free_i64(fp0);
b6d96bed 8025 }
5a5012ec
TS
8026 opn = "trunc.l.d";
8027 break;
bf4120ad 8028 case OPC_CEIL_L_D:
5e755519 8029 check_cp1_64bitmode(ctx);
b6d96bed 8030 {
a7812ae4 8031 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8032
8033 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8034 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8035 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8036 tcg_temp_free_i64(fp0);
b6d96bed 8037 }
5a5012ec
TS
8038 opn = "ceil.l.d";
8039 break;
bf4120ad 8040 case OPC_FLOOR_L_D:
5e755519 8041 check_cp1_64bitmode(ctx);
b6d96bed 8042 {
a7812ae4 8043 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8044
8045 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8046 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8047 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8048 tcg_temp_free_i64(fp0);
b6d96bed 8049 }
5a5012ec
TS
8050 opn = "floor.l.d";
8051 break;
bf4120ad 8052 case OPC_ROUND_W_D:
5e755519 8053 check_cp1_registers(ctx, fs);
b6d96bed 8054 {
a7812ae4
PB
8055 TCGv_i32 fp32 = tcg_temp_new_i32();
8056 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8057
8058 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8059 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8060 tcg_temp_free_i64(fp64);
b6d96bed 8061 gen_store_fpr32(fp32, fd);
a7812ae4 8062 tcg_temp_free_i32(fp32);
b6d96bed 8063 }
6ea83fed
FB
8064 opn = "round.w.d";
8065 break;
bf4120ad 8066 case OPC_TRUNC_W_D:
5e755519 8067 check_cp1_registers(ctx, fs);
b6d96bed 8068 {
a7812ae4
PB
8069 TCGv_i32 fp32 = tcg_temp_new_i32();
8070 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8071
8072 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8073 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8074 tcg_temp_free_i64(fp64);
b6d96bed 8075 gen_store_fpr32(fp32, fd);
a7812ae4 8076 tcg_temp_free_i32(fp32);
b6d96bed 8077 }
6ea83fed
FB
8078 opn = "trunc.w.d";
8079 break;
bf4120ad 8080 case OPC_CEIL_W_D:
5e755519 8081 check_cp1_registers(ctx, fs);
b6d96bed 8082 {
a7812ae4
PB
8083 TCGv_i32 fp32 = tcg_temp_new_i32();
8084 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8085
8086 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8087 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8088 tcg_temp_free_i64(fp64);
b6d96bed 8089 gen_store_fpr32(fp32, fd);
a7812ae4 8090 tcg_temp_free_i32(fp32);
b6d96bed 8091 }
6ea83fed
FB
8092 opn = "ceil.w.d";
8093 break;
bf4120ad 8094 case OPC_FLOOR_W_D:
5e755519 8095 check_cp1_registers(ctx, fs);
b6d96bed 8096 {
a7812ae4
PB
8097 TCGv_i32 fp32 = tcg_temp_new_i32();
8098 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8099
8100 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8101 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8102 tcg_temp_free_i64(fp64);
b6d96bed 8103 gen_store_fpr32(fp32, fd);
a7812ae4 8104 tcg_temp_free_i32(fp32);
b6d96bed 8105 }
7a387fff 8106 opn = "floor.w.d";
6ea83fed 8107 break;
bf4120ad 8108 case OPC_MOVCF_D:
b6d96bed 8109 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8110 opn = "movcf.d";
dd016883 8111 break;
bf4120ad 8112 case OPC_MOVZ_D:
a16336e4
TS
8113 {
8114 int l1 = gen_new_label();
c9297f4d 8115 TCGv_i64 fp0;
a16336e4 8116
c9297f4d
AJ
8117 if (ft != 0) {
8118 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8119 }
8120 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8121 gen_load_fpr64(ctx, fp0, fs);
8122 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8123 tcg_temp_free_i64(fp0);
a16336e4
TS
8124 gen_set_label(l1);
8125 }
5a5012ec
TS
8126 opn = "movz.d";
8127 break;
bf4120ad 8128 case OPC_MOVN_D:
a16336e4
TS
8129 {
8130 int l1 = gen_new_label();
c9297f4d
AJ
8131 TCGv_i64 fp0;
8132
8133 if (ft != 0) {
8134 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8135 fp0 = tcg_temp_new_i64();
8136 gen_load_fpr64(ctx, fp0, fs);
8137 gen_store_fpr64(ctx, fp0, fd);
8138 tcg_temp_free_i64(fp0);
8139 gen_set_label(l1);
8140 }
a16336e4 8141 }
5a5012ec 8142 opn = "movn.d";
6ea83fed 8143 break;
bf4120ad 8144 case OPC_RECIP_D:
b8aa4598 8145 check_cp1_64bitmode(ctx);
b6d96bed 8146 {
a7812ae4 8147 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8148
8149 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8150 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8151 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8152 tcg_temp_free_i64(fp0);
b6d96bed 8153 }
57fa1fb3
TS
8154 opn = "recip.d";
8155 break;
bf4120ad 8156 case OPC_RSQRT_D:
b8aa4598 8157 check_cp1_64bitmode(ctx);
b6d96bed 8158 {
a7812ae4 8159 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8160
8161 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8162 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8163 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8164 tcg_temp_free_i64(fp0);
b6d96bed 8165 }
57fa1fb3
TS
8166 opn = "rsqrt.d";
8167 break;
bf4120ad 8168 case OPC_RECIP2_D:
5e755519 8169 check_cp1_64bitmode(ctx);
b6d96bed 8170 {
a7812ae4
PB
8171 TCGv_i64 fp0 = tcg_temp_new_i64();
8172 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8173
8174 gen_load_fpr64(ctx, fp0, fs);
8175 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8176 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8177 tcg_temp_free_i64(fp1);
b6d96bed 8178 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8179 tcg_temp_free_i64(fp0);
b6d96bed 8180 }
57fa1fb3
TS
8181 opn = "recip2.d";
8182 break;
bf4120ad 8183 case OPC_RECIP1_D:
5e755519 8184 check_cp1_64bitmode(ctx);
b6d96bed 8185 {
a7812ae4 8186 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8187
8188 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8189 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8190 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8191 tcg_temp_free_i64(fp0);
b6d96bed 8192 }
57fa1fb3
TS
8193 opn = "recip1.d";
8194 break;
bf4120ad 8195 case OPC_RSQRT1_D:
5e755519 8196 check_cp1_64bitmode(ctx);
b6d96bed 8197 {
a7812ae4 8198 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8199
8200 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8201 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8202 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8203 tcg_temp_free_i64(fp0);
b6d96bed 8204 }
57fa1fb3
TS
8205 opn = "rsqrt1.d";
8206 break;
bf4120ad 8207 case OPC_RSQRT2_D:
5e755519 8208 check_cp1_64bitmode(ctx);
b6d96bed 8209 {
a7812ae4
PB
8210 TCGv_i64 fp0 = tcg_temp_new_i64();
8211 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8212
8213 gen_load_fpr64(ctx, fp0, fs);
8214 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8215 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8216 tcg_temp_free_i64(fp1);
b6d96bed 8217 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8218 tcg_temp_free_i64(fp0);
b6d96bed 8219 }
57fa1fb3
TS
8220 opn = "rsqrt2.d";
8221 break;
bf4120ad
NF
8222 case OPC_CMP_F_D:
8223 case OPC_CMP_UN_D:
8224 case OPC_CMP_EQ_D:
8225 case OPC_CMP_UEQ_D:
8226 case OPC_CMP_OLT_D:
8227 case OPC_CMP_ULT_D:
8228 case OPC_CMP_OLE_D:
8229 case OPC_CMP_ULE_D:
8230 case OPC_CMP_SF_D:
8231 case OPC_CMP_NGLE_D:
8232 case OPC_CMP_SEQ_D:
8233 case OPC_CMP_NGL_D:
8234 case OPC_CMP_LT_D:
8235 case OPC_CMP_NGE_D:
8236 case OPC_CMP_LE_D:
8237 case OPC_CMP_NGT_D:
8153667c
NF
8238 if (ctx->opcode & (1 << 6)) {
8239 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8240 opn = condnames_abs[func-48];
8241 } else {
8242 gen_cmp_d(ctx, func-48, ft, fs, cc);
8243 opn = condnames[func-48];
5a1e8ffb 8244 }
6ea83fed 8245 break;
bf4120ad 8246 case OPC_CVT_S_D:
5e755519 8247 check_cp1_registers(ctx, fs);
b6d96bed 8248 {
a7812ae4
PB
8249 TCGv_i32 fp32 = tcg_temp_new_i32();
8250 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8251
8252 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8253 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8254 tcg_temp_free_i64(fp64);
b6d96bed 8255 gen_store_fpr32(fp32, fd);
a7812ae4 8256 tcg_temp_free_i32(fp32);
b6d96bed 8257 }
5a5012ec
TS
8258 opn = "cvt.s.d";
8259 break;
bf4120ad 8260 case OPC_CVT_W_D:
5e755519 8261 check_cp1_registers(ctx, fs);
b6d96bed 8262 {
a7812ae4
PB
8263 TCGv_i32 fp32 = tcg_temp_new_i32();
8264 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8265
8266 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8267 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8268 tcg_temp_free_i64(fp64);
b6d96bed 8269 gen_store_fpr32(fp32, fd);
a7812ae4 8270 tcg_temp_free_i32(fp32);
b6d96bed 8271 }
5a5012ec
TS
8272 opn = "cvt.w.d";
8273 break;
bf4120ad 8274 case OPC_CVT_L_D:
5e755519 8275 check_cp1_64bitmode(ctx);
b6d96bed 8276 {
a7812ae4 8277 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8278
8279 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8280 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8281 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8282 tcg_temp_free_i64(fp0);
b6d96bed 8283 }
5a5012ec
TS
8284 opn = "cvt.l.d";
8285 break;
bf4120ad 8286 case OPC_CVT_S_W:
b6d96bed 8287 {
a7812ae4 8288 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8289
8290 gen_load_fpr32(fp0, fs);
895c2d04 8291 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8292 gen_store_fpr32(fp0, fd);
a7812ae4 8293 tcg_temp_free_i32(fp0);
b6d96bed 8294 }
5a5012ec 8295 opn = "cvt.s.w";
6ea83fed 8296 break;
bf4120ad 8297 case OPC_CVT_D_W:
5e755519 8298 check_cp1_registers(ctx, fd);
b6d96bed 8299 {
a7812ae4
PB
8300 TCGv_i32 fp32 = tcg_temp_new_i32();
8301 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8302
8303 gen_load_fpr32(fp32, fs);
895c2d04 8304 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8305 tcg_temp_free_i32(fp32);
b6d96bed 8306 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8307 tcg_temp_free_i64(fp64);
b6d96bed 8308 }
5a5012ec
TS
8309 opn = "cvt.d.w";
8310 break;
bf4120ad 8311 case OPC_CVT_S_L:
5e755519 8312 check_cp1_64bitmode(ctx);
b6d96bed 8313 {
a7812ae4
PB
8314 TCGv_i32 fp32 = tcg_temp_new_i32();
8315 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8316
8317 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8318 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8319 tcg_temp_free_i64(fp64);
b6d96bed 8320 gen_store_fpr32(fp32, fd);
a7812ae4 8321 tcg_temp_free_i32(fp32);
b6d96bed 8322 }
5a5012ec
TS
8323 opn = "cvt.s.l";
8324 break;
bf4120ad 8325 case OPC_CVT_D_L:
5e755519 8326 check_cp1_64bitmode(ctx);
b6d96bed 8327 {
a7812ae4 8328 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8329
8330 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8331 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8332 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8333 tcg_temp_free_i64(fp0);
b6d96bed 8334 }
5a5012ec
TS
8335 opn = "cvt.d.l";
8336 break;
bf4120ad 8337 case OPC_CVT_PS_PW:
5e755519 8338 check_cp1_64bitmode(ctx);
b6d96bed 8339 {
a7812ae4 8340 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8341
8342 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8343 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8344 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8345 tcg_temp_free_i64(fp0);
b6d96bed 8346 }
5a5012ec
TS
8347 opn = "cvt.ps.pw";
8348 break;
bf4120ad 8349 case OPC_ADD_PS:
5e755519 8350 check_cp1_64bitmode(ctx);
b6d96bed 8351 {
a7812ae4
PB
8352 TCGv_i64 fp0 = tcg_temp_new_i64();
8353 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8354
8355 gen_load_fpr64(ctx, fp0, fs);
8356 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8357 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8358 tcg_temp_free_i64(fp1);
b6d96bed 8359 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8360 tcg_temp_free_i64(fp0);
b6d96bed 8361 }
5a5012ec 8362 opn = "add.ps";
6ea83fed 8363 break;
bf4120ad 8364 case OPC_SUB_PS:
5e755519 8365 check_cp1_64bitmode(ctx);
b6d96bed 8366 {
a7812ae4
PB
8367 TCGv_i64 fp0 = tcg_temp_new_i64();
8368 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8369
8370 gen_load_fpr64(ctx, fp0, fs);
8371 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8372 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8373 tcg_temp_free_i64(fp1);
b6d96bed 8374 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8375 tcg_temp_free_i64(fp0);
b6d96bed 8376 }
5a5012ec 8377 opn = "sub.ps";
6ea83fed 8378 break;
bf4120ad 8379 case OPC_MUL_PS:
5e755519 8380 check_cp1_64bitmode(ctx);
b6d96bed 8381 {
a7812ae4
PB
8382 TCGv_i64 fp0 = tcg_temp_new_i64();
8383 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8384
8385 gen_load_fpr64(ctx, fp0, fs);
8386 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8387 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8388 tcg_temp_free_i64(fp1);
b6d96bed 8389 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8390 tcg_temp_free_i64(fp0);
b6d96bed 8391 }
5a5012ec 8392 opn = "mul.ps";
6ea83fed 8393 break;
bf4120ad 8394 case OPC_ABS_PS:
5e755519 8395 check_cp1_64bitmode(ctx);
b6d96bed 8396 {
a7812ae4 8397 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8398
8399 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8400 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8401 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8402 tcg_temp_free_i64(fp0);
b6d96bed 8403 }
5a5012ec 8404 opn = "abs.ps";
6ea83fed 8405 break;
bf4120ad 8406 case OPC_MOV_PS:
5e755519 8407 check_cp1_64bitmode(ctx);
b6d96bed 8408 {
a7812ae4 8409 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8410
8411 gen_load_fpr64(ctx, fp0, fs);
8412 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8413 tcg_temp_free_i64(fp0);
b6d96bed 8414 }
5a5012ec 8415 opn = "mov.ps";
6ea83fed 8416 break;
bf4120ad 8417 case OPC_NEG_PS:
5e755519 8418 check_cp1_64bitmode(ctx);
b6d96bed 8419 {
a7812ae4 8420 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8421
8422 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8423 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8424 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8425 tcg_temp_free_i64(fp0);
b6d96bed 8426 }
5a5012ec 8427 opn = "neg.ps";
6ea83fed 8428 break;
bf4120ad 8429 case OPC_MOVCF_PS:
5e755519 8430 check_cp1_64bitmode(ctx);
b6d96bed 8431 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8432 opn = "movcf.ps";
6ea83fed 8433 break;
bf4120ad 8434 case OPC_MOVZ_PS:
5e755519 8435 check_cp1_64bitmode(ctx);
a16336e4
TS
8436 {
8437 int l1 = gen_new_label();
30a3848b 8438 TCGv_i64 fp0;
a16336e4 8439
c9297f4d
AJ
8440 if (ft != 0)
8441 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8442 fp0 = tcg_temp_new_i64();
8443 gen_load_fpr64(ctx, fp0, fs);
8444 gen_store_fpr64(ctx, fp0, fd);
8445 tcg_temp_free_i64(fp0);
a16336e4
TS
8446 gen_set_label(l1);
8447 }
5a5012ec 8448 opn = "movz.ps";
6ea83fed 8449 break;
bf4120ad 8450 case OPC_MOVN_PS:
5e755519 8451 check_cp1_64bitmode(ctx);
a16336e4
TS
8452 {
8453 int l1 = gen_new_label();
30a3848b 8454 TCGv_i64 fp0;
c9297f4d
AJ
8455
8456 if (ft != 0) {
8457 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8458 fp0 = tcg_temp_new_i64();
8459 gen_load_fpr64(ctx, fp0, fs);
8460 gen_store_fpr64(ctx, fp0, fd);
8461 tcg_temp_free_i64(fp0);
8462 gen_set_label(l1);
8463 }
a16336e4 8464 }
5a5012ec 8465 opn = "movn.ps";
6ea83fed 8466 break;
bf4120ad 8467 case OPC_ADDR_PS:
5e755519 8468 check_cp1_64bitmode(ctx);
b6d96bed 8469 {
a7812ae4
PB
8470 TCGv_i64 fp0 = tcg_temp_new_i64();
8471 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8472
8473 gen_load_fpr64(ctx, fp0, ft);
8474 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8475 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8476 tcg_temp_free_i64(fp1);
b6d96bed 8477 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8478 tcg_temp_free_i64(fp0);
b6d96bed 8479 }
fbcc6828
TS
8480 opn = "addr.ps";
8481 break;
bf4120ad 8482 case OPC_MULR_PS:
5e755519 8483 check_cp1_64bitmode(ctx);
b6d96bed 8484 {
a7812ae4
PB
8485 TCGv_i64 fp0 = tcg_temp_new_i64();
8486 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8487
8488 gen_load_fpr64(ctx, fp0, ft);
8489 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8490 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8491 tcg_temp_free_i64(fp1);
b6d96bed 8492 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8493 tcg_temp_free_i64(fp0);
b6d96bed 8494 }
57fa1fb3
TS
8495 opn = "mulr.ps";
8496 break;
bf4120ad 8497 case OPC_RECIP2_PS:
5e755519 8498 check_cp1_64bitmode(ctx);
b6d96bed 8499 {
a7812ae4
PB
8500 TCGv_i64 fp0 = tcg_temp_new_i64();
8501 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8502
8503 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8504 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8505 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8506 tcg_temp_free_i64(fp1);
b6d96bed 8507 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8508 tcg_temp_free_i64(fp0);
b6d96bed 8509 }
57fa1fb3
TS
8510 opn = "recip2.ps";
8511 break;
bf4120ad 8512 case OPC_RECIP1_PS:
5e755519 8513 check_cp1_64bitmode(ctx);
b6d96bed 8514 {
a7812ae4 8515 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8516
8517 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8518 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8519 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8520 tcg_temp_free_i64(fp0);
b6d96bed 8521 }
57fa1fb3
TS
8522 opn = "recip1.ps";
8523 break;
bf4120ad 8524 case OPC_RSQRT1_PS:
5e755519 8525 check_cp1_64bitmode(ctx);
b6d96bed 8526 {
a7812ae4 8527 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8528
8529 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8530 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8531 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8532 tcg_temp_free_i64(fp0);
b6d96bed 8533 }
57fa1fb3
TS
8534 opn = "rsqrt1.ps";
8535 break;
bf4120ad 8536 case OPC_RSQRT2_PS:
5e755519 8537 check_cp1_64bitmode(ctx);
b6d96bed 8538 {
a7812ae4
PB
8539 TCGv_i64 fp0 = tcg_temp_new_i64();
8540 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8541
8542 gen_load_fpr64(ctx, fp0, fs);
8543 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8544 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8545 tcg_temp_free_i64(fp1);
b6d96bed 8546 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8547 tcg_temp_free_i64(fp0);
b6d96bed 8548 }
57fa1fb3
TS
8549 opn = "rsqrt2.ps";
8550 break;
bf4120ad 8551 case OPC_CVT_S_PU:
5e755519 8552 check_cp1_64bitmode(ctx);
b6d96bed 8553 {
a7812ae4 8554 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8555
8556 gen_load_fpr32h(fp0, fs);
895c2d04 8557 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8558 gen_store_fpr32(fp0, fd);
a7812ae4 8559 tcg_temp_free_i32(fp0);
b6d96bed 8560 }
5a5012ec 8561 opn = "cvt.s.pu";
dd016883 8562 break;
bf4120ad 8563 case OPC_CVT_PW_PS:
5e755519 8564 check_cp1_64bitmode(ctx);
b6d96bed 8565 {
a7812ae4 8566 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8567
8568 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8569 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8570 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8571 tcg_temp_free_i64(fp0);
b6d96bed 8572 }
5a5012ec 8573 opn = "cvt.pw.ps";
6ea83fed 8574 break;
bf4120ad 8575 case OPC_CVT_S_PL:
5e755519 8576 check_cp1_64bitmode(ctx);
b6d96bed 8577 {
a7812ae4 8578 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8579
8580 gen_load_fpr32(fp0, fs);
895c2d04 8581 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8582 gen_store_fpr32(fp0, fd);
a7812ae4 8583 tcg_temp_free_i32(fp0);
b6d96bed 8584 }
5a5012ec 8585 opn = "cvt.s.pl";
6ea83fed 8586 break;
bf4120ad 8587 case OPC_PLL_PS:
5e755519 8588 check_cp1_64bitmode(ctx);
b6d96bed 8589 {
a7812ae4
PB
8590 TCGv_i32 fp0 = tcg_temp_new_i32();
8591 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8592
8593 gen_load_fpr32(fp0, fs);
8594 gen_load_fpr32(fp1, ft);
8595 gen_store_fpr32h(fp0, fd);
8596 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8597 tcg_temp_free_i32(fp0);
8598 tcg_temp_free_i32(fp1);
b6d96bed 8599 }
5a5012ec 8600 opn = "pll.ps";
6ea83fed 8601 break;
bf4120ad 8602 case OPC_PLU_PS:
5e755519 8603 check_cp1_64bitmode(ctx);
b6d96bed 8604 {
a7812ae4
PB
8605 TCGv_i32 fp0 = tcg_temp_new_i32();
8606 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8607
8608 gen_load_fpr32(fp0, fs);
8609 gen_load_fpr32h(fp1, ft);
8610 gen_store_fpr32(fp1, fd);
8611 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8612 tcg_temp_free_i32(fp0);
8613 tcg_temp_free_i32(fp1);
b6d96bed 8614 }
5a5012ec
TS
8615 opn = "plu.ps";
8616 break;
bf4120ad 8617 case OPC_PUL_PS:
5e755519 8618 check_cp1_64bitmode(ctx);
b6d96bed 8619 {
a7812ae4
PB
8620 TCGv_i32 fp0 = tcg_temp_new_i32();
8621 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8622
8623 gen_load_fpr32h(fp0, fs);
8624 gen_load_fpr32(fp1, ft);
8625 gen_store_fpr32(fp1, fd);
8626 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8627 tcg_temp_free_i32(fp0);
8628 tcg_temp_free_i32(fp1);
b6d96bed 8629 }
5a5012ec
TS
8630 opn = "pul.ps";
8631 break;
bf4120ad 8632 case OPC_PUU_PS:
5e755519 8633 check_cp1_64bitmode(ctx);
b6d96bed 8634 {
a7812ae4
PB
8635 TCGv_i32 fp0 = tcg_temp_new_i32();
8636 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8637
8638 gen_load_fpr32h(fp0, fs);
8639 gen_load_fpr32h(fp1, ft);
8640 gen_store_fpr32(fp1, fd);
8641 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8642 tcg_temp_free_i32(fp0);
8643 tcg_temp_free_i32(fp1);
b6d96bed 8644 }
5a5012ec
TS
8645 opn = "puu.ps";
8646 break;
bf4120ad
NF
8647 case OPC_CMP_F_PS:
8648 case OPC_CMP_UN_PS:
8649 case OPC_CMP_EQ_PS:
8650 case OPC_CMP_UEQ_PS:
8651 case OPC_CMP_OLT_PS:
8652 case OPC_CMP_ULT_PS:
8653 case OPC_CMP_OLE_PS:
8654 case OPC_CMP_ULE_PS:
8655 case OPC_CMP_SF_PS:
8656 case OPC_CMP_NGLE_PS:
8657 case OPC_CMP_SEQ_PS:
8658 case OPC_CMP_NGL_PS:
8659 case OPC_CMP_LT_PS:
8660 case OPC_CMP_NGE_PS:
8661 case OPC_CMP_LE_PS:
8662 case OPC_CMP_NGT_PS:
8153667c
NF
8663 if (ctx->opcode & (1 << 6)) {
8664 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8665 opn = condnames_abs[func-48];
8666 } else {
8667 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8668 opn = condnames[func-48];
5a1e8ffb 8669 }
6ea83fed 8670 break;
5a5012ec 8671 default:
923617a3 8672 MIPS_INVAL(opn);
e397ee33 8673 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8674 return;
8675 }
2abf314d 8676 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8677 switch (optype) {
8678 case BINOP:
6ea83fed 8679 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8680 break;
8681 case CMPOP:
8682 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8683 break;
8684 default:
6ea83fed 8685 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8686 break;
8687 }
6ea83fed 8688}
6af0bf9c 8689
5a5012ec 8690/* Coprocessor 3 (FPU) */
5e755519
TS
8691static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8692 int fd, int fs, int base, int index)
7a387fff 8693{
923617a3 8694 const char *opn = "extended float load/store";
93b12ccc 8695 int store = 0;
4e2474d6 8696 TCGv t0 = tcg_temp_new();
7a387fff 8697
93b12ccc 8698 if (base == 0) {
6c5c1e20 8699 gen_load_gpr(t0, index);
93b12ccc 8700 } else if (index == 0) {
6c5c1e20 8701 gen_load_gpr(t0, base);
93b12ccc 8702 } else {
05168674 8703 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8704 }
5a5012ec 8705 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8706 memory access. */
5a5012ec
TS
8707 switch (opc) {
8708 case OPC_LWXC1:
8c0ab41f 8709 check_cop1x(ctx);
b6d96bed 8710 {
a7812ae4 8711 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8712
585c88d5
AJ
8713 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8714 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8715 gen_store_fpr32(fp0, fd);
a7812ae4 8716 tcg_temp_free_i32(fp0);
b6d96bed 8717 }
5a5012ec
TS
8718 opn = "lwxc1";
8719 break;
8720 case OPC_LDXC1:
8c0ab41f
AJ
8721 check_cop1x(ctx);
8722 check_cp1_registers(ctx, fd);
b6d96bed 8723 {
a7812ae4 8724 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8725
8726 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8727 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8728 tcg_temp_free_i64(fp0);
b6d96bed 8729 }
5a5012ec
TS
8730 opn = "ldxc1";
8731 break;
8732 case OPC_LUXC1:
8c0ab41f 8733 check_cp1_64bitmode(ctx);
6c5c1e20 8734 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8735 {
a7812ae4 8736 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8737
8738 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8739 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8740 tcg_temp_free_i64(fp0);
b6d96bed 8741 }
5a5012ec
TS
8742 opn = "luxc1";
8743 break;
8744 case OPC_SWXC1:
8c0ab41f 8745 check_cop1x(ctx);
b6d96bed 8746 {
a7812ae4 8747 TCGv_i32 fp0 = tcg_temp_new_i32();
585c88d5 8748 TCGv t1 = tcg_temp_new();
b6d96bed
TS
8749
8750 gen_load_fpr32(fp0, fs);
a7812ae4
PB
8751 tcg_gen_extu_i32_tl(t1, fp0);
8752 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8753 tcg_temp_free_i32(fp0);
a6035857 8754 tcg_temp_free(t1);
b6d96bed 8755 }
5a5012ec 8756 opn = "swxc1";
93b12ccc 8757 store = 1;
5a5012ec
TS
8758 break;
8759 case OPC_SDXC1:
8c0ab41f
AJ
8760 check_cop1x(ctx);
8761 check_cp1_registers(ctx, fs);
b6d96bed 8762 {
a7812ae4 8763 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8764
8765 gen_load_fpr64(ctx, fp0, fs);
8766 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8767 tcg_temp_free_i64(fp0);
b6d96bed 8768 }
5a5012ec 8769 opn = "sdxc1";
93b12ccc 8770 store = 1;
5a5012ec
TS
8771 break;
8772 case OPC_SUXC1:
8c0ab41f 8773 check_cp1_64bitmode(ctx);
6c5c1e20 8774 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8775 {
a7812ae4 8776 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8777
8778 gen_load_fpr64(ctx, fp0, fs);
8779 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8780 tcg_temp_free_i64(fp0);
b6d96bed 8781 }
5a5012ec 8782 opn = "suxc1";
93b12ccc 8783 store = 1;
5a5012ec 8784 break;
5a5012ec 8785 }
6c5c1e20 8786 tcg_temp_free(t0);
2abf314d 8787 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8788 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8789 regnames[index], regnames[base]);
5a5012ec
TS
8790}
8791
5e755519
TS
8792static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8793 int fd, int fr, int fs, int ft)
5a5012ec 8794{
923617a3 8795 const char *opn = "flt3_arith";
5a5012ec 8796
5a5012ec
TS
8797 switch (opc) {
8798 case OPC_ALNV_PS:
b8aa4598 8799 check_cp1_64bitmode(ctx);
a16336e4 8800 {
a7812ae4 8801 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8802 TCGv_i32 fp = tcg_temp_new_i32();
8803 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8804 int l1 = gen_new_label();
8805 int l2 = gen_new_label();
8806
6c5c1e20
TS
8807 gen_load_gpr(t0, fr);
8808 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8809
8810 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac
AJ
8811 gen_load_fpr32(fp, fs);
8812 gen_load_fpr32h(fph, fs);
8813 gen_store_fpr32(fp, fd);
8814 gen_store_fpr32h(fph, fd);
a16336e4
TS
8815 tcg_gen_br(l2);
8816 gen_set_label(l1);
6c5c1e20
TS
8817 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8818 tcg_temp_free(t0);
a16336e4 8819#ifdef TARGET_WORDS_BIGENDIAN
c905fdac
AJ
8820 gen_load_fpr32(fp, fs);
8821 gen_load_fpr32h(fph, ft);
8822 gen_store_fpr32h(fp, fd);
8823 gen_store_fpr32(fph, fd);
a16336e4 8824#else
c905fdac
AJ
8825 gen_load_fpr32h(fph, fs);
8826 gen_load_fpr32(fp, ft);
8827 gen_store_fpr32(fph, fd);
8828 gen_store_fpr32h(fp, fd);
a16336e4
TS
8829#endif
8830 gen_set_label(l2);
c905fdac
AJ
8831 tcg_temp_free_i32(fp);
8832 tcg_temp_free_i32(fph);
a16336e4 8833 }
5a5012ec
TS
8834 opn = "alnv.ps";
8835 break;
8836 case OPC_MADD_S:
b8aa4598 8837 check_cop1x(ctx);
b6d96bed 8838 {
a7812ae4
PB
8839 TCGv_i32 fp0 = tcg_temp_new_i32();
8840 TCGv_i32 fp1 = tcg_temp_new_i32();
8841 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8842
8843 gen_load_fpr32(fp0, fs);
8844 gen_load_fpr32(fp1, ft);
8845 gen_load_fpr32(fp2, fr);
b3d6cd44 8846 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8847 tcg_temp_free_i32(fp0);
8848 tcg_temp_free_i32(fp1);
b6d96bed 8849 gen_store_fpr32(fp2, fd);
a7812ae4 8850 tcg_temp_free_i32(fp2);
b6d96bed 8851 }
5a5012ec
TS
8852 opn = "madd.s";
8853 break;
8854 case OPC_MADD_D:
b8aa4598
TS
8855 check_cop1x(ctx);
8856 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8857 {
a7812ae4
PB
8858 TCGv_i64 fp0 = tcg_temp_new_i64();
8859 TCGv_i64 fp1 = tcg_temp_new_i64();
8860 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8861
8862 gen_load_fpr64(ctx, fp0, fs);
8863 gen_load_fpr64(ctx, fp1, ft);
8864 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8865 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8866 tcg_temp_free_i64(fp0);
8867 tcg_temp_free_i64(fp1);
b6d96bed 8868 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8869 tcg_temp_free_i64(fp2);
b6d96bed 8870 }
5a5012ec
TS
8871 opn = "madd.d";
8872 break;
8873 case OPC_MADD_PS:
b8aa4598 8874 check_cp1_64bitmode(ctx);
b6d96bed 8875 {
a7812ae4
PB
8876 TCGv_i64 fp0 = tcg_temp_new_i64();
8877 TCGv_i64 fp1 = tcg_temp_new_i64();
8878 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8879
8880 gen_load_fpr64(ctx, fp0, fs);
8881 gen_load_fpr64(ctx, fp1, ft);
8882 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8883 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8884 tcg_temp_free_i64(fp0);
8885 tcg_temp_free_i64(fp1);
b6d96bed 8886 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8887 tcg_temp_free_i64(fp2);
b6d96bed 8888 }
5a5012ec
TS
8889 opn = "madd.ps";
8890 break;
8891 case OPC_MSUB_S:
b8aa4598 8892 check_cop1x(ctx);
b6d96bed 8893 {
a7812ae4
PB
8894 TCGv_i32 fp0 = tcg_temp_new_i32();
8895 TCGv_i32 fp1 = tcg_temp_new_i32();
8896 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8897
8898 gen_load_fpr32(fp0, fs);
8899 gen_load_fpr32(fp1, ft);
8900 gen_load_fpr32(fp2, fr);
b3d6cd44 8901 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8902 tcg_temp_free_i32(fp0);
8903 tcg_temp_free_i32(fp1);
b6d96bed 8904 gen_store_fpr32(fp2, fd);
a7812ae4 8905 tcg_temp_free_i32(fp2);
b6d96bed 8906 }
5a5012ec
TS
8907 opn = "msub.s";
8908 break;
8909 case OPC_MSUB_D:
b8aa4598
TS
8910 check_cop1x(ctx);
8911 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8912 {
a7812ae4
PB
8913 TCGv_i64 fp0 = tcg_temp_new_i64();
8914 TCGv_i64 fp1 = tcg_temp_new_i64();
8915 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8916
8917 gen_load_fpr64(ctx, fp0, fs);
8918 gen_load_fpr64(ctx, fp1, ft);
8919 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8920 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8921 tcg_temp_free_i64(fp0);
8922 tcg_temp_free_i64(fp1);
b6d96bed 8923 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8924 tcg_temp_free_i64(fp2);
b6d96bed 8925 }
5a5012ec
TS
8926 opn = "msub.d";
8927 break;
8928 case OPC_MSUB_PS:
b8aa4598 8929 check_cp1_64bitmode(ctx);
b6d96bed 8930 {
a7812ae4
PB
8931 TCGv_i64 fp0 = tcg_temp_new_i64();
8932 TCGv_i64 fp1 = tcg_temp_new_i64();
8933 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8934
8935 gen_load_fpr64(ctx, fp0, fs);
8936 gen_load_fpr64(ctx, fp1, ft);
8937 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8938 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8939 tcg_temp_free_i64(fp0);
8940 tcg_temp_free_i64(fp1);
b6d96bed 8941 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8942 tcg_temp_free_i64(fp2);
b6d96bed 8943 }
5a5012ec
TS
8944 opn = "msub.ps";
8945 break;
8946 case OPC_NMADD_S:
b8aa4598 8947 check_cop1x(ctx);
b6d96bed 8948 {
a7812ae4
PB
8949 TCGv_i32 fp0 = tcg_temp_new_i32();
8950 TCGv_i32 fp1 = tcg_temp_new_i32();
8951 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8952
8953 gen_load_fpr32(fp0, fs);
8954 gen_load_fpr32(fp1, ft);
8955 gen_load_fpr32(fp2, fr);
b3d6cd44 8956 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8957 tcg_temp_free_i32(fp0);
8958 tcg_temp_free_i32(fp1);
b6d96bed 8959 gen_store_fpr32(fp2, fd);
a7812ae4 8960 tcg_temp_free_i32(fp2);
b6d96bed 8961 }
5a5012ec
TS
8962 opn = "nmadd.s";
8963 break;
8964 case OPC_NMADD_D:
b8aa4598
TS
8965 check_cop1x(ctx);
8966 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8967 {
a7812ae4
PB
8968 TCGv_i64 fp0 = tcg_temp_new_i64();
8969 TCGv_i64 fp1 = tcg_temp_new_i64();
8970 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8971
8972 gen_load_fpr64(ctx, fp0, fs);
8973 gen_load_fpr64(ctx, fp1, ft);
8974 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8975 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8976 tcg_temp_free_i64(fp0);
8977 tcg_temp_free_i64(fp1);
b6d96bed 8978 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8979 tcg_temp_free_i64(fp2);
b6d96bed 8980 }
5a5012ec
TS
8981 opn = "nmadd.d";
8982 break;
8983 case OPC_NMADD_PS:
b8aa4598 8984 check_cp1_64bitmode(ctx);
b6d96bed 8985 {
a7812ae4
PB
8986 TCGv_i64 fp0 = tcg_temp_new_i64();
8987 TCGv_i64 fp1 = tcg_temp_new_i64();
8988 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8989
8990 gen_load_fpr64(ctx, fp0, fs);
8991 gen_load_fpr64(ctx, fp1, ft);
8992 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8993 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8994 tcg_temp_free_i64(fp0);
8995 tcg_temp_free_i64(fp1);
b6d96bed 8996 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8997 tcg_temp_free_i64(fp2);
b6d96bed 8998 }
5a5012ec
TS
8999 opn = "nmadd.ps";
9000 break;
9001 case OPC_NMSUB_S:
b8aa4598 9002 check_cop1x(ctx);
b6d96bed 9003 {
a7812ae4
PB
9004 TCGv_i32 fp0 = tcg_temp_new_i32();
9005 TCGv_i32 fp1 = tcg_temp_new_i32();
9006 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9007
9008 gen_load_fpr32(fp0, fs);
9009 gen_load_fpr32(fp1, ft);
9010 gen_load_fpr32(fp2, fr);
b3d6cd44 9011 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9012 tcg_temp_free_i32(fp0);
9013 tcg_temp_free_i32(fp1);
b6d96bed 9014 gen_store_fpr32(fp2, fd);
a7812ae4 9015 tcg_temp_free_i32(fp2);
b6d96bed 9016 }
5a5012ec
TS
9017 opn = "nmsub.s";
9018 break;
9019 case OPC_NMSUB_D:
b8aa4598
TS
9020 check_cop1x(ctx);
9021 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9022 {
a7812ae4
PB
9023 TCGv_i64 fp0 = tcg_temp_new_i64();
9024 TCGv_i64 fp1 = tcg_temp_new_i64();
9025 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9026
9027 gen_load_fpr64(ctx, fp0, fs);
9028 gen_load_fpr64(ctx, fp1, ft);
9029 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9030 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9031 tcg_temp_free_i64(fp0);
9032 tcg_temp_free_i64(fp1);
b6d96bed 9033 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9034 tcg_temp_free_i64(fp2);
b6d96bed 9035 }
5a5012ec
TS
9036 opn = "nmsub.d";
9037 break;
9038 case OPC_NMSUB_PS:
b8aa4598 9039 check_cp1_64bitmode(ctx);
b6d96bed 9040 {
a7812ae4
PB
9041 TCGv_i64 fp0 = tcg_temp_new_i64();
9042 TCGv_i64 fp1 = tcg_temp_new_i64();
9043 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9044
9045 gen_load_fpr64(ctx, fp0, fs);
9046 gen_load_fpr64(ctx, fp1, ft);
9047 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9048 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9049 tcg_temp_free_i64(fp0);
9050 tcg_temp_free_i64(fp1);
b6d96bed 9051 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9052 tcg_temp_free_i64(fp2);
b6d96bed 9053 }
5a5012ec
TS
9054 opn = "nmsub.ps";
9055 break;
923617a3
TS
9056 default:
9057 MIPS_INVAL(opn);
5a5012ec
TS
9058 generate_exception (ctx, EXCP_RI);
9059 return;
9060 }
2abf314d 9061 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9062 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9063 fregnames[fs], fregnames[ft]);
7a387fff
TS
9064}
9065
26ebe468 9066static void
7db13fae 9067gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
26ebe468
NF
9068{
9069 TCGv t0;
9070
b3167288
RH
9071#if !defined(CONFIG_USER_ONLY)
9072 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9073 Therefore only check the ISA in system mode. */
26ebe468 9074 check_insn(env, ctx, ISA_MIPS32R2);
b3167288 9075#endif
26ebe468
NF
9076 t0 = tcg_temp_new();
9077
9078 switch (rd) {
9079 case 0:
9080 save_cpu_state(ctx, 1);
895c2d04 9081 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9082 gen_store_gpr(t0, rt);
9083 break;
9084 case 1:
9085 save_cpu_state(ctx, 1);
895c2d04 9086 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9087 gen_store_gpr(t0, rt);
9088 break;
9089 case 2:
9090 save_cpu_state(ctx, 1);
895c2d04 9091 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9092 gen_store_gpr(t0, rt);
9093 break;
9094 case 3:
9095 save_cpu_state(ctx, 1);
895c2d04 9096 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9097 gen_store_gpr(t0, rt);
9098 break;
9099 case 29:
9100#if defined(CONFIG_USER_ONLY)
7db13fae 9101 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9102 gen_store_gpr(t0, rt);
9103 break;
9104#else
9105 /* XXX: Some CPUs implement this in hardware.
9106 Not supported yet. */
9107#endif
9108 default: /* Invalid */
9109 MIPS_INVAL("rdhwr");
9110 generate_exception(ctx, EXCP_RI);
9111 break;
9112 }
9113 tcg_temp_free(t0);
9114}
9115
7db13fae 9116static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
c9602061
NF
9117 int insn_bytes)
9118{
9119 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9120 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9121 /* Branches completion */
9122 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9123 ctx->bstate = BS_BRANCH;
9124 save_cpu_state(ctx, 0);
9125 /* FIXME: Need to clear can_do_io. */
364d4831 9126 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9127 case MIPS_HFLAG_B:
9128 /* unconditional branch */
9129 MIPS_DEBUG("unconditional branch");
364d4831
NF
9130 if (proc_hflags & MIPS_HFLAG_BX) {
9131 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9132 }
c9602061
NF
9133 gen_goto_tb(ctx, 0, ctx->btarget);
9134 break;
9135 case MIPS_HFLAG_BL:
9136 /* blikely taken case */
9137 MIPS_DEBUG("blikely branch taken");
9138 gen_goto_tb(ctx, 0, ctx->btarget);
9139 break;
9140 case MIPS_HFLAG_BC:
9141 /* Conditional branch */
9142 MIPS_DEBUG("conditional branch");
9143 {
9144 int l1 = gen_new_label();
9145
9146 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9147 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9148 gen_set_label(l1);
9149 gen_goto_tb(ctx, 0, ctx->btarget);
9150 }
9151 break;
9152 case MIPS_HFLAG_BR:
9153 /* unconditional branch to register */
9154 MIPS_DEBUG("branch to register");
3c824109 9155 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9156 TCGv t0 = tcg_temp_new();
9157 TCGv_i32 t1 = tcg_temp_new_i32();
9158
9159 tcg_gen_andi_tl(t0, btarget, 0x1);
9160 tcg_gen_trunc_tl_i32(t1, t0);
9161 tcg_temp_free(t0);
9162 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9163 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9164 tcg_gen_or_i32(hflags, hflags, t1);
9165 tcg_temp_free_i32(t1);
9166
9167 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9168 } else {
9169 tcg_gen_mov_tl(cpu_PC, btarget);
9170 }
c9602061
NF
9171 if (ctx->singlestep_enabled) {
9172 save_cpu_state(ctx, 0);
895c2d04 9173 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9174 }
9175 tcg_gen_exit_tb(0);
9176 break;
9177 default:
9178 MIPS_DEBUG("unknown branch");
9179 break;
9180 }
9181 }
9182}
9183
7a387fff 9184/* ISA extensions (ASEs) */
6af0bf9c 9185/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9186
9187/* MIPS16 major opcodes */
9188enum {
9189 M16_OPC_ADDIUSP = 0x00,
9190 M16_OPC_ADDIUPC = 0x01,
9191 M16_OPC_B = 0x02,
9192 M16_OPC_JAL = 0x03,
9193 M16_OPC_BEQZ = 0x04,
9194 M16_OPC_BNEQZ = 0x05,
9195 M16_OPC_SHIFT = 0x06,
9196 M16_OPC_LD = 0x07,
9197 M16_OPC_RRIA = 0x08,
9198 M16_OPC_ADDIU8 = 0x09,
9199 M16_OPC_SLTI = 0x0a,
9200 M16_OPC_SLTIU = 0x0b,
9201 M16_OPC_I8 = 0x0c,
9202 M16_OPC_LI = 0x0d,
9203 M16_OPC_CMPI = 0x0e,
9204 M16_OPC_SD = 0x0f,
9205 M16_OPC_LB = 0x10,
9206 M16_OPC_LH = 0x11,
9207 M16_OPC_LWSP = 0x12,
9208 M16_OPC_LW = 0x13,
9209 M16_OPC_LBU = 0x14,
9210 M16_OPC_LHU = 0x15,
9211 M16_OPC_LWPC = 0x16,
9212 M16_OPC_LWU = 0x17,
9213 M16_OPC_SB = 0x18,
9214 M16_OPC_SH = 0x19,
9215 M16_OPC_SWSP = 0x1a,
9216 M16_OPC_SW = 0x1b,
9217 M16_OPC_RRR = 0x1c,
9218 M16_OPC_RR = 0x1d,
9219 M16_OPC_EXTEND = 0x1e,
9220 M16_OPC_I64 = 0x1f
9221};
9222
9223/* I8 funct field */
9224enum {
9225 I8_BTEQZ = 0x0,
9226 I8_BTNEZ = 0x1,
9227 I8_SWRASP = 0x2,
9228 I8_ADJSP = 0x3,
9229 I8_SVRS = 0x4,
9230 I8_MOV32R = 0x5,
9231 I8_MOVR32 = 0x7
9232};
9233
9234/* RRR f field */
9235enum {
9236 RRR_DADDU = 0x0,
9237 RRR_ADDU = 0x1,
9238 RRR_DSUBU = 0x2,
9239 RRR_SUBU = 0x3
9240};
9241
9242/* RR funct field */
9243enum {
9244 RR_JR = 0x00,
9245 RR_SDBBP = 0x01,
9246 RR_SLT = 0x02,
9247 RR_SLTU = 0x03,
9248 RR_SLLV = 0x04,
9249 RR_BREAK = 0x05,
9250 RR_SRLV = 0x06,
9251 RR_SRAV = 0x07,
9252 RR_DSRL = 0x08,
9253 RR_CMP = 0x0a,
9254 RR_NEG = 0x0b,
9255 RR_AND = 0x0c,
9256 RR_OR = 0x0d,
9257 RR_XOR = 0x0e,
9258 RR_NOT = 0x0f,
9259 RR_MFHI = 0x10,
9260 RR_CNVT = 0x11,
9261 RR_MFLO = 0x12,
9262 RR_DSRA = 0x13,
9263 RR_DSLLV = 0x14,
9264 RR_DSRLV = 0x16,
9265 RR_DSRAV = 0x17,
9266 RR_MULT = 0x18,
9267 RR_MULTU = 0x19,
9268 RR_DIV = 0x1a,
9269 RR_DIVU = 0x1b,
9270 RR_DMULT = 0x1c,
9271 RR_DMULTU = 0x1d,
9272 RR_DDIV = 0x1e,
9273 RR_DDIVU = 0x1f
9274};
9275
9276/* I64 funct field */
9277enum {
9278 I64_LDSP = 0x0,
9279 I64_SDSP = 0x1,
9280 I64_SDRASP = 0x2,
9281 I64_DADJSP = 0x3,
9282 I64_LDPC = 0x4,
364d4831 9283 I64_DADDIU5 = 0x5,
6ea219d0
NF
9284 I64_DADDIUPC = 0x6,
9285 I64_DADDIUSP = 0x7
9286};
9287
9288/* RR ry field for CNVT */
9289enum {
9290 RR_RY_CNVT_ZEB = 0x0,
9291 RR_RY_CNVT_ZEH = 0x1,
9292 RR_RY_CNVT_ZEW = 0x2,
9293 RR_RY_CNVT_SEB = 0x4,
9294 RR_RY_CNVT_SEH = 0x5,
9295 RR_RY_CNVT_SEW = 0x6,
9296};
9297
364d4831
NF
9298static int xlat (int r)
9299{
9300 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9301
9302 return map[r];
9303}
9304
9305static void gen_mips16_save (DisasContext *ctx,
9306 int xsregs, int aregs,
9307 int do_ra, int do_s0, int do_s1,
9308 int framesize)
9309{
9310 TCGv t0 = tcg_temp_new();
9311 TCGv t1 = tcg_temp_new();
9312 int args, astatic;
9313
9314 switch (aregs) {
9315 case 0:
9316 case 1:
9317 case 2:
9318 case 3:
9319 case 11:
9320 args = 0;
9321 break;
9322 case 4:
9323 case 5:
9324 case 6:
9325 case 7:
9326 args = 1;
9327 break;
9328 case 8:
9329 case 9:
9330 case 10:
9331 args = 2;
9332 break;
9333 case 12:
9334 case 13:
9335 args = 3;
9336 break;
9337 case 14:
9338 args = 4;
9339 break;
9340 default:
9341 generate_exception(ctx, EXCP_RI);
9342 return;
9343 }
9344
9345 switch (args) {
9346 case 4:
9347 gen_base_offset_addr(ctx, t0, 29, 12);
9348 gen_load_gpr(t1, 7);
2910c6cb 9349 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9350 /* Fall through */
9351 case 3:
9352 gen_base_offset_addr(ctx, t0, 29, 8);
9353 gen_load_gpr(t1, 6);
2910c6cb 9354 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9355 /* Fall through */
9356 case 2:
9357 gen_base_offset_addr(ctx, t0, 29, 4);
9358 gen_load_gpr(t1, 5);
2910c6cb 9359 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9360 /* Fall through */
9361 case 1:
9362 gen_base_offset_addr(ctx, t0, 29, 0);
9363 gen_load_gpr(t1, 4);
2910c6cb 9364 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9365 }
9366
9367 gen_load_gpr(t0, 29);
9368
9369#define DECR_AND_STORE(reg) do { \
9370 tcg_gen_subi_tl(t0, t0, 4); \
9371 gen_load_gpr(t1, reg); \
2910c6cb 9372 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
364d4831
NF
9373 } while (0)
9374
9375 if (do_ra) {
9376 DECR_AND_STORE(31);
9377 }
9378
9379 switch (xsregs) {
9380 case 7:
9381 DECR_AND_STORE(30);
9382 /* Fall through */
9383 case 6:
9384 DECR_AND_STORE(23);
9385 /* Fall through */
9386 case 5:
9387 DECR_AND_STORE(22);
9388 /* Fall through */
9389 case 4:
9390 DECR_AND_STORE(21);
9391 /* Fall through */
9392 case 3:
9393 DECR_AND_STORE(20);
9394 /* Fall through */
9395 case 2:
9396 DECR_AND_STORE(19);
9397 /* Fall through */
9398 case 1:
9399 DECR_AND_STORE(18);
9400 }
9401
9402 if (do_s1) {
9403 DECR_AND_STORE(17);
9404 }
9405 if (do_s0) {
9406 DECR_AND_STORE(16);
9407 }
9408
9409 switch (aregs) {
9410 case 0:
9411 case 4:
9412 case 8:
9413 case 12:
9414 case 14:
9415 astatic = 0;
9416 break;
9417 case 1:
9418 case 5:
9419 case 9:
9420 case 13:
9421 astatic = 1;
9422 break;
9423 case 2:
9424 case 6:
9425 case 10:
9426 astatic = 2;
9427 break;
9428 case 3:
9429 case 7:
9430 astatic = 3;
9431 break;
9432 case 11:
9433 astatic = 4;
9434 break;
9435 default:
9436 generate_exception(ctx, EXCP_RI);
9437 return;
9438 }
9439
9440 if (astatic > 0) {
9441 DECR_AND_STORE(7);
9442 if (astatic > 1) {
9443 DECR_AND_STORE(6);
9444 if (astatic > 2) {
9445 DECR_AND_STORE(5);
9446 if (astatic > 3) {
9447 DECR_AND_STORE(4);
9448 }
9449 }
9450 }
9451 }
9452#undef DECR_AND_STORE
9453
9454 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9455 tcg_temp_free(t0);
9456 tcg_temp_free(t1);
9457}
9458
9459static void gen_mips16_restore (DisasContext *ctx,
9460 int xsregs, int aregs,
9461 int do_ra, int do_s0, int do_s1,
9462 int framesize)
9463{
9464 int astatic;
9465 TCGv t0 = tcg_temp_new();
9466 TCGv t1 = tcg_temp_new();
9467
9468 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9469
2910c6cb
AJ
9470#define DECR_AND_LOAD(reg) do { \
9471 tcg_gen_subi_tl(t0, t0, 4); \
9472 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9473 gen_store_gpr(t1, reg); \
364d4831
NF
9474 } while (0)
9475
9476 if (do_ra) {
9477 DECR_AND_LOAD(31);
9478 }
9479
9480 switch (xsregs) {
9481 case 7:
9482 DECR_AND_LOAD(30);
9483 /* Fall through */
9484 case 6:
9485 DECR_AND_LOAD(23);
9486 /* Fall through */
9487 case 5:
9488 DECR_AND_LOAD(22);
9489 /* Fall through */
9490 case 4:
9491 DECR_AND_LOAD(21);
9492 /* Fall through */
9493 case 3:
9494 DECR_AND_LOAD(20);
9495 /* Fall through */
9496 case 2:
9497 DECR_AND_LOAD(19);
9498 /* Fall through */
9499 case 1:
9500 DECR_AND_LOAD(18);
9501 }
9502
9503 if (do_s1) {
9504 DECR_AND_LOAD(17);
9505 }
9506 if (do_s0) {
9507 DECR_AND_LOAD(16);
9508 }
9509
9510 switch (aregs) {
9511 case 0:
9512 case 4:
9513 case 8:
9514 case 12:
9515 case 14:
9516 astatic = 0;
9517 break;
9518 case 1:
9519 case 5:
9520 case 9:
9521 case 13:
9522 astatic = 1;
9523 break;
9524 case 2:
9525 case 6:
9526 case 10:
9527 astatic = 2;
9528 break;
9529 case 3:
9530 case 7:
9531 astatic = 3;
9532 break;
9533 case 11:
9534 astatic = 4;
9535 break;
9536 default:
9537 generate_exception(ctx, EXCP_RI);
9538 return;
9539 }
9540
9541 if (astatic > 0) {
9542 DECR_AND_LOAD(7);
9543 if (astatic > 1) {
9544 DECR_AND_LOAD(6);
9545 if (astatic > 2) {
9546 DECR_AND_LOAD(5);
9547 if (astatic > 3) {
9548 DECR_AND_LOAD(4);
9549 }
9550 }
9551 }
9552 }
9553#undef DECR_AND_LOAD
9554
9555 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9556 tcg_temp_free(t0);
9557 tcg_temp_free(t1);
9558}
9559
9560static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9561 int is_64_bit, int extended)
9562{
9563 TCGv t0;
9564
9565 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9566 generate_exception(ctx, EXCP_RI);
9567 return;
9568 }
9569
9570 t0 = tcg_temp_new();
9571
9572 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9573 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9574 if (!is_64_bit) {
9575 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9576 }
9577
9578 tcg_temp_free(t0);
9579}
9580
9581#if defined(TARGET_MIPS64)
7db13fae 9582static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9583 int ry, int funct, int16_t offset,
9584 int extended)
9585{
9586 switch (funct) {
9587 case I64_LDSP:
9588 check_mips_64(ctx);
9589 offset = extended ? offset : offset << 3;
afa88c3a 9590 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9591 break;
9592 case I64_SDSP:
9593 check_mips_64(ctx);
9594 offset = extended ? offset : offset << 3;
5c13fdfd 9595 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9596 break;
9597 case I64_SDRASP:
9598 check_mips_64(ctx);
9599 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9600 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9601 break;
9602 case I64_DADJSP:
9603 check_mips_64(ctx);
9604 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9605 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9606 break;
9607 case I64_LDPC:
9608 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9609 generate_exception(ctx, EXCP_RI);
9610 } else {
9611 offset = extended ? offset : offset << 3;
afa88c3a 9612 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9613 }
9614 break;
9615 case I64_DADDIU5:
9616 check_mips_64(ctx);
9617 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9618 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9619 break;
9620 case I64_DADDIUPC:
9621 check_mips_64(ctx);
9622 offset = extended ? offset : offset << 2;
9623 gen_addiupc(ctx, ry, offset, 1, extended);
9624 break;
9625 case I64_DADDIUSP:
9626 check_mips_64(ctx);
9627 offset = extended ? offset : offset << 2;
9628 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9629 break;
9630 }
9631}
9632#endif
9633
7db13fae 9634static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9635 int *is_branch)
9636{
895c2d04 9637 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9638 int op, rx, ry, funct, sa;
9639 int16_t imm, offset;
9640
9641 ctx->opcode = (ctx->opcode << 16) | extend;
9642 op = (ctx->opcode >> 11) & 0x1f;
9643 sa = (ctx->opcode >> 22) & 0x1f;
9644 funct = (ctx->opcode >> 8) & 0x7;
9645 rx = xlat((ctx->opcode >> 8) & 0x7);
9646 ry = xlat((ctx->opcode >> 5) & 0x7);
9647 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9648 | ((ctx->opcode >> 21) & 0x3f) << 5
9649 | (ctx->opcode & 0x1f));
9650
9651 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9652 counterparts. */
9653 switch (op) {
9654 case M16_OPC_ADDIUSP:
9655 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9656 break;
9657 case M16_OPC_ADDIUPC:
9658 gen_addiupc(ctx, rx, imm, 0, 1);
9659 break;
9660 case M16_OPC_B:
9661 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9662 /* No delay slot, so just process as a normal instruction */
9663 break;
9664 case M16_OPC_BEQZ:
9665 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9666 /* No delay slot, so just process as a normal instruction */
9667 break;
9668 case M16_OPC_BNEQZ:
9669 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9670 /* No delay slot, so just process as a normal instruction */
9671 break;
9672 case M16_OPC_SHIFT:
9673 switch (ctx->opcode & 0x3) {
9674 case 0x0:
9675 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9676 break;
9677 case 0x1:
9678#if defined(TARGET_MIPS64)
9679 check_mips_64(ctx);
9680 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9681#else
9682 generate_exception(ctx, EXCP_RI);
9683#endif
9684 break;
9685 case 0x2:
9686 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9687 break;
9688 case 0x3:
9689 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9690 break;
9691 }
9692 break;
9693#if defined(TARGET_MIPS64)
9694 case M16_OPC_LD:
9695 check_mips_64(ctx);
afa88c3a 9696 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9697 break;
9698#endif
9699 case M16_OPC_RRIA:
9700 imm = ctx->opcode & 0xf;
9701 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9702 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9703 imm = (int16_t) (imm << 1) >> 1;
9704 if ((ctx->opcode >> 4) & 0x1) {
9705#if defined(TARGET_MIPS64)
9706 check_mips_64(ctx);
9707 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9708#else
9709 generate_exception(ctx, EXCP_RI);
9710#endif
9711 } else {
9712 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9713 }
9714 break;
9715 case M16_OPC_ADDIU8:
9716 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9717 break;
9718 case M16_OPC_SLTI:
9fa77488 9719 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9720 break;
9721 case M16_OPC_SLTIU:
9fa77488 9722 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9723 break;
9724 case M16_OPC_I8:
9725 switch (funct) {
9726 case I8_BTEQZ:
9727 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9728 break;
9729 case I8_BTNEZ:
9730 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9731 break;
9732 case I8_SWRASP:
5c13fdfd 9733 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9734 break;
9735 case I8_ADJSP:
9736 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9737 break;
9738 case I8_SVRS:
9739 {
9740 int xsregs = (ctx->opcode >> 24) & 0x7;
9741 int aregs = (ctx->opcode >> 16) & 0xf;
9742 int do_ra = (ctx->opcode >> 6) & 0x1;
9743 int do_s0 = (ctx->opcode >> 5) & 0x1;
9744 int do_s1 = (ctx->opcode >> 4) & 0x1;
9745 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9746 | (ctx->opcode & 0xf)) << 3;
9747
9748 if (ctx->opcode & (1 << 7)) {
9749 gen_mips16_save(ctx, xsregs, aregs,
9750 do_ra, do_s0, do_s1,
9751 framesize);
9752 } else {
9753 gen_mips16_restore(ctx, xsregs, aregs,
9754 do_ra, do_s0, do_s1,
9755 framesize);
9756 }
9757 }
9758 break;
9759 default:
9760 generate_exception(ctx, EXCP_RI);
9761 break;
9762 }
9763 break;
9764 case M16_OPC_LI:
9765 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9766 break;
9767 case M16_OPC_CMPI:
9768 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9769 break;
9770#if defined(TARGET_MIPS64)
9771 case M16_OPC_SD:
5c13fdfd 9772 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9773 break;
9774#endif
9775 case M16_OPC_LB:
afa88c3a 9776 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9777 break;
9778 case M16_OPC_LH:
afa88c3a 9779 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9780 break;
9781 case M16_OPC_LWSP:
afa88c3a 9782 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9783 break;
9784 case M16_OPC_LW:
afa88c3a 9785 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9786 break;
9787 case M16_OPC_LBU:
afa88c3a 9788 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9789 break;
9790 case M16_OPC_LHU:
afa88c3a 9791 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9792 break;
9793 case M16_OPC_LWPC:
afa88c3a 9794 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9795 break;
9796#if defined(TARGET_MIPS64)
9797 case M16_OPC_LWU:
afa88c3a 9798 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9799 break;
9800#endif
9801 case M16_OPC_SB:
5c13fdfd 9802 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9803 break;
9804 case M16_OPC_SH:
5c13fdfd 9805 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9806 break;
9807 case M16_OPC_SWSP:
5c13fdfd 9808 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9809 break;
9810 case M16_OPC_SW:
5c13fdfd 9811 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9812 break;
9813#if defined(TARGET_MIPS64)
9814 case M16_OPC_I64:
9815 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9816 break;
9817#endif
9818 default:
9819 generate_exception(ctx, EXCP_RI);
9820 break;
9821 }
9822
9823 return 4;
9824}
9825
7db13fae 9826static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9827 int *is_branch)
9828{
9829 int rx, ry;
9830 int sa;
9831 int op, cnvt_op, op1, offset;
9832 int funct;
9833 int n_bytes;
9834
9835 op = (ctx->opcode >> 11) & 0x1f;
9836 sa = (ctx->opcode >> 2) & 0x7;
9837 sa = sa == 0 ? 8 : sa;
9838 rx = xlat((ctx->opcode >> 8) & 0x7);
9839 cnvt_op = (ctx->opcode >> 5) & 0x7;
9840 ry = xlat((ctx->opcode >> 5) & 0x7);
9841 op1 = offset = ctx->opcode & 0x1f;
9842
9843 n_bytes = 2;
9844
9845 switch (op) {
9846 case M16_OPC_ADDIUSP:
9847 {
9848 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9849
9850 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9851 }
9852 break;
9853 case M16_OPC_ADDIUPC:
9854 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9855 break;
9856 case M16_OPC_B:
9857 offset = (ctx->opcode & 0x7ff) << 1;
9858 offset = (int16_t)(offset << 4) >> 4;
9859 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9860 /* No delay slot, so just process as a normal instruction */
9861 break;
9862 case M16_OPC_JAL:
895c2d04 9863 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9864 offset = (((ctx->opcode & 0x1f) << 21)
9865 | ((ctx->opcode >> 5) & 0x1f) << 16
9866 | offset) << 2;
620e48f6 9867 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9868 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9869 n_bytes = 4;
9870 *is_branch = 1;
9871 break;
9872 case M16_OPC_BEQZ:
9873 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9874 /* No delay slot, so just process as a normal instruction */
9875 break;
9876 case M16_OPC_BNEQZ:
9877 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9878 /* No delay slot, so just process as a normal instruction */
9879 break;
9880 case M16_OPC_SHIFT:
9881 switch (ctx->opcode & 0x3) {
9882 case 0x0:
9883 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9884 break;
9885 case 0x1:
9886#if defined(TARGET_MIPS64)
9887 check_mips_64(ctx);
9888 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9889#else
9890 generate_exception(ctx, EXCP_RI);
9891#endif
9892 break;
9893 case 0x2:
9894 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9895 break;
9896 case 0x3:
9897 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9898 break;
9899 }
9900 break;
9901#if defined(TARGET_MIPS64)
9902 case M16_OPC_LD:
9903 check_mips_64(ctx);
afa88c3a 9904 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9905 break;
9906#endif
9907 case M16_OPC_RRIA:
9908 {
9909 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9910
9911 if ((ctx->opcode >> 4) & 1) {
9912#if defined(TARGET_MIPS64)
9913 check_mips_64(ctx);
9914 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9915#else
9916 generate_exception(ctx, EXCP_RI);
9917#endif
9918 } else {
9919 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9920 }
9921 }
9922 break;
9923 case M16_OPC_ADDIU8:
9924 {
9925 int16_t imm = (int8_t) ctx->opcode;
9926
9927 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9928 }
9929 break;
9930 case M16_OPC_SLTI:
9931 {
9932 int16_t imm = (uint8_t) ctx->opcode;
9fa77488 9933 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9934 }
9935 break;
9936 case M16_OPC_SLTIU:
9937 {
9938 int16_t imm = (uint8_t) ctx->opcode;
9fa77488 9939 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9940 }
9941 break;
9942 case M16_OPC_I8:
9943 {
9944 int reg32;
9945
9946 funct = (ctx->opcode >> 8) & 0x7;
9947 switch (funct) {
9948 case I8_BTEQZ:
9949 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9950 ((int8_t)ctx->opcode) << 1);
9951 break;
9952 case I8_BTNEZ:
9953 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9954 ((int8_t)ctx->opcode) << 1);
9955 break;
9956 case I8_SWRASP:
5c13fdfd 9957 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9958 break;
9959 case I8_ADJSP:
9960 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9961 ((int8_t)ctx->opcode) << 3);
9962 break;
9963 case I8_SVRS:
9964 {
9965 int do_ra = ctx->opcode & (1 << 6);
9966 int do_s0 = ctx->opcode & (1 << 5);
9967 int do_s1 = ctx->opcode & (1 << 4);
9968 int framesize = ctx->opcode & 0xf;
9969
9970 if (framesize == 0) {
9971 framesize = 128;
9972 } else {
9973 framesize = framesize << 3;
9974 }
9975
9976 if (ctx->opcode & (1 << 7)) {
9977 gen_mips16_save(ctx, 0, 0,
9978 do_ra, do_s0, do_s1, framesize);
9979 } else {
9980 gen_mips16_restore(ctx, 0, 0,
9981 do_ra, do_s0, do_s1, framesize);
9982 }
9983 }
9984 break;
9985 case I8_MOV32R:
9986 {
9987 int rz = xlat(ctx->opcode & 0x7);
9988
9989 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9990 ((ctx->opcode >> 5) & 0x7);
9991 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9992 }
9993 break;
9994 case I8_MOVR32:
9995 reg32 = ctx->opcode & 0x1f;
9996 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9997 break;
9998 default:
9999 generate_exception(ctx, EXCP_RI);
10000 break;
10001 }
10002 }
10003 break;
10004 case M16_OPC_LI:
10005 {
10006 int16_t imm = (uint8_t) ctx->opcode;
10007
10008 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10009 }
10010 break;
10011 case M16_OPC_CMPI:
10012 {
10013 int16_t imm = (uint8_t) ctx->opcode;
9fa77488 10014 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
10015 }
10016 break;
10017#if defined(TARGET_MIPS64)
10018 case M16_OPC_SD:
10019 check_mips_64(ctx);
5c13fdfd 10020 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
10021 break;
10022#endif
10023 case M16_OPC_LB:
afa88c3a 10024 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10025 break;
10026 case M16_OPC_LH:
afa88c3a 10027 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
10028 break;
10029 case M16_OPC_LWSP:
afa88c3a 10030 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10031 break;
10032 case M16_OPC_LW:
afa88c3a 10033 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10034 break;
10035 case M16_OPC_LBU:
afa88c3a 10036 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10037 break;
10038 case M16_OPC_LHU:
afa88c3a 10039 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10040 break;
10041 case M16_OPC_LWPC:
afa88c3a 10042 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10043 break;
10044#if defined (TARGET_MIPS64)
10045 case M16_OPC_LWU:
10046 check_mips_64(ctx);
afa88c3a 10047 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10048 break;
10049#endif
10050 case M16_OPC_SB:
5c13fdfd 10051 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10052 break;
10053 case M16_OPC_SH:
5c13fdfd 10054 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10055 break;
10056 case M16_OPC_SWSP:
5c13fdfd 10057 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10058 break;
10059 case M16_OPC_SW:
5c13fdfd 10060 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10061 break;
10062 case M16_OPC_RRR:
10063 {
10064 int rz = xlat((ctx->opcode >> 2) & 0x7);
10065 int mips32_op;
10066
10067 switch (ctx->opcode & 0x3) {
10068 case RRR_ADDU:
10069 mips32_op = OPC_ADDU;
10070 break;
10071 case RRR_SUBU:
10072 mips32_op = OPC_SUBU;
10073 break;
10074#if defined(TARGET_MIPS64)
10075 case RRR_DADDU:
10076 mips32_op = OPC_DADDU;
10077 check_mips_64(ctx);
10078 break;
10079 case RRR_DSUBU:
10080 mips32_op = OPC_DSUBU;
10081 check_mips_64(ctx);
10082 break;
10083#endif
10084 default:
10085 generate_exception(ctx, EXCP_RI);
10086 goto done;
10087 }
10088
10089 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10090 done:
10091 ;
10092 }
10093 break;
10094 case M16_OPC_RR:
10095 switch (op1) {
10096 case RR_JR:
10097 {
10098 int nd = (ctx->opcode >> 7) & 0x1;
10099 int link = (ctx->opcode >> 6) & 0x1;
10100 int ra = (ctx->opcode >> 5) & 0x1;
10101
10102 if (link) {
620e48f6 10103 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10104 } else {
10105 op = OPC_JR;
10106 }
10107
10108 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10109 if (!nd) {
10110 *is_branch = 1;
10111 }
10112 }
10113 break;
10114 case RR_SDBBP:
10115 /* XXX: not clear which exception should be raised
10116 * when in debug mode...
10117 */
10118 check_insn(env, ctx, ISA_MIPS32);
10119 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10120 generate_exception(ctx, EXCP_DBp);
10121 } else {
10122 generate_exception(ctx, EXCP_DBp);
10123 }
10124 break;
10125 case RR_SLT:
9fa77488 10126 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10127 break;
10128 case RR_SLTU:
9fa77488 10129 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10130 break;
10131 case RR_BREAK:
10132 generate_exception(ctx, EXCP_BREAK);
10133 break;
10134 case RR_SLLV:
10135 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10136 break;
10137 case RR_SRLV:
10138 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10139 break;
10140 case RR_SRAV:
10141 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10142 break;
10143#if defined (TARGET_MIPS64)
10144 case RR_DSRL:
10145 check_mips_64(ctx);
10146 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10147 break;
10148#endif
10149 case RR_CMP:
9fa77488 10150 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10151 break;
10152 case RR_NEG:
10153 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10154 break;
10155 case RR_AND:
9fa77488 10156 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10157 break;
10158 case RR_OR:
9fa77488 10159 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10160 break;
10161 case RR_XOR:
9fa77488 10162 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10163 break;
10164 case RR_NOT:
9fa77488 10165 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10166 break;
10167 case RR_MFHI:
10168 gen_HILO(ctx, OPC_MFHI, rx);
10169 break;
10170 case RR_CNVT:
10171 switch (cnvt_op) {
10172 case RR_RY_CNVT_ZEB:
10173 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10174 break;
10175 case RR_RY_CNVT_ZEH:
10176 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10177 break;
10178 case RR_RY_CNVT_SEB:
10179 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10180 break;
10181 case RR_RY_CNVT_SEH:
10182 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10183 break;
10184#if defined (TARGET_MIPS64)
10185 case RR_RY_CNVT_ZEW:
10186 check_mips_64(ctx);
10187 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10188 break;
10189 case RR_RY_CNVT_SEW:
10190 check_mips_64(ctx);
10191 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10192 break;
10193#endif
10194 default:
10195 generate_exception(ctx, EXCP_RI);
10196 break;
10197 }
10198 break;
10199 case RR_MFLO:
10200 gen_HILO(ctx, OPC_MFLO, rx);
10201 break;
10202#if defined (TARGET_MIPS64)
10203 case RR_DSRA:
10204 check_mips_64(ctx);
10205 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10206 break;
10207 case RR_DSLLV:
10208 check_mips_64(ctx);
10209 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10210 break;
10211 case RR_DSRLV:
10212 check_mips_64(ctx);
10213 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10214 break;
10215 case RR_DSRAV:
10216 check_mips_64(ctx);
10217 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10218 break;
10219#endif
10220 case RR_MULT:
10221 gen_muldiv(ctx, OPC_MULT, rx, ry);
10222 break;
10223 case RR_MULTU:
10224 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10225 break;
10226 case RR_DIV:
10227 gen_muldiv(ctx, OPC_DIV, rx, ry);
10228 break;
10229 case RR_DIVU:
10230 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10231 break;
10232#if defined (TARGET_MIPS64)
10233 case RR_DMULT:
10234 check_mips_64(ctx);
10235 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10236 break;
10237 case RR_DMULTU:
10238 check_mips_64(ctx);
10239 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10240 break;
10241 case RR_DDIV:
10242 check_mips_64(ctx);
10243 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10244 break;
10245 case RR_DDIVU:
10246 check_mips_64(ctx);
10247 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10248 break;
10249#endif
10250 default:
10251 generate_exception(ctx, EXCP_RI);
10252 break;
10253 }
10254 break;
10255 case M16_OPC_EXTEND:
10256 decode_extended_mips16_opc(env, ctx, is_branch);
10257 n_bytes = 4;
10258 break;
10259#if defined(TARGET_MIPS64)
10260 case M16_OPC_I64:
10261 funct = (ctx->opcode >> 8) & 0x7;
10262 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10263 break;
10264#endif
10265 default:
10266 generate_exception(ctx, EXCP_RI);
10267 break;
10268 }
10269
10270 return n_bytes;
10271}
10272
3c824109 10273/* microMIPS extension to MIPS32 */
6af0bf9c 10274
3c824109 10275/* microMIPS32 major opcodes */
6af0bf9c 10276
3c824109
NF
10277enum {
10278 POOL32A = 0x00,
10279 POOL16A = 0x01,
10280 LBU16 = 0x02,
10281 MOVE16 = 0x03,
10282 ADDI32 = 0x04,
10283 LBU32 = 0x05,
10284 SB32 = 0x06,
10285 LB32 = 0x07,
10286
10287 POOL32B = 0x08,
10288 POOL16B = 0x09,
10289 LHU16 = 0x0a,
10290 ANDI16 = 0x0b,
10291 ADDIU32 = 0x0c,
10292 LHU32 = 0x0d,
10293 SH32 = 0x0e,
10294 LH32 = 0x0f,
10295
10296 POOL32I = 0x10,
10297 POOL16C = 0x11,
10298 LWSP16 = 0x12,
10299 POOL16D = 0x13,
10300 ORI32 = 0x14,
10301 POOL32F = 0x15,
10302 POOL32S = 0x16,
10303 DADDIU32 = 0x17,
10304
10305 POOL32C = 0x18,
10306 LWGP16 = 0x19,
10307 LW16 = 0x1a,
10308 POOL16E = 0x1b,
10309 XORI32 = 0x1c,
10310 JALS32 = 0x1d,
10311 ADDIUPC = 0x1e,
10312 POOL48A = 0x1f,
10313
10314 /* 0x20 is reserved */
10315 RES_20 = 0x20,
10316 POOL16F = 0x21,
10317 SB16 = 0x22,
10318 BEQZ16 = 0x23,
10319 SLTI32 = 0x24,
10320 BEQ32 = 0x25,
10321 SWC132 = 0x26,
10322 LWC132 = 0x27,
10323
10324 /* 0x28 and 0x29 are reserved */
10325 RES_28 = 0x28,
10326 RES_29 = 0x29,
10327 SH16 = 0x2a,
10328 BNEZ16 = 0x2b,
10329 SLTIU32 = 0x2c,
10330 BNE32 = 0x2d,
10331 SDC132 = 0x2e,
10332 LDC132 = 0x2f,
10333
10334 /* 0x30 and 0x31 are reserved */
10335 RES_30 = 0x30,
10336 RES_31 = 0x31,
10337 SWSP16 = 0x32,
10338 B16 = 0x33,
10339 ANDI32 = 0x34,
10340 J32 = 0x35,
10341 SD32 = 0x36,
10342 LD32 = 0x37,
10343
10344 /* 0x38 and 0x39 are reserved */
10345 RES_38 = 0x38,
10346 RES_39 = 0x39,
10347 SW16 = 0x3a,
10348 LI16 = 0x3b,
10349 JALX32 = 0x3c,
10350 JAL32 = 0x3d,
10351 SW32 = 0x3e,
10352 LW32 = 0x3f
10353};
10354
10355/* POOL32A encoding of minor opcode field */
10356
10357enum {
10358 /* These opcodes are distinguished only by bits 9..6; those bits are
10359 * what are recorded below. */
10360 SLL32 = 0x0,
10361 SRL32 = 0x1,
10362 SRA = 0x2,
10363 ROTR = 0x3,
10364
10365 SLLV = 0x0,
10366 SRLV = 0x1,
10367 SRAV = 0x2,
10368 ROTRV = 0x3,
10369 ADD = 0x4,
10370 ADDU32 = 0x5,
10371 SUB = 0x6,
10372 SUBU32 = 0x7,
10373 MUL = 0x8,
10374 AND = 0x9,
10375 OR32 = 0xa,
10376 NOR = 0xb,
10377 XOR32 = 0xc,
10378 SLT = 0xd,
10379 SLTU = 0xe,
10380
10381 MOVN = 0x0,
10382 MOVZ = 0x1,
10383 LWXS = 0x4,
10384
10385 /* The following can be distinguished by their lower 6 bits. */
10386 INS = 0x0c,
10387 EXT = 0x2c,
10388 POOL32AXF = 0x3c
10389};
10390
10391/* POOL32AXF encoding of minor opcode field extension */
10392
10393enum {
10394 /* bits 11..6 */
10395 TEQ = 0x00,
10396 TGE = 0x08,
10397 TGEU = 0x10,
10398 TLT = 0x20,
10399 TLTU = 0x28,
10400 TNE = 0x30,
10401
10402 MFC0 = 0x03,
10403 MTC0 = 0x0b,
10404
10405 /* bits 13..12 for 0x01 */
10406 MFHI_ACC = 0x0,
10407 MFLO_ACC = 0x1,
10408 MTHI_ACC = 0x2,
10409 MTLO_ACC = 0x3,
10410
10411 /* bits 13..12 for 0x2a */
10412 MADD_ACC = 0x0,
10413 MADDU_ACC = 0x1,
10414 MSUB_ACC = 0x2,
10415 MSUBU_ACC = 0x3,
10416
10417 /* bits 13..12 for 0x32 */
10418 MULT_ACC = 0x0,
10419 MULTU_ACC = 0x0,
10420
10421 /* bits 15..12 for 0x2c */
10422 SEB = 0x2,
10423 SEH = 0x3,
10424 CLO = 0x4,
10425 CLZ = 0x5,
10426 RDHWR = 0x6,
10427 WSBH = 0x7,
10428 MULT = 0x8,
10429 MULTU = 0x9,
10430 DIV = 0xa,
10431 DIVU = 0xb,
10432 MADD = 0xc,
10433 MADDU = 0xd,
10434 MSUB = 0xe,
10435 MSUBU = 0xf,
10436
10437 /* bits 15..12 for 0x34 */
10438 MFC2 = 0x4,
10439 MTC2 = 0x5,
10440 MFHC2 = 0x8,
10441 MTHC2 = 0x9,
10442 CFC2 = 0xc,
10443 CTC2 = 0xd,
10444
10445 /* bits 15..12 for 0x3c */
10446 JALR = 0x0,
10447 JR = 0x0, /* alias */
10448 JALR_HB = 0x1,
10449 JALRS = 0x4,
10450 JALRS_HB = 0x5,
10451
10452 /* bits 15..12 for 0x05 */
10453 RDPGPR = 0xe,
10454 WRPGPR = 0xf,
10455
10456 /* bits 15..12 for 0x0d */
10457 TLBP = 0x0,
10458 TLBR = 0x1,
10459 TLBWI = 0x2,
10460 TLBWR = 0x3,
10461 WAIT = 0x9,
10462 IRET = 0xd,
10463 DERET = 0xe,
10464 ERET = 0xf,
10465
10466 /* bits 15..12 for 0x15 */
10467 DMT = 0x0,
10468 DVPE = 0x1,
10469 EMT = 0x2,
10470 EVPE = 0x3,
10471
10472 /* bits 15..12 for 0x1d */
10473 DI = 0x4,
10474 EI = 0x5,
10475
10476 /* bits 15..12 for 0x2d */
10477 SYNC = 0x6,
10478 SYSCALL = 0x8,
10479 SDBBP = 0xd,
10480
10481 /* bits 15..12 for 0x35 */
10482 MFHI32 = 0x0,
10483 MFLO32 = 0x1,
10484 MTHI32 = 0x2,
10485 MTLO32 = 0x3,
10486};
10487
10488/* POOL32B encoding of minor opcode field (bits 15..12) */
10489
10490enum {
10491 LWC2 = 0x0,
10492 LWP = 0x1,
10493 LDP = 0x4,
10494 LWM32 = 0x5,
10495 CACHE = 0x6,
10496 LDM = 0x7,
10497 SWC2 = 0x8,
10498 SWP = 0x9,
10499 SDP = 0xc,
10500 SWM32 = 0xd,
10501 SDM = 0xf
10502};
10503
10504/* POOL32C encoding of minor opcode field (bits 15..12) */
10505
10506enum {
10507 LWL = 0x0,
10508 SWL = 0x8,
10509 LWR = 0x1,
10510 SWR = 0x9,
10511 PREF = 0x2,
10512 /* 0xa is reserved */
10513 LL = 0x3,
10514 SC = 0xb,
10515 LDL = 0x4,
10516 SDL = 0xc,
10517 LDR = 0x5,
10518 SDR = 0xd,
10519 /* 0x6 is reserved */
10520 LWU = 0xe,
10521 LLD = 0x7,
10522 SCD = 0xf
10523};
10524
10525/* POOL32F encoding of minor opcode field (bits 5..0) */
10526
10527enum {
10528 /* These are the bit 7..6 values */
10529 ADD_FMT = 0x0,
10530 MOVN_FMT = 0x0,
10531
10532 SUB_FMT = 0x1,
10533 MOVZ_FMT = 0x1,
10534
10535 MUL_FMT = 0x2,
10536
10537 DIV_FMT = 0x3,
10538
10539 /* These are the bit 8..6 values */
10540 RSQRT2_FMT = 0x0,
10541 MOVF_FMT = 0x0,
10542
10543 LWXC1 = 0x1,
10544 MOVT_FMT = 0x1,
10545
10546 PLL_PS = 0x2,
10547 SWXC1 = 0x2,
10548
10549 PLU_PS = 0x3,
10550 LDXC1 = 0x3,
10551
10552 PUL_PS = 0x4,
10553 SDXC1 = 0x4,
10554 RECIP2_FMT = 0x4,
10555
10556 PUU_PS = 0x5,
10557 LUXC1 = 0x5,
10558
10559 CVT_PS_S = 0x6,
10560 SUXC1 = 0x6,
10561 ADDR_PS = 0x6,
10562 PREFX = 0x6,
10563
10564 MULR_PS = 0x7,
10565
10566 MADD_S = 0x01,
10567 MADD_D = 0x09,
10568 MADD_PS = 0x11,
10569 ALNV_PS = 0x19,
10570 MSUB_S = 0x21,
10571 MSUB_D = 0x29,
10572 MSUB_PS = 0x31,
10573
10574 NMADD_S = 0x02,
10575 NMADD_D = 0x0a,
10576 NMADD_PS = 0x12,
10577 NMSUB_S = 0x22,
10578 NMSUB_D = 0x2a,
10579 NMSUB_PS = 0x32,
10580
10581 POOL32FXF = 0x3b,
10582
10583 CABS_COND_FMT = 0x1c, /* MIPS3D */
10584 C_COND_FMT = 0x3c
10585};
10586
10587/* POOL32Fxf encoding of minor opcode extension field */
10588
10589enum {
10590 CVT_L = 0x04,
10591 RSQRT_FMT = 0x08,
10592 FLOOR_L = 0x0c,
10593 CVT_PW_PS = 0x1c,
10594 CVT_W = 0x24,
10595 SQRT_FMT = 0x28,
10596 FLOOR_W = 0x2c,
10597 CVT_PS_PW = 0x3c,
10598 CFC1 = 0x40,
10599 RECIP_FMT = 0x48,
10600 CEIL_L = 0x4c,
10601 CTC1 = 0x60,
10602 CEIL_W = 0x6c,
10603 MFC1 = 0x80,
10604 CVT_S_PL = 0x84,
10605 TRUNC_L = 0x8c,
10606 MTC1 = 0xa0,
10607 CVT_S_PU = 0xa4,
10608 TRUNC_W = 0xac,
10609 MFHC1 = 0xc0,
10610 ROUND_L = 0xcc,
10611 MTHC1 = 0xe0,
10612 ROUND_W = 0xec,
10613
10614 MOV_FMT = 0x01,
10615 MOVF = 0x05,
10616 ABS_FMT = 0x0d,
10617 RSQRT1_FMT = 0x1d,
10618 MOVT = 0x25,
10619 NEG_FMT = 0x2d,
10620 CVT_D = 0x4d,
10621 RECIP1_FMT = 0x5d,
10622 CVT_S = 0x6d
10623};
10624
10625/* POOL32I encoding of minor opcode field (bits 25..21) */
10626
10627enum {
10628 BLTZ = 0x00,
10629 BLTZAL = 0x01,
10630 BGEZ = 0x02,
10631 BGEZAL = 0x03,
10632 BLEZ = 0x04,
10633 BNEZC = 0x05,
10634 BGTZ = 0x06,
10635 BEQZC = 0x07,
10636 TLTI = 0x08,
10637 TGEI = 0x09,
10638 TLTIU = 0x0a,
10639 TGEIU = 0x0b,
10640 TNEI = 0x0c,
10641 LUI = 0x0d,
10642 TEQI = 0x0e,
10643 SYNCI = 0x10,
10644 BLTZALS = 0x11,
10645 BGEZALS = 0x13,
10646 BC2F = 0x14,
10647 BC2T = 0x15,
10648 BPOSGE64 = 0x1a,
10649 BPOSGE32 = 0x1b,
10650 /* These overlap and are distinguished by bit16 of the instruction */
10651 BC1F = 0x1c,
10652 BC1T = 0x1d,
10653 BC1ANY2F = 0x1c,
10654 BC1ANY2T = 0x1d,
10655 BC1ANY4F = 0x1e,
10656 BC1ANY4T = 0x1f
10657};
10658
10659/* POOL16A encoding of minor opcode field */
10660
10661enum {
10662 ADDU16 = 0x0,
10663 SUBU16 = 0x1
10664};
10665
10666/* POOL16B encoding of minor opcode field */
10667
10668enum {
10669 SLL16 = 0x0,
10670 SRL16 = 0x1
10671};
10672
10673/* POOL16C encoding of minor opcode field */
10674
10675enum {
10676 NOT16 = 0x00,
10677 XOR16 = 0x04,
10678 AND16 = 0x08,
10679 OR16 = 0x0c,
10680 LWM16 = 0x10,
10681 SWM16 = 0x14,
10682 JR16 = 0x18,
10683 JRC16 = 0x1a,
10684 JALR16 = 0x1c,
10685 JALR16S = 0x1e,
10686 MFHI16 = 0x20,
10687 MFLO16 = 0x24,
10688 BREAK16 = 0x28,
10689 SDBBP16 = 0x2c,
10690 JRADDIUSP = 0x30
10691};
10692
10693/* POOL16D encoding of minor opcode field */
10694
10695enum {
10696 ADDIUS5 = 0x0,
10697 ADDIUSP = 0x1
10698};
10699
10700/* POOL16E encoding of minor opcode field */
10701
10702enum {
10703 ADDIUR2 = 0x0,
10704 ADDIUR1SP = 0x1
10705};
10706
10707static int mmreg (int r)
10708{
10709 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10710
10711 return map[r];
10712}
10713
10714/* Used for 16-bit store instructions. */
10715static int mmreg2 (int r)
10716{
10717 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10718
10719 return map[r];
10720}
10721
10722#define uMIPS_RD(op) ((op >> 7) & 0x7)
10723#define uMIPS_RS(op) ((op >> 4) & 0x7)
10724#define uMIPS_RS2(op) uMIPS_RS(op)
10725#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10726#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10727#define uMIPS_RS5(op) (op & 0x1f)
10728
10729/* Signed immediate */
10730#define SIMM(op, start, width) \
10731 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10732 << (32-width)) \
10733 >> (32-width))
10734/* Zero-extended immediate */
10735#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10736
7db13fae 10737static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10738{
10739 int rd = mmreg(uMIPS_RD(ctx->opcode));
10740
10741 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10742}
10743
7db13fae 10744static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10745{
10746 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10747 int rd = mmreg(uMIPS_RD(ctx->opcode));
10748 int rs = mmreg(uMIPS_RS(ctx->opcode));
10749
10750 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10751}
10752
7db13fae 10753static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10754{
10755 int encoded = ZIMM(ctx->opcode, 1, 9);
10756 int decoded;
10757
10758 if (encoded <= 1) {
10759 decoded = 256 + encoded;
10760 } else if (encoded <= 255) {
10761 decoded = encoded;
10762 } else if (encoded <= 509) {
10763 decoded = encoded - 512;
10764 } else {
10765 decoded = encoded - 768;
10766 }
10767
10768 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10769}
10770
7db13fae 10771static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10772{
10773 int imm = SIMM(ctx->opcode, 1, 4);
10774 int rd = (ctx->opcode >> 5) & 0x1f;
10775
10776 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10777}
10778
7db13fae 10779static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10780{
10781 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10782 31, 32, 63, 64, 255, 32768, 65535 };
10783 int rd = mmreg(uMIPS_RD(ctx->opcode));
10784 int rs = mmreg(uMIPS_RS(ctx->opcode));
10785 int encoded = ZIMM(ctx->opcode, 0, 4);
10786
9fa77488 10787 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10788}
10789
10790static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10791 int base, int16_t offset)
10792{
e1050a76 10793 const char *opn = "ldst_multiple";
3c824109
NF
10794 TCGv t0, t1;
10795 TCGv_i32 t2;
10796
10797 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10798 generate_exception(ctx, EXCP_RI);
10799 return;
10800 }
10801
10802 t0 = tcg_temp_new();
10803
10804 gen_base_offset_addr(ctx, t0, base, offset);
10805
10806 t1 = tcg_const_tl(reglist);
10807 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10808
3c824109
NF
10809 save_cpu_state(ctx, 1);
10810 switch (opc) {
10811 case LWM32:
895c2d04 10812 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10813 opn = "lwm";
3c824109
NF
10814 break;
10815 case SWM32:
895c2d04 10816 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10817 opn = "swm";
3c824109
NF
10818 break;
10819#ifdef TARGET_MIPS64
10820 case LDM:
895c2d04 10821 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10822 opn = "ldm";
3c824109
NF
10823 break;
10824 case SDM:
895c2d04 10825 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10826 opn = "sdm";
3c824109 10827 break;
6af0bf9c 10828#endif
3c824109 10829 }
e1050a76 10830 (void)opn;
3c824109
NF
10831 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10832 tcg_temp_free(t0);
33087598 10833 tcg_temp_free(t1);
3c824109
NF
10834 tcg_temp_free_i32(t2);
10835}
6af0bf9c 10836
3c824109 10837
7db13fae 10838static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
6af0bf9c 10839{
3c824109
NF
10840 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10841 int rs = mmreg(ctx->opcode & 0x7);
10842 int opc;
6af0bf9c 10843
3c824109
NF
10844 switch (((ctx->opcode) >> 4) & 0x3f) {
10845 case NOT16 + 0:
10846 case NOT16 + 1:
10847 case NOT16 + 2:
10848 case NOT16 + 3:
9fa77488 10849 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10850 break;
10851 case XOR16 + 0:
10852 case XOR16 + 1:
10853 case XOR16 + 2:
10854 case XOR16 + 3:
9fa77488 10855 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10856 break;
10857 case AND16 + 0:
10858 case AND16 + 1:
10859 case AND16 + 2:
10860 case AND16 + 3:
9fa77488 10861 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10862 break;
10863 case OR16 + 0:
10864 case OR16 + 1:
10865 case OR16 + 2:
10866 case OR16 + 3:
9fa77488 10867 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10868 break;
10869 case LWM16 + 0:
10870 case LWM16 + 1:
10871 case LWM16 + 2:
10872 case LWM16 + 3:
10873 {
10874 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10875 int offset = ZIMM(ctx->opcode, 0, 4);
10876
10877 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10878 29, offset << 2);
10879 }
10880 break;
10881 case SWM16 + 0:
10882 case SWM16 + 1:
10883 case SWM16 + 2:
10884 case SWM16 + 3:
10885 {
10886 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10887 int offset = ZIMM(ctx->opcode, 0, 4);
10888
10889 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10890 29, offset << 2);
10891 }
10892 break;
10893 case JR16 + 0:
10894 case JR16 + 1:
10895 {
10896 int reg = ctx->opcode & 0x1f;
10897
10898 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10899 }
10900 *is_branch = 1;
10901 break;
10902 case JRC16 + 0:
10903 case JRC16 + 1:
10904 {
10905 int reg = ctx->opcode & 0x1f;
10906
10907 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10908 /* Let normal delay slot handling in our caller take us
10909 to the branch target. */
10910 }
10911 break;
10912 case JALR16 + 0:
10913 case JALR16 + 1:
10914 opc = OPC_JALR;
10915 goto do_jalr;
10916 case JALR16S + 0:
10917 case JALR16S + 1:
10918 opc = OPC_JALRS;
10919 do_jalr:
10920 {
10921 int reg = ctx->opcode & 0x1f;
10922
10923 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10924 }
10925 *is_branch = 1;
10926 break;
10927 case MFHI16 + 0:
10928 case MFHI16 + 1:
10929 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10930 break;
10931 case MFLO16 + 0:
10932 case MFLO16 + 1:
10933 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10934 break;
10935 case BREAK16:
10936 generate_exception(ctx, EXCP_BREAK);
10937 break;
10938 case SDBBP16:
10939 /* XXX: not clear which exception should be raised
10940 * when in debug mode...
10941 */
10942 check_insn(env, ctx, ISA_MIPS32);
10943 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10944 generate_exception(ctx, EXCP_DBp);
10945 } else {
10946 generate_exception(ctx, EXCP_DBp);
10947 }
10948 break;
10949 case JRADDIUSP + 0:
10950 case JRADDIUSP + 1:
10951 {
10952 int imm = ZIMM(ctx->opcode, 0, 5);
10953
10954 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10955 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10956 /* Let normal delay slot handling in our caller take us
10957 to the branch target. */
10958 }
10959 break;
10960 default:
10961 generate_exception(ctx, EXCP_RI);
10962 break;
10963 }
10964}
10965
10966static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10967{
10968 TCGv t0 = tcg_temp_new();
10969 TCGv t1 = tcg_temp_new();
10970
10971 gen_load_gpr(t0, base);
10972
10973 if (index != 0) {
10974 gen_load_gpr(t1, index);
10975 tcg_gen_shli_tl(t1, t1, 2);
10976 gen_op_addr_add(ctx, t0, t1, t0);
10977 }
10978
2910c6cb 10979 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
10980 gen_store_gpr(t1, rd);
10981
10982 tcg_temp_free(t0);
10983 tcg_temp_free(t1);
10984}
10985
10986static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10987 int base, int16_t offset)
10988{
10989 const char *opn = "ldst_pair";
10990 TCGv t0, t1;
10991
36c6711b 10992 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10993 generate_exception(ctx, EXCP_RI);
d796321b
FB
10994 return;
10995 }
10996
3c824109
NF
10997 t0 = tcg_temp_new();
10998 t1 = tcg_temp_new();
8e9ade68 10999
3c824109
NF
11000 gen_base_offset_addr(ctx, t0, base, offset);
11001
11002 switch (opc) {
11003 case LWP:
36c6711b
EJ
11004 if (rd == base) {
11005 generate_exception(ctx, EXCP_RI);
11006 return;
11007 }
2910c6cb 11008 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11009 gen_store_gpr(t1, rd);
11010 tcg_gen_movi_tl(t1, 4);
11011 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11012 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11013 gen_store_gpr(t1, rd+1);
11014 opn = "lwp";
11015 break;
11016 case SWP:
3c824109 11017 gen_load_gpr(t1, rd);
2910c6cb 11018 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11019 tcg_gen_movi_tl(t1, 4);
11020 gen_op_addr_add(ctx, t0, t0, t1);
11021 gen_load_gpr(t1, rd+1);
2910c6cb 11022 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11023 opn = "swp";
11024 break;
11025#ifdef TARGET_MIPS64
11026 case LDP:
36c6711b
EJ
11027 if (rd == base) {
11028 generate_exception(ctx, EXCP_RI);
11029 return;
11030 }
2910c6cb 11031 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11032 gen_store_gpr(t1, rd);
11033 tcg_gen_movi_tl(t1, 8);
11034 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11035 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11036 gen_store_gpr(t1, rd+1);
11037 opn = "ldp";
11038 break;
11039 case SDP:
3c824109 11040 gen_load_gpr(t1, rd);
2910c6cb 11041 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11042 tcg_gen_movi_tl(t1, 8);
11043 gen_op_addr_add(ctx, t0, t0, t1);
11044 gen_load_gpr(t1, rd+1);
2910c6cb 11045 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11046 opn = "sdp";
11047 break;
11048#endif
6af0bf9c 11049 }
2abf314d 11050 (void)opn; /* avoid a compiler warning */
3c824109
NF
11051 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11052 tcg_temp_free(t0);
11053 tcg_temp_free(t1);
11054}
618b0fe9 11055
7db13fae 11056static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
3c824109
NF
11057 int *is_branch)
11058{
11059 int extension = (ctx->opcode >> 6) & 0x3f;
11060 int minor = (ctx->opcode >> 12) & 0xf;
11061 uint32_t mips32_op;
11062
11063 switch (extension) {
11064 case TEQ:
11065 mips32_op = OPC_TEQ;
11066 goto do_trap;
11067 case TGE:
11068 mips32_op = OPC_TGE;
11069 goto do_trap;
11070 case TGEU:
11071 mips32_op = OPC_TGEU;
11072 goto do_trap;
11073 case TLT:
11074 mips32_op = OPC_TLT;
11075 goto do_trap;
11076 case TLTU:
11077 mips32_op = OPC_TLTU;
11078 goto do_trap;
11079 case TNE:
11080 mips32_op = OPC_TNE;
11081 do_trap:
11082 gen_trap(ctx, mips32_op, rs, rt, -1);
11083 break;
11084#ifndef CONFIG_USER_ONLY
11085 case MFC0:
11086 case MFC0 + 32:
2e15497c 11087 check_cp0_enabled(ctx);
3c824109
NF
11088 if (rt == 0) {
11089 /* Treat as NOP. */
11090 break;
11091 }
11092 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11093 break;
11094 case MTC0:
11095 case MTC0 + 32:
2e15497c 11096 check_cp0_enabled(ctx);
3c824109
NF
11097 {
11098 TCGv t0 = tcg_temp_new();
618b0fe9 11099
3c824109
NF
11100 gen_load_gpr(t0, rt);
11101 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11102 tcg_temp_free(t0);
11103 }
11104 break;
11105#endif
11106 case 0x2c:
11107 switch (minor) {
11108 case SEB:
11109 gen_bshfl(ctx, OPC_SEB, rs, rt);
11110 break;
11111 case SEH:
11112 gen_bshfl(ctx, OPC_SEH, rs, rt);
11113 break;
11114 case CLO:
11115 mips32_op = OPC_CLO;
11116 goto do_cl;
11117 case CLZ:
11118 mips32_op = OPC_CLZ;
11119 do_cl:
11120 check_insn(env, ctx, ISA_MIPS32);
11121 gen_cl(ctx, mips32_op, rt, rs);
11122 break;
11123 case RDHWR:
11124 gen_rdhwr(env, ctx, rt, rs);
11125 break;
11126 case WSBH:
11127 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11128 break;
11129 case MULT:
11130 mips32_op = OPC_MULT;
11131 goto do_muldiv;
11132 case MULTU:
11133 mips32_op = OPC_MULTU;
11134 goto do_muldiv;
11135 case DIV:
11136 mips32_op = OPC_DIV;
11137 goto do_muldiv;
11138 case DIVU:
11139 mips32_op = OPC_DIVU;
11140 goto do_muldiv;
11141 case MADD:
11142 mips32_op = OPC_MADD;
11143 goto do_muldiv;
11144 case MADDU:
11145 mips32_op = OPC_MADDU;
11146 goto do_muldiv;
11147 case MSUB:
11148 mips32_op = OPC_MSUB;
11149 goto do_muldiv;
11150 case MSUBU:
11151 mips32_op = OPC_MSUBU;
11152 do_muldiv:
11153 check_insn(env, ctx, ISA_MIPS32);
11154 gen_muldiv(ctx, mips32_op, rs, rt);
11155 break;
11156 default:
11157 goto pool32axf_invalid;
11158 }
11159 break;
11160 case 0x34:
11161 switch (minor) {
11162 case MFC2:
11163 case MTC2:
11164 case MFHC2:
11165 case MTHC2:
11166 case CFC2:
11167 case CTC2:
11168 generate_exception_err(ctx, EXCP_CpU, 2);
11169 break;
11170 default:
11171 goto pool32axf_invalid;
11172 }
11173 break;
11174 case 0x3c:
11175 switch (minor) {
11176 case JALR:
11177 case JALR_HB:
11178 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11179 *is_branch = 1;
11180 break;
11181 case JALRS:
11182 case JALRS_HB:
11183 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11184 *is_branch = 1;
11185 break;
11186 default:
11187 goto pool32axf_invalid;
11188 }
11189 break;
11190 case 0x05:
11191 switch (minor) {
11192 case RDPGPR:
2e15497c 11193 check_cp0_enabled(ctx);
3c824109
NF
11194 check_insn(env, ctx, ISA_MIPS32R2);
11195 gen_load_srsgpr(rt, rs);
11196 break;
11197 case WRPGPR:
2e15497c 11198 check_cp0_enabled(ctx);
3c824109
NF
11199 check_insn(env, ctx, ISA_MIPS32R2);
11200 gen_store_srsgpr(rt, rs);
11201 break;
11202 default:
11203 goto pool32axf_invalid;
11204 }
11205 break;
11206#ifndef CONFIG_USER_ONLY
11207 case 0x0d:
11208 switch (minor) {
11209 case TLBP:
11210 mips32_op = OPC_TLBP;
11211 goto do_cp0;
11212 case TLBR:
11213 mips32_op = OPC_TLBR;
11214 goto do_cp0;
11215 case TLBWI:
11216 mips32_op = OPC_TLBWI;
11217 goto do_cp0;
11218 case TLBWR:
11219 mips32_op = OPC_TLBWR;
11220 goto do_cp0;
11221 case WAIT:
11222 mips32_op = OPC_WAIT;
11223 goto do_cp0;
11224 case DERET:
11225 mips32_op = OPC_DERET;
11226 goto do_cp0;
11227 case ERET:
11228 mips32_op = OPC_ERET;
11229 do_cp0:
11230 gen_cp0(env, ctx, mips32_op, rt, rs);
11231 break;
11232 default:
11233 goto pool32axf_invalid;
11234 }
11235 break;
11236 case 0x1d:
11237 switch (minor) {
11238 case DI:
2e15497c 11239 check_cp0_enabled(ctx);
3c824109
NF
11240 {
11241 TCGv t0 = tcg_temp_new();
11242
11243 save_cpu_state(ctx, 1);
895c2d04 11244 gen_helper_di(t0, cpu_env);
3c824109
NF
11245 gen_store_gpr(t0, rs);
11246 /* Stop translation as we may have switched the execution mode */
11247 ctx->bstate = BS_STOP;
11248 tcg_temp_free(t0);
11249 }
11250 break;
11251 case EI:
2e15497c 11252 check_cp0_enabled(ctx);
3c824109
NF
11253 {
11254 TCGv t0 = tcg_temp_new();
11255
11256 save_cpu_state(ctx, 1);
895c2d04 11257 gen_helper_ei(t0, cpu_env);
3c824109
NF
11258 gen_store_gpr(t0, rs);
11259 /* Stop translation as we may have switched the execution mode */
11260 ctx->bstate = BS_STOP;
11261 tcg_temp_free(t0);
11262 }
11263 break;
11264 default:
11265 goto pool32axf_invalid;
11266 }
11267 break;
11268#endif
11269 case 0x2d:
11270 switch (minor) {
11271 case SYNC:
11272 /* NOP */
11273 break;
11274 case SYSCALL:
11275 generate_exception(ctx, EXCP_SYSCALL);
11276 ctx->bstate = BS_STOP;
11277 break;
11278 case SDBBP:
11279 check_insn(env, ctx, ISA_MIPS32);
11280 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11281 generate_exception(ctx, EXCP_DBp);
11282 } else {
11283 generate_exception(ctx, EXCP_DBp);
11284 }
11285 break;
11286 default:
11287 goto pool32axf_invalid;
11288 }
11289 break;
11290 case 0x35:
11291 switch (minor) {
11292 case MFHI32:
11293 gen_HILO(ctx, OPC_MFHI, rs);
11294 break;
11295 case MFLO32:
11296 gen_HILO(ctx, OPC_MFLO, rs);
11297 break;
11298 case MTHI32:
11299 gen_HILO(ctx, OPC_MTHI, rs);
11300 break;
11301 case MTLO32:
11302 gen_HILO(ctx, OPC_MTLO, rs);
11303 break;
11304 default:
11305 goto pool32axf_invalid;
11306 }
11307 break;
11308 default:
11309 pool32axf_invalid:
11310 MIPS_INVAL("pool32axf");
11311 generate_exception(ctx, EXCP_RI);
11312 break;
11313 }
11314}
11315
11316/* Values for microMIPS fmt field. Variable-width, depending on which
11317 formats the instruction supports. */
11318
11319enum {
11320 FMT_SD_S = 0,
11321 FMT_SD_D = 1,
11322
11323 FMT_SDPS_S = 0,
11324 FMT_SDPS_D = 1,
11325 FMT_SDPS_PS = 2,
11326
11327 FMT_SWL_S = 0,
11328 FMT_SWL_W = 1,
11329 FMT_SWL_L = 2,
11330
11331 FMT_DWL_D = 0,
11332 FMT_DWL_W = 1,
11333 FMT_DWL_L = 2
11334};
11335
7db13fae 11336static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
11337{
11338 int extension = (ctx->opcode >> 6) & 0x3ff;
11339 uint32_t mips32_op;
11340
11341#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11342#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11343#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11344
11345 switch (extension) {
11346 case FLOAT_1BIT_FMT(CFC1, 0):
11347 mips32_op = OPC_CFC1;
11348 goto do_cp1;
11349 case FLOAT_1BIT_FMT(CTC1, 0):
11350 mips32_op = OPC_CTC1;
11351 goto do_cp1;
11352 case FLOAT_1BIT_FMT(MFC1, 0):
11353 mips32_op = OPC_MFC1;
11354 goto do_cp1;
11355 case FLOAT_1BIT_FMT(MTC1, 0):
11356 mips32_op = OPC_MTC1;
11357 goto do_cp1;
11358 case FLOAT_1BIT_FMT(MFHC1, 0):
11359 mips32_op = OPC_MFHC1;
11360 goto do_cp1;
11361 case FLOAT_1BIT_FMT(MTHC1, 0):
11362 mips32_op = OPC_MTHC1;
11363 do_cp1:
11364 gen_cp1(ctx, mips32_op, rt, rs);
11365 break;
11366
11367 /* Reciprocal square root */
11368 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11369 mips32_op = OPC_RSQRT_S;
11370 goto do_unaryfp;
11371 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11372 mips32_op = OPC_RSQRT_D;
11373 goto do_unaryfp;
11374
11375 /* Square root */
11376 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11377 mips32_op = OPC_SQRT_S;
11378 goto do_unaryfp;
11379 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11380 mips32_op = OPC_SQRT_D;
11381 goto do_unaryfp;
11382
11383 /* Reciprocal */
11384 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11385 mips32_op = OPC_RECIP_S;
11386 goto do_unaryfp;
11387 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11388 mips32_op = OPC_RECIP_D;
11389 goto do_unaryfp;
11390
11391 /* Floor */
11392 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11393 mips32_op = OPC_FLOOR_L_S;
11394 goto do_unaryfp;
11395 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11396 mips32_op = OPC_FLOOR_L_D;
11397 goto do_unaryfp;
11398 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11399 mips32_op = OPC_FLOOR_W_S;
11400 goto do_unaryfp;
11401 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11402 mips32_op = OPC_FLOOR_W_D;
11403 goto do_unaryfp;
11404
11405 /* Ceiling */
11406 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11407 mips32_op = OPC_CEIL_L_S;
11408 goto do_unaryfp;
11409 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11410 mips32_op = OPC_CEIL_L_D;
11411 goto do_unaryfp;
11412 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11413 mips32_op = OPC_CEIL_W_S;
11414 goto do_unaryfp;
11415 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11416 mips32_op = OPC_CEIL_W_D;
11417 goto do_unaryfp;
11418
11419 /* Truncation */
11420 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11421 mips32_op = OPC_TRUNC_L_S;
11422 goto do_unaryfp;
11423 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11424 mips32_op = OPC_TRUNC_L_D;
11425 goto do_unaryfp;
11426 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11427 mips32_op = OPC_TRUNC_W_S;
11428 goto do_unaryfp;
11429 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11430 mips32_op = OPC_TRUNC_W_D;
11431 goto do_unaryfp;
11432
11433 /* Round */
11434 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11435 mips32_op = OPC_ROUND_L_S;
11436 goto do_unaryfp;
11437 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11438 mips32_op = OPC_ROUND_L_D;
11439 goto do_unaryfp;
11440 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11441 mips32_op = OPC_ROUND_W_S;
11442 goto do_unaryfp;
11443 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11444 mips32_op = OPC_ROUND_W_D;
11445 goto do_unaryfp;
11446
11447 /* Integer to floating-point conversion */
11448 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11449 mips32_op = OPC_CVT_L_S;
11450 goto do_unaryfp;
11451 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11452 mips32_op = OPC_CVT_L_D;
11453 goto do_unaryfp;
11454 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11455 mips32_op = OPC_CVT_W_S;
11456 goto do_unaryfp;
11457 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11458 mips32_op = OPC_CVT_W_D;
11459 goto do_unaryfp;
11460
11461 /* Paired-foo conversions */
11462 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11463 mips32_op = OPC_CVT_S_PL;
11464 goto do_unaryfp;
11465 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11466 mips32_op = OPC_CVT_S_PU;
11467 goto do_unaryfp;
11468 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11469 mips32_op = OPC_CVT_PW_PS;
11470 goto do_unaryfp;
11471 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11472 mips32_op = OPC_CVT_PS_PW;
11473 goto do_unaryfp;
11474
11475 /* Floating-point moves */
11476 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11477 mips32_op = OPC_MOV_S;
11478 goto do_unaryfp;
11479 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11480 mips32_op = OPC_MOV_D;
11481 goto do_unaryfp;
11482 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11483 mips32_op = OPC_MOV_PS;
11484 goto do_unaryfp;
11485
11486 /* Absolute value */
11487 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11488 mips32_op = OPC_ABS_S;
11489 goto do_unaryfp;
11490 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11491 mips32_op = OPC_ABS_D;
11492 goto do_unaryfp;
11493 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11494 mips32_op = OPC_ABS_PS;
11495 goto do_unaryfp;
11496
11497 /* Negation */
11498 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11499 mips32_op = OPC_NEG_S;
11500 goto do_unaryfp;
11501 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11502 mips32_op = OPC_NEG_D;
11503 goto do_unaryfp;
11504 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11505 mips32_op = OPC_NEG_PS;
11506 goto do_unaryfp;
11507
11508 /* Reciprocal square root step */
11509 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11510 mips32_op = OPC_RSQRT1_S;
11511 goto do_unaryfp;
11512 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11513 mips32_op = OPC_RSQRT1_D;
11514 goto do_unaryfp;
11515 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11516 mips32_op = OPC_RSQRT1_PS;
11517 goto do_unaryfp;
11518
11519 /* Reciprocal step */
11520 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11521 mips32_op = OPC_RECIP1_S;
11522 goto do_unaryfp;
11523 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11524 mips32_op = OPC_RECIP1_S;
11525 goto do_unaryfp;
11526 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11527 mips32_op = OPC_RECIP1_PS;
11528 goto do_unaryfp;
11529
11530 /* Conversions from double */
11531 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11532 mips32_op = OPC_CVT_D_S;
11533 goto do_unaryfp;
11534 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11535 mips32_op = OPC_CVT_D_W;
11536 goto do_unaryfp;
11537 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11538 mips32_op = OPC_CVT_D_L;
11539 goto do_unaryfp;
11540
11541 /* Conversions from single */
11542 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11543 mips32_op = OPC_CVT_S_D;
11544 goto do_unaryfp;
11545 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11546 mips32_op = OPC_CVT_S_W;
11547 goto do_unaryfp;
11548 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11549 mips32_op = OPC_CVT_S_L;
11550 do_unaryfp:
11551 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11552 break;
11553
11554 /* Conditional moves on floating-point codes */
11555 case COND_FLOAT_MOV(MOVT, 0):
11556 case COND_FLOAT_MOV(MOVT, 1):
11557 case COND_FLOAT_MOV(MOVT, 2):
11558 case COND_FLOAT_MOV(MOVT, 3):
11559 case COND_FLOAT_MOV(MOVT, 4):
11560 case COND_FLOAT_MOV(MOVT, 5):
11561 case COND_FLOAT_MOV(MOVT, 6):
11562 case COND_FLOAT_MOV(MOVT, 7):
11563 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11564 break;
11565 case COND_FLOAT_MOV(MOVF, 0):
11566 case COND_FLOAT_MOV(MOVF, 1):
11567 case COND_FLOAT_MOV(MOVF, 2):
11568 case COND_FLOAT_MOV(MOVF, 3):
11569 case COND_FLOAT_MOV(MOVF, 4):
11570 case COND_FLOAT_MOV(MOVF, 5):
11571 case COND_FLOAT_MOV(MOVF, 6):
11572 case COND_FLOAT_MOV(MOVF, 7):
11573 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11574 break;
11575 default:
11576 MIPS_INVAL("pool32fxf");
11577 generate_exception(ctx, EXCP_RI);
11578 break;
11579 }
11580}
11581
7db13fae 11582static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
3c824109
NF
11583 uint16_t insn_hw1, int *is_branch)
11584{
11585 int32_t offset;
11586 uint16_t insn;
11587 int rt, rs, rd, rr;
11588 int16_t imm;
11589 uint32_t op, minor, mips32_op;
11590 uint32_t cond, fmt, cc;
11591
895c2d04 11592 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11593 ctx->opcode = (ctx->opcode << 16) | insn;
11594
11595 rt = (ctx->opcode >> 21) & 0x1f;
11596 rs = (ctx->opcode >> 16) & 0x1f;
11597 rd = (ctx->opcode >> 11) & 0x1f;
11598 rr = (ctx->opcode >> 6) & 0x1f;
11599 imm = (int16_t) ctx->opcode;
11600
11601 op = (ctx->opcode >> 26) & 0x3f;
11602 switch (op) {
11603 case POOL32A:
11604 minor = ctx->opcode & 0x3f;
11605 switch (minor) {
11606 case 0x00:
11607 minor = (ctx->opcode >> 6) & 0xf;
11608 switch (minor) {
11609 case SLL32:
11610 mips32_op = OPC_SLL;
11611 goto do_shifti;
11612 case SRA:
11613 mips32_op = OPC_SRA;
11614 goto do_shifti;
11615 case SRL32:
11616 mips32_op = OPC_SRL;
11617 goto do_shifti;
11618 case ROTR:
11619 mips32_op = OPC_ROTR;
11620 do_shifti:
11621 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11622 break;
11623 default:
11624 goto pool32a_invalid;
11625 }
11626 break;
11627 case 0x10:
11628 minor = (ctx->opcode >> 6) & 0xf;
11629 switch (minor) {
11630 /* Arithmetic */
11631 case ADD:
11632 mips32_op = OPC_ADD;
11633 goto do_arith;
11634 case ADDU32:
11635 mips32_op = OPC_ADDU;
11636 goto do_arith;
11637 case SUB:
11638 mips32_op = OPC_SUB;
11639 goto do_arith;
11640 case SUBU32:
11641 mips32_op = OPC_SUBU;
11642 goto do_arith;
11643 case MUL:
11644 mips32_op = OPC_MUL;
11645 do_arith:
11646 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11647 break;
11648 /* Shifts */
11649 case SLLV:
11650 mips32_op = OPC_SLLV;
11651 goto do_shift;
11652 case SRLV:
11653 mips32_op = OPC_SRLV;
11654 goto do_shift;
11655 case SRAV:
11656 mips32_op = OPC_SRAV;
11657 goto do_shift;
11658 case ROTRV:
11659 mips32_op = OPC_ROTRV;
11660 do_shift:
11661 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11662 break;
11663 /* Logical operations */
11664 case AND:
11665 mips32_op = OPC_AND;
11666 goto do_logic;
11667 case OR32:
11668 mips32_op = OPC_OR;
11669 goto do_logic;
11670 case NOR:
11671 mips32_op = OPC_NOR;
11672 goto do_logic;
11673 case XOR32:
11674 mips32_op = OPC_XOR;
11675 do_logic:
9fa77488 11676 gen_logic(env, ctx, mips32_op, rd, rs, rt);
3c824109
NF
11677 break;
11678 /* Set less than */
11679 case SLT:
11680 mips32_op = OPC_SLT;
11681 goto do_slt;
11682 case SLTU:
11683 mips32_op = OPC_SLTU;
11684 do_slt:
9fa77488 11685 gen_slt(env, ctx, mips32_op, rd, rs, rt);
3c824109
NF
11686 break;
11687 default:
11688 goto pool32a_invalid;
11689 }
11690 break;
11691 case 0x18:
11692 minor = (ctx->opcode >> 6) & 0xf;
11693 switch (minor) {
11694 /* Conditional moves */
11695 case MOVN:
11696 mips32_op = OPC_MOVN;
11697 goto do_cmov;
11698 case MOVZ:
11699 mips32_op = OPC_MOVZ;
11700 do_cmov:
9fa77488 11701 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
3c824109
NF
11702 break;
11703 case LWXS:
11704 gen_ldxs(ctx, rs, rt, rd);
11705 break;
11706 default:
11707 goto pool32a_invalid;
11708 }
11709 break;
11710 case INS:
11711 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11712 return;
11713 case EXT:
11714 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11715 return;
11716 case POOL32AXF:
11717 gen_pool32axf(env, ctx, rt, rs, is_branch);
11718 break;
11719 case 0x07:
11720 generate_exception(ctx, EXCP_BREAK);
11721 break;
11722 default:
11723 pool32a_invalid:
11724 MIPS_INVAL("pool32a");
11725 generate_exception(ctx, EXCP_RI);
11726 break;
11727 }
11728 break;
11729 case POOL32B:
11730 minor = (ctx->opcode >> 12) & 0xf;
11731 switch (minor) {
11732 case CACHE:
2e15497c 11733 check_cp0_enabled(ctx);
3c824109
NF
11734 /* Treat as no-op. */
11735 break;
11736 case LWC2:
11737 case SWC2:
11738 /* COP2: Not implemented. */
11739 generate_exception_err(ctx, EXCP_CpU, 2);
11740 break;
11741 case LWP:
11742 case SWP:
11743#ifdef TARGET_MIPS64
11744 case LDP:
11745 case SDP:
11746#endif
11747 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11748 break;
11749 case LWM32:
11750 case SWM32:
11751#ifdef TARGET_MIPS64
11752 case LDM:
11753 case SDM:
11754#endif
11755 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11756 break;
11757 default:
11758 MIPS_INVAL("pool32b");
11759 generate_exception(ctx, EXCP_RI);
11760 break;
11761 }
11762 break;
11763 case POOL32F:
11764 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11765 minor = ctx->opcode & 0x3f;
11766 check_cp1_enabled(ctx);
11767 switch (minor) {
11768 case ALNV_PS:
11769 mips32_op = OPC_ALNV_PS;
11770 goto do_madd;
11771 case MADD_S:
11772 mips32_op = OPC_MADD_S;
11773 goto do_madd;
11774 case MADD_D:
11775 mips32_op = OPC_MADD_D;
11776 goto do_madd;
11777 case MADD_PS:
11778 mips32_op = OPC_MADD_PS;
11779 goto do_madd;
11780 case MSUB_S:
11781 mips32_op = OPC_MSUB_S;
11782 goto do_madd;
11783 case MSUB_D:
11784 mips32_op = OPC_MSUB_D;
11785 goto do_madd;
11786 case MSUB_PS:
11787 mips32_op = OPC_MSUB_PS;
11788 goto do_madd;
11789 case NMADD_S:
11790 mips32_op = OPC_NMADD_S;
11791 goto do_madd;
11792 case NMADD_D:
11793 mips32_op = OPC_NMADD_D;
11794 goto do_madd;
11795 case NMADD_PS:
11796 mips32_op = OPC_NMADD_PS;
11797 goto do_madd;
11798 case NMSUB_S:
11799 mips32_op = OPC_NMSUB_S;
11800 goto do_madd;
11801 case NMSUB_D:
11802 mips32_op = OPC_NMSUB_D;
11803 goto do_madd;
11804 case NMSUB_PS:
11805 mips32_op = OPC_NMSUB_PS;
11806 do_madd:
11807 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11808 break;
11809 case CABS_COND_FMT:
11810 cond = (ctx->opcode >> 6) & 0xf;
11811 cc = (ctx->opcode >> 13) & 0x7;
11812 fmt = (ctx->opcode >> 10) & 0x3;
11813 switch (fmt) {
11814 case 0x0:
11815 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11816 break;
11817 case 0x1:
11818 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11819 break;
11820 case 0x2:
11821 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11822 break;
11823 default:
11824 goto pool32f_invalid;
11825 }
11826 break;
11827 case C_COND_FMT:
11828 cond = (ctx->opcode >> 6) & 0xf;
11829 cc = (ctx->opcode >> 13) & 0x7;
11830 fmt = (ctx->opcode >> 10) & 0x3;
11831 switch (fmt) {
11832 case 0x0:
11833 gen_cmp_s(ctx, cond, rt, rs, cc);
11834 break;
11835 case 0x1:
11836 gen_cmp_d(ctx, cond, rt, rs, cc);
11837 break;
11838 case 0x2:
11839 gen_cmp_ps(ctx, cond, rt, rs, cc);
11840 break;
11841 default:
11842 goto pool32f_invalid;
11843 }
11844 break;
11845 case POOL32FXF:
11846 gen_pool32fxf(env, ctx, rt, rs);
11847 break;
11848 case 0x00:
11849 /* PLL foo */
11850 switch ((ctx->opcode >> 6) & 0x7) {
11851 case PLL_PS:
11852 mips32_op = OPC_PLL_PS;
11853 goto do_ps;
11854 case PLU_PS:
11855 mips32_op = OPC_PLU_PS;
11856 goto do_ps;
11857 case PUL_PS:
11858 mips32_op = OPC_PUL_PS;
11859 goto do_ps;
11860 case PUU_PS:
11861 mips32_op = OPC_PUU_PS;
11862 goto do_ps;
11863 case CVT_PS_S:
11864 mips32_op = OPC_CVT_PS_S;
11865 do_ps:
11866 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11867 break;
11868 default:
11869 goto pool32f_invalid;
11870 }
11871 break;
11872 case 0x08:
11873 /* [LS][WDU]XC1 */
11874 switch ((ctx->opcode >> 6) & 0x7) {
11875 case LWXC1:
11876 mips32_op = OPC_LWXC1;
11877 goto do_ldst_cp1;
11878 case SWXC1:
11879 mips32_op = OPC_SWXC1;
11880 goto do_ldst_cp1;
11881 case LDXC1:
11882 mips32_op = OPC_LDXC1;
11883 goto do_ldst_cp1;
11884 case SDXC1:
11885 mips32_op = OPC_SDXC1;
11886 goto do_ldst_cp1;
11887 case LUXC1:
11888 mips32_op = OPC_LUXC1;
11889 goto do_ldst_cp1;
11890 case SUXC1:
11891 mips32_op = OPC_SUXC1;
11892 do_ldst_cp1:
11893 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11894 break;
11895 default:
11896 goto pool32f_invalid;
11897 }
11898 break;
11899 case 0x18:
11900 /* 3D insns */
11901 fmt = (ctx->opcode >> 9) & 0x3;
11902 switch ((ctx->opcode >> 6) & 0x7) {
11903 case RSQRT2_FMT:
11904 switch (fmt) {
11905 case FMT_SDPS_S:
11906 mips32_op = OPC_RSQRT2_S;
11907 goto do_3d;
11908 case FMT_SDPS_D:
11909 mips32_op = OPC_RSQRT2_D;
11910 goto do_3d;
11911 case FMT_SDPS_PS:
11912 mips32_op = OPC_RSQRT2_PS;
11913 goto do_3d;
11914 default:
11915 goto pool32f_invalid;
11916 }
11917 break;
11918 case RECIP2_FMT:
11919 switch (fmt) {
11920 case FMT_SDPS_S:
11921 mips32_op = OPC_RECIP2_S;
11922 goto do_3d;
11923 case FMT_SDPS_D:
11924 mips32_op = OPC_RECIP2_D;
11925 goto do_3d;
11926 case FMT_SDPS_PS:
11927 mips32_op = OPC_RECIP2_PS;
11928 goto do_3d;
11929 default:
11930 goto pool32f_invalid;
11931 }
11932 break;
11933 case ADDR_PS:
11934 mips32_op = OPC_ADDR_PS;
11935 goto do_3d;
11936 case MULR_PS:
11937 mips32_op = OPC_MULR_PS;
11938 do_3d:
11939 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11940 break;
11941 default:
11942 goto pool32f_invalid;
11943 }
11944 break;
11945 case 0x20:
11946 /* MOV[FT].fmt and PREFX */
11947 cc = (ctx->opcode >> 13) & 0x7;
11948 fmt = (ctx->opcode >> 9) & 0x3;
11949 switch ((ctx->opcode >> 6) & 0x7) {
11950 case MOVF_FMT:
11951 switch (fmt) {
11952 case FMT_SDPS_S:
11953 gen_movcf_s(rs, rt, cc, 0);
11954 break;
11955 case FMT_SDPS_D:
11956 gen_movcf_d(ctx, rs, rt, cc, 0);
11957 break;
11958 case FMT_SDPS_PS:
11959 gen_movcf_ps(rs, rt, cc, 0);
11960 break;
11961 default:
11962 goto pool32f_invalid;
11963 }
11964 break;
11965 case MOVT_FMT:
11966 switch (fmt) {
11967 case FMT_SDPS_S:
11968 gen_movcf_s(rs, rt, cc, 1);
11969 break;
11970 case FMT_SDPS_D:
11971 gen_movcf_d(ctx, rs, rt, cc, 1);
11972 break;
11973 case FMT_SDPS_PS:
11974 gen_movcf_ps(rs, rt, cc, 1);
11975 break;
11976 default:
11977 goto pool32f_invalid;
11978 }
11979 break;
11980 case PREFX:
11981 break;
11982 default:
11983 goto pool32f_invalid;
11984 }
11985 break;
11986#define FINSN_3ARG_SDPS(prfx) \
11987 switch ((ctx->opcode >> 8) & 0x3) { \
11988 case FMT_SDPS_S: \
11989 mips32_op = OPC_##prfx##_S; \
11990 goto do_fpop; \
11991 case FMT_SDPS_D: \
11992 mips32_op = OPC_##prfx##_D; \
11993 goto do_fpop; \
11994 case FMT_SDPS_PS: \
11995 mips32_op = OPC_##prfx##_PS; \
11996 goto do_fpop; \
11997 default: \
11998 goto pool32f_invalid; \
11999 }
12000 case 0x30:
12001 /* regular FP ops */
12002 switch ((ctx->opcode >> 6) & 0x3) {
12003 case ADD_FMT:
12004 FINSN_3ARG_SDPS(ADD);
12005 break;
12006 case SUB_FMT:
12007 FINSN_3ARG_SDPS(SUB);
12008 break;
12009 case MUL_FMT:
12010 FINSN_3ARG_SDPS(MUL);
12011 break;
12012 case DIV_FMT:
12013 fmt = (ctx->opcode >> 8) & 0x3;
12014 if (fmt == 1) {
12015 mips32_op = OPC_DIV_D;
12016 } else if (fmt == 0) {
12017 mips32_op = OPC_DIV_S;
12018 } else {
12019 goto pool32f_invalid;
12020 }
12021 goto do_fpop;
12022 default:
12023 goto pool32f_invalid;
12024 }
12025 break;
12026 case 0x38:
12027 /* cmovs */
12028 switch ((ctx->opcode >> 6) & 0x3) {
12029 case MOVN_FMT:
12030 FINSN_3ARG_SDPS(MOVN);
12031 break;
12032 case MOVZ_FMT:
12033 FINSN_3ARG_SDPS(MOVZ);
12034 break;
12035 default:
12036 goto pool32f_invalid;
12037 }
12038 break;
12039 do_fpop:
12040 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12041 break;
12042 default:
12043 pool32f_invalid:
12044 MIPS_INVAL("pool32f");
12045 generate_exception(ctx, EXCP_RI);
12046 break;
12047 }
12048 } else {
12049 generate_exception_err(ctx, EXCP_CpU, 1);
12050 }
12051 break;
12052 case POOL32I:
12053 minor = (ctx->opcode >> 21) & 0x1f;
12054 switch (minor) {
12055 case BLTZ:
12056 mips32_op = OPC_BLTZ;
12057 goto do_branch;
12058 case BLTZAL:
12059 mips32_op = OPC_BLTZAL;
12060 goto do_branch;
12061 case BLTZALS:
12062 mips32_op = OPC_BLTZALS;
12063 goto do_branch;
12064 case BGEZ:
12065 mips32_op = OPC_BGEZ;
12066 goto do_branch;
12067 case BGEZAL:
12068 mips32_op = OPC_BGEZAL;
12069 goto do_branch;
12070 case BGEZALS:
12071 mips32_op = OPC_BGEZALS;
12072 goto do_branch;
12073 case BLEZ:
12074 mips32_op = OPC_BLEZ;
12075 goto do_branch;
12076 case BGTZ:
12077 mips32_op = OPC_BGTZ;
12078 do_branch:
12079 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12080 *is_branch = 1;
12081 break;
12082
12083 /* Traps */
12084 case TLTI:
12085 mips32_op = OPC_TLTI;
12086 goto do_trapi;
12087 case TGEI:
12088 mips32_op = OPC_TGEI;
12089 goto do_trapi;
12090 case TLTIU:
12091 mips32_op = OPC_TLTIU;
12092 goto do_trapi;
12093 case TGEIU:
12094 mips32_op = OPC_TGEIU;
12095 goto do_trapi;
12096 case TNEI:
12097 mips32_op = OPC_TNEI;
12098 goto do_trapi;
12099 case TEQI:
12100 mips32_op = OPC_TEQI;
12101 do_trapi:
12102 gen_trap(ctx, mips32_op, rs, -1, imm);
12103 break;
12104
12105 case BNEZC:
12106 case BEQZC:
12107 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12108 4, rs, 0, imm << 1);
12109 /* Compact branches don't have a delay slot, so just let
12110 the normal delay slot handling take us to the branch
12111 target. */
12112 break;
12113 case LUI:
9fa77488 12114 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12115 break;
12116 case SYNCI:
12117 break;
12118 case BC2F:
12119 case BC2T:
12120 /* COP2: Not implemented. */
12121 generate_exception_err(ctx, EXCP_CpU, 2);
12122 break;
12123 case BC1F:
12124 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12125 goto do_cp1branch;
12126 case BC1T:
12127 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12128 goto do_cp1branch;
12129 case BC1ANY4F:
12130 mips32_op = OPC_BC1FANY4;
12131 goto do_cp1mips3d;
12132 case BC1ANY4T:
12133 mips32_op = OPC_BC1TANY4;
12134 do_cp1mips3d:
12135 check_cop1x(ctx);
12136 check_insn(env, ctx, ASE_MIPS3D);
12137 /* Fall through */
12138 do_cp1branch:
12139 gen_compute_branch1(env, ctx, mips32_op,
12140 (ctx->opcode >> 18) & 0x7, imm << 1);
12141 *is_branch = 1;
12142 break;
12143 case BPOSGE64:
12144 case BPOSGE32:
12145 /* MIPS DSP: not implemented */
12146 /* Fall through */
12147 default:
12148 MIPS_INVAL("pool32i");
12149 generate_exception(ctx, EXCP_RI);
12150 break;
12151 }
12152 break;
12153 case POOL32C:
12154 minor = (ctx->opcode >> 12) & 0xf;
12155 switch (minor) {
12156 case LWL:
12157 mips32_op = OPC_LWL;
5c13fdfd 12158 goto do_ld_lr;
3c824109
NF
12159 case SWL:
12160 mips32_op = OPC_SWL;
5c13fdfd 12161 goto do_st_lr;
3c824109
NF
12162 case LWR:
12163 mips32_op = OPC_LWR;
5c13fdfd 12164 goto do_ld_lr;
3c824109
NF
12165 case SWR:
12166 mips32_op = OPC_SWR;
5c13fdfd 12167 goto do_st_lr;
3c824109
NF
12168#if defined(TARGET_MIPS64)
12169 case LDL:
12170 mips32_op = OPC_LDL;
5c13fdfd 12171 goto do_ld_lr;
3c824109
NF
12172 case SDL:
12173 mips32_op = OPC_SDL;
5c13fdfd 12174 goto do_st_lr;
3c824109
NF
12175 case LDR:
12176 mips32_op = OPC_LDR;
5c13fdfd 12177 goto do_ld_lr;
3c824109
NF
12178 case SDR:
12179 mips32_op = OPC_SDR;
5c13fdfd 12180 goto do_st_lr;
3c824109
NF
12181 case LWU:
12182 mips32_op = OPC_LWU;
5c13fdfd 12183 goto do_ld_lr;
3c824109
NF
12184 case LLD:
12185 mips32_op = OPC_LLD;
5c13fdfd 12186 goto do_ld_lr;
3c824109
NF
12187#endif
12188 case LL:
12189 mips32_op = OPC_LL;
5c13fdfd
AJ
12190 goto do_ld_lr;
12191 do_ld_lr:
afa88c3a 12192 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12193 break;
12194 do_st_lr:
12195 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12196 break;
12197 case SC:
12198 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12199 break;
12200#if defined(TARGET_MIPS64)
12201 case SCD:
12202 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12203 break;
12204#endif
12205 case PREF:
12206 /* Treat as no-op */
12207 break;
12208 default:
12209 MIPS_INVAL("pool32c");
12210 generate_exception(ctx, EXCP_RI);
12211 break;
12212 }
12213 break;
12214 case ADDI32:
12215 mips32_op = OPC_ADDI;
12216 goto do_addi;
12217 case ADDIU32:
12218 mips32_op = OPC_ADDIU;
12219 do_addi:
12220 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12221 break;
12222
12223 /* Logical operations */
12224 case ORI32:
12225 mips32_op = OPC_ORI;
12226 goto do_logici;
12227 case XORI32:
12228 mips32_op = OPC_XORI;
12229 goto do_logici;
12230 case ANDI32:
12231 mips32_op = OPC_ANDI;
12232 do_logici:
9fa77488 12233 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
3c824109
NF
12234 break;
12235
12236 /* Set less than immediate */
12237 case SLTI32:
12238 mips32_op = OPC_SLTI;
12239 goto do_slti;
12240 case SLTIU32:
12241 mips32_op = OPC_SLTIU;
12242 do_slti:
9fa77488 12243 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
3c824109
NF
12244 break;
12245 case JALX32:
12246 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12247 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12248 *is_branch = 1;
12249 break;
12250 case JALS32:
12251 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12252 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12253 *is_branch = 1;
12254 break;
12255 case BEQ32:
12256 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12257 *is_branch = 1;
12258 break;
12259 case BNE32:
12260 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12261 *is_branch = 1;
12262 break;
12263 case J32:
12264 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12265 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12266 *is_branch = 1;
12267 break;
12268 case JAL32:
12269 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12270 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12271 *is_branch = 1;
12272 break;
12273 /* Floating point (COP1) */
12274 case LWC132:
12275 mips32_op = OPC_LWC1;
12276 goto do_cop1;
12277 case LDC132:
12278 mips32_op = OPC_LDC1;
12279 goto do_cop1;
12280 case SWC132:
12281 mips32_op = OPC_SWC1;
12282 goto do_cop1;
12283 case SDC132:
12284 mips32_op = OPC_SDC1;
12285 do_cop1:
12286 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12287 break;
12288 case ADDIUPC:
12289 {
12290 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12291 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12292
12293 gen_addiupc(ctx, reg, offset, 0, 0);
12294 }
12295 break;
12296 /* Loads and stores */
12297 case LB32:
12298 mips32_op = OPC_LB;
5c13fdfd 12299 goto do_ld;
3c824109
NF
12300 case LBU32:
12301 mips32_op = OPC_LBU;
5c13fdfd 12302 goto do_ld;
3c824109
NF
12303 case LH32:
12304 mips32_op = OPC_LH;
5c13fdfd 12305 goto do_ld;
3c824109
NF
12306 case LHU32:
12307 mips32_op = OPC_LHU;
5c13fdfd 12308 goto do_ld;
3c824109
NF
12309 case LW32:
12310 mips32_op = OPC_LW;
5c13fdfd 12311 goto do_ld;
3c824109
NF
12312#ifdef TARGET_MIPS64
12313 case LD32:
12314 mips32_op = OPC_LD;
5c13fdfd 12315 goto do_ld;
3c824109
NF
12316 case SD32:
12317 mips32_op = OPC_SD;
5c13fdfd 12318 goto do_st;
3c824109
NF
12319#endif
12320 case SB32:
12321 mips32_op = OPC_SB;
5c13fdfd 12322 goto do_st;
3c824109
NF
12323 case SH32:
12324 mips32_op = OPC_SH;
5c13fdfd 12325 goto do_st;
3c824109
NF
12326 case SW32:
12327 mips32_op = OPC_SW;
5c13fdfd
AJ
12328 goto do_st;
12329 do_ld:
afa88c3a 12330 gen_ld(env, ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12331 break;
12332 do_st:
12333 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12334 break;
12335 default:
12336 generate_exception(ctx, EXCP_RI);
12337 break;
12338 }
12339}
12340
7db13fae 12341static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
12342{
12343 uint32_t op;
12344
12345 /* make sure instructions are on a halfword boundary */
12346 if (ctx->pc & 0x1) {
12347 env->CP0_BadVAddr = ctx->pc;
12348 generate_exception(ctx, EXCP_AdEL);
12349 ctx->bstate = BS_STOP;
12350 return 2;
12351 }
12352
12353 op = (ctx->opcode >> 10) & 0x3f;
12354 /* Enforce properly-sized instructions in a delay slot */
12355 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12356 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12357
12358 switch (op) {
12359 case POOL32A:
12360 case POOL32B:
12361 case POOL32I:
12362 case POOL32C:
12363 case ADDI32:
12364 case ADDIU32:
12365 case ORI32:
12366 case XORI32:
12367 case SLTI32:
12368 case SLTIU32:
12369 case ANDI32:
12370 case JALX32:
12371 case LBU32:
12372 case LHU32:
12373 case POOL32F:
12374 case JALS32:
12375 case BEQ32:
12376 case BNE32:
12377 case J32:
12378 case JAL32:
12379 case SB32:
12380 case SH32:
12381 case POOL32S:
12382 case ADDIUPC:
12383 case SWC132:
12384 case SDC132:
12385 case SD32:
12386 case SW32:
12387 case LB32:
12388 case LH32:
12389 case DADDIU32:
12390 case POOL48A: /* ??? */
12391 case LWC132:
12392 case LDC132:
12393 case LD32:
12394 case LW32:
12395 if (bits & MIPS_HFLAG_BDS16) {
12396 generate_exception(ctx, EXCP_RI);
12397 /* Just stop translation; the user is confused. */
12398 ctx->bstate = BS_STOP;
12399 return 2;
12400 }
12401 break;
12402 case POOL16A:
12403 case POOL16B:
12404 case POOL16C:
12405 case LWGP16:
12406 case POOL16F:
12407 case LBU16:
12408 case LHU16:
12409 case LWSP16:
12410 case LW16:
12411 case SB16:
12412 case SH16:
12413 case SWSP16:
12414 case SW16:
12415 case MOVE16:
12416 case ANDI16:
12417 case POOL16D:
12418 case POOL16E:
12419 case BEQZ16:
12420 case BNEZ16:
12421 case B16:
12422 case LI16:
12423 if (bits & MIPS_HFLAG_BDS32) {
12424 generate_exception(ctx, EXCP_RI);
12425 /* Just stop translation; the user is confused. */
12426 ctx->bstate = BS_STOP;
12427 return 2;
12428 }
12429 break;
12430 default:
12431 break;
12432 }
12433 }
12434 switch (op) {
12435 case POOL16A:
12436 {
12437 int rd = mmreg(uMIPS_RD(ctx->opcode));
12438 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12439 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12440 uint32_t opc = 0;
12441
12442 switch (ctx->opcode & 0x1) {
12443 case ADDU16:
12444 opc = OPC_ADDU;
12445 break;
12446 case SUBU16:
12447 opc = OPC_SUBU;
12448 break;
12449 }
12450
12451 gen_arith(env, ctx, opc, rd, rs1, rs2);
12452 }
12453 break;
12454 case POOL16B:
12455 {
12456 int rd = mmreg(uMIPS_RD(ctx->opcode));
12457 int rs = mmreg(uMIPS_RS(ctx->opcode));
12458 int amount = (ctx->opcode >> 1) & 0x7;
12459 uint32_t opc = 0;
12460 amount = amount == 0 ? 8 : amount;
12461
12462 switch (ctx->opcode & 0x1) {
12463 case SLL16:
12464 opc = OPC_SLL;
12465 break;
12466 case SRL16:
12467 opc = OPC_SRL;
12468 break;
12469 }
12470
12471 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12472 }
12473 break;
12474 case POOL16C:
12475 gen_pool16c_insn(env, ctx, is_branch);
12476 break;
12477 case LWGP16:
12478 {
12479 int rd = mmreg(uMIPS_RD(ctx->opcode));
12480 int rb = 28; /* GP */
12481 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12482
afa88c3a 12483 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12484 }
12485 break;
12486 case POOL16F:
12487 if (ctx->opcode & 1) {
12488 generate_exception(ctx, EXCP_RI);
12489 } else {
12490 /* MOVEP */
12491 int enc_dest = uMIPS_RD(ctx->opcode);
12492 int enc_rt = uMIPS_RS2(ctx->opcode);
12493 int enc_rs = uMIPS_RS1(ctx->opcode);
12494 int rd, rs, re, rt;
12495 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12496 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12497 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12498
12499 rd = rd_enc[enc_dest];
12500 re = re_enc[enc_dest];
12501 rs = rs_rt_enc[enc_rs];
12502 rt = rs_rt_enc[enc_rt];
12503
12504 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12505 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12506 }
12507 break;
12508 case LBU16:
12509 {
12510 int rd = mmreg(uMIPS_RD(ctx->opcode));
12511 int rb = mmreg(uMIPS_RS(ctx->opcode));
12512 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12513 offset = (offset == 0xf ? -1 : offset);
12514
afa88c3a 12515 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12516 }
12517 break;
12518 case LHU16:
12519 {
12520 int rd = mmreg(uMIPS_RD(ctx->opcode));
12521 int rb = mmreg(uMIPS_RS(ctx->opcode));
12522 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12523
afa88c3a 12524 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12525 }
12526 break;
12527 case LWSP16:
12528 {
12529 int rd = (ctx->opcode >> 5) & 0x1f;
12530 int rb = 29; /* SP */
12531 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12532
afa88c3a 12533 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12534 }
12535 break;
12536 case LW16:
12537 {
12538 int rd = mmreg(uMIPS_RD(ctx->opcode));
12539 int rb = mmreg(uMIPS_RS(ctx->opcode));
12540 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12541
afa88c3a 12542 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12543 }
12544 break;
12545 case SB16:
12546 {
12547 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12548 int rb = mmreg(uMIPS_RS(ctx->opcode));
12549 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12550
5c13fdfd 12551 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12552 }
12553 break;
12554 case SH16:
12555 {
12556 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12557 int rb = mmreg(uMIPS_RS(ctx->opcode));
12558 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12559
5c13fdfd 12560 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12561 }
12562 break;
12563 case SWSP16:
12564 {
12565 int rd = (ctx->opcode >> 5) & 0x1f;
12566 int rb = 29; /* SP */
12567 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12568
5c13fdfd 12569 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12570 }
12571 break;
12572 case SW16:
12573 {
12574 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12575 int rb = mmreg(uMIPS_RS(ctx->opcode));
12576 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12577
5c13fdfd 12578 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12579 }
12580 break;
12581 case MOVE16:
12582 {
12583 int rd = uMIPS_RD5(ctx->opcode);
12584 int rs = uMIPS_RS5(ctx->opcode);
12585
12586 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12587 }
12588 break;
12589 case ANDI16:
12590 gen_andi16(env, ctx);
12591 break;
12592 case POOL16D:
12593 switch (ctx->opcode & 0x1) {
12594 case ADDIUS5:
12595 gen_addius5(env, ctx);
12596 break;
12597 case ADDIUSP:
12598 gen_addiusp(env, ctx);
12599 break;
12600 }
12601 break;
12602 case POOL16E:
12603 switch (ctx->opcode & 0x1) {
12604 case ADDIUR2:
12605 gen_addiur2(env, ctx);
12606 break;
12607 case ADDIUR1SP:
12608 gen_addiur1sp(env, ctx);
12609 break;
12610 }
12611 break;
12612 case B16:
12613 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12614 SIMM(ctx->opcode, 0, 10) << 1);
12615 *is_branch = 1;
12616 break;
12617 case BNEZ16:
12618 case BEQZ16:
12619 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12620 mmreg(uMIPS_RD(ctx->opcode)),
12621 0, SIMM(ctx->opcode, 0, 7) << 1);
12622 *is_branch = 1;
12623 break;
12624 case LI16:
12625 {
12626 int reg = mmreg(uMIPS_RD(ctx->opcode));
12627 int imm = ZIMM(ctx->opcode, 0, 7);
12628
12629 imm = (imm == 0x7f ? -1 : imm);
12630 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12631 }
12632 break;
12633 case RES_20:
12634 case RES_28:
12635 case RES_29:
12636 case RES_30:
12637 case RES_31:
12638 case RES_38:
12639 case RES_39:
12640 generate_exception(ctx, EXCP_RI);
12641 break;
12642 default:
12643 decode_micromips32_opc (env, ctx, op, is_branch);
12644 return 4;
12645 }
12646
12647 return 2;
12648}
12649
12650/* SmartMIPS extension to MIPS32 */
12651
12652#if defined(TARGET_MIPS64)
12653
12654/* MDMX extension to MIPS64 */
12655
12656#endif
12657
9b1a1d68
JL
12658/* MIPSDSP functions. */
12659static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12660 int rd, int base, int offset)
12661{
12662 const char *opn = "ldx";
12663 TCGv t0;
12664
12665 if (rd == 0) {
12666 MIPS_DEBUG("NOP");
12667 return;
12668 }
12669
12670 check_dsp(ctx);
12671 t0 = tcg_temp_new();
12672
12673 if (base == 0) {
12674 gen_load_gpr(t0, offset);
12675 } else if (offset == 0) {
12676 gen_load_gpr(t0, base);
12677 } else {
12678 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12679 }
12680
9b1a1d68
JL
12681 switch (opc) {
12682 case OPC_LBUX:
2910c6cb 12683 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12684 gen_store_gpr(t0, rd);
12685 opn = "lbux";
12686 break;
12687 case OPC_LHX:
2910c6cb 12688 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12689 gen_store_gpr(t0, rd);
12690 opn = "lhx";
12691 break;
12692 case OPC_LWX:
2910c6cb 12693 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12694 gen_store_gpr(t0, rd);
12695 opn = "lwx";
12696 break;
12697#if defined(TARGET_MIPS64)
12698 case OPC_LDX:
2910c6cb 12699 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12700 gen_store_gpr(t0, rd);
12701 opn = "ldx";
12702 break;
12703#endif
12704 }
12705 (void)opn; /* avoid a compiler warning */
12706 MIPS_DEBUG("%s %s, %s(%s)", opn,
12707 regnames[rd], regnames[offset], regnames[base]);
12708 tcg_temp_free(t0);
12709}
12710
461c08df
JL
12711static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12712 int ret, int v1, int v2)
12713{
12714 const char *opn = "mipsdsp arith";
12715 TCGv v1_t;
12716 TCGv v2_t;
12717
12718 if (ret == 0) {
12719 /* Treat as NOP. */
12720 MIPS_DEBUG("NOP");
12721 return;
12722 }
12723
12724 v1_t = tcg_temp_new();
12725 v2_t = tcg_temp_new();
12726
12727 gen_load_gpr(v1_t, v1);
12728 gen_load_gpr(v2_t, v2);
12729
12730 switch (op1) {
12731 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12732 case OPC_MULT_G_2E:
12733 check_dspr2(ctx);
12734 switch (op2) {
12735 case OPC_ADDUH_QB:
12736 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12737 break;
12738 case OPC_ADDUH_R_QB:
12739 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12740 break;
12741 case OPC_ADDQH_PH:
12742 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12743 break;
12744 case OPC_ADDQH_R_PH:
12745 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12746 break;
12747 case OPC_ADDQH_W:
12748 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12749 break;
12750 case OPC_ADDQH_R_W:
12751 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12752 break;
12753 case OPC_SUBUH_QB:
12754 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12755 break;
12756 case OPC_SUBUH_R_QB:
12757 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12758 break;
12759 case OPC_SUBQH_PH:
12760 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12761 break;
12762 case OPC_SUBQH_R_PH:
12763 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12764 break;
12765 case OPC_SUBQH_W:
12766 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12767 break;
12768 case OPC_SUBQH_R_W:
12769 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12770 break;
12771 }
12772 break;
12773 case OPC_ABSQ_S_PH_DSP:
12774 switch (op2) {
12775 case OPC_ABSQ_S_QB:
12776 check_dspr2(ctx);
12777 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12778 break;
12779 case OPC_ABSQ_S_PH:
12780 check_dsp(ctx);
12781 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12782 break;
12783 case OPC_ABSQ_S_W:
12784 check_dsp(ctx);
12785 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12786 break;
12787 case OPC_PRECEQ_W_PHL:
12788 check_dsp(ctx);
12789 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12790 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12791 break;
12792 case OPC_PRECEQ_W_PHR:
12793 check_dsp(ctx);
12794 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12795 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12796 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12797 break;
12798 case OPC_PRECEQU_PH_QBL:
12799 check_dsp(ctx);
12800 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12801 break;
12802 case OPC_PRECEQU_PH_QBR:
12803 check_dsp(ctx);
12804 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12805 break;
12806 case OPC_PRECEQU_PH_QBLA:
12807 check_dsp(ctx);
12808 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12809 break;
12810 case OPC_PRECEQU_PH_QBRA:
12811 check_dsp(ctx);
12812 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12813 break;
12814 case OPC_PRECEU_PH_QBL:
12815 check_dsp(ctx);
12816 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12817 break;
12818 case OPC_PRECEU_PH_QBR:
12819 check_dsp(ctx);
12820 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12821 break;
12822 case OPC_PRECEU_PH_QBLA:
12823 check_dsp(ctx);
12824 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12825 break;
12826 case OPC_PRECEU_PH_QBRA:
12827 check_dsp(ctx);
12828 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12829 break;
12830 }
12831 break;
12832 case OPC_ADDU_QB_DSP:
12833 switch (op2) {
12834 case OPC_ADDQ_PH:
12835 check_dsp(ctx);
12836 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12837 break;
12838 case OPC_ADDQ_S_PH:
12839 check_dsp(ctx);
12840 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841 break;
12842 case OPC_ADDQ_S_W:
12843 check_dsp(ctx);
12844 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12845 break;
12846 case OPC_ADDU_QB:
12847 check_dsp(ctx);
12848 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 break;
12850 case OPC_ADDU_S_QB:
12851 check_dsp(ctx);
12852 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 break;
12854 case OPC_ADDU_PH:
12855 check_dspr2(ctx);
12856 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857 break;
12858 case OPC_ADDU_S_PH:
12859 check_dspr2(ctx);
12860 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 break;
12862 case OPC_SUBQ_PH:
12863 check_dsp(ctx);
12864 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 break;
12866 case OPC_SUBQ_S_PH:
12867 check_dsp(ctx);
12868 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869 break;
12870 case OPC_SUBQ_S_W:
12871 check_dsp(ctx);
12872 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873 break;
12874 case OPC_SUBU_QB:
12875 check_dsp(ctx);
12876 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877 break;
12878 case OPC_SUBU_S_QB:
12879 check_dsp(ctx);
12880 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881 break;
12882 case OPC_SUBU_PH:
12883 check_dspr2(ctx);
12884 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 break;
12886 case OPC_SUBU_S_PH:
12887 check_dspr2(ctx);
12888 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 break;
12890 case OPC_ADDSC:
12891 check_dsp(ctx);
12892 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12893 break;
12894 case OPC_ADDWC:
12895 check_dsp(ctx);
12896 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12897 break;
12898 case OPC_MODSUB:
12899 check_dsp(ctx);
12900 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12901 break;
12902 case OPC_RADDU_W_QB:
12903 check_dsp(ctx);
12904 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12905 break;
12906 }
12907 break;
12908 case OPC_CMPU_EQ_QB_DSP:
12909 switch (op2) {
12910 case OPC_PRECR_QB_PH:
12911 check_dspr2(ctx);
12912 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12913 break;
12914 case OPC_PRECRQ_QB_PH:
12915 check_dsp(ctx);
12916 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12917 break;
12918 case OPC_PRECR_SRA_PH_W:
12919 check_dspr2(ctx);
12920 {
12921 TCGv_i32 sa_t = tcg_const_i32(v2);
12922 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12923 cpu_gpr[ret]);
12924 tcg_temp_free_i32(sa_t);
12925 break;
12926 }
12927 case OPC_PRECR_SRA_R_PH_W:
12928 check_dspr2(ctx);
12929 {
12930 TCGv_i32 sa_t = tcg_const_i32(v2);
12931 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12932 cpu_gpr[ret]);
12933 tcg_temp_free_i32(sa_t);
12934 break;
12935 }
12936 case OPC_PRECRQ_PH_W:
12937 check_dsp(ctx);
12938 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12939 break;
12940 case OPC_PRECRQ_RS_PH_W:
12941 check_dsp(ctx);
12942 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12943 break;
12944 case OPC_PRECRQU_S_QB_PH:
12945 check_dsp(ctx);
12946 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12947 break;
12948 }
12949 break;
12950#ifdef TARGET_MIPS64
12951 case OPC_ABSQ_S_QH_DSP:
12952 switch (op2) {
12953 case OPC_PRECEQ_L_PWL:
12954 check_dsp(ctx);
12955 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12956 break;
12957 case OPC_PRECEQ_L_PWR:
12958 check_dsp(ctx);
12959 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12960 break;
12961 case OPC_PRECEQ_PW_QHL:
12962 check_dsp(ctx);
12963 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12964 break;
12965 case OPC_PRECEQ_PW_QHR:
12966 check_dsp(ctx);
12967 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12968 break;
12969 case OPC_PRECEQ_PW_QHLA:
12970 check_dsp(ctx);
12971 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12972 break;
12973 case OPC_PRECEQ_PW_QHRA:
12974 check_dsp(ctx);
12975 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12976 break;
12977 case OPC_PRECEQU_QH_OBL:
12978 check_dsp(ctx);
12979 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12980 break;
12981 case OPC_PRECEQU_QH_OBR:
12982 check_dsp(ctx);
12983 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12984 break;
12985 case OPC_PRECEQU_QH_OBLA:
12986 check_dsp(ctx);
12987 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12988 break;
12989 case OPC_PRECEQU_QH_OBRA:
12990 check_dsp(ctx);
12991 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12992 break;
12993 case OPC_PRECEU_QH_OBL:
12994 check_dsp(ctx);
12995 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12996 break;
12997 case OPC_PRECEU_QH_OBR:
12998 check_dsp(ctx);
12999 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13000 break;
13001 case OPC_PRECEU_QH_OBLA:
13002 check_dsp(ctx);
13003 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13004 break;
13005 case OPC_PRECEU_QH_OBRA:
13006 check_dsp(ctx);
13007 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13008 break;
13009 case OPC_ABSQ_S_OB:
13010 check_dspr2(ctx);
13011 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13012 break;
13013 case OPC_ABSQ_S_PW:
13014 check_dsp(ctx);
13015 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13016 break;
13017 case OPC_ABSQ_S_QH:
13018 check_dsp(ctx);
13019 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13020 break;
13021 }
13022 break;
13023 case OPC_ADDU_OB_DSP:
13024 switch (op2) {
13025 case OPC_RADDU_L_OB:
13026 check_dsp(ctx);
13027 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13028 break;
13029 case OPC_SUBQ_PW:
13030 check_dsp(ctx);
13031 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13032 break;
13033 case OPC_SUBQ_S_PW:
13034 check_dsp(ctx);
13035 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13036 break;
13037 case OPC_SUBQ_QH:
13038 check_dsp(ctx);
13039 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13040 break;
13041 case OPC_SUBQ_S_QH:
13042 check_dsp(ctx);
13043 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 break;
13045 case OPC_SUBU_OB:
13046 check_dsp(ctx);
13047 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 break;
13049 case OPC_SUBU_S_OB:
13050 check_dsp(ctx);
13051 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 break;
13053 case OPC_SUBU_QH:
13054 check_dspr2(ctx);
13055 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13056 break;
13057 case OPC_SUBU_S_QH:
13058 check_dspr2(ctx);
13059 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13060 break;
13061 case OPC_SUBUH_OB:
13062 check_dspr2(ctx);
13063 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13064 break;
13065 case OPC_SUBUH_R_OB:
13066 check_dspr2(ctx);
13067 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13068 break;
13069 case OPC_ADDQ_PW:
13070 check_dsp(ctx);
13071 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13072 break;
13073 case OPC_ADDQ_S_PW:
13074 check_dsp(ctx);
13075 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13076 break;
13077 case OPC_ADDQ_QH:
13078 check_dsp(ctx);
13079 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13080 break;
13081 case OPC_ADDQ_S_QH:
13082 check_dsp(ctx);
13083 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 break;
13085 case OPC_ADDU_OB:
13086 check_dsp(ctx);
13087 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13088 break;
13089 case OPC_ADDU_S_OB:
13090 check_dsp(ctx);
13091 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 break;
13093 case OPC_ADDU_QH:
13094 check_dspr2(ctx);
13095 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13096 break;
13097 case OPC_ADDU_S_QH:
13098 check_dspr2(ctx);
13099 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13100 break;
13101 case OPC_ADDUH_OB:
13102 check_dspr2(ctx);
13103 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13104 break;
13105 case OPC_ADDUH_R_OB:
13106 check_dspr2(ctx);
13107 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13108 break;
13109 }
13110 break;
13111 case OPC_CMPU_EQ_OB_DSP:
13112 switch (op2) {
13113 case OPC_PRECR_OB_QH:
13114 check_dspr2(ctx);
13115 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13116 break;
13117 case OPC_PRECR_SRA_QH_PW:
13118 check_dspr2(ctx);
13119 {
13120 TCGv_i32 ret_t = tcg_const_i32(ret);
13121 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13122 tcg_temp_free_i32(ret_t);
13123 break;
13124 }
13125 case OPC_PRECR_SRA_R_QH_PW:
13126 check_dspr2(ctx);
13127 {
13128 TCGv_i32 sa_v = tcg_const_i32(ret);
13129 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13130 tcg_temp_free_i32(sa_v);
13131 break;
13132 }
13133 case OPC_PRECRQ_OB_QH:
13134 check_dsp(ctx);
13135 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13136 break;
13137 case OPC_PRECRQ_PW_L:
13138 check_dsp(ctx);
13139 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13140 break;
13141 case OPC_PRECRQ_QH_PW:
13142 check_dsp(ctx);
13143 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13144 break;
13145 case OPC_PRECRQ_RS_QH_PW:
13146 check_dsp(ctx);
13147 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13148 break;
13149 case OPC_PRECRQU_S_OB_QH:
13150 check_dsp(ctx);
13151 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13152 break;
13153 }
13154 break;
13155#endif
13156 }
13157
13158 tcg_temp_free(v1_t);
13159 tcg_temp_free(v2_t);
13160
13161 (void)opn; /* avoid a compiler warning */
13162 MIPS_DEBUG("%s", opn);
13163}
9b1a1d68 13164
77c5fa8b
JL
13165static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13166 int ret, int v1, int v2)
13167{
13168 uint32_t op2;
13169 const char *opn = "mipsdsp shift";
13170 TCGv t0;
13171 TCGv v1_t;
13172 TCGv v2_t;
13173
13174 if (ret == 0) {
13175 /* Treat as NOP. */
13176 MIPS_DEBUG("NOP");
13177 return;
13178 }
13179
13180 t0 = tcg_temp_new();
13181 v1_t = tcg_temp_new();
13182 v2_t = tcg_temp_new();
13183
13184 tcg_gen_movi_tl(t0, v1);
13185 gen_load_gpr(v1_t, v1);
13186 gen_load_gpr(v2_t, v2);
13187
13188 switch (opc) {
13189 case OPC_SHLL_QB_DSP:
13190 {
13191 op2 = MASK_SHLL_QB(ctx->opcode);
13192 switch (op2) {
13193 case OPC_SHLL_QB:
13194 check_dsp(ctx);
13195 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13196 break;
13197 case OPC_SHLLV_QB:
13198 check_dsp(ctx);
13199 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13200 break;
13201 case OPC_SHLL_PH:
13202 check_dsp(ctx);
13203 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13204 break;
13205 case OPC_SHLLV_PH:
13206 check_dsp(ctx);
13207 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13208 break;
13209 case OPC_SHLL_S_PH:
13210 check_dsp(ctx);
13211 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13212 break;
13213 case OPC_SHLLV_S_PH:
13214 check_dsp(ctx);
13215 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13216 break;
13217 case OPC_SHLL_S_W:
13218 check_dsp(ctx);
13219 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13220 break;
13221 case OPC_SHLLV_S_W:
13222 check_dsp(ctx);
13223 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13224 break;
13225 case OPC_SHRL_QB:
13226 check_dsp(ctx);
13227 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13228 break;
13229 case OPC_SHRLV_QB:
13230 check_dsp(ctx);
13231 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13232 break;
13233 case OPC_SHRL_PH:
13234 check_dspr2(ctx);
13235 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13236 break;
13237 case OPC_SHRLV_PH:
13238 check_dspr2(ctx);
13239 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13240 break;
13241 case OPC_SHRA_QB:
13242 check_dspr2(ctx);
13243 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13244 break;
13245 case OPC_SHRA_R_QB:
13246 check_dspr2(ctx);
13247 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13248 break;
13249 case OPC_SHRAV_QB:
13250 check_dspr2(ctx);
13251 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13252 break;
13253 case OPC_SHRAV_R_QB:
13254 check_dspr2(ctx);
13255 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13256 break;
13257 case OPC_SHRA_PH:
13258 check_dsp(ctx);
13259 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13260 break;
13261 case OPC_SHRA_R_PH:
13262 check_dsp(ctx);
13263 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13264 break;
13265 case OPC_SHRAV_PH:
13266 check_dsp(ctx);
13267 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13268 break;
13269 case OPC_SHRAV_R_PH:
13270 check_dsp(ctx);
13271 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13272 break;
13273 case OPC_SHRA_R_W:
13274 check_dsp(ctx);
13275 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13276 break;
13277 case OPC_SHRAV_R_W:
13278 check_dsp(ctx);
13279 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13280 break;
13281 default: /* Invalid */
13282 MIPS_INVAL("MASK SHLL.QB");
13283 generate_exception(ctx, EXCP_RI);
13284 break;
13285 }
13286 break;
13287 }
13288#ifdef TARGET_MIPS64
13289 case OPC_SHLL_OB_DSP:
13290 op2 = MASK_SHLL_OB(ctx->opcode);
13291 switch (op2) {
13292 case OPC_SHLL_PW:
13293 check_dsp(ctx);
13294 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13295 break;
13296 case OPC_SHLLV_PW:
13297 check_dsp(ctx);
13298 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13299 break;
13300 case OPC_SHLL_S_PW:
13301 check_dsp(ctx);
13302 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13303 break;
13304 case OPC_SHLLV_S_PW:
13305 check_dsp(ctx);
13306 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13307 break;
13308 case OPC_SHLL_OB:
13309 check_dsp(ctx);
13310 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13311 break;
13312 case OPC_SHLLV_OB:
13313 check_dsp(ctx);
13314 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13315 break;
13316 case OPC_SHLL_QH:
13317 check_dsp(ctx);
13318 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13319 break;
13320 case OPC_SHLLV_QH:
13321 check_dsp(ctx);
13322 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13323 break;
13324 case OPC_SHLL_S_QH:
13325 check_dsp(ctx);
13326 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13327 break;
13328 case OPC_SHLLV_S_QH:
13329 check_dsp(ctx);
13330 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13331 break;
13332 case OPC_SHRA_OB:
13333 check_dspr2(ctx);
13334 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13335 break;
13336 case OPC_SHRAV_OB:
13337 check_dspr2(ctx);
13338 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13339 break;
13340 case OPC_SHRA_R_OB:
13341 check_dspr2(ctx);
13342 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13343 break;
13344 case OPC_SHRAV_R_OB:
13345 check_dspr2(ctx);
13346 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13347 break;
13348 case OPC_SHRA_PW:
13349 check_dsp(ctx);
13350 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13351 break;
13352 case OPC_SHRAV_PW:
13353 check_dsp(ctx);
13354 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13355 break;
13356 case OPC_SHRA_R_PW:
13357 check_dsp(ctx);
13358 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13359 break;
13360 case OPC_SHRAV_R_PW:
13361 check_dsp(ctx);
13362 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13363 break;
13364 case OPC_SHRA_QH:
13365 check_dsp(ctx);
13366 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13367 break;
13368 case OPC_SHRAV_QH:
13369 check_dsp(ctx);
13370 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13371 break;
13372 case OPC_SHRA_R_QH:
13373 check_dsp(ctx);
13374 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13375 break;
13376 case OPC_SHRAV_R_QH:
13377 check_dsp(ctx);
13378 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13379 break;
13380 case OPC_SHRL_OB:
13381 check_dsp(ctx);
13382 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13383 break;
13384 case OPC_SHRLV_OB:
13385 check_dsp(ctx);
13386 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13387 break;
13388 case OPC_SHRL_QH:
13389 check_dspr2(ctx);
13390 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13391 break;
13392 case OPC_SHRLV_QH:
13393 check_dspr2(ctx);
13394 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13395 break;
13396 default: /* Invalid */
13397 MIPS_INVAL("MASK SHLL.OB");
13398 generate_exception(ctx, EXCP_RI);
13399 break;
13400 }
13401 break;
13402#endif
13403 }
13404
13405 tcg_temp_free(t0);
13406 tcg_temp_free(v1_t);
13407 tcg_temp_free(v2_t);
13408 (void)opn; /* avoid a compiler warning */
13409 MIPS_DEBUG("%s", opn);
13410}
13411
a22260ae
JL
13412static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13413 int ret, int v1, int v2, int check_ret)
13414{
13415 const char *opn = "mipsdsp multiply";
13416 TCGv_i32 t0;
13417 TCGv v1_t;
13418 TCGv v2_t;
13419
13420 if ((ret == 0) && (check_ret == 1)) {
13421 /* Treat as NOP. */
13422 MIPS_DEBUG("NOP");
13423 return;
13424 }
13425
13426 t0 = tcg_temp_new_i32();
13427 v1_t = tcg_temp_new();
13428 v2_t = tcg_temp_new();
13429
13430 tcg_gen_movi_i32(t0, ret);
13431 gen_load_gpr(v1_t, v1);
13432 gen_load_gpr(v2_t, v2);
13433
13434 switch (op1) {
13435 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13436 * the same mask and op1. */
13437 case OPC_MULT_G_2E:
13438 switch (op2) {
13439 case OPC_MUL_PH:
13440 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13441 break;
13442 case OPC_MUL_S_PH:
13443 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13444 break;
13445 case OPC_MULQ_S_W:
13446 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13447 break;
13448 case OPC_MULQ_RS_W:
13449 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13450 break;
13451 }
13452 break;
13453 case OPC_DPA_W_PH_DSP:
13454 switch (op2) {
13455 case OPC_DPAU_H_QBL:
13456 check_dsp(ctx);
13457 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13458 break;
13459 case OPC_DPAU_H_QBR:
13460 check_dsp(ctx);
13461 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13462 break;
13463 case OPC_DPSU_H_QBL:
13464 check_dsp(ctx);
13465 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13466 break;
13467 case OPC_DPSU_H_QBR:
13468 check_dsp(ctx);
13469 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13470 break;
13471 case OPC_DPA_W_PH:
13472 check_dspr2(ctx);
13473 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13474 break;
13475 case OPC_DPAX_W_PH:
13476 check_dspr2(ctx);
13477 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13478 break;
13479 case OPC_DPAQ_S_W_PH:
13480 check_dsp(ctx);
13481 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13482 break;
13483 case OPC_DPAQX_S_W_PH:
13484 check_dspr2(ctx);
13485 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13486 break;
13487 case OPC_DPAQX_SA_W_PH:
13488 check_dspr2(ctx);
13489 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13490 break;
13491 case OPC_DPS_W_PH:
13492 check_dspr2(ctx);
13493 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13494 break;
13495 case OPC_DPSX_W_PH:
13496 check_dspr2(ctx);
13497 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13498 break;
13499 case OPC_DPSQ_S_W_PH:
13500 check_dsp(ctx);
13501 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13502 break;
13503 case OPC_DPSQX_S_W_PH:
13504 check_dspr2(ctx);
13505 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13506 break;
13507 case OPC_DPSQX_SA_W_PH:
13508 check_dspr2(ctx);
13509 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13510 break;
13511 case OPC_MULSAQ_S_W_PH:
13512 check_dsp(ctx);
13513 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13514 break;
13515 case OPC_DPAQ_SA_L_W:
13516 check_dsp(ctx);
13517 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13518 break;
13519 case OPC_DPSQ_SA_L_W:
13520 check_dsp(ctx);
13521 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13522 break;
13523 case OPC_MAQ_S_W_PHL:
13524 check_dsp(ctx);
13525 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13526 break;
13527 case OPC_MAQ_S_W_PHR:
13528 check_dsp(ctx);
13529 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13530 break;
13531 case OPC_MAQ_SA_W_PHL:
13532 check_dsp(ctx);
13533 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13534 break;
13535 case OPC_MAQ_SA_W_PHR:
13536 check_dsp(ctx);
13537 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13538 break;
13539 case OPC_MULSA_W_PH:
13540 check_dspr2(ctx);
13541 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13542 break;
13543 }
13544 break;
13545#ifdef TARGET_MIPS64
13546 case OPC_DPAQ_W_QH_DSP:
13547 {
13548 int ac = ret & 0x03;
13549 tcg_gen_movi_i32(t0, ac);
13550
13551 switch (op2) {
13552 case OPC_DMADD:
13553 check_dsp(ctx);
13554 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13555 break;
13556 case OPC_DMADDU:
13557 check_dsp(ctx);
13558 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13559 break;
13560 case OPC_DMSUB:
13561 check_dsp(ctx);
13562 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13563 break;
13564 case OPC_DMSUBU:
13565 check_dsp(ctx);
13566 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13567 break;
13568 case OPC_DPA_W_QH:
13569 check_dspr2(ctx);
13570 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13571 break;
13572 case OPC_DPAQ_S_W_QH:
13573 check_dsp(ctx);
13574 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13575 break;
13576 case OPC_DPAQ_SA_L_PW:
13577 check_dsp(ctx);
13578 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13579 break;
13580 case OPC_DPAU_H_OBL:
13581 check_dsp(ctx);
13582 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13583 break;
13584 case OPC_DPAU_H_OBR:
13585 check_dsp(ctx);
13586 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13587 break;
13588 case OPC_DPS_W_QH:
13589 check_dspr2(ctx);
13590 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13591 break;
13592 case OPC_DPSQ_S_W_QH:
13593 check_dsp(ctx);
13594 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13595 break;
13596 case OPC_DPSQ_SA_L_PW:
13597 check_dsp(ctx);
13598 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13599 break;
13600 case OPC_DPSU_H_OBL:
13601 check_dsp(ctx);
13602 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13603 break;
13604 case OPC_DPSU_H_OBR:
13605 check_dsp(ctx);
13606 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13607 break;
13608 case OPC_MAQ_S_L_PWL:
13609 check_dsp(ctx);
13610 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13611 break;
13612 case OPC_MAQ_S_L_PWR:
13613 check_dsp(ctx);
13614 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13615 break;
13616 case OPC_MAQ_S_W_QHLL:
13617 check_dsp(ctx);
13618 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13619 break;
13620 case OPC_MAQ_SA_W_QHLL:
13621 check_dsp(ctx);
13622 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13623 break;
13624 case OPC_MAQ_S_W_QHLR:
13625 check_dsp(ctx);
13626 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13627 break;
13628 case OPC_MAQ_SA_W_QHLR:
13629 check_dsp(ctx);
13630 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13631 break;
13632 case OPC_MAQ_S_W_QHRL:
13633 check_dsp(ctx);
13634 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13635 break;
13636 case OPC_MAQ_SA_W_QHRL:
13637 check_dsp(ctx);
13638 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13639 break;
13640 case OPC_MAQ_S_W_QHRR:
13641 check_dsp(ctx);
13642 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13643 break;
13644 case OPC_MAQ_SA_W_QHRR:
13645 check_dsp(ctx);
13646 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13647 break;
13648 case OPC_MULSAQ_S_L_PW:
13649 check_dsp(ctx);
13650 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13651 break;
13652 case OPC_MULSAQ_S_W_QH:
13653 check_dsp(ctx);
13654 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13655 break;
13656 }
13657 }
13658 break;
13659#endif
13660 case OPC_ADDU_QB_DSP:
13661 switch (op2) {
13662 case OPC_MULEU_S_PH_QBL:
13663 check_dsp(ctx);
13664 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13665 break;
13666 case OPC_MULEU_S_PH_QBR:
13667 check_dsp(ctx);
13668 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13669 break;
13670 case OPC_MULQ_RS_PH:
13671 check_dsp(ctx);
13672 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13673 break;
13674 case OPC_MULEQ_S_W_PHL:
13675 check_dsp(ctx);
13676 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13677 break;
13678 case OPC_MULEQ_S_W_PHR:
13679 check_dsp(ctx);
13680 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13681 break;
13682 case OPC_MULQ_S_PH:
13683 check_dspr2(ctx);
13684 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13685 break;
13686 }
13687 break;
13688#ifdef TARGET_MIPS64
13689 case OPC_ADDU_OB_DSP:
13690 switch (op2) {
13691 case OPC_MULEQ_S_PW_QHL:
13692 check_dsp(ctx);
13693 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13694 break;
13695 case OPC_MULEQ_S_PW_QHR:
13696 check_dsp(ctx);
13697 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13698 break;
13699 case OPC_MULEU_S_QH_OBL:
13700 check_dsp(ctx);
13701 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13702 break;
13703 case OPC_MULEU_S_QH_OBR:
13704 check_dsp(ctx);
13705 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13706 break;
13707 case OPC_MULQ_RS_QH:
13708 check_dsp(ctx);
13709 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13710 break;
13711 }
13712 break;
13713#endif
13714 }
13715
13716 tcg_temp_free_i32(t0);
13717 tcg_temp_free(v1_t);
13718 tcg_temp_free(v2_t);
13719
13720 (void)opn; /* avoid a compiler warning */
13721 MIPS_DEBUG("%s", opn);
13722
13723}
13724
1cb6686c
JL
13725static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13726 uint32_t op1, uint32_t op2,
13727 int ret, int val)
13728{
13729 const char *opn = "mipsdsp Bit/ Manipulation";
13730 int16_t imm;
13731 TCGv t0;
13732 TCGv val_t;
13733
13734 if (ret == 0) {
13735 /* Treat as NOP. */
13736 MIPS_DEBUG("NOP");
13737 return;
13738 }
13739
13740 t0 = tcg_temp_new();
13741 val_t = tcg_temp_new();
13742 gen_load_gpr(val_t, val);
13743
13744 switch (op1) {
13745 case OPC_ABSQ_S_PH_DSP:
13746 switch (op2) {
13747 case OPC_BITREV:
13748 check_dsp(ctx);
13749 gen_helper_bitrev(cpu_gpr[ret], val_t);
13750 break;
13751 case OPC_REPL_QB:
13752 check_dsp(ctx);
13753 {
13754 target_long result;
13755 imm = (ctx->opcode >> 16) & 0xFF;
13756 result = (uint32_t)imm << 24 |
13757 (uint32_t)imm << 16 |
13758 (uint32_t)imm << 8 |
13759 (uint32_t)imm;
13760 result = (int32_t)result;
13761 tcg_gen_movi_tl(cpu_gpr[ret], result);
13762 }
13763 break;
13764 case OPC_REPLV_QB:
13765 check_dsp(ctx);
13766 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13767 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13768 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13769 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13770 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13771 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13772 break;
13773 case OPC_REPL_PH:
13774 check_dsp(ctx);
13775 {
13776 imm = (ctx->opcode >> 16) & 0x03FF;
13777 tcg_gen_movi_tl(cpu_gpr[ret], \
13778 (target_long)((int32_t)imm << 16 | \
13779 (uint32_t)(uint16_t)imm));
13780 }
13781 break;
13782 case OPC_REPLV_PH:
13783 check_dsp(ctx);
13784 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13785 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13786 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13787 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13788 break;
13789 }
13790 break;
13791#ifdef TARGET_MIPS64
13792 case OPC_ABSQ_S_QH_DSP:
13793 switch (op2) {
13794 case OPC_REPL_OB:
13795 check_dsp(ctx);
13796 {
13797 target_long temp;
13798
13799 imm = (ctx->opcode >> 16) & 0xFF;
13800 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13801 temp = (temp << 16) | temp;
13802 temp = (temp << 32) | temp;
13803 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13804 break;
13805 }
13806 case OPC_REPL_PW:
13807 check_dsp(ctx);
13808 {
13809 target_long temp;
13810
13811 imm = (ctx->opcode >> 16) & 0x03FF;
13812 imm = (int16_t)(imm << 6) >> 6;
13813 temp = ((target_long)imm << 32) \
13814 | ((target_long)imm & 0xFFFFFFFF);
13815 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13816 break;
13817 }
13818 case OPC_REPL_QH:
13819 check_dsp(ctx);
13820 {
13821 target_long temp;
13822
13823 imm = (ctx->opcode >> 16) & 0x03FF;
13824 imm = (int16_t)(imm << 6) >> 6;
13825
13826 temp = ((uint64_t)(uint16_t)imm << 48) |
13827 ((uint64_t)(uint16_t)imm << 32) |
13828 ((uint64_t)(uint16_t)imm << 16) |
13829 (uint64_t)(uint16_t)imm;
13830 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13831 break;
13832 }
13833 case OPC_REPLV_OB:
13834 check_dsp(ctx);
13835 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13836 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13837 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13838 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13839 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13840 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13841 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13842 break;
13843 case OPC_REPLV_PW:
13844 check_dsp(ctx);
13845 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13846 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13847 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13848 break;
13849 case OPC_REPLV_QH:
13850 check_dsp(ctx);
13851 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13852 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13853 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13854 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13855 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13856 break;
13857 }
13858 break;
13859#endif
13860 }
13861 tcg_temp_free(t0);
13862 tcg_temp_free(val_t);
13863
13864 (void)opn; /* avoid a compiler warning */
13865 MIPS_DEBUG("%s", opn);
13866}
13867
26690560
JL
13868static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13869 uint32_t op1, uint32_t op2,
13870 int ret, int v1, int v2, int check_ret)
13871{
13872 const char *opn = "mipsdsp add compare pick";
13873 TCGv_i32 t0;
13874 TCGv t1;
13875 TCGv v1_t;
13876 TCGv v2_t;
13877
13878 if ((ret == 0) && (check_ret == 1)) {
13879 /* Treat as NOP. */
13880 MIPS_DEBUG("NOP");
13881 return;
13882 }
13883
13884 t0 = tcg_temp_new_i32();
13885 t1 = tcg_temp_new();
13886 v1_t = tcg_temp_new();
13887 v2_t = tcg_temp_new();
13888
13889 gen_load_gpr(v1_t, v1);
13890 gen_load_gpr(v2_t, v2);
13891
13892 switch (op1) {
13893 case OPC_APPEND_DSP:
13894 switch (op2) {
13895 case OPC_APPEND:
13896 tcg_gen_movi_i32(t0, v2);
13897 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13898 break;
13899 case OPC_PREPEND:
13900 tcg_gen_movi_i32(t0, v2);
13901 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13902 break;
13903 case OPC_BALIGN:
13904 tcg_gen_movi_i32(t0, v2);
13905 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13906 break;
13907 default: /* Invid */
13908 MIPS_INVAL("MASK APPEND");
13909 generate_exception(ctx, EXCP_RI);
13910 break;
13911 }
13912 break;
13913 case OPC_CMPU_EQ_QB_DSP:
13914 switch (op2) {
13915 case OPC_CMPU_EQ_QB:
13916 check_dsp(ctx);
13917 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13918 break;
13919 case OPC_CMPU_LT_QB:
13920 check_dsp(ctx);
13921 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13922 break;
13923 case OPC_CMPU_LE_QB:
13924 check_dsp(ctx);
13925 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13926 break;
13927 case OPC_CMPGU_EQ_QB:
13928 check_dsp(ctx);
13929 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13930 break;
13931 case OPC_CMPGU_LT_QB:
13932 check_dsp(ctx);
13933 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13934 break;
13935 case OPC_CMPGU_LE_QB:
13936 check_dsp(ctx);
13937 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13938 break;
13939 case OPC_CMPGDU_EQ_QB:
13940 check_dspr2(ctx);
13941 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13942 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13943 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13944 tcg_gen_shli_tl(t1, t1, 24);
13945 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13946 break;
13947 case OPC_CMPGDU_LT_QB:
13948 check_dspr2(ctx);
13949 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13950 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13951 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13952 tcg_gen_shli_tl(t1, t1, 24);
13953 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13954 break;
13955 case OPC_CMPGDU_LE_QB:
13956 check_dspr2(ctx);
13957 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13958 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13959 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13960 tcg_gen_shli_tl(t1, t1, 24);
13961 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13962 break;
13963 case OPC_CMP_EQ_PH:
13964 check_dsp(ctx);
13965 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13966 break;
13967 case OPC_CMP_LT_PH:
13968 check_dsp(ctx);
13969 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13970 break;
13971 case OPC_CMP_LE_PH:
13972 check_dsp(ctx);
13973 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13974 break;
13975 case OPC_PICK_QB:
13976 check_dsp(ctx);
13977 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13978 break;
13979 case OPC_PICK_PH:
13980 check_dsp(ctx);
13981 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13982 break;
13983 case OPC_PACKRL_PH:
13984 check_dsp(ctx);
13985 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13986 break;
13987 }
13988 break;
13989#ifdef TARGET_MIPS64
13990 case OPC_CMPU_EQ_OB_DSP:
13991 switch (op2) {
13992 case OPC_CMP_EQ_PW:
13993 check_dsp(ctx);
13994 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13995 break;
13996 case OPC_CMP_LT_PW:
13997 check_dsp(ctx);
13998 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13999 break;
14000 case OPC_CMP_LE_PW:
14001 check_dsp(ctx);
14002 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14003 break;
14004 case OPC_CMP_EQ_QH:
14005 check_dsp(ctx);
14006 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14007 break;
14008 case OPC_CMP_LT_QH:
14009 check_dsp(ctx);
14010 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14011 break;
14012 case OPC_CMP_LE_QH:
14013 check_dsp(ctx);
14014 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14015 break;
14016 case OPC_CMPGDU_EQ_OB:
14017 check_dspr2(ctx);
14018 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14019 break;
14020 case OPC_CMPGDU_LT_OB:
14021 check_dspr2(ctx);
14022 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14023 break;
14024 case OPC_CMPGDU_LE_OB:
14025 check_dspr2(ctx);
14026 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14027 break;
14028 case OPC_CMPGU_EQ_OB:
14029 check_dsp(ctx);
14030 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14031 break;
14032 case OPC_CMPGU_LT_OB:
14033 check_dsp(ctx);
14034 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14035 break;
14036 case OPC_CMPGU_LE_OB:
14037 check_dsp(ctx);
14038 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14039 break;
14040 case OPC_CMPU_EQ_OB:
14041 check_dsp(ctx);
14042 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14043 break;
14044 case OPC_CMPU_LT_OB:
14045 check_dsp(ctx);
14046 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14047 break;
14048 case OPC_CMPU_LE_OB:
14049 check_dsp(ctx);
14050 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14051 break;
14052 case OPC_PACKRL_PW:
14053 check_dsp(ctx);
14054 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14055 break;
14056 case OPC_PICK_OB:
14057 check_dsp(ctx);
14058 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14059 break;
14060 case OPC_PICK_PW:
14061 check_dsp(ctx);
14062 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14063 break;
14064 case OPC_PICK_QH:
14065 check_dsp(ctx);
14066 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14067 break;
14068 }
14069 break;
14070 case OPC_DAPPEND_DSP:
14071 switch (op2) {
14072 case OPC_DAPPEND:
14073 tcg_gen_movi_i32(t0, v2);
14074 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14075 break;
14076 case OPC_PREPENDD:
14077 tcg_gen_movi_i32(t0, v2);
14078 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14079 break;
14080 case OPC_PREPENDW:
14081 tcg_gen_movi_i32(t0, v2);
14082 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14083 break;
14084 case OPC_DBALIGN:
14085 tcg_gen_movi_i32(t0, v2);
14086 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14087 break;
14088 default: /* Invalid */
14089 MIPS_INVAL("MASK DAPPEND");
14090 generate_exception(ctx, EXCP_RI);
14091 break;
14092 }
14093 break;
14094#endif
14095 }
14096
14097 tcg_temp_free_i32(t0);
14098 tcg_temp_free(t1);
14099 tcg_temp_free(v1_t);
14100 tcg_temp_free(v2_t);
14101
14102 (void)opn; /* avoid a compiler warning */
14103 MIPS_DEBUG("%s", opn);
14104}
14105
b53371ed
JL
14106static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14107 int ret, int v1, int v2, int check_ret)
14108
14109{
14110 const char *opn = "mipsdsp accumulator";
14111 TCGv t0;
14112 TCGv t1;
14113 TCGv v1_t;
14114 TCGv v2_t;
14115 int16_t imm;
14116
14117 if ((ret == 0) && (check_ret == 1)) {
14118 /* Treat as NOP. */
14119 MIPS_DEBUG("NOP");
14120 return;
14121 }
14122
14123 t0 = tcg_temp_new();
14124 t1 = tcg_temp_new();
14125 v1_t = tcg_temp_new();
14126 v2_t = tcg_temp_new();
14127
14128 gen_load_gpr(v1_t, v1);
14129 gen_load_gpr(v2_t, v2);
14130
14131 switch (op1) {
14132 case OPC_EXTR_W_DSP:
14133 check_dsp(ctx);
14134 switch (op2) {
14135 case OPC_EXTR_W:
14136 tcg_gen_movi_tl(t0, v2);
14137 tcg_gen_movi_tl(t1, v1);
14138 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14139 break;
14140 case OPC_EXTR_R_W:
14141 tcg_gen_movi_tl(t0, v2);
14142 tcg_gen_movi_tl(t1, v1);
14143 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14144 break;
14145 case OPC_EXTR_RS_W:
14146 tcg_gen_movi_tl(t0, v2);
14147 tcg_gen_movi_tl(t1, v1);
14148 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14149 break;
14150 case OPC_EXTR_S_H:
14151 tcg_gen_movi_tl(t0, v2);
14152 tcg_gen_movi_tl(t1, v1);
14153 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14154 break;
14155 case OPC_EXTRV_S_H:
14156 tcg_gen_movi_tl(t0, v2);
14157 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14158 break;
14159 case OPC_EXTRV_W:
14160 tcg_gen_movi_tl(t0, v2);
14161 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14162 break;
14163 case OPC_EXTRV_R_W:
14164 tcg_gen_movi_tl(t0, v2);
14165 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14166 break;
14167 case OPC_EXTRV_RS_W:
14168 tcg_gen_movi_tl(t0, v2);
14169 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14170 break;
14171 case OPC_EXTP:
14172 tcg_gen_movi_tl(t0, v2);
14173 tcg_gen_movi_tl(t1, v1);
14174 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14175 break;
14176 case OPC_EXTPV:
14177 tcg_gen_movi_tl(t0, v2);
14178 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14179 break;
14180 case OPC_EXTPDP:
14181 tcg_gen_movi_tl(t0, v2);
14182 tcg_gen_movi_tl(t1, v1);
14183 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14184 break;
14185 case OPC_EXTPDPV:
14186 tcg_gen_movi_tl(t0, v2);
14187 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14188 break;
14189 case OPC_SHILO:
14190 imm = (ctx->opcode >> 20) & 0x3F;
14191 tcg_gen_movi_tl(t0, ret);
14192 tcg_gen_movi_tl(t1, imm);
14193 gen_helper_shilo(t0, t1, cpu_env);
14194 break;
14195 case OPC_SHILOV:
14196 tcg_gen_movi_tl(t0, ret);
14197 gen_helper_shilo(t0, v1_t, cpu_env);
14198 break;
14199 case OPC_MTHLIP:
14200 tcg_gen_movi_tl(t0, ret);
14201 gen_helper_mthlip(t0, v1_t, cpu_env);
14202 break;
14203 case OPC_WRDSP:
14204 imm = (ctx->opcode >> 11) & 0x3FF;
14205 tcg_gen_movi_tl(t0, imm);
14206 gen_helper_wrdsp(v1_t, t0, cpu_env);
14207 break;
14208 case OPC_RDDSP:
14209 imm = (ctx->opcode >> 16) & 0x03FF;
14210 tcg_gen_movi_tl(t0, imm);
14211 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14212 break;
14213 }
14214 break;
14215#ifdef TARGET_MIPS64
14216 case OPC_DEXTR_W_DSP:
14217 check_dsp(ctx);
14218 switch (op2) {
14219 case OPC_DMTHLIP:
14220 tcg_gen_movi_tl(t0, ret);
14221 gen_helper_dmthlip(v1_t, t0, cpu_env);
14222 break;
14223 case OPC_DSHILO:
14224 {
14225 int shift = (ctx->opcode >> 19) & 0x7F;
14226 int ac = (ctx->opcode >> 11) & 0x03;
14227 tcg_gen_movi_tl(t0, shift);
14228 tcg_gen_movi_tl(t1, ac);
14229 gen_helper_dshilo(t0, t1, cpu_env);
14230 break;
14231 }
14232 case OPC_DSHILOV:
14233 {
14234 int ac = (ctx->opcode >> 11) & 0x03;
14235 tcg_gen_movi_tl(t0, ac);
14236 gen_helper_dshilo(v1_t, t0, cpu_env);
14237 break;
14238 }
14239 case OPC_DEXTP:
14240 tcg_gen_movi_tl(t0, v2);
14241 tcg_gen_movi_tl(t1, v1);
14242
14243 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14244 break;
14245 case OPC_DEXTPV:
14246 tcg_gen_movi_tl(t0, v2);
14247 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14248 break;
14249 case OPC_DEXTPDP:
14250 tcg_gen_movi_tl(t0, v2);
14251 tcg_gen_movi_tl(t1, v1);
14252 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14253 break;
14254 case OPC_DEXTPDPV:
14255 tcg_gen_movi_tl(t0, v2);
14256 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14257 break;
14258 case OPC_DEXTR_L:
14259 tcg_gen_movi_tl(t0, v2);
14260 tcg_gen_movi_tl(t1, v1);
14261 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14262 break;
14263 case OPC_DEXTR_R_L:
14264 tcg_gen_movi_tl(t0, v2);
14265 tcg_gen_movi_tl(t1, v1);
14266 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14267 break;
14268 case OPC_DEXTR_RS_L:
14269 tcg_gen_movi_tl(t0, v2);
14270 tcg_gen_movi_tl(t1, v1);
14271 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14272 break;
14273 case OPC_DEXTR_W:
14274 tcg_gen_movi_tl(t0, v2);
14275 tcg_gen_movi_tl(t1, v1);
14276 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14277 break;
14278 case OPC_DEXTR_R_W:
14279 tcg_gen_movi_tl(t0, v2);
14280 tcg_gen_movi_tl(t1, v1);
14281 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14282 break;
14283 case OPC_DEXTR_RS_W:
14284 tcg_gen_movi_tl(t0, v2);
14285 tcg_gen_movi_tl(t1, v1);
14286 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14287 break;
14288 case OPC_DEXTR_S_H:
14289 tcg_gen_movi_tl(t0, v2);
14290 tcg_gen_movi_tl(t1, v1);
14291 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14292 break;
14293 case OPC_DEXTRV_S_H:
14294 tcg_gen_movi_tl(t0, v2);
14295 tcg_gen_movi_tl(t1, v1);
14296 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14297 break;
14298 case OPC_DEXTRV_L:
14299 tcg_gen_movi_tl(t0, v2);
14300 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14301 break;
14302 case OPC_DEXTRV_R_L:
14303 tcg_gen_movi_tl(t0, v2);
14304 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14305 break;
14306 case OPC_DEXTRV_RS_L:
14307 tcg_gen_movi_tl(t0, v2);
14308 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14309 break;
14310 case OPC_DEXTRV_W:
14311 tcg_gen_movi_tl(t0, v2);
14312 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14313 break;
14314 case OPC_DEXTRV_R_W:
14315 tcg_gen_movi_tl(t0, v2);
14316 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14317 break;
14318 case OPC_DEXTRV_RS_W:
14319 tcg_gen_movi_tl(t0, v2);
14320 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14321 break;
14322 }
14323 break;
14324#endif
14325 }
14326
14327 tcg_temp_free(t0);
14328 tcg_temp_free(t1);
14329 tcg_temp_free(v1_t);
14330 tcg_temp_free(v2_t);
14331
14332 (void)opn; /* avoid a compiler warning */
14333 MIPS_DEBUG("%s", opn);
14334}
14335
9b1a1d68
JL
14336/* End MIPSDSP functions. */
14337
7db13fae 14338static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
14339{
14340 int32_t offset;
14341 int rs, rt, rd, sa;
14342 uint32_t op, op1, op2;
14343 int16_t imm;
14344
14345 /* make sure instructions are on a word boundary */
14346 if (ctx->pc & 0x3) {
14347 env->CP0_BadVAddr = ctx->pc;
14348 generate_exception(ctx, EXCP_AdEL);
14349 return;
14350 }
14351
14352 /* Handle blikely not taken case */
14353 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14354 int l1 = gen_new_label();
14355
14356 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14357 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14358 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14359 gen_goto_tb(ctx, 1, ctx->pc + 4);
14360 gen_set_label(l1);
14361 }
14362
fdefe51c 14363 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14364 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14365 }
3c824109
NF
14366
14367 op = MASK_OP_MAJOR(ctx->opcode);
14368 rs = (ctx->opcode >> 21) & 0x1f;
14369 rt = (ctx->opcode >> 16) & 0x1f;
14370 rd = (ctx->opcode >> 11) & 0x1f;
14371 sa = (ctx->opcode >> 6) & 0x1f;
14372 imm = (int16_t)ctx->opcode;
14373 switch (op) {
7a387fff
TS
14374 case OPC_SPECIAL:
14375 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14376 switch (op1) {
324d9e32
AJ
14377 case OPC_SLL: /* Shift with immediate */
14378 case OPC_SRA:
324d9e32 14379 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7a387fff 14380 break;
ea63e2c3
NF
14381 case OPC_SRL:
14382 switch ((ctx->opcode >> 21) & 0x1f) {
14383 case 1:
14384 /* rotr is decoded as srl on non-R2 CPUs */
14385 if (env->insn_flags & ISA_MIPS32R2) {
14386 op1 = OPC_ROTR;
14387 }
14388 /* Fallthrough */
14389 case 0:
14390 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14391 break;
14392 default:
14393 generate_exception(ctx, EXCP_RI);
14394 break;
14395 }
14396 break;
460f00c4
AJ
14397 case OPC_MOVN: /* Conditional move */
14398 case OPC_MOVZ:
aa8f4009
AJ
14399 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14400 INSN_LOONGSON2E | INSN_LOONGSON2F);
9fa77488 14401 gen_cond_move(env, ctx, op1, rd, rs, rt);
460f00c4
AJ
14402 break;
14403 case OPC_ADD ... OPC_SUBU:
e189e748 14404 gen_arith(env, ctx, op1, rd, rs, rt);
7a387fff 14405 break;
460f00c4 14406 case OPC_SLLV: /* Shifts */
460f00c4
AJ
14407 case OPC_SRAV:
14408 gen_shift(env, ctx, op1, rd, rs, rt);
14409 break;
ea63e2c3
NF
14410 case OPC_SRLV:
14411 switch ((ctx->opcode >> 6) & 0x1f) {
14412 case 1:
14413 /* rotrv is decoded as srlv on non-R2 CPUs */
14414 if (env->insn_flags & ISA_MIPS32R2) {
14415 op1 = OPC_ROTRV;
14416 }
14417 /* Fallthrough */
14418 case 0:
14419 gen_shift(env, ctx, op1, rd, rs, rt);
14420 break;
14421 default:
14422 generate_exception(ctx, EXCP_RI);
14423 break;
14424 }
14425 break;
460f00c4
AJ
14426 case OPC_SLT: /* Set on less than */
14427 case OPC_SLTU:
9fa77488 14428 gen_slt(env, ctx, op1, rd, rs, rt);
460f00c4
AJ
14429 break;
14430 case OPC_AND: /* Logic*/
14431 case OPC_OR:
14432 case OPC_NOR:
14433 case OPC_XOR:
9fa77488 14434 gen_logic(env, ctx, op1, rd, rs, rt);
460f00c4 14435 break;
7a387fff 14436 case OPC_MULT ... OPC_DIVU:
e9c71dd1
TS
14437 if (sa) {
14438 check_insn(env, ctx, INSN_VR54XX);
14439 op1 = MASK_MUL_VR54XX(ctx->opcode);
14440 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14441 } else
14442 gen_muldiv(ctx, op1, rs, rt);
7a387fff
TS
14443 break;
14444 case OPC_JR ... OPC_JALR:
7dca4ad0 14445 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061
NF
14446 *is_branch = 1;
14447 break;
7a387fff
TS
14448 case OPC_TGE ... OPC_TEQ: /* Traps */
14449 case OPC_TNE:
14450 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14451 break;
7a387fff
TS
14452 case OPC_MFHI: /* Move from HI/LO */
14453 case OPC_MFLO:
14454 gen_HILO(ctx, op1, rd);
6af0bf9c 14455 break;
7a387fff
TS
14456 case OPC_MTHI:
14457 case OPC_MTLO: /* Move to HI/LO */
14458 gen_HILO(ctx, op1, rs);
6af0bf9c 14459 break;
b48cfdff
TS
14460 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14461#ifdef MIPS_STRICT_STANDARD
14462 MIPS_INVAL("PMON / selsl");
14463 generate_exception(ctx, EXCP_RI);
14464#else
895c2d04 14465 gen_helper_0e0i(pmon, sa);
b48cfdff 14466#endif
7a387fff
TS
14467 break;
14468 case OPC_SYSCALL:
6af0bf9c 14469 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14470 ctx->bstate = BS_STOP;
6af0bf9c 14471 break;
7a387fff 14472 case OPC_BREAK:
6af0bf9c
FB
14473 generate_exception(ctx, EXCP_BREAK);
14474 break;
b48cfdff
TS
14475 case OPC_SPIM:
14476#ifdef MIPS_STRICT_STANDARD
14477 MIPS_INVAL("SPIM");
14478 generate_exception(ctx, EXCP_RI);
14479#else
7a387fff
TS
14480 /* Implemented as RI exception for now. */
14481 MIPS_INVAL("spim (unofficial)");
14482 generate_exception(ctx, EXCP_RI);
b48cfdff 14483#endif
6af0bf9c 14484 break;
7a387fff 14485 case OPC_SYNC:
ead9360e 14486 /* Treat as NOP. */
6af0bf9c 14487 break;
4ad40f36 14488
7a387fff 14489 case OPC_MOVCI:
e189e748 14490 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14491 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14492 check_cp1_enabled(ctx);
36d23958
TS
14493 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14494 (ctx->opcode >> 16) & 1);
14495 } else {
e397ee33 14496 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14497 }
4ad40f36
FB
14498 break;
14499
d26bc211 14500#if defined(TARGET_MIPS64)
7a387fff
TS
14501 /* MIPS64 specific opcodes */
14502 case OPC_DSLL:
324d9e32 14503 case OPC_DSRA:
7a387fff 14504 case OPC_DSLL32:
324d9e32 14505 case OPC_DSRA32:
e189e748
TS
14506 check_insn(env, ctx, ISA_MIPS3);
14507 check_mips_64(ctx);
324d9e32 14508 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7a387fff 14509 break;
ea63e2c3
NF
14510 case OPC_DSRL:
14511 switch ((ctx->opcode >> 21) & 0x1f) {
14512 case 1:
14513 /* drotr is decoded as dsrl on non-R2 CPUs */
14514 if (env->insn_flags & ISA_MIPS32R2) {
14515 op1 = OPC_DROTR;
14516 }
14517 /* Fallthrough */
14518 case 0:
14519 check_insn(env, ctx, ISA_MIPS3);
14520 check_mips_64(ctx);
14521 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14522 break;
14523 default:
14524 generate_exception(ctx, EXCP_RI);
14525 break;
14526 }
14527 break;
14528 case OPC_DSRL32:
14529 switch ((ctx->opcode >> 21) & 0x1f) {
14530 case 1:
14531 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14532 if (env->insn_flags & ISA_MIPS32R2) {
14533 op1 = OPC_DROTR32;
14534 }
14535 /* Fallthrough */
14536 case 0:
14537 check_insn(env, ctx, ISA_MIPS3);
14538 check_mips_64(ctx);
14539 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14540 break;
14541 default:
14542 generate_exception(ctx, EXCP_RI);
14543 break;
14544 }
14545 break;
7a387fff 14546 case OPC_DADD ... OPC_DSUBU:
e189e748
TS
14547 check_insn(env, ctx, ISA_MIPS3);
14548 check_mips_64(ctx);
14549 gen_arith(env, ctx, op1, rd, rs, rt);
7a387fff 14550 break;
460f00c4
AJ
14551 case OPC_DSLLV:
14552 case OPC_DSRAV:
460f00c4
AJ
14553 check_insn(env, ctx, ISA_MIPS3);
14554 check_mips_64(ctx);
14555 gen_shift(env, ctx, op1, rd, rs, rt);
14556 break;
ea63e2c3
NF
14557 case OPC_DSRLV:
14558 switch ((ctx->opcode >> 6) & 0x1f) {
14559 case 1:
14560 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14561 if (env->insn_flags & ISA_MIPS32R2) {
14562 op1 = OPC_DROTRV;
14563 }
14564 /* Fallthrough */
14565 case 0:
14566 check_insn(env, ctx, ISA_MIPS3);
14567 check_mips_64(ctx);
14568 gen_shift(env, ctx, op1, rd, rs, rt);
14569 break;
14570 default:
14571 generate_exception(ctx, EXCP_RI);
14572 break;
14573 }
14574 break;
7a387fff 14575 case OPC_DMULT ... OPC_DDIVU:
e189e748
TS
14576 check_insn(env, ctx, ISA_MIPS3);
14577 check_mips_64(ctx);
7a387fff
TS
14578 gen_muldiv(ctx, op1, rs, rt);
14579 break;
6af0bf9c
FB
14580#endif
14581 default: /* Invalid */
14582 MIPS_INVAL("special");
14583 generate_exception(ctx, EXCP_RI);
14584 break;
14585 }
14586 break;
7a387fff
TS
14587 case OPC_SPECIAL2:
14588 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14589 switch (op1) {
7a387fff
TS
14590 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14591 case OPC_MSUB ... OPC_MSUBU:
e189e748 14592 check_insn(env, ctx, ISA_MIPS32);
7a387fff 14593 gen_muldiv(ctx, op1, rs, rt);
6af0bf9c 14594 break;
7a387fff 14595 case OPC_MUL:
e189e748 14596 gen_arith(env, ctx, op1, rd, rs, rt);
6af0bf9c 14597 break;
20e1fb52
AJ
14598 case OPC_CLO:
14599 case OPC_CLZ:
e189e748 14600 check_insn(env, ctx, ISA_MIPS32);
7a387fff 14601 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14602 break;
7a387fff 14603 case OPC_SDBBP:
6af0bf9c
FB
14604 /* XXX: not clear which exception should be raised
14605 * when in debug mode...
14606 */
e189e748 14607 check_insn(env, ctx, ISA_MIPS32);
6af0bf9c
FB
14608 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14609 generate_exception(ctx, EXCP_DBp);
14610 } else {
14611 generate_exception(ctx, EXCP_DBp);
14612 }
ead9360e 14613 /* Treat as NOP. */
6af0bf9c 14614 break;
161f85e6
AJ
14615 case OPC_DIV_G_2F:
14616 case OPC_DIVU_G_2F:
14617 case OPC_MULT_G_2F:
14618 case OPC_MULTU_G_2F:
14619 case OPC_MOD_G_2F:
14620 case OPC_MODU_G_2F:
14621 check_insn(env, ctx, INSN_LOONGSON2F);
14622 gen_loongson_integer(ctx, op1, rd, rs, rt);
14623 break;
d26bc211 14624#if defined(TARGET_MIPS64)
20e1fb52
AJ
14625 case OPC_DCLO:
14626 case OPC_DCLZ:
e189e748
TS
14627 check_insn(env, ctx, ISA_MIPS64);
14628 check_mips_64(ctx);
7a387fff
TS
14629 gen_cl(ctx, op1, rd, rs);
14630 break;
161f85e6
AJ
14631 case OPC_DMULT_G_2F:
14632 case OPC_DMULTU_G_2F:
14633 case OPC_DDIV_G_2F:
14634 case OPC_DDIVU_G_2F:
14635 case OPC_DMOD_G_2F:
14636 case OPC_DMODU_G_2F:
14637 check_insn(env, ctx, INSN_LOONGSON2F);
14638 gen_loongson_integer(ctx, op1, rd, rs, rt);
14639 break;
7a387fff 14640#endif
6af0bf9c
FB
14641 default: /* Invalid */
14642 MIPS_INVAL("special2");
14643 generate_exception(ctx, EXCP_RI);
14644 break;
14645 }
14646 break;
7a387fff 14647 case OPC_SPECIAL3:
2b0233ab
TS
14648 op1 = MASK_SPECIAL3(ctx->opcode);
14649 switch (op1) {
14650 case OPC_EXT:
14651 case OPC_INS:
14652 check_insn(env, ctx, ISA_MIPS32R2);
14653 gen_bitops(ctx, op1, rt, rs, sa, rd);
14654 break;
14655 case OPC_BSHFL:
14656 check_insn(env, ctx, ISA_MIPS32R2);
14657 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14658 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14659 break;
1579a72e 14660 case OPC_RDHWR:
26ebe468 14661 gen_rdhwr(env, ctx, rt, rd);
1579a72e 14662 break;
ead9360e 14663 case OPC_FORK:
7385ac0b 14664 check_insn(env, ctx, ASE_MT);
6c5c1e20 14665 {
35fbce2c
AJ
14666 TCGv t0 = tcg_temp_new();
14667 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14668
14669 gen_load_gpr(t0, rt);
14670 gen_load_gpr(t1, rs);
a7812ae4 14671 gen_helper_fork(t0, t1);
6c5c1e20
TS
14672 tcg_temp_free(t0);
14673 tcg_temp_free(t1);
14674 }
ead9360e
TS
14675 break;
14676 case OPC_YIELD:
7385ac0b 14677 check_insn(env, ctx, ASE_MT);
6c5c1e20 14678 {
35fbce2c 14679 TCGv t0 = tcg_temp_new();
6c5c1e20 14680
35fbce2c 14681 save_cpu_state(ctx, 1);
6c5c1e20 14682 gen_load_gpr(t0, rs);
895c2d04 14683 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14684 gen_store_gpr(t0, rd);
14685 tcg_temp_free(t0);
14686 }
ead9360e 14687 break;
161f85e6 14688 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14689 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14690 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14691 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14692 * the same mask and op1. */
14693 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14694 op2 = MASK_ADDUH_QB(ctx->opcode);
14695 switch (op2) {
14696 case OPC_ADDUH_QB:
14697 case OPC_ADDUH_R_QB:
14698 case OPC_ADDQH_PH:
14699 case OPC_ADDQH_R_PH:
14700 case OPC_ADDQH_W:
14701 case OPC_ADDQH_R_W:
14702 case OPC_SUBUH_QB:
14703 case OPC_SUBUH_R_QB:
14704 case OPC_SUBQH_PH:
14705 case OPC_SUBQH_R_PH:
14706 case OPC_SUBQH_W:
14707 case OPC_SUBQH_R_W:
14708 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14709 break;
a22260ae
JL
14710 case OPC_MUL_PH:
14711 case OPC_MUL_S_PH:
14712 case OPC_MULQ_S_W:
14713 case OPC_MULQ_RS_W:
14714 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14715 break;
461c08df
JL
14716 default:
14717 MIPS_INVAL("MASK ADDUH.QB");
14718 generate_exception(ctx, EXCP_RI);
14719 break;
14720 }
14721 } else if (env->insn_flags & INSN_LOONGSON2E) {
14722 gen_loongson_integer(ctx, op1, rd, rs, rt);
14723 } else {
14724 generate_exception(ctx, EXCP_RI);
14725 }
161f85e6 14726 break;
9b1a1d68
JL
14727 case OPC_LX_DSP:
14728 op2 = MASK_LX(ctx->opcode);
14729 switch (op2) {
14730#if defined(TARGET_MIPS64)
14731 case OPC_LDX:
14732#endif
14733 case OPC_LBUX:
14734 case OPC_LHX:
14735 case OPC_LWX:
14736 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14737 break;
14738 default: /* Invalid */
14739 MIPS_INVAL("MASK LX");
14740 generate_exception(ctx, EXCP_RI);
14741 break;
14742 }
14743 break;
461c08df
JL
14744 case OPC_ABSQ_S_PH_DSP:
14745 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14746 switch (op2) {
14747 case OPC_ABSQ_S_QB:
14748 case OPC_ABSQ_S_PH:
14749 case OPC_ABSQ_S_W:
14750 case OPC_PRECEQ_W_PHL:
14751 case OPC_PRECEQ_W_PHR:
14752 case OPC_PRECEQU_PH_QBL:
14753 case OPC_PRECEQU_PH_QBR:
14754 case OPC_PRECEQU_PH_QBLA:
14755 case OPC_PRECEQU_PH_QBRA:
14756 case OPC_PRECEU_PH_QBL:
14757 case OPC_PRECEU_PH_QBR:
14758 case OPC_PRECEU_PH_QBLA:
14759 case OPC_PRECEU_PH_QBRA:
14760 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14761 break;
1cb6686c
JL
14762 case OPC_BITREV:
14763 case OPC_REPL_QB:
14764 case OPC_REPLV_QB:
14765 case OPC_REPL_PH:
14766 case OPC_REPLV_PH:
14767 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14768 break;
461c08df
JL
14769 default:
14770 MIPS_INVAL("MASK ABSQ_S.PH");
14771 generate_exception(ctx, EXCP_RI);
14772 break;
14773 }
14774 break;
14775 case OPC_ADDU_QB_DSP:
14776 op2 = MASK_ADDU_QB(ctx->opcode);
14777 switch (op2) {
14778 case OPC_ADDQ_PH:
14779 case OPC_ADDQ_S_PH:
14780 case OPC_ADDQ_S_W:
14781 case OPC_ADDU_QB:
14782 case OPC_ADDU_S_QB:
14783 case OPC_ADDU_PH:
14784 case OPC_ADDU_S_PH:
14785 case OPC_SUBQ_PH:
14786 case OPC_SUBQ_S_PH:
14787 case OPC_SUBQ_S_W:
14788 case OPC_SUBU_QB:
14789 case OPC_SUBU_S_QB:
14790 case OPC_SUBU_PH:
14791 case OPC_SUBU_S_PH:
14792 case OPC_ADDSC:
14793 case OPC_ADDWC:
14794 case OPC_MODSUB:
14795 case OPC_RADDU_W_QB:
14796 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14797 break;
a22260ae
JL
14798 case OPC_MULEU_S_PH_QBL:
14799 case OPC_MULEU_S_PH_QBR:
14800 case OPC_MULQ_RS_PH:
14801 case OPC_MULEQ_S_W_PHL:
14802 case OPC_MULEQ_S_W_PHR:
14803 case OPC_MULQ_S_PH:
14804 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14805 break;
461c08df
JL
14806 default: /* Invalid */
14807 MIPS_INVAL("MASK ADDU.QB");
14808 generate_exception(ctx, EXCP_RI);
14809 break;
14810
14811 }
14812 break;
14813 case OPC_CMPU_EQ_QB_DSP:
14814 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14815 switch (op2) {
14816 case OPC_PRECR_SRA_PH_W:
14817 case OPC_PRECR_SRA_R_PH_W:
14818 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14819 break;
14820 case OPC_PRECR_QB_PH:
14821 case OPC_PRECRQ_QB_PH:
14822 case OPC_PRECRQ_PH_W:
14823 case OPC_PRECRQ_RS_PH_W:
14824 case OPC_PRECRQU_S_QB_PH:
14825 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14826 break;
26690560
JL
14827 case OPC_CMPU_EQ_QB:
14828 case OPC_CMPU_LT_QB:
14829 case OPC_CMPU_LE_QB:
14830 case OPC_CMP_EQ_PH:
14831 case OPC_CMP_LT_PH:
14832 case OPC_CMP_LE_PH:
14833 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14834 break;
14835 case OPC_CMPGU_EQ_QB:
14836 case OPC_CMPGU_LT_QB:
14837 case OPC_CMPGU_LE_QB:
14838 case OPC_CMPGDU_EQ_QB:
14839 case OPC_CMPGDU_LT_QB:
14840 case OPC_CMPGDU_LE_QB:
14841 case OPC_PICK_QB:
14842 case OPC_PICK_PH:
14843 case OPC_PACKRL_PH:
14844 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14845 break;
461c08df
JL
14846 default: /* Invalid */
14847 MIPS_INVAL("MASK CMPU.EQ.QB");
14848 generate_exception(ctx, EXCP_RI);
14849 break;
14850 }
14851 break;
77c5fa8b
JL
14852 case OPC_SHLL_QB_DSP:
14853 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14854 break;
a22260ae
JL
14855 case OPC_DPA_W_PH_DSP:
14856 op2 = MASK_DPA_W_PH(ctx->opcode);
14857 switch (op2) {
14858 case OPC_DPAU_H_QBL:
14859 case OPC_DPAU_H_QBR:
14860 case OPC_DPSU_H_QBL:
14861 case OPC_DPSU_H_QBR:
14862 case OPC_DPA_W_PH:
14863 case OPC_DPAX_W_PH:
14864 case OPC_DPAQ_S_W_PH:
14865 case OPC_DPAQX_S_W_PH:
14866 case OPC_DPAQX_SA_W_PH:
14867 case OPC_DPS_W_PH:
14868 case OPC_DPSX_W_PH:
14869 case OPC_DPSQ_S_W_PH:
14870 case OPC_DPSQX_S_W_PH:
14871 case OPC_DPSQX_SA_W_PH:
14872 case OPC_MULSAQ_S_W_PH:
14873 case OPC_DPAQ_SA_L_W:
14874 case OPC_DPSQ_SA_L_W:
14875 case OPC_MAQ_S_W_PHL:
14876 case OPC_MAQ_S_W_PHR:
14877 case OPC_MAQ_SA_W_PHL:
14878 case OPC_MAQ_SA_W_PHR:
14879 case OPC_MULSA_W_PH:
14880 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14881 break;
14882 default: /* Invalid */
14883 MIPS_INVAL("MASK DPAW.PH");
14884 generate_exception(ctx, EXCP_RI);
14885 break;
14886 }
14887 break;
1cb6686c
JL
14888 case OPC_INSV_DSP:
14889 op2 = MASK_INSV(ctx->opcode);
14890 switch (op2) {
14891 case OPC_INSV:
14892 check_dsp(ctx);
14893 {
14894 TCGv t0, t1;
14895
14896 if (rt == 0) {
14897 MIPS_DEBUG("NOP");
14898 break;
14899 }
14900
14901 t0 = tcg_temp_new();
14902 t1 = tcg_temp_new();
14903
14904 gen_load_gpr(t0, rt);
14905 gen_load_gpr(t1, rs);
14906
14907 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14908
14909 tcg_temp_free(t0);
14910 tcg_temp_free(t1);
14911 break;
14912 }
14913 default: /* Invalid */
14914 MIPS_INVAL("MASK INSV");
14915 generate_exception(ctx, EXCP_RI);
14916 break;
14917 }
14918 break;
26690560
JL
14919 case OPC_APPEND_DSP:
14920 check_dspr2(ctx);
14921 op2 = MASK_APPEND(ctx->opcode);
14922 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14923 break;
b53371ed
JL
14924 case OPC_EXTR_W_DSP:
14925 op2 = MASK_EXTR_W(ctx->opcode);
14926 switch (op2) {
14927 case OPC_EXTR_W:
14928 case OPC_EXTR_R_W:
14929 case OPC_EXTR_RS_W:
14930 case OPC_EXTR_S_H:
14931 case OPC_EXTRV_S_H:
14932 case OPC_EXTRV_W:
14933 case OPC_EXTRV_R_W:
14934 case OPC_EXTRV_RS_W:
14935 case OPC_EXTP:
14936 case OPC_EXTPV:
14937 case OPC_EXTPDP:
14938 case OPC_EXTPDPV:
14939 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14940 break;
14941 case OPC_RDDSP:
14942 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14943 break;
14944 case OPC_SHILO:
14945 case OPC_SHILOV:
14946 case OPC_MTHLIP:
14947 case OPC_WRDSP:
14948 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14949 break;
14950 default: /* Invalid */
14951 MIPS_INVAL("MASK EXTR.W");
14952 generate_exception(ctx, EXCP_RI);
14953 break;
14954 }
14955 break;
d26bc211 14956#if defined(TARGET_MIPS64)
1579a72e
TS
14957 case OPC_DEXTM ... OPC_DEXT:
14958 case OPC_DINSM ... OPC_DINS:
e189e748
TS
14959 check_insn(env, ctx, ISA_MIPS64R2);
14960 check_mips_64(ctx);
1579a72e 14961 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 14962 break;
1579a72e 14963 case OPC_DBSHFL:
e189e748
TS
14964 check_insn(env, ctx, ISA_MIPS64R2);
14965 check_mips_64(ctx);
1579a72e 14966 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 14967 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 14968 break;
161f85e6
AJ
14969 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14970 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14971 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14972 check_insn(env, ctx, INSN_LOONGSON2E);
14973 gen_loongson_integer(ctx, op1, rd, rs, rt);
14974 break;
461c08df
JL
14975 case OPC_ABSQ_S_QH_DSP:
14976 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14977 switch (op2) {
14978 case OPC_PRECEQ_L_PWL:
14979 case OPC_PRECEQ_L_PWR:
14980 case OPC_PRECEQ_PW_QHL:
14981 case OPC_PRECEQ_PW_QHR:
14982 case OPC_PRECEQ_PW_QHLA:
14983 case OPC_PRECEQ_PW_QHRA:
14984 case OPC_PRECEQU_QH_OBL:
14985 case OPC_PRECEQU_QH_OBR:
14986 case OPC_PRECEQU_QH_OBLA:
14987 case OPC_PRECEQU_QH_OBRA:
14988 case OPC_PRECEU_QH_OBL:
14989 case OPC_PRECEU_QH_OBR:
14990 case OPC_PRECEU_QH_OBLA:
14991 case OPC_PRECEU_QH_OBRA:
14992 case OPC_ABSQ_S_OB:
14993 case OPC_ABSQ_S_PW:
14994 case OPC_ABSQ_S_QH:
14995 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14996 break;
1cb6686c
JL
14997 case OPC_REPL_OB:
14998 case OPC_REPL_PW:
14999 case OPC_REPL_QH:
15000 case OPC_REPLV_OB:
15001 case OPC_REPLV_PW:
15002 case OPC_REPLV_QH:
15003 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
15004 break;
461c08df
JL
15005 default: /* Invalid */
15006 MIPS_INVAL("MASK ABSQ_S.QH");
15007 generate_exception(ctx, EXCP_RI);
15008 break;
15009 }
15010 break;
15011 case OPC_ADDU_OB_DSP:
15012 op2 = MASK_ADDU_OB(ctx->opcode);
15013 switch (op2) {
15014 case OPC_RADDU_L_OB:
15015 case OPC_SUBQ_PW:
15016 case OPC_SUBQ_S_PW:
15017 case OPC_SUBQ_QH:
15018 case OPC_SUBQ_S_QH:
15019 case OPC_SUBU_OB:
15020 case OPC_SUBU_S_OB:
15021 case OPC_SUBU_QH:
15022 case OPC_SUBU_S_QH:
15023 case OPC_SUBUH_OB:
15024 case OPC_SUBUH_R_OB:
15025 case OPC_ADDQ_PW:
15026 case OPC_ADDQ_S_PW:
15027 case OPC_ADDQ_QH:
15028 case OPC_ADDQ_S_QH:
15029 case OPC_ADDU_OB:
15030 case OPC_ADDU_S_OB:
15031 case OPC_ADDU_QH:
15032 case OPC_ADDU_S_QH:
15033 case OPC_ADDUH_OB:
15034 case OPC_ADDUH_R_OB:
15035 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15036 break;
a22260ae
JL
15037 case OPC_MULEQ_S_PW_QHL:
15038 case OPC_MULEQ_S_PW_QHR:
15039 case OPC_MULEU_S_QH_OBL:
15040 case OPC_MULEU_S_QH_OBR:
15041 case OPC_MULQ_RS_QH:
15042 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15043 break;
461c08df
JL
15044 default: /* Invalid */
15045 MIPS_INVAL("MASK ADDU.OB");
15046 generate_exception(ctx, EXCP_RI);
15047 break;
15048 }
15049 break;
15050 case OPC_CMPU_EQ_OB_DSP:
15051 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15052 switch (op2) {
15053 case OPC_PRECR_SRA_QH_PW:
15054 case OPC_PRECR_SRA_R_QH_PW:
15055 /* Return value is rt. */
15056 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15057 break;
15058 case OPC_PRECR_OB_QH:
15059 case OPC_PRECRQ_OB_QH:
15060 case OPC_PRECRQ_PW_L:
15061 case OPC_PRECRQ_QH_PW:
15062 case OPC_PRECRQ_RS_QH_PW:
15063 case OPC_PRECRQU_S_OB_QH:
15064 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15065 break;
26690560
JL
15066 case OPC_CMPU_EQ_OB:
15067 case OPC_CMPU_LT_OB:
15068 case OPC_CMPU_LE_OB:
15069 case OPC_CMP_EQ_QH:
15070 case OPC_CMP_LT_QH:
15071 case OPC_CMP_LE_QH:
15072 case OPC_CMP_EQ_PW:
15073 case OPC_CMP_LT_PW:
15074 case OPC_CMP_LE_PW:
15075 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15076 break;
15077 case OPC_CMPGDU_EQ_OB:
15078 case OPC_CMPGDU_LT_OB:
15079 case OPC_CMPGDU_LE_OB:
15080 case OPC_CMPGU_EQ_OB:
15081 case OPC_CMPGU_LT_OB:
15082 case OPC_CMPGU_LE_OB:
15083 case OPC_PACKRL_PW:
15084 case OPC_PICK_OB:
15085 case OPC_PICK_PW:
15086 case OPC_PICK_QH:
15087 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15088 break;
461c08df
JL
15089 default: /* Invalid */
15090 MIPS_INVAL("MASK CMPU_EQ.OB");
15091 generate_exception(ctx, EXCP_RI);
15092 break;
15093 }
15094 break;
26690560
JL
15095 case OPC_DAPPEND_DSP:
15096 check_dspr2(ctx);
15097 op2 = MASK_DAPPEND(ctx->opcode);
15098 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15099 break;
b53371ed
JL
15100 case OPC_DEXTR_W_DSP:
15101 op2 = MASK_DEXTR_W(ctx->opcode);
15102 switch (op2) {
15103 case OPC_DEXTP:
15104 case OPC_DEXTPDP:
15105 case OPC_DEXTPDPV:
15106 case OPC_DEXTPV:
15107 case OPC_DEXTR_L:
15108 case OPC_DEXTR_R_L:
15109 case OPC_DEXTR_RS_L:
15110 case OPC_DEXTR_W:
15111 case OPC_DEXTR_R_W:
15112 case OPC_DEXTR_RS_W:
15113 case OPC_DEXTR_S_H:
15114 case OPC_DEXTRV_L:
15115 case OPC_DEXTRV_R_L:
15116 case OPC_DEXTRV_RS_L:
15117 case OPC_DEXTRV_S_H:
15118 case OPC_DEXTRV_W:
15119 case OPC_DEXTRV_R_W:
15120 case OPC_DEXTRV_RS_W:
15121 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15122 break;
15123 case OPC_DMTHLIP:
15124 case OPC_DSHILO:
15125 case OPC_DSHILOV:
15126 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15127 break;
15128 default: /* Invalid */
15129 MIPS_INVAL("MASK EXTR.W");
15130 generate_exception(ctx, EXCP_RI);
15131 break;
15132 }
15133 break;
a22260ae
JL
15134 case OPC_DPAQ_W_QH_DSP:
15135 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15136 switch (op2) {
15137 case OPC_DPAU_H_OBL:
15138 case OPC_DPAU_H_OBR:
15139 case OPC_DPSU_H_OBL:
15140 case OPC_DPSU_H_OBR:
15141 case OPC_DPA_W_QH:
15142 case OPC_DPAQ_S_W_QH:
15143 case OPC_DPS_W_QH:
15144 case OPC_DPSQ_S_W_QH:
15145 case OPC_MULSAQ_S_W_QH:
15146 case OPC_DPAQ_SA_L_PW:
15147 case OPC_DPSQ_SA_L_PW:
15148 case OPC_MULSAQ_S_L_PW:
15149 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15150 break;
15151 case OPC_MAQ_S_W_QHLL:
15152 case OPC_MAQ_S_W_QHLR:
15153 case OPC_MAQ_S_W_QHRL:
15154 case OPC_MAQ_S_W_QHRR:
15155 case OPC_MAQ_SA_W_QHLL:
15156 case OPC_MAQ_SA_W_QHLR:
15157 case OPC_MAQ_SA_W_QHRL:
15158 case OPC_MAQ_SA_W_QHRR:
15159 case OPC_MAQ_S_L_PWL:
15160 case OPC_MAQ_S_L_PWR:
15161 case OPC_DMADD:
15162 case OPC_DMADDU:
15163 case OPC_DMSUB:
15164 case OPC_DMSUBU:
15165 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15166 break;
15167 default: /* Invalid */
15168 MIPS_INVAL("MASK DPAQ.W.QH");
15169 generate_exception(ctx, EXCP_RI);
15170 break;
15171 }
15172 break;
1cb6686c
JL
15173 case OPC_DINSV_DSP:
15174 op2 = MASK_INSV(ctx->opcode);
15175 switch (op2) {
15176 case OPC_DINSV:
15177 {
15178 TCGv t0, t1;
15179
15180 if (rt == 0) {
15181 MIPS_DEBUG("NOP");
15182 break;
15183 }
15184 check_dsp(ctx);
15185
15186 t0 = tcg_temp_new();
15187 t1 = tcg_temp_new();
15188
15189 gen_load_gpr(t0, rt);
15190 gen_load_gpr(t1, rs);
15191
15192 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15193 break;
15194 }
15195 default: /* Invalid */
15196 MIPS_INVAL("MASK DINSV");
15197 generate_exception(ctx, EXCP_RI);
15198 break;
15199 }
15200 break;
77c5fa8b
JL
15201 case OPC_SHLL_OB_DSP:
15202 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15203 break;
7a387fff
TS
15204#endif
15205 default: /* Invalid */
15206 MIPS_INVAL("special3");
15207 generate_exception(ctx, EXCP_RI);
15208 break;
15209 }
15210 break;
15211 case OPC_REGIMM:
15212 op1 = MASK_REGIMM(ctx->opcode);
15213 switch (op1) {
15214 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15215 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15216 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061
NF
15217 *is_branch = 1;
15218 break;
7a387fff
TS
15219 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15220 case OPC_TNEI:
15221 gen_trap(ctx, op1, rs, -1, imm);
15222 break;
15223 case OPC_SYNCI:
e189e748 15224 check_insn(env, ctx, ISA_MIPS32R2);
ead9360e 15225 /* Treat as NOP. */
6af0bf9c 15226 break;
e45a93e2
JL
15227 case OPC_BPOSGE32: /* MIPS DSP branch */
15228#if defined(TARGET_MIPS64)
15229 case OPC_BPOSGE64:
15230#endif
15231 check_dsp(ctx);
15232 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15233 *is_branch = 1;
15234 break;
6af0bf9c 15235 default: /* Invalid */
923617a3 15236 MIPS_INVAL("regimm");
6af0bf9c
FB
15237 generate_exception(ctx, EXCP_RI);
15238 break;
15239 }
15240 break;
7a387fff 15241 case OPC_CP0:
387a8fe5 15242 check_cp0_enabled(ctx);
7a387fff 15243 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15244 switch (op1) {
7a387fff
TS
15245 case OPC_MFC0:
15246 case OPC_MTC0:
ead9360e
TS
15247 case OPC_MFTR:
15248 case OPC_MTTR:
d26bc211 15249#if defined(TARGET_MIPS64)
7a387fff
TS
15250 case OPC_DMFC0:
15251 case OPC_DMTC0:
15252#endif
f1aa6320 15253#ifndef CONFIG_USER_ONLY
932e71cd 15254 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15255#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15256 break;
15257 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15258#ifndef CONFIG_USER_ONLY
932e71cd 15259 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15260#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15261 break;
15262 case OPC_MFMC0:
8706c382 15263#ifndef CONFIG_USER_ONLY
932e71cd 15264 {
35fbce2c 15265 TCGv t0 = tcg_temp_new();
6c5c1e20 15266
0eaef5aa 15267 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15268 switch (op2) {
15269 case OPC_DMT:
15270 check_insn(env, ctx, ASE_MT);
9ed5726c 15271 gen_helper_dmt(t0);
35fbce2c 15272 gen_store_gpr(t0, rt);
6c5c1e20
TS
15273 break;
15274 case OPC_EMT:
15275 check_insn(env, ctx, ASE_MT);
9ed5726c 15276 gen_helper_emt(t0);
35fbce2c 15277 gen_store_gpr(t0, rt);
da80682b 15278 break;
6c5c1e20
TS
15279 case OPC_DVPE:
15280 check_insn(env, ctx, ASE_MT);
895c2d04 15281 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15282 gen_store_gpr(t0, rt);
6c5c1e20
TS
15283 break;
15284 case OPC_EVPE:
15285 check_insn(env, ctx, ASE_MT);
895c2d04 15286 gen_helper_evpe(t0, cpu_env);
35fbce2c 15287 gen_store_gpr(t0, rt);
6c5c1e20
TS
15288 break;
15289 case OPC_DI:
15290 check_insn(env, ctx, ISA_MIPS32R2);
867abc7e 15291 save_cpu_state(ctx, 1);
895c2d04 15292 gen_helper_di(t0, cpu_env);
35fbce2c 15293 gen_store_gpr(t0, rt);
6c5c1e20
TS
15294 /* Stop translation as we may have switched the execution mode */
15295 ctx->bstate = BS_STOP;
15296 break;
15297 case OPC_EI:
15298 check_insn(env, ctx, ISA_MIPS32R2);
867abc7e 15299 save_cpu_state(ctx, 1);
895c2d04 15300 gen_helper_ei(t0, cpu_env);
35fbce2c 15301 gen_store_gpr(t0, rt);
6c5c1e20
TS
15302 /* Stop translation as we may have switched the execution mode */
15303 ctx->bstate = BS_STOP;
15304 break;
15305 default: /* Invalid */
15306 MIPS_INVAL("mfmc0");
15307 generate_exception(ctx, EXCP_RI);
15308 break;
15309 }
6c5c1e20 15310 tcg_temp_free(t0);
7a387fff 15311 }
0eaef5aa 15312#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15313 break;
7a387fff 15314 case OPC_RDPGPR:
e189e748 15315 check_insn(env, ctx, ISA_MIPS32R2);
be24bb4f 15316 gen_load_srsgpr(rt, rd);
ead9360e 15317 break;
7a387fff 15318 case OPC_WRPGPR:
e189e748 15319 check_insn(env, ctx, ISA_MIPS32R2);
be24bb4f 15320 gen_store_srsgpr(rt, rd);
38121543 15321 break;
6af0bf9c 15322 default:
923617a3 15323 MIPS_INVAL("cp0");
7a387fff 15324 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15325 break;
15326 }
15327 break;
324d9e32
AJ
15328 case OPC_ADDI: /* Arithmetic with immediate opcode */
15329 case OPC_ADDIU:
e189e748 15330 gen_arith_imm(env, ctx, op, rt, rs, imm);
7a387fff 15331 break;
324d9e32
AJ
15332 case OPC_SLTI: /* Set on less than with immediate opcode */
15333 case OPC_SLTIU:
9fa77488 15334 gen_slt_imm(env, ctx, op, rt, rs, imm);
324d9e32
AJ
15335 break;
15336 case OPC_ANDI: /* Arithmetic with immediate opcode */
15337 case OPC_LUI:
15338 case OPC_ORI:
15339 case OPC_XORI:
9fa77488 15340 gen_logic_imm(env, ctx, op, rt, rs, imm);
324d9e32 15341 break;
7a387fff
TS
15342 case OPC_J ... OPC_JAL: /* Jump */
15343 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15344 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061
NF
15345 *is_branch = 1;
15346 break;
7a387fff
TS
15347 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15348 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15349 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061
NF
15350 *is_branch = 1;
15351 break;
7a387fff 15352 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15353 case OPC_LL:
afa88c3a 15354 gen_ld(env, ctx, op, rt, rs, imm);
5c13fdfd 15355 break;
7a387fff
TS
15356 case OPC_SB ... OPC_SW:
15357 case OPC_SWR:
5c13fdfd 15358 gen_st(ctx, op, rt, rs, imm);
7a387fff 15359 break;
d66c7132
AJ
15360 case OPC_SC:
15361 gen_st_cond(ctx, op, rt, rs, imm);
15362 break;
7a387fff 15363 case OPC_CACHE:
2e15497c 15364 check_cp0_enabled(ctx);
e189e748 15365 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15366 /* Treat as NOP. */
34ae7b51 15367 break;
7a387fff 15368 case OPC_PREF:
e189e748 15369 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15370 /* Treat as NOP. */
6af0bf9c 15371 break;
4ad40f36 15372
923617a3 15373 /* Floating point (COP1). */
7a387fff
TS
15374 case OPC_LWC1:
15375 case OPC_LDC1:
15376 case OPC_SWC1:
15377 case OPC_SDC1:
26ebe468 15378 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15379 break;
15380
7a387fff 15381 case OPC_CP1:
36d23958 15382 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15383 check_cp1_enabled(ctx);
36d23958
TS
15384 op1 = MASK_CP1(ctx->opcode);
15385 switch (op1) {
3a95e3a7
TS
15386 case OPC_MFHC1:
15387 case OPC_MTHC1:
e189e748 15388 check_insn(env, ctx, ISA_MIPS32R2);
36d23958
TS
15389 case OPC_MFC1:
15390 case OPC_CFC1:
15391 case OPC_MTC1:
15392 case OPC_CTC1:
e189e748
TS
15393 gen_cp1(ctx, op1, rt, rd);
15394 break;
d26bc211 15395#if defined(TARGET_MIPS64)
36d23958
TS
15396 case OPC_DMFC1:
15397 case OPC_DMTC1:
e189e748 15398 check_insn(env, ctx, ISA_MIPS3);
36d23958
TS
15399 gen_cp1(ctx, op1, rt, rd);
15400 break;
e189e748 15401#endif
fbcc6828
TS
15402 case OPC_BC1ANY2:
15403 case OPC_BC1ANY4:
b8aa4598 15404 check_cop1x(ctx);
7385ac0b 15405 check_insn(env, ctx, ASE_MIPS3D);
d8a5950a
TS
15406 /* fall through */
15407 case OPC_BC1:
e189e748 15408 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
5a5012ec 15409 (rt >> 2) & 0x7, imm << 2);
c9602061
NF
15410 *is_branch = 1;
15411 break;
36d23958
TS
15412 case OPC_S_FMT:
15413 case OPC_D_FMT:
15414 case OPC_W_FMT:
15415 case OPC_L_FMT:
5a5012ec 15416 case OPC_PS_FMT:
bf4120ad 15417 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15418 (imm >> 8) & 0x7);
36d23958
TS
15419 break;
15420 default:
923617a3 15421 MIPS_INVAL("cp1");
e397ee33 15422 generate_exception (ctx, EXCP_RI);
36d23958
TS
15423 break;
15424 }
15425 } else {
15426 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15427 }
4ad40f36
FB
15428 break;
15429
15430 /* COP2. */
7a387fff
TS
15431 case OPC_LWC2:
15432 case OPC_LDC2:
15433 case OPC_SWC2:
15434 case OPC_SDC2:
7a387fff 15435 /* COP2: Not implemented. */
4ad40f36
FB
15436 generate_exception_err(ctx, EXCP_CpU, 2);
15437 break;
bd277fa1
RH
15438 case OPC_CP2:
15439 check_insn(env, ctx, INSN_LOONGSON2F);
15440 /* Note that these instructions use different fields. */
15441 gen_loongson_multimedia(ctx, sa, rd, rt);
15442 break;
4ad40f36 15443
7a387fff 15444 case OPC_CP3:
36d23958 15445 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15446 check_cp1_enabled(ctx);
36d23958
TS
15447 op1 = MASK_CP3(ctx->opcode);
15448 switch (op1) {
5a5012ec
TS
15449 case OPC_LWXC1:
15450 case OPC_LDXC1:
15451 case OPC_LUXC1:
15452 case OPC_SWXC1:
15453 case OPC_SDXC1:
15454 case OPC_SUXC1:
93b12ccc 15455 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15456 break;
e0c84da7 15457 case OPC_PREFX:
ead9360e 15458 /* Treat as NOP. */
e0c84da7 15459 break;
5a5012ec
TS
15460 case OPC_ALNV_PS:
15461 case OPC_MADD_S:
15462 case OPC_MADD_D:
15463 case OPC_MADD_PS:
15464 case OPC_MSUB_S:
15465 case OPC_MSUB_D:
15466 case OPC_MSUB_PS:
15467 case OPC_NMADD_S:
15468 case OPC_NMADD_D:
15469 case OPC_NMADD_PS:
15470 case OPC_NMSUB_S:
15471 case OPC_NMSUB_D:
15472 case OPC_NMSUB_PS:
15473 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15474 break;
36d23958 15475 default:
923617a3 15476 MIPS_INVAL("cp3");
e397ee33 15477 generate_exception (ctx, EXCP_RI);
36d23958
TS
15478 break;
15479 }
15480 } else {
e397ee33 15481 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15482 }
4ad40f36
FB
15483 break;
15484
d26bc211 15485#if defined(TARGET_MIPS64)
7a387fff
TS
15486 /* MIPS64 opcodes */
15487 case OPC_LWU:
15488 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15489 case OPC_LLD:
15490 case OPC_LD:
5c13fdfd
AJ
15491 check_insn(env, ctx, ISA_MIPS3);
15492 check_mips_64(ctx);
afa88c3a 15493 gen_ld(env, ctx, op, rt, rs, imm);
5c13fdfd
AJ
15494 break;
15495 case OPC_SDL ... OPC_SDR:
7a387fff 15496 case OPC_SD:
e189e748
TS
15497 check_insn(env, ctx, ISA_MIPS3);
15498 check_mips_64(ctx);
5c13fdfd 15499 gen_st(ctx, op, rt, rs, imm);
7a387fff 15500 break;
d66c7132
AJ
15501 case OPC_SCD:
15502 check_insn(env, ctx, ISA_MIPS3);
15503 check_mips_64(ctx);
15504 gen_st_cond(ctx, op, rt, rs, imm);
15505 break;
324d9e32
AJ
15506 case OPC_DADDI:
15507 case OPC_DADDIU:
e189e748
TS
15508 check_insn(env, ctx, ISA_MIPS3);
15509 check_mips_64(ctx);
15510 gen_arith_imm(env, ctx, op, rt, rs, imm);
7a387fff 15511 break;
6af0bf9c 15512#endif
7a387fff 15513 case OPC_JALX:
3c824109 15514 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15515 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15516 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15517 *is_branch = 1;
15518 break;
7a387fff 15519 case OPC_MDMX:
e189e748 15520 check_insn(env, ctx, ASE_MDMX);
7a387fff 15521 /* MDMX: Not implemented. */
6af0bf9c 15522 default: /* Invalid */
923617a3 15523 MIPS_INVAL("major opcode");
6af0bf9c
FB
15524 generate_exception(ctx, EXCP_RI);
15525 break;
15526 }
6af0bf9c
FB
15527}
15528
2cfc5f17 15529static inline void
7db13fae 15530gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
820e00f2 15531 int search_pc)
6af0bf9c 15532{
278d0702 15533 DisasContext ctx;
6af0bf9c
FB
15534 target_ulong pc_start;
15535 uint16_t *gen_opc_end;
a1d1bb31 15536 CPUBreakpoint *bp;
6af0bf9c 15537 int j, lj = -1;
2e70f6ef
PB
15538 int num_insns;
15539 int max_insns;
c9602061
NF
15540 int insn_bytes;
15541 int is_branch;
6af0bf9c 15542
93fcfe39
AL
15543 if (search_pc)
15544 qemu_log("search pc %d\n", search_pc);
4ad40f36 15545
6af0bf9c 15546 pc_start = tb->pc;
d42320c2 15547 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15548 ctx.pc = pc_start;
4ad40f36 15549 ctx.saved_pc = -1;
7b270ef2 15550 ctx.singlestep_enabled = env->singlestep_enabled;
6af0bf9c
FB
15551 ctx.tb = tb;
15552 ctx.bstate = BS_NONE;
4ad40f36 15553 /* Restore delay slot state from the tb context. */
c068688b 15554 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15555 restore_cpu_state(env, &ctx);
932e71cd 15556#ifdef CONFIG_USER_ONLY
0eaef5aa 15557 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15558#else
0eaef5aa 15559 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15560#endif
2e70f6ef
PB
15561 num_insns = 0;
15562 max_insns = tb->cflags & CF_COUNT_MASK;
15563 if (max_insns == 0)
15564 max_insns = CF_COUNT_MASK;
d12d51d5 15565 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
2e70f6ef 15566 gen_icount_start();
faf7aaa9 15567 while (ctx.bstate == BS_NONE) {
72cf2d4f
BS
15568 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15569 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 15570 if (bp->pc == ctx.pc) {
278d0702 15571 save_cpu_state(&ctx, 1);
4ad40f36 15572 ctx.bstate = BS_BRANCH;
895c2d04 15573 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15574 /* Include the breakpoint location or the tb won't
15575 * be flushed when it must be. */
15576 ctx.pc += 4;
4ad40f36
FB
15577 goto done_generating;
15578 }
15579 }
15580 }
15581
6af0bf9c
FB
15582 if (search_pc) {
15583 j = gen_opc_ptr - gen_opc_buf;
6af0bf9c
FB
15584 if (lj < j) {
15585 lj++;
15586 while (lj < j)
15587 gen_opc_instr_start[lj++] = 0;
6af0bf9c 15588 }
4ad40f36
FB
15589 gen_opc_pc[lj] = ctx.pc;
15590 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15591 gen_opc_btarget[lj] = ctx.btarget;
4ad40f36 15592 gen_opc_instr_start[lj] = 1;
2e70f6ef 15593 gen_opc_icount[lj] = num_insns;
6af0bf9c 15594 }
2e70f6ef
PB
15595 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15596 gen_io_start();
c9602061
NF
15597
15598 is_branch = 0;
364d4831 15599 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15600 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061
NF
15601 insn_bytes = 4;
15602 decode_opc(env, &ctx, &is_branch);
3c824109 15603 } else if (env->insn_flags & ASE_MICROMIPS) {
895c2d04 15604 ctx.opcode = cpu_lduw_code(env, ctx.pc);
3c824109 15605 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
364d4831 15606 } else if (env->insn_flags & ASE_MIPS16) {
895c2d04 15607 ctx.opcode = cpu_lduw_code(env, ctx.pc);
364d4831 15608 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
c9602061
NF
15609 } else {
15610 generate_exception(&ctx, EXCP_RI);
3c824109 15611 ctx.bstate = BS_STOP;
c9602061
NF
15612 break;
15613 }
15614 if (!is_branch) {
15615 handle_delay_slot(env, &ctx, insn_bytes);
15616 }
15617 ctx.pc += insn_bytes;
15618
2e70f6ef 15619 num_insns++;
4ad40f36 15620
7b270ef2
NF
15621 /* Execute a branch and its delay slot as a single instruction.
15622 This is what GDB expects and is consistent with what the
15623 hardware does (e.g. if a delay slot instruction faults, the
15624 reported PC is the PC of the branch). */
15625 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
4ad40f36
FB
15626 break;
15627
6af0bf9c
FB
15628 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15629 break;
4ad40f36 15630
faf7aaa9
TS
15631 if (gen_opc_ptr >= gen_opc_end)
15632 break;
15633
2e70f6ef
PB
15634 if (num_insns >= max_insns)
15635 break;
1b530a6d
AJ
15636
15637 if (singlestep)
15638 break;
6af0bf9c 15639 }
2e70f6ef
PB
15640 if (tb->cflags & CF_LAST_IO)
15641 gen_io_end();
7b270ef2 15642 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15643 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15644 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15645 } else {
6958549d 15646 switch (ctx.bstate) {
16c00cb2 15647 case BS_STOP:
df1561e2
TS
15648 gen_goto_tb(&ctx, 0, ctx.pc);
15649 break;
16c00cb2 15650 case BS_NONE:
278d0702 15651 save_cpu_state(&ctx, 0);
16c00cb2
TS
15652 gen_goto_tb(&ctx, 0, ctx.pc);
15653 break;
5a5012ec 15654 case BS_EXCP:
57fec1fe 15655 tcg_gen_exit_tb(0);
16c00cb2 15656 break;
5a5012ec
TS
15657 case BS_BRANCH:
15658 default:
15659 break;
6958549d 15660 }
6af0bf9c 15661 }
4ad40f36 15662done_generating:
2e70f6ef 15663 gen_icount_end(tb, num_insns);
6af0bf9c
FB
15664 *gen_opc_ptr = INDEX_op_end;
15665 if (search_pc) {
15666 j = gen_opc_ptr - gen_opc_buf;
15667 lj++;
15668 while (lj <= j)
15669 gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15670 } else {
15671 tb->size = ctx.pc - pc_start;
2e70f6ef 15672 tb->icount = num_insns;
6af0bf9c
FB
15673 }
15674#ifdef DEBUG_DISAS
d12d51d5 15675 LOG_DISAS("\n");
8fec2b8c 15676 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39
AL
15677 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15678 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15679 qemu_log("\n");
6af0bf9c
FB
15680 }
15681#endif
6af0bf9c
FB
15682}
15683
7db13fae 15684void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15685{
2cfc5f17 15686 gen_intermediate_code_internal(env, tb, 0);
6af0bf9c
FB
15687}
15688
7db13fae 15689void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15690{
2cfc5f17 15691 gen_intermediate_code_internal(env, tb, 1);
6af0bf9c
FB
15692}
15693
7db13fae 15694static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15695 int flags)
6ea83fed
FB
15696{
15697 int i;
5e755519 15698 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15699
2a5612e6
SW
15700#define printfpr(fp) \
15701 do { \
15702 if (is_fpu64) \
15703 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15704 " fd:%13g fs:%13g psu: %13g\n", \
15705 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15706 (double)(fp)->fd, \
15707 (double)(fp)->fs[FP_ENDIAN_IDX], \
15708 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15709 else { \
15710 fpr_t tmp; \
15711 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15712 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15713 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15714 " fd:%13g fs:%13g psu:%13g\n", \
15715 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15716 (double)tmp.fd, \
15717 (double)tmp.fs[FP_ENDIAN_IDX], \
15718 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15719 } \
6ea83fed
FB
15720 } while(0)
15721
5a5012ec 15722
9a78eead
SW
15723 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15724 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15725 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15726 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15727 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15728 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15729 }
15730
15731#undef printfpr
15732}
15733
d26bc211 15734#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15735/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15736 sign-extended values on 64bit machines. */
c570fd16
TS
15737
15738#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15739
8706c382 15740static void
7db13fae 15741cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15742 fprintf_function cpu_fprintf,
8706c382 15743 int flags)
c570fd16
TS
15744{
15745 int i;
15746
b5dc7732
TS
15747 if (!SIGN_EXT_P(env->active_tc.PC))
15748 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15749 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15750 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15751 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15752 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15753 if (!SIGN_EXT_P(env->btarget))
3594c774 15754 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15755
15756 for (i = 0; i < 32; i++) {
b5dc7732
TS
15757 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15758 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15759 }
15760
15761 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15762 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15763 if (!SIGN_EXT_P(env->lladdr))
15764 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15765}
15766#endif
15767
7db13fae 15768void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
6af0bf9c
FB
15769 int flags)
15770{
15771 int i;
3b46e624 15772
a7200c9f
SW
15773 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15774 " LO=0x" TARGET_FMT_lx " ds %04x "
15775 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15776 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15777 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15778 for (i = 0; i < 32; i++) {
15779 if ((i & 3) == 0)
15780 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15781 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15782 if ((i & 3) == 3)
15783 cpu_fprintf(f, "\n");
15784 }
568b600d 15785
3594c774 15786 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15787 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15788 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15789 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15790 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15791 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15792#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15793 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15794#endif
6af0bf9c
FB
15795}
15796
39454628
TS
15797static void mips_tcg_init(void)
15798{
f01be154 15799 int i;
39454628
TS
15800 static int inited;
15801
15802 /* Initialize various static tables. */
15803 if (inited)
6958549d 15804 return;
39454628 15805
a7812ae4 15806 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15807 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15808 for (i = 1; i < 32; i++)
a7812ae4 15809 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15810 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15811 regnames[i]);
d73ee8a2
RH
15812
15813 for (i = 0; i < 32; i++) {
15814 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15815 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15816 }
15817
a7812ae4 15818 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15819 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15820 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15821 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15822 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15823 regnames_HI[i]);
a7812ae4 15824 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15825 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15826 regnames_LO[i]);
a7812ae4 15827 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15828 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15829 regnames_ACX[i]);
15830 }
a7812ae4 15831 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15832 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15833 "DSPControl");
1ba74fb8 15834 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15835 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15836 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15837 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15838 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15839 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15840
a7812ae4 15841 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15842 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15843 "fcr0");
15844 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15845 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15846 "fcr31");
39454628 15847
7dd9e556 15848 /* register helpers */
a7812ae4 15849#define GEN_HELPER 2
7dd9e556
TS
15850#include "helper.h"
15851
39454628
TS
15852 inited = 1;
15853}
15854
aaed909a
FB
15855#include "translate_init.c"
15856
30bf942d 15857MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15858{
0f71a709 15859 MIPSCPU *cpu;
6af0bf9c 15860 CPUMIPSState *env;
c227f099 15861 const mips_def_t *def;
6af0bf9c 15862
aaed909a
FB
15863 def = cpu_mips_find_by_name(cpu_model);
15864 if (!def)
15865 return NULL;
0f71a709
AF
15866 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15867 env = &cpu->env;
aaed909a 15868 env->cpu_model = def;
51cc2e78 15869 env->cpu_model_str = cpu_model;
aaed909a 15870
51cc2e78
BS
15871#ifndef CONFIG_USER_ONLY
15872 mmu_init(env, def);
15873#endif
15874 fpu_init(env, def);
15875 mvp_init(env, def);
39454628 15876 mips_tcg_init();
3bd4122e 15877 cpu_reset(CPU(cpu));
0bf46a40 15878 qemu_init_vcpu(env);
30bf942d 15879 return cpu;
6ae81775
TS
15880}
15881
1bba0dc9 15882void cpu_state_reset(CPUMIPSState *env)
6ae81775 15883{
eca1bdf4
AL
15884 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15885 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15886 log_cpu_state(env, 0);
15887 }
15888
6ae81775 15889 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6af0bf9c 15890 tlb_flush(env, 1);
6ae81775 15891
51cc2e78
BS
15892 /* Reset registers to their default values */
15893 env->CP0_PRid = env->cpu_model->CP0_PRid;
15894 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15895#ifdef TARGET_WORDS_BIGENDIAN
15896 env->CP0_Config0 |= (1 << CP0C0_BE);
15897#endif
15898 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15899 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15900 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15901 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15902 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15903 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15904 << env->cpu_model->CP0_LLAddr_shift;
15905 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15906 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15907 env->CCRes = env->cpu_model->CCRes;
15908 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15909 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15910 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15911 env->current_tc = 0;
15912 env->SEGBITS = env->cpu_model->SEGBITS;
15913 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15914#if defined(TARGET_MIPS64)
15915 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15916 env->SEGMask |= 3ULL << 62;
15917 }
15918#endif
15919 env->PABITS = env->cpu_model->PABITS;
15920 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15921 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15922 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15923 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15924 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15925 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15926 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15927 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15928 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15929 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15930 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15931 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15932 env->insn_flags = env->cpu_model->insn_flags;
15933
0eaef5aa 15934#if defined(CONFIG_USER_ONLY)
03e6e501 15935 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
94159135
MI
15936 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15937 hardware registers. */
15938 env->CP0_HWREna |= 0x0000000F;
91a75935 15939 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 15940 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 15941 }
853c3240
JL
15942 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15943 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15944 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15945 env->hflags |= MIPS_HFLAG_DSP;
15946 }
932e71cd
AJ
15947#else
15948 if (env->hflags & MIPS_HFLAG_BMASK) {
15949 /* If the exception was raised from a delay slot,
15950 come back to the jump. */
15951 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 15952 } else {
932e71cd
AJ
15953 env->CP0_ErrorEPC = env->active_tc.PC;
15954 }
15955 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
15956 env->CP0_Random = env->tlb->nb_tlb - 1;
15957 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 15958 env->CP0_Wired = 0;
671b0f36 15959 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
932e71cd
AJ
15960 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15961 /* vectored interrupts not implemented, timer on int 7,
15962 no performance counters. */
15963 env->CP0_IntCtl = 0xe0000000;
15964 {
15965 int i;
15966
15967 for (i = 0; i < 7; i++) {
15968 env->CP0_WatchLo[i] = 0;
15969 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 15970 }
932e71cd
AJ
15971 env->CP0_WatchLo[7] = 0;
15972 env->CP0_WatchHi[7] = 0;
fd88b6ab 15973 }
932e71cd
AJ
15974 /* Count register increments in debug mode, EJTAG version 1 */
15975 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
15976
15977 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15978 int i;
15979
15980 /* Only TC0 on VPE 0 starts as active. */
15981 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15982 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15983 env->tcs[i].CP0_TCHalt = 1;
15984 }
15985 env->active_tc.CP0_TCHalt = 1;
15986 env->halted = 1;
15987
15988 if (!env->cpu_index) {
15989 /* VPE0 starts up enabled. */
15990 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15991 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15992
15993 /* TC0 starts up unhalted. */
15994 env->halted = 0;
15995 env->active_tc.CP0_TCHalt = 0;
15996 env->tcs[0].CP0_TCHalt = 0;
15997 /* With thread 0 active. */
15998 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15999 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16000 }
16001 }
51cc2e78 16002#endif
03e6e501 16003 compute_hflags(env);
6af0bf9c 16004 env->exception_index = EXCP_NONE;
6af0bf9c 16005}
d2856f1a 16006
7db13fae 16007void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16008{
b5dc7732 16009 env->active_tc.PC = gen_opc_pc[pc_pos];
d2856f1a
AJ
16010 env->hflags &= ~MIPS_HFLAG_BMASK;
16011 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16012 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16013 case MIPS_HFLAG_BR:
16014 break;
16015 case MIPS_HFLAG_BC:
16016 case MIPS_HFLAG_BL:
16017 case MIPS_HFLAG_B:
16018 env->btarget = gen_opc_btarget[pc_pos];
16019 break;
16020 }
d2856f1a 16021}