]> git.proxmox.com Git - qemu.git/blame - target-mips/translate.c
target-mips: copy insn_flags in DisasContext
[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"
76cad711 25#include "disas/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
022c62cb 1020#include "exec/gen-icount.h"
2e70f6ef 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;
d75c135e 1069 int insn_flags;
8e9ade68
TS
1070 /* Routine used to access memory */
1071 int mem_idx;
1072 uint32_t hflags, saved_hflags;
1073 int bstate;
1074 target_ulong btarget;
1075} DisasContext;
1076
1077enum {
1078 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1079 * exception condition */
8e9ade68
TS
1080 BS_STOP = 1, /* We want to stop translation for any reason */
1081 BS_BRANCH = 2, /* We reached a branch condition */
1082 BS_EXCP = 3, /* We reached an exception condition */
1083};
1084
d73ee8a2
RH
1085static const char * const regnames[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1090};
6af0bf9c 1091
d73ee8a2
RH
1092static const char * const regnames_HI[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1094};
4b2eb8d2 1095
d73ee8a2
RH
1096static const char * const regnames_LO[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1098};
4b2eb8d2 1099
d73ee8a2
RH
1100static const char * const regnames_ACX[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1102};
4b2eb8d2 1103
d73ee8a2
RH
1104static const char * const fregnames[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1109};
958fb4a9 1110
fb7729e2
RH
1111#define MIPS_DEBUG(fmt, ...) \
1112 do { \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1117 } \
1118 } while (0)
1119
1120#define LOG_DISAS(...) \
1121 do { \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1124 } \
1125 } while (0)
958fb4a9 1126
8e9ade68 1127#define MIPS_INVAL(op) \
8e9ade68 1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1130
8e9ade68
TS
1131/* General purpose registers moves. */
1132static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1133{
8e9ade68
TS
1134 if (reg == 0)
1135 tcg_gen_movi_tl(t, 0);
1136 else
4b2eb8d2 1137 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1138}
1139
8e9ade68 1140static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1141{
8e9ade68 1142 if (reg != 0)
4b2eb8d2 1143 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1144}
1145
b10fa3c9 1146/* Moves to/from ACX register. */
4b2eb8d2 1147static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1148{
4b2eb8d2 1149 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1150}
1151
4b2eb8d2 1152static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1153{
4b2eb8d2 1154 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1155}
1156
8e9ade68 1157/* Moves to/from shadow registers. */
be24bb4f 1158static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1159{
d9bea114 1160 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1161
1162 if (from == 0)
d9bea114 1163 tcg_gen_movi_tl(t0, 0);
8e9ade68 1164 else {
d9bea114 1165 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1166 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1167
7db13fae 1168 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1169 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1170 tcg_gen_andi_i32(t2, t2, 0xf);
1171 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1172 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1173 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1174
d9bea114 1175 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1176 tcg_temp_free_ptr(addr);
d9bea114 1177 tcg_temp_free_i32(t2);
8e9ade68 1178 }
d9bea114
AJ
1179 gen_store_gpr(t0, to);
1180 tcg_temp_free(t0);
aaa9128a
TS
1181}
1182
be24bb4f 1183static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1184{
be24bb4f 1185 if (to != 0) {
d9bea114
AJ
1186 TCGv t0 = tcg_temp_new();
1187 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1188 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1189
d9bea114 1190 gen_load_gpr(t0, from);
7db13fae 1191 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1192 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1193 tcg_gen_andi_i32(t2, t2, 0xf);
1194 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1195 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1196 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1197
d9bea114 1198 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1199 tcg_temp_free_ptr(addr);
d9bea114
AJ
1200 tcg_temp_free_i32(t2);
1201 tcg_temp_free(t0);
8e9ade68 1202 }
aaa9128a
TS
1203}
1204
aaa9128a 1205/* Floating point register moves. */
d73ee8a2 1206static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1207{
d73ee8a2 1208 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1209}
1210
d73ee8a2 1211static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1212{
d73ee8a2
RH
1213 TCGv_i64 t64 = tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64, t);
1215 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1216 tcg_temp_free_i64(t64);
6d066274
AJ
1217}
1218
d73ee8a2 1219static void gen_load_fpr32h(TCGv_i32 t, int reg)
6d066274 1220{
d73ee8a2
RH
1221 TCGv_i64 t64 = tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1223 tcg_gen_trunc_i64_i32(t, t64);
1224 tcg_temp_free_i64(t64);
6d066274
AJ
1225}
1226
d73ee8a2 1227static void gen_store_fpr32h(TCGv_i32 t, int reg)
6d066274 1228{
d73ee8a2
RH
1229 TCGv_i64 t64 = tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64, t);
1231 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1232 tcg_temp_free_i64(t64);
aa0bf00b 1233}
6ea83fed 1234
d73ee8a2 1235static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1236{
f364515c 1237 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1238 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1239 } else {
d73ee8a2 1240 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1241 }
1242}
6ea83fed 1243
d73ee8a2 1244static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1245{
f364515c 1246 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1247 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1248 } else {
d73ee8a2
RH
1249 TCGv_i64 t0;
1250 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1251 t0 = tcg_temp_new_i64();
6d066274 1252 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1253 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1254 tcg_temp_free_i64(t0);
aa0bf00b
TS
1255 }
1256}
6ea83fed 1257
d94536f4 1258static inline int get_fp_bit (int cc)
a16336e4 1259{
d94536f4
AJ
1260 if (cc)
1261 return 24 + cc;
1262 else
1263 return 23;
a16336e4
TS
1264}
1265
30898801 1266/* Tests */
8e9ade68
TS
1267static inline void gen_save_pc(target_ulong pc)
1268{
1eb75d4a 1269 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1270}
30898801 1271
356265ae 1272static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1273{
d12d51d5 1274 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1275 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1276 gen_save_pc(ctx->pc);
6af0bf9c
FB
1277 ctx->saved_pc = ctx->pc;
1278 }
1279 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1280 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1281 ctx->saved_hflags = ctx->hflags;
364d4831 1282 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1283 case MIPS_HFLAG_BR:
5a5012ec
TS
1284 break;
1285 case MIPS_HFLAG_BC:
5a5012ec 1286 case MIPS_HFLAG_BL:
5a5012ec 1287 case MIPS_HFLAG_B:
d077b6f7 1288 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1289 break;
6af0bf9c
FB
1290 }
1291 }
1292}
1293
7db13fae 1294static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1295{
fd4a04eb 1296 ctx->saved_hflags = ctx->hflags;
364d4831 1297 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1298 case MIPS_HFLAG_BR:
fd4a04eb
TS
1299 break;
1300 case MIPS_HFLAG_BC:
1301 case MIPS_HFLAG_BL:
39454628 1302 case MIPS_HFLAG_B:
fd4a04eb 1303 ctx->btarget = env->btarget;
fd4a04eb 1304 break;
5a5012ec
TS
1305 }
1306}
1307
356265ae 1308static inline void
48d38ca5 1309generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1310{
a7812ae4
PB
1311 TCGv_i32 texcp = tcg_const_i32(excp);
1312 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1313 save_cpu_state(ctx, 1);
895c2d04 1314 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1315 tcg_temp_free_i32(terr);
1316 tcg_temp_free_i32(texcp);
aaa9128a
TS
1317}
1318
356265ae 1319static inline void
48d38ca5 1320generate_exception (DisasContext *ctx, int excp)
aaa9128a 1321{
6af0bf9c 1322 save_cpu_state(ctx, 1);
895c2d04 1323 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1324}
1325
48d38ca5 1326/* Addresses computation */
941694d0 1327static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1328{
941694d0 1329 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1330
1331#if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1335 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1336 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1337 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1338 }
1339#endif
4ad40f36
FB
1340}
1341
356265ae 1342static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1343{
fe253235 1344 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1345 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1346}
1347
356265ae 1348static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1349{
fe253235 1350 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1351 generate_exception_err(ctx, EXCP_CpU, 1);
1352}
1353
b8aa4598
TS
1354/* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1356 opcode tables. */
1357
356265ae 1358static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1359{
1360 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1361 generate_exception(ctx, EXCP_RI);
1362}
1363
1364/* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1366
356265ae 1367static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1368{
b8aa4598 1369 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1370 generate_exception(ctx, EXCP_RI);
1371}
1372
1373/*
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 *
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 */
356265ae 1384static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1385{
fe253235 1386 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1387 generate_exception(ctx, EXCP_RI);
1388}
1389
853c3240
JL
1390/* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1392 */
1393
1394static inline void check_dsp(DisasContext *ctx)
1395{
1396 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1397 generate_exception(ctx, EXCP_DSPDIS);
1398 }
1399}
1400
1401static inline void check_dspr2(DisasContext *ctx)
1402{
1403 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1404 generate_exception(ctx, EXCP_DSPDIS);
1405 }
1406}
1407
3a95e3a7 1408/* This code generates a "reserved instruction" exception if the
e189e748 1409 CPU does not support the instruction set corresponding to flags. */
d75c135e 1410static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1411{
d75c135e 1412 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1413 generate_exception(ctx, EXCP_RI);
d75c135e 1414 }
3a95e3a7
TS
1415}
1416
e189e748
TS
1417/* This code generates a "reserved instruction" exception if 64-bit
1418 instructions are not enabled. */
356265ae 1419static inline void check_mips_64(DisasContext *ctx)
e189e748 1420{
fe253235 1421 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1422 generate_exception(ctx, EXCP_RI);
1423}
1424
8153667c
NF
1425/* Define small wrappers for gen_load_fpr* so that we have a uniform
1426 calling interface for 32 and 64-bit FPRs. No sense in changing
1427 all callers for gen_load_fpr32 when we need the CTX parameter for
1428 this one use. */
1429#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1430#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1431#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1432static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1433 int ft, int fs, int cc) \
1434{ \
1435 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1436 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1437 switch (ifmt) { \
1438 case FMT_PS: \
1439 check_cp1_64bitmode(ctx); \
1440 break; \
1441 case FMT_D: \
1442 if (abs) { \
1443 check_cop1x(ctx); \
1444 } \
1445 check_cp1_registers(ctx, fs | ft); \
1446 break; \
1447 case FMT_S: \
1448 if (abs) { \
1449 check_cop1x(ctx); \
1450 } \
1451 break; \
1452 } \
1453 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1454 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1455 switch (n) { \
895c2d04
BS
1456 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1457 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1458 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1459 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1460 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1461 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1462 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1463 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1464 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1465 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1466 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1467 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1468 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1469 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1470 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1471 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1472 default: abort(); \
1473 } \
1474 tcg_temp_free_i##bits (fp0); \
1475 tcg_temp_free_i##bits (fp1); \
1476}
1477
1478FOP_CONDS(, 0, d, FMT_D, 64)
1479FOP_CONDS(abs, 1, d, FMT_D, 64)
1480FOP_CONDS(, 0, s, FMT_S, 32)
1481FOP_CONDS(abs, 1, s, FMT_S, 32)
1482FOP_CONDS(, 0, ps, FMT_PS, 64)
1483FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1484#undef FOP_CONDS
1485#undef gen_ldcmp_fpr32
1486#undef gen_ldcmp_fpr64
1487
958fb4a9 1488/* load/store instructions. */
e7139c44 1489#ifdef CONFIG_USER_ONLY
d9bea114 1490#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1491static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1492{ \
1493 TCGv t0 = tcg_temp_new(); \
1494 tcg_gen_mov_tl(t0, arg1); \
1495 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1496 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1497 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1498 tcg_temp_free(t0); \
aaa9128a 1499}
e7139c44
AJ
1500#else
1501#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1502static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1503{ \
895c2d04 1504 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1505}
1506#endif
aaa9128a
TS
1507OP_LD_ATOMIC(ll,ld32s);
1508#if defined(TARGET_MIPS64)
1509OP_LD_ATOMIC(lld,ld64);
1510#endif
1511#undef OP_LD_ATOMIC
1512
590bc601
PB
1513#ifdef CONFIG_USER_ONLY
1514#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1515static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1516{ \
1517 TCGv t0 = tcg_temp_new(); \
1518 int l1 = gen_new_label(); \
1519 int l2 = gen_new_label(); \
1520 \
1521 tcg_gen_andi_tl(t0, arg2, almask); \
1522 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1523 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1524 generate_exception(ctx, EXCP_AdES); \
1525 gen_set_label(l1); \
7db13fae 1526 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1527 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1528 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1529 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1530 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1531 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1532 gen_set_label(l2); \
1533 tcg_gen_movi_tl(t0, 0); \
1534 gen_store_gpr(t0, rt); \
1535 tcg_temp_free(t0); \
1536}
1537#else
1538#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1539static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1540{ \
1541 TCGv t0 = tcg_temp_new(); \
895c2d04 1542 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1543 gen_store_gpr(t0, rt); \
590bc601
PB
1544 tcg_temp_free(t0); \
1545}
1546#endif
590bc601 1547OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1548#if defined(TARGET_MIPS64)
590bc601 1549OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1550#endif
1551#undef OP_ST_ATOMIC
1552
662d7485
NF
1553static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1554 int base, int16_t offset)
1555{
1556 if (base == 0) {
1557 tcg_gen_movi_tl(addr, offset);
1558 } else if (offset == 0) {
1559 gen_load_gpr(addr, base);
1560 } else {
1561 tcg_gen_movi_tl(addr, offset);
1562 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1563 }
1564}
1565
364d4831
NF
1566static target_ulong pc_relative_pc (DisasContext *ctx)
1567{
1568 target_ulong pc = ctx->pc;
1569
1570 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1571 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1572
1573 pc -= branch_bytes;
1574 }
1575
1576 pc &= ~(target_ulong)3;
1577 return pc;
1578}
1579
5c13fdfd 1580/* Load */
d75c135e
AJ
1581static void gen_ld(DisasContext *ctx, uint32_t opc,
1582 int rt, int base, int16_t offset)
6af0bf9c 1583{
5c13fdfd 1584 const char *opn = "ld";
fc40787a 1585 TCGv t0, t1, t2;
afa88c3a 1586
d75c135e 1587 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1588 /* Loongson CPU uses a load to zero register for prefetch.
1589 We emulate it as a NOP. On other CPU we must perform the
1590 actual memory access. */
1591 MIPS_DEBUG("NOP");
1592 return;
1593 }
6af0bf9c 1594
afa88c3a 1595 t0 = tcg_temp_new();
662d7485 1596 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1597
6af0bf9c 1598 switch (opc) {
d26bc211 1599#if defined(TARGET_MIPS64)
6e473128 1600 case OPC_LWU:
2910c6cb 1601 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
78723684 1602 gen_store_gpr(t0, rt);
6e473128
TS
1603 opn = "lwu";
1604 break;
6af0bf9c 1605 case OPC_LD:
2910c6cb 1606 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
78723684 1607 gen_store_gpr(t0, rt);
6af0bf9c
FB
1608 opn = "ld";
1609 break;
7a387fff 1610 case OPC_LLD:
b835e919 1611 save_cpu_state(ctx, 1);
5c13fdfd 1612 op_ld_lld(t0, t0, ctx);
78723684 1613 gen_store_gpr(t0, rt);
7a387fff
TS
1614 opn = "lld";
1615 break;
6af0bf9c 1616 case OPC_LDL:
3cee3050 1617 t1 = tcg_temp_new();
fc40787a
AJ
1618 tcg_gen_andi_tl(t1, t0, 7);
1619#ifndef TARGET_WORDS_BIGENDIAN
1620 tcg_gen_xori_tl(t1, t1, 7);
1621#endif
1622 tcg_gen_shli_tl(t1, t1, 3);
1623 tcg_gen_andi_tl(t0, t0, ~7);
1624 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1625 tcg_gen_shl_tl(t0, t0, t1);
1626 tcg_gen_xori_tl(t1, t1, 63);
1627 t2 = tcg_const_tl(0x7fffffffffffffffull);
1628 tcg_gen_shr_tl(t2, t2, t1);
78723684 1629 gen_load_gpr(t1, rt);
fc40787a
AJ
1630 tcg_gen_and_tl(t1, t1, t2);
1631 tcg_temp_free(t2);
1632 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1633 tcg_temp_free(t1);
fc40787a 1634 gen_store_gpr(t0, rt);
6af0bf9c
FB
1635 opn = "ldl";
1636 break;
6af0bf9c 1637 case OPC_LDR:
3cee3050 1638 t1 = tcg_temp_new();
fc40787a
AJ
1639 tcg_gen_andi_tl(t1, t0, 7);
1640#ifdef TARGET_WORDS_BIGENDIAN
1641 tcg_gen_xori_tl(t1, t1, 7);
1642#endif
1643 tcg_gen_shli_tl(t1, t1, 3);
1644 tcg_gen_andi_tl(t0, t0, ~7);
1645 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1646 tcg_gen_shr_tl(t0, t0, t1);
1647 tcg_gen_xori_tl(t1, t1, 63);
1648 t2 = tcg_const_tl(0xfffffffffffffffeull);
1649 tcg_gen_shl_tl(t2, t2, t1);
78723684 1650 gen_load_gpr(t1, rt);
fc40787a
AJ
1651 tcg_gen_and_tl(t1, t1, t2);
1652 tcg_temp_free(t2);
1653 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1654 tcg_temp_free(t1);
fc40787a 1655 gen_store_gpr(t0, rt);
6af0bf9c
FB
1656 opn = "ldr";
1657 break;
364d4831 1658 case OPC_LDPC:
3cee3050 1659 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1660 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1661 tcg_temp_free(t1);
2910c6cb 1662 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
364d4831 1663 gen_store_gpr(t0, rt);
5c13fdfd 1664 opn = "ldpc";
364d4831 1665 break;
6af0bf9c 1666#endif
364d4831 1667 case OPC_LWPC:
3cee3050 1668 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1669 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1670 tcg_temp_free(t1);
2910c6cb 1671 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
364d4831 1672 gen_store_gpr(t0, rt);
5c13fdfd 1673 opn = "lwpc";
364d4831 1674 break;
6af0bf9c 1675 case OPC_LW:
2910c6cb 1676 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
78723684 1677 gen_store_gpr(t0, rt);
6af0bf9c
FB
1678 opn = "lw";
1679 break;
6af0bf9c 1680 case OPC_LH:
2910c6cb 1681 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
78723684 1682 gen_store_gpr(t0, rt);
6af0bf9c
FB
1683 opn = "lh";
1684 break;
6af0bf9c 1685 case OPC_LHU:
2910c6cb 1686 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
78723684 1687 gen_store_gpr(t0, rt);
6af0bf9c
FB
1688 opn = "lhu";
1689 break;
1690 case OPC_LB:
2910c6cb 1691 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
78723684 1692 gen_store_gpr(t0, rt);
6af0bf9c
FB
1693 opn = "lb";
1694 break;
6af0bf9c 1695 case OPC_LBU:
2910c6cb 1696 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
78723684 1697 gen_store_gpr(t0, rt);
6af0bf9c
FB
1698 opn = "lbu";
1699 break;
1700 case OPC_LWL:
3cee3050 1701 t1 = tcg_temp_new();
fc40787a
AJ
1702 tcg_gen_andi_tl(t1, t0, 3);
1703#ifndef TARGET_WORDS_BIGENDIAN
1704 tcg_gen_xori_tl(t1, t1, 3);
1705#endif
1706 tcg_gen_shli_tl(t1, t1, 3);
1707 tcg_gen_andi_tl(t0, t0, ~3);
1708 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1709 tcg_gen_shl_tl(t0, t0, t1);
1710 tcg_gen_xori_tl(t1, t1, 31);
1711 t2 = tcg_const_tl(0x7fffffffull);
1712 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1713 gen_load_gpr(t1, rt);
fc40787a
AJ
1714 tcg_gen_and_tl(t1, t1, t2);
1715 tcg_temp_free(t2);
1716 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1717 tcg_temp_free(t1);
fc40787a
AJ
1718 tcg_gen_ext32s_tl(t0, t0);
1719 gen_store_gpr(t0, rt);
6af0bf9c
FB
1720 opn = "lwl";
1721 break;
6af0bf9c 1722 case OPC_LWR:
3cee3050 1723 t1 = tcg_temp_new();
fc40787a
AJ
1724 tcg_gen_andi_tl(t1, t0, 3);
1725#ifdef TARGET_WORDS_BIGENDIAN
1726 tcg_gen_xori_tl(t1, t1, 3);
1727#endif
1728 tcg_gen_shli_tl(t1, t1, 3);
1729 tcg_gen_andi_tl(t0, t0, ~3);
1730 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1731 tcg_gen_shr_tl(t0, t0, t1);
1732 tcg_gen_xori_tl(t1, t1, 31);
1733 t2 = tcg_const_tl(0xfffffffeull);
1734 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1735 gen_load_gpr(t1, rt);
fc40787a
AJ
1736 tcg_gen_and_tl(t1, t1, t2);
1737 tcg_temp_free(t2);
1738 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1739 tcg_temp_free(t1);
fc40787a 1740 gen_store_gpr(t0, rt);
6af0bf9c
FB
1741 opn = "lwr";
1742 break;
6af0bf9c 1743 case OPC_LL:
e7139c44 1744 save_cpu_state(ctx, 1);
5c13fdfd 1745 op_ld_ll(t0, t0, ctx);
78723684 1746 gen_store_gpr(t0, rt);
6af0bf9c
FB
1747 opn = "ll";
1748 break;
d66c7132 1749 }
2abf314d 1750 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1751 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1752 tcg_temp_free(t0);
d66c7132
AJ
1753}
1754
5c13fdfd
AJ
1755/* Store */
1756static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1757 int base, int16_t offset)
1758{
1759 const char *opn = "st";
1760 TCGv t0 = tcg_temp_new();
1761 TCGv t1 = tcg_temp_new();
1762
1763 gen_base_offset_addr(ctx, t0, base, offset);
1764 gen_load_gpr(t1, rt);
1765 switch (opc) {
1766#if defined(TARGET_MIPS64)
1767 case OPC_SD:
2910c6cb 1768 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1769 opn = "sd";
1770 break;
1771 case OPC_SDL:
1772 save_cpu_state(ctx, 1);
895c2d04 1773 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1774 opn = "sdl";
1775 break;
1776 case OPC_SDR:
1777 save_cpu_state(ctx, 1);
895c2d04 1778 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1779 opn = "sdr";
1780 break;
1781#endif
1782 case OPC_SW:
2910c6cb 1783 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1784 opn = "sw";
1785 break;
1786 case OPC_SH:
2910c6cb 1787 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1788 opn = "sh";
1789 break;
1790 case OPC_SB:
2910c6cb 1791 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1792 opn = "sb";
1793 break;
1794 case OPC_SWL:
1795 save_cpu_state(ctx, 1);
895c2d04 1796 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1797 opn = "swl";
1798 break;
1799 case OPC_SWR:
1800 save_cpu_state(ctx, 1);
895c2d04 1801 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1802 opn = "swr";
1803 break;
1804 }
2abf314d 1805 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1806 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1807 tcg_temp_free(t0);
1808 tcg_temp_free(t1);
1809}
1810
1811
d66c7132
AJ
1812/* Store conditional */
1813static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1814 int base, int16_t offset)
1815{
1816 const char *opn = "st_cond";
1817 TCGv t0, t1;
1818
2d2826b9 1819#ifdef CONFIG_USER_ONLY
d66c7132 1820 t0 = tcg_temp_local_new();
d66c7132 1821 t1 = tcg_temp_local_new();
2d2826b9
AJ
1822#else
1823 t0 = tcg_temp_new();
1824 t1 = tcg_temp_new();
1825#endif
1826 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1827 gen_load_gpr(t1, rt);
1828 switch (opc) {
1829#if defined(TARGET_MIPS64)
1830 case OPC_SCD:
b835e919 1831 save_cpu_state(ctx, 1);
5c13fdfd 1832 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1833 opn = "scd";
1834 break;
1835#endif
6af0bf9c 1836 case OPC_SC:
e7139c44 1837 save_cpu_state(ctx, 1);
5c13fdfd 1838 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1839 opn = "sc";
1840 break;
6af0bf9c 1841 }
2abf314d 1842 (void)opn; /* avoid a compiler warning */
6af0bf9c 1843 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1844 tcg_temp_free(t1);
d66c7132 1845 tcg_temp_free(t0);
6af0bf9c
FB
1846}
1847
6ea83fed 1848/* Load and store */
7a387fff 1849static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1850 int base, int16_t offset)
6ea83fed 1851{
923617a3 1852 const char *opn = "flt_ldst";
4e2474d6 1853 TCGv t0 = tcg_temp_new();
6ea83fed 1854
662d7485 1855 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1856 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1857 memory access. */
6ea83fed
FB
1858 switch (opc) {
1859 case OPC_LWC1:
b6d96bed 1860 {
a7812ae4 1861 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1862
c407df81
AJ
1863 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1864 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 1865 gen_store_fpr32(fp0, ft);
a7812ae4 1866 tcg_temp_free_i32(fp0);
b6d96bed 1867 }
6ea83fed
FB
1868 opn = "lwc1";
1869 break;
1870 case OPC_SWC1:
b6d96bed 1871 {
a7812ae4
PB
1872 TCGv_i32 fp0 = tcg_temp_new_i32();
1873 TCGv t1 = tcg_temp_new();
b6d96bed
TS
1874
1875 gen_load_fpr32(fp0, ft);
a7812ae4
PB
1876 tcg_gen_extu_i32_tl(t1, fp0);
1877 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1878 tcg_temp_free(t1);
1879 tcg_temp_free_i32(fp0);
b6d96bed 1880 }
6ea83fed
FB
1881 opn = "swc1";
1882 break;
1883 case OPC_LDC1:
b6d96bed 1884 {
a7812ae4 1885 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1886
1887 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1888 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1889 tcg_temp_free_i64(fp0);
b6d96bed 1890 }
6ea83fed
FB
1891 opn = "ldc1";
1892 break;
1893 case OPC_SDC1:
b6d96bed 1894 {
a7812ae4 1895 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1896
1897 gen_load_fpr64(ctx, fp0, ft);
1898 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 1899 tcg_temp_free_i64(fp0);
b6d96bed 1900 }
6ea83fed
FB
1901 opn = "sdc1";
1902 break;
1903 default:
923617a3 1904 MIPS_INVAL(opn);
e397ee33 1905 generate_exception(ctx, EXCP_RI);
78723684 1906 goto out;
6ea83fed 1907 }
2abf314d 1908 (void)opn; /* avoid a compiler warning */
6ea83fed 1909 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1910 out:
1911 tcg_temp_free(t0);
6ea83fed 1912}
6ea83fed 1913
7db13fae 1914static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1915 uint32_t op, int rt, int rs, int16_t imm)
1916{
1917 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1918 check_cp1_enabled(ctx);
1919 gen_flt_ldst(ctx, op, rt, rs, imm);
1920 } else {
1921 generate_exception_err(ctx, EXCP_CpU, 1);
1922 }
1923}
1924
6af0bf9c 1925/* Arithmetic with immediate operand */
d75c135e
AJ
1926static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1927 int rt, int rs, int16_t imm)
6af0bf9c 1928{
324d9e32 1929 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1930 const char *opn = "imm arith";
6af0bf9c 1931
7a387fff 1932 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1933 /* If no destination, treat it as a NOP.
1934 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1935 MIPS_DEBUG("NOP");
324d9e32 1936 return;
6af0bf9c
FB
1937 }
1938 switch (opc) {
1939 case OPC_ADDI:
48d38ca5 1940 {
324d9e32
AJ
1941 TCGv t0 = tcg_temp_local_new();
1942 TCGv t1 = tcg_temp_new();
1943 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1944 int l1 = gen_new_label();
1945
324d9e32
AJ
1946 gen_load_gpr(t1, rs);
1947 tcg_gen_addi_tl(t0, t1, uimm);
1948 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1949
324d9e32
AJ
1950 tcg_gen_xori_tl(t1, t1, ~uimm);
1951 tcg_gen_xori_tl(t2, t0, uimm);
1952 tcg_gen_and_tl(t1, t1, t2);
1953 tcg_temp_free(t2);
1954 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1955 tcg_temp_free(t1);
48d38ca5
TS
1956 /* operands of same sign, result different sign */
1957 generate_exception(ctx, EXCP_OVERFLOW);
1958 gen_set_label(l1);
78723684 1959 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1960 gen_store_gpr(t0, rt);
1961 tcg_temp_free(t0);
48d38ca5 1962 }
6af0bf9c
FB
1963 opn = "addi";
1964 break;
1965 case OPC_ADDIU:
324d9e32
AJ
1966 if (rs != 0) {
1967 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1968 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1969 } else {
1970 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1971 }
6af0bf9c
FB
1972 opn = "addiu";
1973 break;
d26bc211 1974#if defined(TARGET_MIPS64)
7a387fff 1975 case OPC_DADDI:
48d38ca5 1976 {
324d9e32
AJ
1977 TCGv t0 = tcg_temp_local_new();
1978 TCGv t1 = tcg_temp_new();
1979 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1980 int l1 = gen_new_label();
1981
324d9e32
AJ
1982 gen_load_gpr(t1, rs);
1983 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1984
324d9e32
AJ
1985 tcg_gen_xori_tl(t1, t1, ~uimm);
1986 tcg_gen_xori_tl(t2, t0, uimm);
1987 tcg_gen_and_tl(t1, t1, t2);
1988 tcg_temp_free(t2);
1989 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1990 tcg_temp_free(t1);
48d38ca5
TS
1991 /* operands of same sign, result different sign */
1992 generate_exception(ctx, EXCP_OVERFLOW);
1993 gen_set_label(l1);
324d9e32
AJ
1994 gen_store_gpr(t0, rt);
1995 tcg_temp_free(t0);
48d38ca5 1996 }
7a387fff
TS
1997 opn = "daddi";
1998 break;
1999 case OPC_DADDIU:
324d9e32
AJ
2000 if (rs != 0) {
2001 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2002 } else {
2003 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2004 }
7a387fff
TS
2005 opn = "daddiu";
2006 break;
2007#endif
324d9e32 2008 }
2abf314d 2009 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2010 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2011}
2012
2013/* Logic with immediate operand */
d75c135e 2014static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2015 int rt, int rs, int16_t imm)
324d9e32
AJ
2016{
2017 target_ulong uimm;
324d9e32
AJ
2018
2019 if (rt == 0) {
2020 /* If no destination, treat it as a NOP. */
2021 MIPS_DEBUG("NOP");
2022 return;
2023 }
2024 uimm = (uint16_t)imm;
2025 switch (opc) {
6af0bf9c 2026 case OPC_ANDI:
324d9e32
AJ
2027 if (likely(rs != 0))
2028 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2029 else
2030 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2031 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2032 regnames[rs], uimm);
6af0bf9c
FB
2033 break;
2034 case OPC_ORI:
324d9e32
AJ
2035 if (rs != 0)
2036 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2037 else
2038 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2039 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2040 regnames[rs], uimm);
6af0bf9c
FB
2041 break;
2042 case OPC_XORI:
324d9e32
AJ
2043 if (likely(rs != 0))
2044 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2045 else
2046 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2047 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2048 regnames[rs], uimm);
6af0bf9c
FB
2049 break;
2050 case OPC_LUI:
324d9e32 2051 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2052 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2053 break;
2054
2055 default:
2056 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2057 break;
324d9e32 2058 }
324d9e32
AJ
2059}
2060
2061/* Set on less than with immediate operand */
d75c135e 2062static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2063 int rt, int rs, int16_t imm)
324d9e32
AJ
2064{
2065 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2066 const char *opn = "imm arith";
2067 TCGv t0;
2068
2069 if (rt == 0) {
2070 /* If no destination, treat it as a NOP. */
2071 MIPS_DEBUG("NOP");
2072 return;
2073 }
2074 t0 = tcg_temp_new();
2075 gen_load_gpr(t0, rs);
2076 switch (opc) {
2077 case OPC_SLTI:
e68dd28f 2078 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2079 opn = "slti";
2080 break;
2081 case OPC_SLTIU:
e68dd28f 2082 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2083 opn = "sltiu";
2084 break;
2085 }
2abf314d 2086 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2087 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2088 tcg_temp_free(t0);
2089}
2090
2091/* Shifts with immediate operand */
d75c135e 2092static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2093 int rt, int rs, int16_t imm)
2094{
2095 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2096 const char *opn = "imm shift";
2097 TCGv t0;
2098
2099 if (rt == 0) {
2100 /* If no destination, treat it as a NOP. */
2101 MIPS_DEBUG("NOP");
2102 return;
2103 }
2104
2105 t0 = tcg_temp_new();
2106 gen_load_gpr(t0, rs);
2107 switch (opc) {
6af0bf9c 2108 case OPC_SLL:
78723684 2109 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2110 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2111 opn = "sll";
2112 break;
2113 case OPC_SRA:
324d9e32 2114 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2115 opn = "sra";
2116 break;
2117 case OPC_SRL:
ea63e2c3
NF
2118 if (uimm != 0) {
2119 tcg_gen_ext32u_tl(t0, t0);
2120 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2121 } else {
2122 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2123 }
ea63e2c3
NF
2124 opn = "srl";
2125 break;
2126 case OPC_ROTR:
2127 if (uimm != 0) {
2128 TCGv_i32 t1 = tcg_temp_new_i32();
2129
2130 tcg_gen_trunc_tl_i32(t1, t0);
2131 tcg_gen_rotri_i32(t1, t1, uimm);
2132 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2133 tcg_temp_free_i32(t1);
3399e30f
NF
2134 } else {
2135 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2136 }
2137 opn = "rotr";
7a387fff 2138 break;
d26bc211 2139#if defined(TARGET_MIPS64)
7a387fff 2140 case OPC_DSLL:
324d9e32 2141 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2142 opn = "dsll";
2143 break;
2144 case OPC_DSRA:
324d9e32 2145 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2146 opn = "dsra";
2147 break;
2148 case OPC_DSRL:
ea63e2c3
NF
2149 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2150 opn = "dsrl";
2151 break;
2152 case OPC_DROTR:
2153 if (uimm != 0) {
2154 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2155 } else {
2156 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2157 }
ea63e2c3 2158 opn = "drotr";
7a387fff
TS
2159 break;
2160 case OPC_DSLL32:
324d9e32 2161 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2162 opn = "dsll32";
2163 break;
2164 case OPC_DSRA32:
324d9e32 2165 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2166 opn = "dsra32";
2167 break;
2168 case OPC_DSRL32:
ea63e2c3
NF
2169 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2170 opn = "dsrl32";
2171 break;
2172 case OPC_DROTR32:
2173 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2174 opn = "drotr32";
6af0bf9c 2175 break;
7a387fff 2176#endif
6af0bf9c 2177 }
2abf314d 2178 (void)opn; /* avoid a compiler warning */
93b12ccc 2179 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2180 tcg_temp_free(t0);
6af0bf9c
FB
2181}
2182
2183/* Arithmetic */
d75c135e
AJ
2184static void gen_arith(DisasContext *ctx, uint32_t opc,
2185 int rd, int rs, int rt)
6af0bf9c 2186{
923617a3 2187 const char *opn = "arith";
6af0bf9c 2188
7a387fff
TS
2189 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2190 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2191 /* If no destination, treat it as a NOP.
2192 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2193 MIPS_DEBUG("NOP");
460f00c4 2194 return;
185f0762 2195 }
460f00c4 2196
6af0bf9c
FB
2197 switch (opc) {
2198 case OPC_ADD:
48d38ca5 2199 {
460f00c4
AJ
2200 TCGv t0 = tcg_temp_local_new();
2201 TCGv t1 = tcg_temp_new();
2202 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2203 int l1 = gen_new_label();
2204
460f00c4
AJ
2205 gen_load_gpr(t1, rs);
2206 gen_load_gpr(t2, rt);
2207 tcg_gen_add_tl(t0, t1, t2);
2208 tcg_gen_ext32s_tl(t0, t0);
2209 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2210 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2211 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2212 tcg_temp_free(t2);
2213 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2214 tcg_temp_free(t1);
48d38ca5
TS
2215 /* operands of same sign, result different sign */
2216 generate_exception(ctx, EXCP_OVERFLOW);
2217 gen_set_label(l1);
460f00c4
AJ
2218 gen_store_gpr(t0, rd);
2219 tcg_temp_free(t0);
48d38ca5 2220 }
6af0bf9c
FB
2221 opn = "add";
2222 break;
2223 case OPC_ADDU:
460f00c4
AJ
2224 if (rs != 0 && rt != 0) {
2225 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2226 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2227 } else if (rs == 0 && rt != 0) {
2228 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2229 } else if (rs != 0 && rt == 0) {
2230 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2231 } else {
2232 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2233 }
6af0bf9c
FB
2234 opn = "addu";
2235 break;
2236 case OPC_SUB:
48d38ca5 2237 {
460f00c4
AJ
2238 TCGv t0 = tcg_temp_local_new();
2239 TCGv t1 = tcg_temp_new();
2240 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2241 int l1 = gen_new_label();
2242
460f00c4
AJ
2243 gen_load_gpr(t1, rs);
2244 gen_load_gpr(t2, rt);
2245 tcg_gen_sub_tl(t0, t1, t2);
2246 tcg_gen_ext32s_tl(t0, t0);
2247 tcg_gen_xor_tl(t2, t1, t2);
2248 tcg_gen_xor_tl(t1, t0, t1);
2249 tcg_gen_and_tl(t1, t1, t2);
2250 tcg_temp_free(t2);
2251 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2252 tcg_temp_free(t1);
31e3104f 2253 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2254 generate_exception(ctx, EXCP_OVERFLOW);
2255 gen_set_label(l1);
460f00c4
AJ
2256 gen_store_gpr(t0, rd);
2257 tcg_temp_free(t0);
48d38ca5 2258 }
6af0bf9c
FB
2259 opn = "sub";
2260 break;
2261 case OPC_SUBU:
460f00c4
AJ
2262 if (rs != 0 && rt != 0) {
2263 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2264 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2265 } else if (rs == 0 && rt != 0) {
2266 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2267 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2268 } else if (rs != 0 && rt == 0) {
2269 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2270 } else {
2271 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2272 }
6af0bf9c
FB
2273 opn = "subu";
2274 break;
d26bc211 2275#if defined(TARGET_MIPS64)
7a387fff 2276 case OPC_DADD:
48d38ca5 2277 {
460f00c4
AJ
2278 TCGv t0 = tcg_temp_local_new();
2279 TCGv t1 = tcg_temp_new();
2280 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2281 int l1 = gen_new_label();
2282
460f00c4
AJ
2283 gen_load_gpr(t1, rs);
2284 gen_load_gpr(t2, rt);
2285 tcg_gen_add_tl(t0, t1, t2);
2286 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2287 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2288 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2289 tcg_temp_free(t2);
2290 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2291 tcg_temp_free(t1);
48d38ca5
TS
2292 /* operands of same sign, result different sign */
2293 generate_exception(ctx, EXCP_OVERFLOW);
2294 gen_set_label(l1);
460f00c4
AJ
2295 gen_store_gpr(t0, rd);
2296 tcg_temp_free(t0);
48d38ca5 2297 }
7a387fff
TS
2298 opn = "dadd";
2299 break;
2300 case OPC_DADDU:
460f00c4
AJ
2301 if (rs != 0 && rt != 0) {
2302 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2303 } else if (rs == 0 && rt != 0) {
2304 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2305 } else if (rs != 0 && rt == 0) {
2306 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2307 } else {
2308 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2309 }
7a387fff
TS
2310 opn = "daddu";
2311 break;
2312 case OPC_DSUB:
48d38ca5 2313 {
460f00c4
AJ
2314 TCGv t0 = tcg_temp_local_new();
2315 TCGv t1 = tcg_temp_new();
2316 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2317 int l1 = gen_new_label();
2318
460f00c4
AJ
2319 gen_load_gpr(t1, rs);
2320 gen_load_gpr(t2, rt);
2321 tcg_gen_sub_tl(t0, t1, t2);
2322 tcg_gen_xor_tl(t2, t1, t2);
2323 tcg_gen_xor_tl(t1, t0, t1);
2324 tcg_gen_and_tl(t1, t1, t2);
2325 tcg_temp_free(t2);
2326 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2327 tcg_temp_free(t1);
31e3104f 2328 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2329 generate_exception(ctx, EXCP_OVERFLOW);
2330 gen_set_label(l1);
460f00c4
AJ
2331 gen_store_gpr(t0, rd);
2332 tcg_temp_free(t0);
48d38ca5 2333 }
7a387fff
TS
2334 opn = "dsub";
2335 break;
2336 case OPC_DSUBU:
460f00c4
AJ
2337 if (rs != 0 && rt != 0) {
2338 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2339 } else if (rs == 0 && rt != 0) {
2340 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2341 } else if (rs != 0 && rt == 0) {
2342 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2343 } else {
2344 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2345 }
7a387fff
TS
2346 opn = "dsubu";
2347 break;
2348#endif
460f00c4
AJ
2349 case OPC_MUL:
2350 if (likely(rs != 0 && rt != 0)) {
2351 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2352 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2353 } else {
2354 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2355 }
2356 opn = "mul";
6af0bf9c 2357 break;
460f00c4 2358 }
2abf314d 2359 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2360 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2361}
2362
2363/* Conditional move */
d75c135e 2364static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2365 int rd, int rs, int rt)
460f00c4
AJ
2366{
2367 const char *opn = "cond move";
acf12465 2368 TCGv t0, t1, t2;
460f00c4
AJ
2369
2370 if (rd == 0) {
acf12465 2371 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2372 MIPS_DEBUG("NOP");
2373 return;
2374 }
2375
acf12465
AJ
2376 t0 = tcg_temp_new();
2377 gen_load_gpr(t0, rt);
2378 t1 = tcg_const_tl(0);
2379 t2 = tcg_temp_new();
2380 gen_load_gpr(t2, rs);
460f00c4
AJ
2381 switch (opc) {
2382 case OPC_MOVN:
acf12465 2383 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2384 opn = "movn";
6af0bf9c 2385 break;
460f00c4 2386 case OPC_MOVZ:
acf12465 2387 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2388 opn = "movz";
2389 break;
2390 }
acf12465
AJ
2391 tcg_temp_free(t2);
2392 tcg_temp_free(t1);
2393 tcg_temp_free(t0);
460f00c4 2394
2abf314d 2395 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2396 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2397}
2398
2399/* Logic */
d75c135e 2400static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2401 int rd, int rs, int rt)
460f00c4
AJ
2402{
2403 const char *opn = "logic";
2404
2405 if (rd == 0) {
2406 /* If no destination, treat it as a NOP. */
2407 MIPS_DEBUG("NOP");
2408 return;
2409 }
2410
2411 switch (opc) {
6af0bf9c 2412 case OPC_AND:
460f00c4
AJ
2413 if (likely(rs != 0 && rt != 0)) {
2414 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2415 } else {
2416 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2417 }
6af0bf9c
FB
2418 opn = "and";
2419 break;
2420 case OPC_NOR:
460f00c4
AJ
2421 if (rs != 0 && rt != 0) {
2422 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2423 } else if (rs == 0 && rt != 0) {
2424 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2425 } else if (rs != 0 && rt == 0) {
2426 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2427 } else {
2428 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2429 }
6af0bf9c
FB
2430 opn = "nor";
2431 break;
2432 case OPC_OR:
460f00c4
AJ
2433 if (likely(rs != 0 && rt != 0)) {
2434 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2435 } else if (rs == 0 && rt != 0) {
2436 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2437 } else if (rs != 0 && rt == 0) {
2438 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2439 } else {
2440 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2441 }
6af0bf9c
FB
2442 opn = "or";
2443 break;
2444 case OPC_XOR:
460f00c4
AJ
2445 if (likely(rs != 0 && rt != 0)) {
2446 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2447 } else if (rs == 0 && rt != 0) {
2448 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2449 } else if (rs != 0 && rt == 0) {
2450 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2451 } else {
2452 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2453 }
6af0bf9c
FB
2454 opn = "xor";
2455 break;
460f00c4 2456 }
2abf314d 2457 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2458 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2459}
2460
2461/* Set on lower than */
d75c135e 2462static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2463 int rd, int rs, int rt)
460f00c4
AJ
2464{
2465 const char *opn = "slt";
2466 TCGv t0, t1;
2467
2468 if (rd == 0) {
2469 /* If no destination, treat it as a NOP. */
2470 MIPS_DEBUG("NOP");
2471 return;
2472 }
2473
2474 t0 = tcg_temp_new();
2475 t1 = tcg_temp_new();
2476 gen_load_gpr(t0, rs);
2477 gen_load_gpr(t1, rt);
2478 switch (opc) {
2479 case OPC_SLT:
e68dd28f 2480 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2481 opn = "slt";
6af0bf9c 2482 break;
460f00c4 2483 case OPC_SLTU:
e68dd28f 2484 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2485 opn = "sltu";
2486 break;
2487 }
2abf314d 2488 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2489 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2490 tcg_temp_free(t0);
2491 tcg_temp_free(t1);
2492}
20c4c97c 2493
460f00c4 2494/* Shifts */
d75c135e
AJ
2495static void gen_shift(DisasContext *ctx, uint32_t opc,
2496 int rd, int rs, int rt)
460f00c4
AJ
2497{
2498 const char *opn = "shifts";
2499 TCGv t0, t1;
20c4c97c 2500
460f00c4
AJ
2501 if (rd == 0) {
2502 /* If no destination, treat it as a NOP.
2503 For add & sub, we must generate the overflow exception when needed. */
2504 MIPS_DEBUG("NOP");
2505 return;
2506 }
2507
2508 t0 = tcg_temp_new();
2509 t1 = tcg_temp_new();
2510 gen_load_gpr(t0, rs);
2511 gen_load_gpr(t1, rt);
2512 switch (opc) {
6af0bf9c 2513 case OPC_SLLV:
78723684
TS
2514 tcg_gen_andi_tl(t0, t0, 0x1f);
2515 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2516 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2517 opn = "sllv";
2518 break;
2519 case OPC_SRAV:
78723684 2520 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2521 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2522 opn = "srav";
2523 break;
2524 case OPC_SRLV:
ea63e2c3
NF
2525 tcg_gen_ext32u_tl(t1, t1);
2526 tcg_gen_andi_tl(t0, t0, 0x1f);
2527 tcg_gen_shr_tl(t0, t1, t0);
2528 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2529 opn = "srlv";
2530 break;
2531 case OPC_ROTRV:
2532 {
2533 TCGv_i32 t2 = tcg_temp_new_i32();
2534 TCGv_i32 t3 = tcg_temp_new_i32();
2535
2536 tcg_gen_trunc_tl_i32(t2, t0);
2537 tcg_gen_trunc_tl_i32(t3, t1);
2538 tcg_gen_andi_i32(t2, t2, 0x1f);
2539 tcg_gen_rotr_i32(t2, t3, t2);
2540 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2541 tcg_temp_free_i32(t2);
2542 tcg_temp_free_i32(t3);
2543 opn = "rotrv";
5a63bcb2 2544 }
7a387fff 2545 break;
d26bc211 2546#if defined(TARGET_MIPS64)
7a387fff 2547 case OPC_DSLLV:
78723684 2548 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2549 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2550 opn = "dsllv";
2551 break;
2552 case OPC_DSRAV:
78723684 2553 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2554 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2555 opn = "dsrav";
2556 break;
2557 case OPC_DSRLV:
ea63e2c3
NF
2558 tcg_gen_andi_tl(t0, t0, 0x3f);
2559 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2560 opn = "dsrlv";
2561 break;
2562 case OPC_DROTRV:
2563 tcg_gen_andi_tl(t0, t0, 0x3f);
2564 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2565 opn = "drotrv";
6af0bf9c 2566 break;
7a387fff 2567#endif
6af0bf9c 2568 }
2abf314d 2569 (void)opn; /* avoid a compiler warning */
6af0bf9c 2570 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2571 tcg_temp_free(t0);
2572 tcg_temp_free(t1);
6af0bf9c
FB
2573}
2574
2575/* Arithmetic on HI/LO registers */
7a387fff 2576static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
6af0bf9c 2577{
923617a3 2578 const char *opn = "hilo";
4133498f 2579 unsigned int acc;
6af0bf9c
FB
2580
2581 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2582 /* Treat as NOP. */
6af0bf9c 2583 MIPS_DEBUG("NOP");
a1f6684d 2584 return;
6af0bf9c 2585 }
4133498f
JL
2586
2587 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2588 acc = ((ctx->opcode) >> 21) & 0x03;
2589 } else {
2590 acc = ((ctx->opcode) >> 11) & 0x03;
2591 }
2592
2593 if (acc != 0) {
2594 check_dsp(ctx);
2595 }
2596
6af0bf9c
FB
2597 switch (opc) {
2598 case OPC_MFHI:
4133498f
JL
2599#if defined(TARGET_MIPS64)
2600 if (acc != 0) {
2601 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2602 } else
2603#endif
2604 {
2605 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2606 }
6af0bf9c
FB
2607 opn = "mfhi";
2608 break;
2609 case OPC_MFLO:
4133498f
JL
2610#if defined(TARGET_MIPS64)
2611 if (acc != 0) {
2612 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2613 } else
2614#endif
2615 {
2616 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2617 }
6af0bf9c
FB
2618 opn = "mflo";
2619 break;
2620 case OPC_MTHI:
4133498f
JL
2621 if (reg != 0) {
2622#if defined(TARGET_MIPS64)
2623 if (acc != 0) {
2624 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2625 } else
2626#endif
2627 {
2628 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2629 }
2630 } else {
2631 tcg_gen_movi_tl(cpu_HI[acc], 0);
2632 }
6af0bf9c
FB
2633 opn = "mthi";
2634 break;
2635 case OPC_MTLO:
4133498f
JL
2636 if (reg != 0) {
2637#if defined(TARGET_MIPS64)
2638 if (acc != 0) {
2639 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2640 } else
2641#endif
2642 {
2643 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2644 }
2645 } else {
2646 tcg_gen_movi_tl(cpu_LO[acc], 0);
2647 }
6af0bf9c
FB
2648 opn = "mtlo";
2649 break;
6af0bf9c 2650 }
2abf314d 2651 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2652 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2653}
2654
7a387fff 2655static void gen_muldiv (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2656 int rs, int rt)
2657{
923617a3 2658 const char *opn = "mul/div";
d45f89f4 2659 TCGv t0, t1;
4133498f 2660 unsigned int acc;
d45f89f4 2661
51127181
AJ
2662 t0 = tcg_temp_new();
2663 t1 = tcg_temp_new();
6af0bf9c 2664
78723684
TS
2665 gen_load_gpr(t0, rs);
2666 gen_load_gpr(t1, rt);
51127181 2667
6af0bf9c
FB
2668 switch (opc) {
2669 case OPC_DIV:
48d38ca5 2670 {
51127181
AJ
2671 TCGv t2 = tcg_temp_new();
2672 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2673 tcg_gen_ext32s_tl(t0, t0);
2674 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2675 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2676 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2677 tcg_gen_and_tl(t2, t2, t3);
2678 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2679 tcg_gen_or_tl(t2, t2, t3);
2680 tcg_gen_movi_tl(t3, 0);
2681 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
d45f89f4
AJ
2682 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2683 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2684 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2685 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
51127181
AJ
2686 tcg_temp_free(t3);
2687 tcg_temp_free(t2);
48d38ca5 2688 }
6af0bf9c
FB
2689 opn = "div";
2690 break;
2691 case OPC_DIVU:
48d38ca5 2692 {
51127181
AJ
2693 TCGv t2 = tcg_const_tl(0);
2694 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2695 tcg_gen_ext32u_tl(t0, t0);
2696 tcg_gen_ext32u_tl(t1, t1);
51127181 2697 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
d45f89f4
AJ
2698 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2699 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2700 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2701 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
51127181
AJ
2702 tcg_temp_free(t3);
2703 tcg_temp_free(t2);
48d38ca5 2704 }
6af0bf9c
FB
2705 opn = "divu";
2706 break;
2707 case OPC_MULT:
214c465f 2708 {
d45f89f4
AJ
2709 TCGv_i64 t2 = tcg_temp_new_i64();
2710 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2711 acc = ((ctx->opcode) >> 11) & 0x03;
2712 if (acc != 0) {
2713 check_dsp(ctx);
2714 }
d45f89f4
AJ
2715
2716 tcg_gen_ext_tl_i64(t2, t0);
2717 tcg_gen_ext_tl_i64(t3, t1);
2718 tcg_gen_mul_i64(t2, t2, t3);
2719 tcg_temp_free_i64(t3);
2720 tcg_gen_trunc_i64_tl(t0, t2);
2721 tcg_gen_shri_i64(t2, t2, 32);
2722 tcg_gen_trunc_i64_tl(t1, t2);
2723 tcg_temp_free_i64(t2);
4133498f
JL
2724 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2725 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2726 }
6af0bf9c
FB
2727 opn = "mult";
2728 break;
2729 case OPC_MULTU:
214c465f 2730 {
d45f89f4
AJ
2731 TCGv_i64 t2 = tcg_temp_new_i64();
2732 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2733 acc = ((ctx->opcode) >> 11) & 0x03;
2734 if (acc != 0) {
2735 check_dsp(ctx);
2736 }
214c465f 2737
78723684
TS
2738 tcg_gen_ext32u_tl(t0, t0);
2739 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2740 tcg_gen_extu_tl_i64(t2, t0);
2741 tcg_gen_extu_tl_i64(t3, t1);
2742 tcg_gen_mul_i64(t2, t2, t3);
2743 tcg_temp_free_i64(t3);
2744 tcg_gen_trunc_i64_tl(t0, t2);
2745 tcg_gen_shri_i64(t2, t2, 32);
2746 tcg_gen_trunc_i64_tl(t1, t2);
2747 tcg_temp_free_i64(t2);
4133498f
JL
2748 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2749 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2750 }
6af0bf9c
FB
2751 opn = "multu";
2752 break;
d26bc211 2753#if defined(TARGET_MIPS64)
7a387fff 2754 case OPC_DDIV:
48d38ca5 2755 {
51127181
AJ
2756 TCGv t2 = tcg_temp_new();
2757 TCGv t3 = tcg_temp_new();
2758 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2759 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2760 tcg_gen_and_tl(t2, t2, t3);
2761 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2762 tcg_gen_or_tl(t2, t2, t3);
2763 tcg_gen_movi_tl(t3, 0);
2764 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2765 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2766 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2767 tcg_temp_free(t3);
2768 tcg_temp_free(t2);
48d38ca5 2769 }
7a387fff
TS
2770 opn = "ddiv";
2771 break;
2772 case OPC_DDIVU:
48d38ca5 2773 {
51127181
AJ
2774 TCGv t2 = tcg_const_tl(0);
2775 TCGv t3 = tcg_const_tl(1);
2776 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
b10fa3c9
AJ
2777 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2778 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
51127181
AJ
2779 tcg_temp_free(t3);
2780 tcg_temp_free(t2);
48d38ca5 2781 }
7a387fff
TS
2782 opn = "ddivu";
2783 break;
2784 case OPC_DMULT:
895c2d04 2785 gen_helper_dmult(cpu_env, t0, t1);
7a387fff
TS
2786 opn = "dmult";
2787 break;
2788 case OPC_DMULTU:
895c2d04 2789 gen_helper_dmultu(cpu_env, t0, t1);
7a387fff
TS
2790 opn = "dmultu";
2791 break;
2792#endif
6af0bf9c 2793 case OPC_MADD:
214c465f 2794 {
d45f89f4
AJ
2795 TCGv_i64 t2 = tcg_temp_new_i64();
2796 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2797 acc = ((ctx->opcode) >> 11) & 0x03;
2798 if (acc != 0) {
2799 check_dsp(ctx);
2800 }
d45f89f4
AJ
2801
2802 tcg_gen_ext_tl_i64(t2, t0);
2803 tcg_gen_ext_tl_i64(t3, t1);
2804 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2805 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2806 tcg_gen_add_i64(t2, t2, t3);
2807 tcg_temp_free_i64(t3);
2808 tcg_gen_trunc_i64_tl(t0, t2);
2809 tcg_gen_shri_i64(t2, t2, 32);
2810 tcg_gen_trunc_i64_tl(t1, t2);
2811 tcg_temp_free_i64(t2);
4133498f
JL
2812 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2813 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2814 }
6af0bf9c
FB
2815 opn = "madd";
2816 break;
2817 case OPC_MADDU:
4133498f 2818 {
d45f89f4
AJ
2819 TCGv_i64 t2 = tcg_temp_new_i64();
2820 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2821 acc = ((ctx->opcode) >> 11) & 0x03;
2822 if (acc != 0) {
2823 check_dsp(ctx);
2824 }
214c465f 2825
78723684
TS
2826 tcg_gen_ext32u_tl(t0, t0);
2827 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2828 tcg_gen_extu_tl_i64(t2, t0);
2829 tcg_gen_extu_tl_i64(t3, t1);
2830 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2831 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2832 tcg_gen_add_i64(t2, t2, t3);
2833 tcg_temp_free_i64(t3);
2834 tcg_gen_trunc_i64_tl(t0, t2);
2835 tcg_gen_shri_i64(t2, t2, 32);
2836 tcg_gen_trunc_i64_tl(t1, t2);
2837 tcg_temp_free_i64(t2);
4133498f
JL
2838 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2839 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2840 }
6af0bf9c
FB
2841 opn = "maddu";
2842 break;
2843 case OPC_MSUB:
214c465f 2844 {
d45f89f4
AJ
2845 TCGv_i64 t2 = tcg_temp_new_i64();
2846 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2847 acc = ((ctx->opcode) >> 11) & 0x03;
2848 if (acc != 0) {
2849 check_dsp(ctx);
2850 }
d45f89f4
AJ
2851
2852 tcg_gen_ext_tl_i64(t2, t0);
2853 tcg_gen_ext_tl_i64(t3, t1);
2854 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2855 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2856 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2857 tcg_temp_free_i64(t3);
2858 tcg_gen_trunc_i64_tl(t0, t2);
2859 tcg_gen_shri_i64(t2, t2, 32);
2860 tcg_gen_trunc_i64_tl(t1, t2);
2861 tcg_temp_free_i64(t2);
4133498f
JL
2862 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2863 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2864 }
6af0bf9c
FB
2865 opn = "msub";
2866 break;
2867 case OPC_MSUBU:
214c465f 2868 {
d45f89f4
AJ
2869 TCGv_i64 t2 = tcg_temp_new_i64();
2870 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2871 acc = ((ctx->opcode) >> 11) & 0x03;
2872 if (acc != 0) {
2873 check_dsp(ctx);
2874 }
214c465f 2875
78723684
TS
2876 tcg_gen_ext32u_tl(t0, t0);
2877 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2878 tcg_gen_extu_tl_i64(t2, t0);
2879 tcg_gen_extu_tl_i64(t3, t1);
2880 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2881 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2882 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2883 tcg_temp_free_i64(t3);
2884 tcg_gen_trunc_i64_tl(t0, t2);
2885 tcg_gen_shri_i64(t2, t2, 32);
2886 tcg_gen_trunc_i64_tl(t1, t2);
2887 tcg_temp_free_i64(t2);
4133498f
JL
2888 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2889 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2890 }
6af0bf9c
FB
2891 opn = "msubu";
2892 break;
2893 default:
923617a3 2894 MIPS_INVAL(opn);
6af0bf9c 2895 generate_exception(ctx, EXCP_RI);
78723684 2896 goto out;
6af0bf9c 2897 }
2abf314d 2898 (void)opn; /* avoid a compiler warning */
6af0bf9c 2899 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2900 out:
2901 tcg_temp_free(t0);
2902 tcg_temp_free(t1);
6af0bf9c
FB
2903}
2904
e9c71dd1
TS
2905static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2906 int rd, int rs, int rt)
2907{
2908 const char *opn = "mul vr54xx";
f157bfe1
AJ
2909 TCGv t0 = tcg_temp_new();
2910 TCGv t1 = tcg_temp_new();
e9c71dd1 2911
6c5c1e20
TS
2912 gen_load_gpr(t0, rs);
2913 gen_load_gpr(t1, rt);
e9c71dd1
TS
2914
2915 switch (opc) {
2916 case OPC_VR54XX_MULS:
895c2d04 2917 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2918 opn = "muls";
6958549d 2919 break;
e9c71dd1 2920 case OPC_VR54XX_MULSU:
895c2d04 2921 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2922 opn = "mulsu";
6958549d 2923 break;
e9c71dd1 2924 case OPC_VR54XX_MACC:
895c2d04 2925 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2926 opn = "macc";
6958549d 2927 break;
e9c71dd1 2928 case OPC_VR54XX_MACCU:
895c2d04 2929 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2930 opn = "maccu";
6958549d 2931 break;
e9c71dd1 2932 case OPC_VR54XX_MSAC:
895c2d04 2933 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2934 opn = "msac";
6958549d 2935 break;
e9c71dd1 2936 case OPC_VR54XX_MSACU:
895c2d04 2937 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2938 opn = "msacu";
6958549d 2939 break;
e9c71dd1 2940 case OPC_VR54XX_MULHI:
895c2d04 2941 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2942 opn = "mulhi";
6958549d 2943 break;
e9c71dd1 2944 case OPC_VR54XX_MULHIU:
895c2d04 2945 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2946 opn = "mulhiu";
6958549d 2947 break;
e9c71dd1 2948 case OPC_VR54XX_MULSHI:
895c2d04 2949 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2950 opn = "mulshi";
6958549d 2951 break;
e9c71dd1 2952 case OPC_VR54XX_MULSHIU:
895c2d04 2953 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2954 opn = "mulshiu";
6958549d 2955 break;
e9c71dd1 2956 case OPC_VR54XX_MACCHI:
895c2d04 2957 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2958 opn = "macchi";
6958549d 2959 break;
e9c71dd1 2960 case OPC_VR54XX_MACCHIU:
895c2d04 2961 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2962 opn = "macchiu";
6958549d 2963 break;
e9c71dd1 2964 case OPC_VR54XX_MSACHI:
895c2d04 2965 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2966 opn = "msachi";
6958549d 2967 break;
e9c71dd1 2968 case OPC_VR54XX_MSACHIU:
895c2d04 2969 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2970 opn = "msachiu";
6958549d 2971 break;
e9c71dd1
TS
2972 default:
2973 MIPS_INVAL("mul vr54xx");
2974 generate_exception(ctx, EXCP_RI);
6c5c1e20 2975 goto out;
e9c71dd1 2976 }
6c5c1e20 2977 gen_store_gpr(t0, rd);
2abf314d 2978 (void)opn; /* avoid a compiler warning */
e9c71dd1 2979 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2980
2981 out:
2982 tcg_temp_free(t0);
2983 tcg_temp_free(t1);
e9c71dd1
TS
2984}
2985
7a387fff 2986static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2987 int rd, int rs)
2988{
923617a3 2989 const char *opn = "CLx";
20e1fb52 2990 TCGv t0;
6c5c1e20 2991
6af0bf9c 2992 if (rd == 0) {
ead9360e 2993 /* Treat as NOP. */
6af0bf9c 2994 MIPS_DEBUG("NOP");
20e1fb52 2995 return;
6af0bf9c 2996 }
20e1fb52 2997 t0 = tcg_temp_new();
6c5c1e20 2998 gen_load_gpr(t0, rs);
6af0bf9c
FB
2999 switch (opc) {
3000 case OPC_CLO:
20e1fb52 3001 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3002 opn = "clo";
3003 break;
3004 case OPC_CLZ:
20e1fb52 3005 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3006 opn = "clz";
3007 break;
d26bc211 3008#if defined(TARGET_MIPS64)
7a387fff 3009 case OPC_DCLO:
20e1fb52 3010 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3011 opn = "dclo";
3012 break;
3013 case OPC_DCLZ:
20e1fb52 3014 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3015 opn = "dclz";
3016 break;
3017#endif
6af0bf9c 3018 }
2abf314d 3019 (void)opn; /* avoid a compiler warning */
6af0bf9c 3020 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3021 tcg_temp_free(t0);
6af0bf9c
FB
3022}
3023
161f85e6 3024/* Godson integer instructions */
bd277fa1
RH
3025static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3026 int rd, int rs, int rt)
161f85e6
AJ
3027{
3028 const char *opn = "loongson";
3029 TCGv t0, t1;
3030
3031 if (rd == 0) {
3032 /* Treat as NOP. */
3033 MIPS_DEBUG("NOP");
3034 return;
3035 }
3036
3037 switch (opc) {
3038 case OPC_MULT_G_2E:
3039 case OPC_MULT_G_2F:
3040 case OPC_MULTU_G_2E:
3041 case OPC_MULTU_G_2F:
3042#if defined(TARGET_MIPS64)
3043 case OPC_DMULT_G_2E:
3044 case OPC_DMULT_G_2F:
3045 case OPC_DMULTU_G_2E:
3046 case OPC_DMULTU_G_2F:
3047#endif
3048 t0 = tcg_temp_new();
3049 t1 = tcg_temp_new();
3050 break;
3051 default:
3052 t0 = tcg_temp_local_new();
3053 t1 = tcg_temp_local_new();
3054 break;
3055 }
3056
3057 gen_load_gpr(t0, rs);
3058 gen_load_gpr(t1, rt);
3059
3060 switch (opc) {
3061 case OPC_MULT_G_2E:
3062 case OPC_MULT_G_2F:
3063 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3064 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3065 opn = "mult.g";
3066 break;
3067 case OPC_MULTU_G_2E:
3068 case OPC_MULTU_G_2F:
3069 tcg_gen_ext32u_tl(t0, t0);
3070 tcg_gen_ext32u_tl(t1, t1);
3071 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3072 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3073 opn = "multu.g";
3074 break;
3075 case OPC_DIV_G_2E:
3076 case OPC_DIV_G_2F:
3077 {
3078 int l1 = gen_new_label();
3079 int l2 = gen_new_label();
3080 int l3 = gen_new_label();
3081 tcg_gen_ext32s_tl(t0, t0);
3082 tcg_gen_ext32s_tl(t1, t1);
3083 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3084 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3085 tcg_gen_br(l3);
3086 gen_set_label(l1);
3087 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3089 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3090 tcg_gen_br(l3);
3091 gen_set_label(l2);
3092 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3093 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3094 gen_set_label(l3);
3095 }
3096 opn = "div.g";
3097 break;
3098 case OPC_DIVU_G_2E:
3099 case OPC_DIVU_G_2F:
3100 {
3101 int l1 = gen_new_label();
3102 int l2 = gen_new_label();
3103 tcg_gen_ext32u_tl(t0, t0);
3104 tcg_gen_ext32u_tl(t1, t1);
3105 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3106 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3107 tcg_gen_br(l2);
3108 gen_set_label(l1);
3109 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3110 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3111 gen_set_label(l2);
3112 }
3113 opn = "divu.g";
3114 break;
3115 case OPC_MOD_G_2E:
3116 case OPC_MOD_G_2F:
3117 {
3118 int l1 = gen_new_label();
3119 int l2 = gen_new_label();
3120 int l3 = gen_new_label();
3121 tcg_gen_ext32u_tl(t0, t0);
3122 tcg_gen_ext32u_tl(t1, t1);
3123 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3124 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3125 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3126 gen_set_label(l1);
3127 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3128 tcg_gen_br(l3);
3129 gen_set_label(l2);
3130 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3131 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3132 gen_set_label(l3);
3133 }
3134 opn = "mod.g";
3135 break;
3136 case OPC_MODU_G_2E:
3137 case OPC_MODU_G_2F:
3138 {
3139 int l1 = gen_new_label();
3140 int l2 = gen_new_label();
3141 tcg_gen_ext32u_tl(t0, t0);
3142 tcg_gen_ext32u_tl(t1, t1);
3143 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3144 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3145 tcg_gen_br(l2);
3146 gen_set_label(l1);
3147 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3148 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3149 gen_set_label(l2);
3150 }
3151 opn = "modu.g";
3152 break;
3153#if defined(TARGET_MIPS64)
3154 case OPC_DMULT_G_2E:
3155 case OPC_DMULT_G_2F:
3156 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3157 opn = "dmult.g";
3158 break;
3159 case OPC_DMULTU_G_2E:
3160 case OPC_DMULTU_G_2F:
3161 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3162 opn = "dmultu.g";
3163 break;
3164 case OPC_DDIV_G_2E:
3165 case OPC_DDIV_G_2F:
3166 {
3167 int l1 = gen_new_label();
3168 int l2 = gen_new_label();
3169 int l3 = gen_new_label();
3170 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3171 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3172 tcg_gen_br(l3);
3173 gen_set_label(l1);
3174 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3175 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3176 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3177 tcg_gen_br(l3);
3178 gen_set_label(l2);
3179 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3180 gen_set_label(l3);
3181 }
3182 opn = "ddiv.g";
3183 break;
3184 case OPC_DDIVU_G_2E:
3185 case OPC_DDIVU_G_2F:
3186 {
3187 int l1 = gen_new_label();
3188 int l2 = gen_new_label();
3189 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3190 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3191 tcg_gen_br(l2);
3192 gen_set_label(l1);
3193 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3194 gen_set_label(l2);
3195 }
3196 opn = "ddivu.g";
3197 break;
3198 case OPC_DMOD_G_2E:
3199 case OPC_DMOD_G_2F:
3200 {
3201 int l1 = gen_new_label();
3202 int l2 = gen_new_label();
3203 int l3 = gen_new_label();
3204 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3205 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3206 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3207 gen_set_label(l1);
3208 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3209 tcg_gen_br(l3);
3210 gen_set_label(l2);
3211 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3212 gen_set_label(l3);
3213 }
3214 opn = "dmod.g";
3215 break;
3216 case OPC_DMODU_G_2E:
3217 case OPC_DMODU_G_2F:
3218 {
3219 int l1 = gen_new_label();
3220 int l2 = gen_new_label();
3221 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3222 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3223 tcg_gen_br(l2);
3224 gen_set_label(l1);
3225 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3226 gen_set_label(l2);
3227 }
3228 opn = "dmodu.g";
3229 break;
3230#endif
3231 }
3232
2abf314d 3233 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3234 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3235 tcg_temp_free(t0);
3236 tcg_temp_free(t1);
3237}
3238
bd277fa1
RH
3239/* Loongson multimedia instructions */
3240static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3241{
3242 const char *opn = "loongson_cp2";
3243 uint32_t opc, shift_max;
3244 TCGv_i64 t0, t1;
3245
3246 opc = MASK_LMI(ctx->opcode);
3247 switch (opc) {
3248 case OPC_ADD_CP2:
3249 case OPC_SUB_CP2:
3250 case OPC_DADD_CP2:
3251 case OPC_DSUB_CP2:
3252 t0 = tcg_temp_local_new_i64();
3253 t1 = tcg_temp_local_new_i64();
3254 break;
3255 default:
3256 t0 = tcg_temp_new_i64();
3257 t1 = tcg_temp_new_i64();
3258 break;
3259 }
3260
3261 gen_load_fpr64(ctx, t0, rs);
3262 gen_load_fpr64(ctx, t1, rt);
3263
3264#define LMI_HELPER(UP, LO) \
3265 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3266#define LMI_HELPER_1(UP, LO) \
3267 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3268#define LMI_DIRECT(UP, LO, OP) \
3269 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3270
3271 switch (opc) {
3272 LMI_HELPER(PADDSH, paddsh);
3273 LMI_HELPER(PADDUSH, paddush);
3274 LMI_HELPER(PADDH, paddh);
3275 LMI_HELPER(PADDW, paddw);
3276 LMI_HELPER(PADDSB, paddsb);
3277 LMI_HELPER(PADDUSB, paddusb);
3278 LMI_HELPER(PADDB, paddb);
3279
3280 LMI_HELPER(PSUBSH, psubsh);
3281 LMI_HELPER(PSUBUSH, psubush);
3282 LMI_HELPER(PSUBH, psubh);
3283 LMI_HELPER(PSUBW, psubw);
3284 LMI_HELPER(PSUBSB, psubsb);
3285 LMI_HELPER(PSUBUSB, psubusb);
3286 LMI_HELPER(PSUBB, psubb);
3287
3288 LMI_HELPER(PSHUFH, pshufh);
3289 LMI_HELPER(PACKSSWH, packsswh);
3290 LMI_HELPER(PACKSSHB, packsshb);
3291 LMI_HELPER(PACKUSHB, packushb);
3292
3293 LMI_HELPER(PUNPCKLHW, punpcklhw);
3294 LMI_HELPER(PUNPCKHHW, punpckhhw);
3295 LMI_HELPER(PUNPCKLBH, punpcklbh);
3296 LMI_HELPER(PUNPCKHBH, punpckhbh);
3297 LMI_HELPER(PUNPCKLWD, punpcklwd);
3298 LMI_HELPER(PUNPCKHWD, punpckhwd);
3299
3300 LMI_HELPER(PAVGH, pavgh);
3301 LMI_HELPER(PAVGB, pavgb);
3302 LMI_HELPER(PMAXSH, pmaxsh);
3303 LMI_HELPER(PMINSH, pminsh);
3304 LMI_HELPER(PMAXUB, pmaxub);
3305 LMI_HELPER(PMINUB, pminub);
3306
3307 LMI_HELPER(PCMPEQW, pcmpeqw);
3308 LMI_HELPER(PCMPGTW, pcmpgtw);
3309 LMI_HELPER(PCMPEQH, pcmpeqh);
3310 LMI_HELPER(PCMPGTH, pcmpgth);
3311 LMI_HELPER(PCMPEQB, pcmpeqb);
3312 LMI_HELPER(PCMPGTB, pcmpgtb);
3313
3314 LMI_HELPER(PSLLW, psllw);
3315 LMI_HELPER(PSLLH, psllh);
3316 LMI_HELPER(PSRLW, psrlw);
3317 LMI_HELPER(PSRLH, psrlh);
3318 LMI_HELPER(PSRAW, psraw);
3319 LMI_HELPER(PSRAH, psrah);
3320
3321 LMI_HELPER(PMULLH, pmullh);
3322 LMI_HELPER(PMULHH, pmulhh);
3323 LMI_HELPER(PMULHUH, pmulhuh);
3324 LMI_HELPER(PMADDHW, pmaddhw);
3325
3326 LMI_HELPER(PASUBUB, pasubub);
3327 LMI_HELPER_1(BIADD, biadd);
3328 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3329
3330 LMI_DIRECT(PADDD, paddd, add);
3331 LMI_DIRECT(PSUBD, psubd, sub);
3332 LMI_DIRECT(XOR_CP2, xor, xor);
3333 LMI_DIRECT(NOR_CP2, nor, nor);
3334 LMI_DIRECT(AND_CP2, and, and);
3335 LMI_DIRECT(PANDN, pandn, andc);
3336 LMI_DIRECT(OR, or, or);
3337
3338 case OPC_PINSRH_0:
3339 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3340 opn = "pinsrh_0";
3341 break;
3342 case OPC_PINSRH_1:
3343 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3344 opn = "pinsrh_1";
3345 break;
3346 case OPC_PINSRH_2:
3347 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3348 opn = "pinsrh_2";
3349 break;
3350 case OPC_PINSRH_3:
3351 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3352 opn = "pinsrh_3";
3353 break;
3354
3355 case OPC_PEXTRH:
3356 tcg_gen_andi_i64(t1, t1, 3);
3357 tcg_gen_shli_i64(t1, t1, 4);
3358 tcg_gen_shr_i64(t0, t0, t1);
3359 tcg_gen_ext16u_i64(t0, t0);
3360 opn = "pextrh";
3361 break;
3362
3363 case OPC_ADDU_CP2:
3364 tcg_gen_add_i64(t0, t0, t1);
3365 tcg_gen_ext32s_i64(t0, t0);
3366 opn = "addu";
3367 break;
3368 case OPC_SUBU_CP2:
3369 tcg_gen_sub_i64(t0, t0, t1);
3370 tcg_gen_ext32s_i64(t0, t0);
3371 opn = "addu";
3372 break;
3373
3374 case OPC_SLL_CP2:
3375 opn = "sll";
3376 shift_max = 32;
3377 goto do_shift;
3378 case OPC_SRL_CP2:
3379 opn = "srl";
3380 shift_max = 32;
3381 goto do_shift;
3382 case OPC_SRA_CP2:
3383 opn = "sra";
3384 shift_max = 32;
3385 goto do_shift;
3386 case OPC_DSLL_CP2:
3387 opn = "dsll";
3388 shift_max = 64;
3389 goto do_shift;
3390 case OPC_DSRL_CP2:
3391 opn = "dsrl";
3392 shift_max = 64;
3393 goto do_shift;
3394 case OPC_DSRA_CP2:
3395 opn = "dsra";
3396 shift_max = 64;
3397 goto do_shift;
3398 do_shift:
3399 /* Make sure shift count isn't TCG undefined behaviour. */
3400 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3401
3402 switch (opc) {
3403 case OPC_SLL_CP2:
3404 case OPC_DSLL_CP2:
3405 tcg_gen_shl_i64(t0, t0, t1);
3406 break;
3407 case OPC_SRA_CP2:
3408 case OPC_DSRA_CP2:
3409 /* Since SRA is UndefinedResult without sign-extended inputs,
3410 we can treat SRA and DSRA the same. */
3411 tcg_gen_sar_i64(t0, t0, t1);
3412 break;
3413 case OPC_SRL_CP2:
3414 /* We want to shift in zeros for SRL; zero-extend first. */
3415 tcg_gen_ext32u_i64(t0, t0);
3416 /* FALLTHRU */
3417 case OPC_DSRL_CP2:
3418 tcg_gen_shr_i64(t0, t0, t1);
3419 break;
3420 }
3421
3422 if (shift_max == 32) {
3423 tcg_gen_ext32s_i64(t0, t0);
3424 }
3425
3426 /* Shifts larger than MAX produce zero. */
3427 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3428 tcg_gen_neg_i64(t1, t1);
3429 tcg_gen_and_i64(t0, t0, t1);
3430 break;
3431
3432 case OPC_ADD_CP2:
3433 case OPC_DADD_CP2:
3434 {
3435 TCGv_i64 t2 = tcg_temp_new_i64();
3436 int lab = gen_new_label();
3437
3438 tcg_gen_mov_i64(t2, t0);
3439 tcg_gen_add_i64(t0, t1, t2);
3440 if (opc == OPC_ADD_CP2) {
3441 tcg_gen_ext32s_i64(t0, t0);
3442 }
3443 tcg_gen_xor_i64(t1, t1, t2);
3444 tcg_gen_xor_i64(t2, t2, t0);
3445 tcg_gen_andc_i64(t1, t2, t1);
3446 tcg_temp_free_i64(t2);
3447 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3448 generate_exception(ctx, EXCP_OVERFLOW);
3449 gen_set_label(lab);
3450
3451 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3452 break;
3453 }
3454
3455 case OPC_SUB_CP2:
3456 case OPC_DSUB_CP2:
3457 {
3458 TCGv_i64 t2 = tcg_temp_new_i64();
3459 int lab = gen_new_label();
3460
3461 tcg_gen_mov_i64(t2, t0);
3462 tcg_gen_sub_i64(t0, t1, t2);
3463 if (opc == OPC_SUB_CP2) {
3464 tcg_gen_ext32s_i64(t0, t0);
3465 }
3466 tcg_gen_xor_i64(t1, t1, t2);
3467 tcg_gen_xor_i64(t2, t2, t0);
3468 tcg_gen_and_i64(t1, t1, t2);
3469 tcg_temp_free_i64(t2);
3470 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3471 generate_exception(ctx, EXCP_OVERFLOW);
3472 gen_set_label(lab);
3473
3474 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3475 break;
3476 }
3477
3478 case OPC_PMULUW:
3479 tcg_gen_ext32u_i64(t0, t0);
3480 tcg_gen_ext32u_i64(t1, t1);
3481 tcg_gen_mul_i64(t0, t0, t1);
3482 opn = "pmuluw";
3483 break;
3484
3485 case OPC_SEQU_CP2:
3486 case OPC_SEQ_CP2:
3487 case OPC_SLTU_CP2:
3488 case OPC_SLT_CP2:
3489 case OPC_SLEU_CP2:
3490 case OPC_SLE_CP2:
3491 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3492 FD field is the CC field? */
3493 default:
3494 MIPS_INVAL(opn);
3495 generate_exception(ctx, EXCP_RI);
3496 return;
3497 }
3498
3499#undef LMI_HELPER
3500#undef LMI_DIRECT
3501
3502 gen_store_fpr64(ctx, t0, rd);
3503
3504 (void)opn; /* avoid a compiler warning */
3505 MIPS_DEBUG("%s %s, %s, %s", opn,
3506 fregnames[rd], fregnames[rs], fregnames[rt]);
3507 tcg_temp_free_i64(t0);
3508 tcg_temp_free_i64(t1);
3509}
3510
6af0bf9c 3511/* Traps */
7a387fff 3512static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3513 int rs, int rt, int16_t imm)
3514{
3515 int cond;
cdc0faa6 3516 TCGv t0 = tcg_temp_new();
1ba74fb8 3517 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3518
3519 cond = 0;
3520 /* Load needed operands */
3521 switch (opc) {
3522 case OPC_TEQ:
3523 case OPC_TGE:
3524 case OPC_TGEU:
3525 case OPC_TLT:
3526 case OPC_TLTU:
3527 case OPC_TNE:
3528 /* Compare two registers */
3529 if (rs != rt) {
be24bb4f
TS
3530 gen_load_gpr(t0, rs);
3531 gen_load_gpr(t1, rt);
6af0bf9c
FB
3532 cond = 1;
3533 }
179e32bb 3534 break;
6af0bf9c
FB
3535 case OPC_TEQI:
3536 case OPC_TGEI:
3537 case OPC_TGEIU:
3538 case OPC_TLTI:
3539 case OPC_TLTIU:
3540 case OPC_TNEI:
3541 /* Compare register to immediate */
3542 if (rs != 0 || imm != 0) {
be24bb4f
TS
3543 gen_load_gpr(t0, rs);
3544 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3545 cond = 1;
3546 }
3547 break;
3548 }
3549 if (cond == 0) {
3550 switch (opc) {
3551 case OPC_TEQ: /* rs == rs */
3552 case OPC_TEQI: /* r0 == 0 */
3553 case OPC_TGE: /* rs >= rs */
3554 case OPC_TGEI: /* r0 >= 0 */
3555 case OPC_TGEU: /* rs >= rs unsigned */
3556 case OPC_TGEIU: /* r0 >= 0 unsigned */
3557 /* Always trap */
cdc0faa6 3558 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3559 break;
3560 case OPC_TLT: /* rs < rs */
3561 case OPC_TLTI: /* r0 < 0 */
3562 case OPC_TLTU: /* rs < rs unsigned */
3563 case OPC_TLTIU: /* r0 < 0 unsigned */
3564 case OPC_TNE: /* rs != rs */
3565 case OPC_TNEI: /* r0 != 0 */
ead9360e 3566 /* Never trap: treat as NOP. */
cdc0faa6 3567 break;
6af0bf9c
FB
3568 }
3569 } else {
cdc0faa6
AJ
3570 int l1 = gen_new_label();
3571
6af0bf9c
FB
3572 switch (opc) {
3573 case OPC_TEQ:
3574 case OPC_TEQI:
cdc0faa6 3575 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3576 break;
3577 case OPC_TGE:
3578 case OPC_TGEI:
cdc0faa6 3579 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3580 break;
3581 case OPC_TGEU:
3582 case OPC_TGEIU:
cdc0faa6 3583 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3584 break;
3585 case OPC_TLT:
3586 case OPC_TLTI:
cdc0faa6 3587 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3588 break;
3589 case OPC_TLTU:
3590 case OPC_TLTIU:
cdc0faa6 3591 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3592 break;
3593 case OPC_TNE:
3594 case OPC_TNEI:
cdc0faa6 3595 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3596 break;
6af0bf9c 3597 }
cdc0faa6 3598 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3599 gen_set_label(l1);
3600 }
be24bb4f
TS
3601 tcg_temp_free(t0);
3602 tcg_temp_free(t1);
6af0bf9c
FB
3603}
3604
356265ae 3605static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3606{
6e256c93
FB
3607 TranslationBlock *tb;
3608 tb = ctx->tb;
7b270ef2
NF
3609 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3610 likely(!ctx->singlestep_enabled)) {
57fec1fe 3611 tcg_gen_goto_tb(n);
9b9e4393 3612 gen_save_pc(dest);
4b4a72e5 3613 tcg_gen_exit_tb((tcg_target_long)tb + n);
6e256c93 3614 } else {
9b9e4393 3615 gen_save_pc(dest);
7b270ef2
NF
3616 if (ctx->singlestep_enabled) {
3617 save_cpu_state(ctx, 0);
895c2d04 3618 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3619 }
57fec1fe 3620 tcg_gen_exit_tb(0);
6e256c93 3621 }
c53be334
FB
3622}
3623
6af0bf9c 3624/* Branches (before delay slot) */
7a387fff 3625static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3626 int insn_bytes,
6af0bf9c
FB
3627 int rs, int rt, int32_t offset)
3628{
d077b6f7 3629 target_ulong btgt = -1;
3ad4bb2d 3630 int blink = 0;
2fdbad25 3631 int bcond_compute = 0;
1ba74fb8
AJ
3632 TCGv t0 = tcg_temp_new();
3633 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3634
3635 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3636#ifdef MIPS_DEBUG_DISAS
d12d51d5 3637 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3638#endif
3ad4bb2d 3639 generate_exception(ctx, EXCP_RI);
6c5c1e20 3640 goto out;
3ad4bb2d 3641 }
6af0bf9c 3642
6af0bf9c
FB
3643 /* Load needed operands */
3644 switch (opc) {
3645 case OPC_BEQ:
3646 case OPC_BEQL:
3647 case OPC_BNE:
3648 case OPC_BNEL:
3649 /* Compare two registers */
3650 if (rs != rt) {
6c5c1e20
TS
3651 gen_load_gpr(t0, rs);
3652 gen_load_gpr(t1, rt);
2fdbad25 3653 bcond_compute = 1;
6af0bf9c 3654 }
7dca4ad0 3655 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3656 break;
3657 case OPC_BGEZ:
3658 case OPC_BGEZAL:
3c824109 3659 case OPC_BGEZALS:
6af0bf9c
FB
3660 case OPC_BGEZALL:
3661 case OPC_BGEZL:
3662 case OPC_BGTZ:
3663 case OPC_BGTZL:
3664 case OPC_BLEZ:
3665 case OPC_BLEZL:
3666 case OPC_BLTZ:
3667 case OPC_BLTZAL:
3c824109 3668 case OPC_BLTZALS:
6af0bf9c
FB
3669 case OPC_BLTZALL:
3670 case OPC_BLTZL:
3671 /* Compare to zero */
3672 if (rs != 0) {
6c5c1e20 3673 gen_load_gpr(t0, rs);
2fdbad25 3674 bcond_compute = 1;
6af0bf9c 3675 }
7dca4ad0 3676 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3677 break;
e45a93e2
JL
3678 case OPC_BPOSGE32:
3679#if defined(TARGET_MIPS64)
3680 case OPC_BPOSGE64:
3681 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3682#else
3683 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3684#endif
3685 bcond_compute = 1;
3686 btgt = ctx->pc + insn_bytes + offset;
3687 break;
6af0bf9c
FB
3688 case OPC_J:
3689 case OPC_JAL:
364d4831 3690 case OPC_JALX:
620e48f6
NF
3691 case OPC_JALS:
3692 case OPC_JALXS:
6af0bf9c 3693 /* Jump to immediate */
7dca4ad0 3694 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3695 break;
3696 case OPC_JR:
3697 case OPC_JALR:
364d4831 3698 case OPC_JALRC:
620e48f6 3699 case OPC_JALRS:
6af0bf9c 3700 /* Jump to register */
7a387fff
TS
3701 if (offset != 0 && offset != 16) {
3702 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3703 others are reserved. */
923617a3 3704 MIPS_INVAL("jump hint");
6af0bf9c 3705 generate_exception(ctx, EXCP_RI);
6c5c1e20 3706 goto out;
6af0bf9c 3707 }
d077b6f7 3708 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3709 break;
3710 default:
3711 MIPS_INVAL("branch/jump");
3712 generate_exception(ctx, EXCP_RI);
6c5c1e20 3713 goto out;
6af0bf9c 3714 }
2fdbad25 3715 if (bcond_compute == 0) {
6af0bf9c
FB
3716 /* No condition to be computed */
3717 switch (opc) {
3718 case OPC_BEQ: /* rx == rx */
3719 case OPC_BEQL: /* rx == rx likely */
3720 case OPC_BGEZ: /* 0 >= 0 */
3721 case OPC_BGEZL: /* 0 >= 0 likely */
3722 case OPC_BLEZ: /* 0 <= 0 */
3723 case OPC_BLEZL: /* 0 <= 0 likely */
3724 /* Always take */
4ad40f36 3725 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3726 MIPS_DEBUG("balways");
3727 break;
3c824109 3728 case OPC_BGEZALS:
6af0bf9c
FB
3729 case OPC_BGEZAL: /* 0 >= 0 */
3730 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3731 ctx->hflags |= (opc == OPC_BGEZALS
3732 ? MIPS_HFLAG_BDS16
3733 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3734 /* Always take and link */
3735 blink = 31;
4ad40f36 3736 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3737 MIPS_DEBUG("balways and link");
3738 break;
3739 case OPC_BNE: /* rx != rx */
3740 case OPC_BGTZ: /* 0 > 0 */
3741 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3742 /* Treat as NOP. */
6af0bf9c 3743 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3744 goto out;
3c824109 3745 case OPC_BLTZALS:
eeef26cd 3746 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3747 ctx->hflags |= (opc == OPC_BLTZALS
3748 ? MIPS_HFLAG_BDS16
3749 : MIPS_HFLAG_BDS32);
3750 /* Handle as an unconditional branch to get correct delay
3751 slot checking. */
3752 blink = 31;
3753 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3754 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3755 MIPS_DEBUG("bnever and link");
3c824109 3756 break;
eeef26cd 3757 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3758 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3759 /* Skip the instruction in the delay slot */
3760 MIPS_DEBUG("bnever, link and skip");
3761 ctx->pc += 4;
6c5c1e20 3762 goto out;
6af0bf9c
FB
3763 case OPC_BNEL: /* rx != rx likely */
3764 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3765 case OPC_BLTZL: /* 0 < 0 likely */
3766 /* Skip the instruction in the delay slot */
3767 MIPS_DEBUG("bnever and skip");
9898128f 3768 ctx->pc += 4;
6c5c1e20 3769 goto out;
6af0bf9c 3770 case OPC_J:
4ad40f36 3771 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3772 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3773 break;
620e48f6 3774 case OPC_JALXS:
364d4831
NF
3775 case OPC_JALX:
3776 ctx->hflags |= MIPS_HFLAG_BX;
3777 /* Fallthrough */
620e48f6 3778 case OPC_JALS:
6af0bf9c
FB
3779 case OPC_JAL:
3780 blink = 31;
4ad40f36 3781 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3782 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3783 ? MIPS_HFLAG_BDS16
3784 : MIPS_HFLAG_BDS32);
d077b6f7 3785 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3786 break;
3787 case OPC_JR:
4ad40f36 3788 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3789 if (insn_bytes == 4)
3790 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3791 MIPS_DEBUG("jr %s", regnames[rs]);
3792 break;
620e48f6 3793 case OPC_JALRS:
6af0bf9c 3794 case OPC_JALR:
364d4831 3795 case OPC_JALRC:
6af0bf9c 3796 blink = rt;
4ad40f36 3797 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3798 ctx->hflags |= (opc == OPC_JALRS
3799 ? MIPS_HFLAG_BDS16
3800 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3801 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3802 break;
3803 default:
3804 MIPS_INVAL("branch/jump");
3805 generate_exception(ctx, EXCP_RI);
6c5c1e20 3806 goto out;
6af0bf9c
FB
3807 }
3808 } else {
3809 switch (opc) {
3810 case OPC_BEQ:
e68dd28f 3811 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3812 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3813 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3814 goto not_likely;
3815 case OPC_BEQL:
e68dd28f 3816 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3817 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3818 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3819 goto likely;
3820 case OPC_BNE:
e68dd28f 3821 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3822 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3823 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3824 goto not_likely;
3825 case OPC_BNEL:
e68dd28f 3826 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3827 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3828 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3829 goto likely;
3830 case OPC_BGEZ:
e68dd28f 3831 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3832 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3833 goto not_likely;
3834 case OPC_BGEZL:
e68dd28f 3835 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3836 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3837 goto likely;
3c824109 3838 case OPC_BGEZALS:
6af0bf9c 3839 case OPC_BGEZAL:
3c824109
NF
3840 ctx->hflags |= (opc == OPC_BGEZALS
3841 ? MIPS_HFLAG_BDS16
3842 : MIPS_HFLAG_BDS32);
e68dd28f 3843 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3844 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3845 blink = 31;
3846 goto not_likely;
3847 case OPC_BGEZALL:
e68dd28f 3848 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3849 blink = 31;
d077b6f7 3850 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3851 goto likely;
3852 case OPC_BGTZ:
e68dd28f 3853 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3854 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3855 goto not_likely;
3856 case OPC_BGTZL:
e68dd28f 3857 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3858 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3859 goto likely;
3860 case OPC_BLEZ:
e68dd28f 3861 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3862 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3863 goto not_likely;
3864 case OPC_BLEZL:
e68dd28f 3865 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3866 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3867 goto likely;
3868 case OPC_BLTZ:
e68dd28f 3869 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3870 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3871 goto not_likely;
3872 case OPC_BLTZL:
e68dd28f 3873 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3874 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3875 goto likely;
e45a93e2
JL
3876 case OPC_BPOSGE32:
3877 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3878 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3879 goto not_likely;
3880#if defined(TARGET_MIPS64)
3881 case OPC_BPOSGE64:
3882 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3883 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3884 goto not_likely;
3885#endif
3c824109 3886 case OPC_BLTZALS:
6af0bf9c 3887 case OPC_BLTZAL:
3c824109
NF
3888 ctx->hflags |= (opc == OPC_BLTZALS
3889 ? MIPS_HFLAG_BDS16
3890 : MIPS_HFLAG_BDS32);
e68dd28f 3891 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3892 blink = 31;
d077b6f7 3893 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3894 not_likely:
4ad40f36 3895 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3896 break;
3897 case OPC_BLTZALL:
e68dd28f 3898 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3899 blink = 31;
d077b6f7 3900 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3901 likely:
4ad40f36 3902 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3903 break;
c53f4a62
TS
3904 default:
3905 MIPS_INVAL("conditional branch/jump");
3906 generate_exception(ctx, EXCP_RI);
6c5c1e20 3907 goto out;
6af0bf9c 3908 }
6af0bf9c 3909 }
923617a3 3910 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3911 blink, ctx->hflags, btgt);
9b9e4393 3912
d077b6f7 3913 ctx->btarget = btgt;
6af0bf9c 3914 if (blink > 0) {
364d4831
NF
3915 int post_delay = insn_bytes;
3916 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3917
3918 if (opc != OPC_JALRC)
3919 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3920
3921 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3922 }
6c5c1e20
TS
3923
3924 out:
364d4831
NF
3925 if (insn_bytes == 2)
3926 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3927 tcg_temp_free(t0);
3928 tcg_temp_free(t1);
6af0bf9c
FB
3929}
3930
7a387fff
TS
3931/* special3 bitfield operations */
3932static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3933 int rs, int lsb, int msb)
7a387fff 3934{
a7812ae4
PB
3935 TCGv t0 = tcg_temp_new();
3936 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3937
3938 gen_load_gpr(t1, rs);
7a387fff
TS
3939 switch (opc) {
3940 case OPC_EXT:
3941 if (lsb + msb > 31)
3942 goto fail;
505ad7c2
AJ
3943 tcg_gen_shri_tl(t0, t1, lsb);
3944 if (msb != 31) {
3945 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3946 } else {
3947 tcg_gen_ext32s_tl(t0, t0);
3948 }
7a387fff 3949 break;
c6d6dd7c 3950#if defined(TARGET_MIPS64)
7a387fff 3951 case OPC_DEXTM:
505ad7c2
AJ
3952 tcg_gen_shri_tl(t0, t1, lsb);
3953 if (msb != 31) {
3954 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3955 }
7a387fff
TS
3956 break;
3957 case OPC_DEXTU:
505ad7c2
AJ
3958 tcg_gen_shri_tl(t0, t1, lsb + 32);
3959 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3960 break;
3961 case OPC_DEXT:
505ad7c2
AJ
3962 tcg_gen_shri_tl(t0, t1, lsb);
3963 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3964 break;
c6d6dd7c 3965#endif
7a387fff
TS
3966 case OPC_INS:
3967 if (lsb > msb)
3968 goto fail;
6c5c1e20 3969 gen_load_gpr(t0, rt);
e0d002f1 3970 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3971 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3972 break;
c6d6dd7c 3973#if defined(TARGET_MIPS64)
7a387fff 3974 case OPC_DINSM:
6c5c1e20 3975 gen_load_gpr(t0, rt);
e0d002f1 3976 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3977 break;
3978 case OPC_DINSU:
6c5c1e20 3979 gen_load_gpr(t0, rt);
e0d002f1 3980 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3981 break;
3982 case OPC_DINS:
6c5c1e20 3983 gen_load_gpr(t0, rt);
e0d002f1 3984 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3985 break;
c6d6dd7c 3986#endif
7a387fff
TS
3987 default:
3988fail:
3989 MIPS_INVAL("bitops");
3990 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3991 tcg_temp_free(t0);
3992 tcg_temp_free(t1);
7a387fff
TS
3993 return;
3994 }
6c5c1e20
TS
3995 gen_store_gpr(t0, rt);
3996 tcg_temp_free(t0);
3997 tcg_temp_free(t1);
7a387fff
TS
3998}
3999
49bcf33c
AJ
4000static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4001{
3a55fa47 4002 TCGv t0;
49bcf33c 4003
3a55fa47
AJ
4004 if (rd == 0) {
4005 /* If no destination, treat it as a NOP. */
4006 MIPS_DEBUG("NOP");
4007 return;
4008 }
4009
4010 t0 = tcg_temp_new();
4011 gen_load_gpr(t0, rt);
49bcf33c
AJ
4012 switch (op2) {
4013 case OPC_WSBH:
3a55fa47
AJ
4014 {
4015 TCGv t1 = tcg_temp_new();
4016
4017 tcg_gen_shri_tl(t1, t0, 8);
4018 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4019 tcg_gen_shli_tl(t0, t0, 8);
4020 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4021 tcg_gen_or_tl(t0, t0, t1);
4022 tcg_temp_free(t1);
4023 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4024 }
49bcf33c
AJ
4025 break;
4026 case OPC_SEB:
3a55fa47 4027 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4028 break;
4029 case OPC_SEH:
3a55fa47 4030 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4031 break;
4032#if defined(TARGET_MIPS64)
4033 case OPC_DSBH:
3a55fa47
AJ
4034 {
4035 TCGv t1 = tcg_temp_new();
4036
4037 tcg_gen_shri_tl(t1, t0, 8);
4038 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4039 tcg_gen_shli_tl(t0, t0, 8);
4040 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4041 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4042 tcg_temp_free(t1);
4043 }
49bcf33c
AJ
4044 break;
4045 case OPC_DSHD:
3a55fa47
AJ
4046 {
4047 TCGv t1 = tcg_temp_new();
4048
4049 tcg_gen_shri_tl(t1, t0, 16);
4050 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4051 tcg_gen_shli_tl(t0, t0, 16);
4052 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4053 tcg_gen_or_tl(t0, t0, t1);
4054 tcg_gen_shri_tl(t1, t0, 32);
4055 tcg_gen_shli_tl(t0, t0, 32);
4056 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4057 tcg_temp_free(t1);
4058 }
49bcf33c
AJ
4059 break;
4060#endif
4061 default:
4062 MIPS_INVAL("bsfhl");
4063 generate_exception(ctx, EXCP_RI);
4064 tcg_temp_free(t0);
49bcf33c
AJ
4065 return;
4066 }
49bcf33c 4067 tcg_temp_free(t0);
49bcf33c
AJ
4068}
4069
f1aa6320 4070#ifndef CONFIG_USER_ONLY
0eaef5aa 4071/* CP0 (MMU and control) */
d9bea114 4072static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4073{
d9bea114 4074 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4075
d9bea114
AJ
4076 tcg_gen_ld_i32(t0, cpu_env, off);
4077 tcg_gen_ext_i32_tl(arg, t0);
4078 tcg_temp_free_i32(t0);
4f57689a
TS
4079}
4080
d9bea114 4081static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4082{
d9bea114
AJ
4083 tcg_gen_ld_tl(arg, cpu_env, off);
4084 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4085}
4086
d9bea114 4087static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4088{
d9bea114 4089 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4090
d9bea114
AJ
4091 tcg_gen_trunc_tl_i32(t0, arg);
4092 tcg_gen_st_i32(t0, cpu_env, off);
4093 tcg_temp_free_i32(t0);
f1aa6320
TS
4094}
4095
d9bea114 4096static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4097{
d9bea114
AJ
4098 tcg_gen_ext32s_tl(arg, arg);
4099 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4100}
4101
d75c135e 4102static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4103{
7a387fff 4104 const char *rn = "invalid";
873eb012 4105
e189e748 4106 if (sel != 0)
d75c135e 4107 check_insn(ctx, ISA_MIPS32);
e189e748 4108
873eb012
TS
4109 switch (reg) {
4110 case 0:
7a387fff
TS
4111 switch (sel) {
4112 case 0:
7db13fae 4113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4114 rn = "Index";
4115 break;
4116 case 1:
d75c135e 4117 check_insn(ctx, ASE_MT);
895c2d04 4118 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4119 rn = "MVPControl";
ead9360e 4120 break;
7a387fff 4121 case 2:
d75c135e 4122 check_insn(ctx, ASE_MT);
895c2d04 4123 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4124 rn = "MVPConf0";
ead9360e 4125 break;
7a387fff 4126 case 3:
d75c135e 4127 check_insn(ctx, ASE_MT);
895c2d04 4128 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4129 rn = "MVPConf1";
ead9360e 4130 break;
7a387fff
TS
4131 default:
4132 goto die;
4133 }
873eb012
TS
4134 break;
4135 case 1:
7a387fff
TS
4136 switch (sel) {
4137 case 0:
895c2d04 4138 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4139 rn = "Random";
2423f660 4140 break;
7a387fff 4141 case 1:
d75c135e 4142 check_insn(ctx, ASE_MT);
7db13fae 4143 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4144 rn = "VPEControl";
ead9360e 4145 break;
7a387fff 4146 case 2:
d75c135e 4147 check_insn(ctx, ASE_MT);
7db13fae 4148 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4149 rn = "VPEConf0";
ead9360e 4150 break;
7a387fff 4151 case 3:
d75c135e 4152 check_insn(ctx, ASE_MT);
7db13fae 4153 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4154 rn = "VPEConf1";
ead9360e 4155 break;
7a387fff 4156 case 4:
d75c135e 4157 check_insn(ctx, ASE_MT);
7db13fae 4158 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4159 rn = "YQMask";
ead9360e 4160 break;
7a387fff 4161 case 5:
d75c135e 4162 check_insn(ctx, ASE_MT);
7db13fae 4163 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4164 rn = "VPESchedule";
ead9360e 4165 break;
7a387fff 4166 case 6:
d75c135e 4167 check_insn(ctx, ASE_MT);
7db13fae 4168 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4169 rn = "VPEScheFBack";
ead9360e 4170 break;
7a387fff 4171 case 7:
d75c135e 4172 check_insn(ctx, ASE_MT);
7db13fae 4173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4174 rn = "VPEOpt";
ead9360e 4175 break;
7a387fff
TS
4176 default:
4177 goto die;
4178 }
873eb012
TS
4179 break;
4180 case 2:
7a387fff
TS
4181 switch (sel) {
4182 case 0:
7db13fae 4183 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4184 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4185 rn = "EntryLo0";
4186 break;
7a387fff 4187 case 1:
d75c135e 4188 check_insn(ctx, ASE_MT);
895c2d04 4189 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4190 rn = "TCStatus";
ead9360e 4191 break;
7a387fff 4192 case 2:
d75c135e 4193 check_insn(ctx, ASE_MT);
895c2d04 4194 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4195 rn = "TCBind";
ead9360e 4196 break;
7a387fff 4197 case 3:
d75c135e 4198 check_insn(ctx, ASE_MT);
895c2d04 4199 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4200 rn = "TCRestart";
ead9360e 4201 break;
7a387fff 4202 case 4:
d75c135e 4203 check_insn(ctx, ASE_MT);
895c2d04 4204 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4205 rn = "TCHalt";
ead9360e 4206 break;
7a387fff 4207 case 5:
d75c135e 4208 check_insn(ctx, ASE_MT);
895c2d04 4209 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4210 rn = "TCContext";
ead9360e 4211 break;
7a387fff 4212 case 6:
d75c135e 4213 check_insn(ctx, ASE_MT);
895c2d04 4214 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4215 rn = "TCSchedule";
ead9360e 4216 break;
7a387fff 4217 case 7:
d75c135e 4218 check_insn(ctx, ASE_MT);
895c2d04 4219 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4220 rn = "TCScheFBack";
ead9360e 4221 break;
7a387fff
TS
4222 default:
4223 goto die;
4224 }
873eb012
TS
4225 break;
4226 case 3:
7a387fff
TS
4227 switch (sel) {
4228 case 0:
7db13fae 4229 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4230 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4231 rn = "EntryLo1";
4232 break;
7a387fff
TS
4233 default:
4234 goto die;
1579a72e 4235 }
873eb012
TS
4236 break;
4237 case 4:
7a387fff
TS
4238 switch (sel) {
4239 case 0:
7db13fae 4240 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4241 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4242 rn = "Context";
4243 break;
7a387fff 4244 case 1:
d9bea114 4245// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4246 rn = "ContextConfig";
4247// break;
7a387fff
TS
4248 default:
4249 goto die;
1579a72e 4250 }
873eb012
TS
4251 break;
4252 case 5:
7a387fff
TS
4253 switch (sel) {
4254 case 0:
7db13fae 4255 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4256 rn = "PageMask";
4257 break;
7a387fff 4258 case 1:
d75c135e 4259 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4261 rn = "PageGrain";
4262 break;
7a387fff
TS
4263 default:
4264 goto die;
1579a72e 4265 }
873eb012
TS
4266 break;
4267 case 6:
7a387fff
TS
4268 switch (sel) {
4269 case 0:
7db13fae 4270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4271 rn = "Wired";
4272 break;
7a387fff 4273 case 1:
d75c135e 4274 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4275 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4276 rn = "SRSConf0";
ead9360e 4277 break;
7a387fff 4278 case 2:
d75c135e 4279 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4280 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4281 rn = "SRSConf1";
ead9360e 4282 break;
7a387fff 4283 case 3:
d75c135e 4284 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4285 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4286 rn = "SRSConf2";
ead9360e 4287 break;
7a387fff 4288 case 4:
d75c135e 4289 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4291 rn = "SRSConf3";
ead9360e 4292 break;
7a387fff 4293 case 5:
d75c135e 4294 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4296 rn = "SRSConf4";
ead9360e 4297 break;
7a387fff
TS
4298 default:
4299 goto die;
1579a72e 4300 }
873eb012 4301 break;
8c0fdd85 4302 case 7:
7a387fff
TS
4303 switch (sel) {
4304 case 0:
d75c135e 4305 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4307 rn = "HWREna";
4308 break;
7a387fff
TS
4309 default:
4310 goto die;
1579a72e 4311 }
8c0fdd85 4312 break;
873eb012 4313 case 8:
7a387fff
TS
4314 switch (sel) {
4315 case 0:
7db13fae 4316 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4317 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4318 rn = "BadVAddr";
2423f660 4319 break;
7a387fff
TS
4320 default:
4321 goto die;
4322 }
873eb012
TS
4323 break;
4324 case 9:
7a387fff
TS
4325 switch (sel) {
4326 case 0:
2e70f6ef
PB
4327 /* Mark as an IO operation because we read the time. */
4328 if (use_icount)
4329 gen_io_start();
895c2d04 4330 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4331 if (use_icount) {
4332 gen_io_end();
2e70f6ef 4333 }
55807224
EI
4334 /* Break the TB to be able to take timer interrupts immediately
4335 after reading count. */
4336 ctx->bstate = BS_STOP;
2423f660
TS
4337 rn = "Count";
4338 break;
4339 /* 6,7 are implementation dependent */
7a387fff
TS
4340 default:
4341 goto die;
2423f660 4342 }
873eb012
TS
4343 break;
4344 case 10:
7a387fff
TS
4345 switch (sel) {
4346 case 0:
7db13fae 4347 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4348 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4349 rn = "EntryHi";
4350 break;
7a387fff
TS
4351 default:
4352 goto die;
1579a72e 4353 }
873eb012
TS
4354 break;
4355 case 11:
7a387fff
TS
4356 switch (sel) {
4357 case 0:
7db13fae 4358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4359 rn = "Compare";
4360 break;
4361 /* 6,7 are implementation dependent */
7a387fff
TS
4362 default:
4363 goto die;
2423f660 4364 }
873eb012
TS
4365 break;
4366 case 12:
7a387fff
TS
4367 switch (sel) {
4368 case 0:
7db13fae 4369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4370 rn = "Status";
4371 break;
7a387fff 4372 case 1:
d75c135e 4373 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4375 rn = "IntCtl";
4376 break;
7a387fff 4377 case 2:
d75c135e 4378 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4380 rn = "SRSCtl";
4381 break;
7a387fff 4382 case 3:
d75c135e 4383 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4385 rn = "SRSMap";
fd88b6ab 4386 break;
7a387fff
TS
4387 default:
4388 goto die;
4389 }
873eb012
TS
4390 break;
4391 case 13:
7a387fff
TS
4392 switch (sel) {
4393 case 0:
7db13fae 4394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4395 rn = "Cause";
4396 break;
7a387fff
TS
4397 default:
4398 goto die;
4399 }
873eb012
TS
4400 break;
4401 case 14:
7a387fff
TS
4402 switch (sel) {
4403 case 0:
7db13fae 4404 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4405 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4406 rn = "EPC";
4407 break;
7a387fff
TS
4408 default:
4409 goto die;
1579a72e 4410 }
873eb012
TS
4411 break;
4412 case 15:
7a387fff
TS
4413 switch (sel) {
4414 case 0:
7db13fae 4415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4416 rn = "PRid";
4417 break;
7a387fff 4418 case 1:
d75c135e 4419 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4421 rn = "EBase";
4422 break;
7a387fff
TS
4423 default:
4424 goto die;
4425 }
873eb012
TS
4426 break;
4427 case 16:
4428 switch (sel) {
4429 case 0:
7db13fae 4430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4431 rn = "Config";
4432 break;
4433 case 1:
7db13fae 4434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4435 rn = "Config1";
4436 break;
7a387fff 4437 case 2:
7db13fae 4438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4439 rn = "Config2";
4440 break;
4441 case 3:
7db13fae 4442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4443 rn = "Config3";
4444 break;
e397ee33
TS
4445 /* 4,5 are reserved */
4446 /* 6,7 are implementation dependent */
4447 case 6:
7db13fae 4448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4449 rn = "Config6";
4450 break;
4451 case 7:
7db13fae 4452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4453 rn = "Config7";
4454 break;
873eb012 4455 default:
873eb012
TS
4456 goto die;
4457 }
4458 break;
4459 case 17:
7a387fff
TS
4460 switch (sel) {
4461 case 0:
895c2d04 4462 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4463 rn = "LLAddr";
4464 break;
7a387fff
TS
4465 default:
4466 goto die;
4467 }
873eb012
TS
4468 break;
4469 case 18:
7a387fff 4470 switch (sel) {
fd88b6ab 4471 case 0 ... 7:
895c2d04 4472 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4473 rn = "WatchLo";
4474 break;
7a387fff
TS
4475 default:
4476 goto die;
4477 }
873eb012
TS
4478 break;
4479 case 19:
7a387fff 4480 switch (sel) {
fd88b6ab 4481 case 0 ...7:
895c2d04 4482 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4483 rn = "WatchHi";
4484 break;
7a387fff
TS
4485 default:
4486 goto die;
4487 }
873eb012 4488 break;
8c0fdd85 4489 case 20:
7a387fff
TS
4490 switch (sel) {
4491 case 0:
d26bc211 4492#if defined(TARGET_MIPS64)
d75c135e 4493 check_insn(ctx, ISA_MIPS3);
7db13fae 4494 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4495 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4496 rn = "XContext";
4497 break;
703eaf37 4498#endif
7a387fff
TS
4499 default:
4500 goto die;
4501 }
8c0fdd85
TS
4502 break;
4503 case 21:
7a387fff
TS
4504 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4505 switch (sel) {
4506 case 0:
7db13fae 4507 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4508 rn = "Framemask";
4509 break;
7a387fff
TS
4510 default:
4511 goto die;
4512 }
8c0fdd85
TS
4513 break;
4514 case 22:
d9bea114 4515 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4516 rn = "'Diagnostic"; /* implementation dependent */
4517 break;
873eb012 4518 case 23:
7a387fff
TS
4519 switch (sel) {
4520 case 0:
895c2d04 4521 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4522 rn = "Debug";
4523 break;
7a387fff 4524 case 1:
d9bea114 4525// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4526 rn = "TraceControl";
4527// break;
7a387fff 4528 case 2:
d9bea114 4529// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4530 rn = "TraceControl2";
4531// break;
7a387fff 4532 case 3:
d9bea114 4533// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4534 rn = "UserTraceData";
4535// break;
7a387fff 4536 case 4:
d9bea114 4537// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4538 rn = "TraceBPC";
4539// break;
7a387fff
TS
4540 default:
4541 goto die;
4542 }
873eb012
TS
4543 break;
4544 case 24:
7a387fff
TS
4545 switch (sel) {
4546 case 0:
f0b3f3ae 4547 /* EJTAG support */
7db13fae 4548 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4549 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4550 rn = "DEPC";
4551 break;
7a387fff
TS
4552 default:
4553 goto die;
4554 }
873eb012 4555 break;
8c0fdd85 4556 case 25:
7a387fff
TS
4557 switch (sel) {
4558 case 0:
7db13fae 4559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4560 rn = "Performance0";
7a387fff
TS
4561 break;
4562 case 1:
d9bea114 4563// gen_helper_mfc0_performance1(arg);
2423f660
TS
4564 rn = "Performance1";
4565// break;
7a387fff 4566 case 2:
d9bea114 4567// gen_helper_mfc0_performance2(arg);
2423f660
TS
4568 rn = "Performance2";
4569// break;
7a387fff 4570 case 3:
d9bea114 4571// gen_helper_mfc0_performance3(arg);
2423f660
TS
4572 rn = "Performance3";
4573// break;
7a387fff 4574 case 4:
d9bea114 4575// gen_helper_mfc0_performance4(arg);
2423f660
TS
4576 rn = "Performance4";
4577// break;
7a387fff 4578 case 5:
d9bea114 4579// gen_helper_mfc0_performance5(arg);
2423f660
TS
4580 rn = "Performance5";
4581// break;
7a387fff 4582 case 6:
d9bea114 4583// gen_helper_mfc0_performance6(arg);
2423f660
TS
4584 rn = "Performance6";
4585// break;
7a387fff 4586 case 7:
d9bea114 4587// gen_helper_mfc0_performance7(arg);
2423f660
TS
4588 rn = "Performance7";
4589// break;
7a387fff
TS
4590 default:
4591 goto die;
4592 }
8c0fdd85
TS
4593 break;
4594 case 26:
d9bea114 4595 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4596 rn = "ECC";
4597 break;
8c0fdd85 4598 case 27:
7a387fff 4599 switch (sel) {
7a387fff 4600 case 0 ... 3:
d9bea114 4601 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4602 rn = "CacheErr";
4603 break;
7a387fff
TS
4604 default:
4605 goto die;
4606 }
8c0fdd85 4607 break;
873eb012
TS
4608 case 28:
4609 switch (sel) {
4610 case 0:
7a387fff
TS
4611 case 2:
4612 case 4:
4613 case 6:
7db13fae 4614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4615 rn = "TagLo";
4616 break;
4617 case 1:
7a387fff
TS
4618 case 3:
4619 case 5:
4620 case 7:
7db13fae 4621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4622 rn = "DataLo";
4623 break;
4624 default:
873eb012
TS
4625 goto die;
4626 }
4627 break;
8c0fdd85 4628 case 29:
7a387fff
TS
4629 switch (sel) {
4630 case 0:
4631 case 2:
4632 case 4:
4633 case 6:
7db13fae 4634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4635 rn = "TagHi";
4636 break;
4637 case 1:
4638 case 3:
4639 case 5:
4640 case 7:
7db13fae 4641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4642 rn = "DataHi";
4643 break;
4644 default:
4645 goto die;
4646 }
8c0fdd85 4647 break;
873eb012 4648 case 30:
7a387fff
TS
4649 switch (sel) {
4650 case 0:
7db13fae 4651 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4652 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4653 rn = "ErrorEPC";
4654 break;
7a387fff
TS
4655 default:
4656 goto die;
4657 }
873eb012
TS
4658 break;
4659 case 31:
7a387fff
TS
4660 switch (sel) {
4661 case 0:
f0b3f3ae 4662 /* EJTAG support */
7db13fae 4663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4664 rn = "DESAVE";
4665 break;
7a387fff
TS
4666 default:
4667 goto die;
4668 }
873eb012
TS
4669 break;
4670 default:
873eb012
TS
4671 goto die;
4672 }
2abf314d 4673 (void)rn; /* avoid a compiler warning */
d12d51d5 4674 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4675 return;
4676
4677die:
d12d51d5 4678 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4679 generate_exception(ctx, EXCP_RI);
4680}
4681
d75c135e 4682static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4683{
7a387fff
TS
4684 const char *rn = "invalid";
4685
e189e748 4686 if (sel != 0)
d75c135e 4687 check_insn(ctx, ISA_MIPS32);
e189e748 4688
2e70f6ef
PB
4689 if (use_icount)
4690 gen_io_start();
4691
8c0fdd85
TS
4692 switch (reg) {
4693 case 0:
7a387fff
TS
4694 switch (sel) {
4695 case 0:
895c2d04 4696 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4697 rn = "Index";
4698 break;
4699 case 1:
d75c135e 4700 check_insn(ctx, ASE_MT);
895c2d04 4701 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4702 rn = "MVPControl";
ead9360e 4703 break;
7a387fff 4704 case 2:
d75c135e 4705 check_insn(ctx, ASE_MT);
ead9360e 4706 /* ignored */
7a387fff 4707 rn = "MVPConf0";
ead9360e 4708 break;
7a387fff 4709 case 3:
d75c135e 4710 check_insn(ctx, ASE_MT);
ead9360e 4711 /* ignored */
7a387fff 4712 rn = "MVPConf1";
ead9360e 4713 break;
7a387fff
TS
4714 default:
4715 goto die;
4716 }
8c0fdd85
TS
4717 break;
4718 case 1:
7a387fff
TS
4719 switch (sel) {
4720 case 0:
2423f660 4721 /* ignored */
7a387fff 4722 rn = "Random";
2423f660 4723 break;
7a387fff 4724 case 1:
d75c135e 4725 check_insn(ctx, ASE_MT);
895c2d04 4726 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4727 rn = "VPEControl";
ead9360e 4728 break;
7a387fff 4729 case 2:
d75c135e 4730 check_insn(ctx, ASE_MT);
895c2d04 4731 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4732 rn = "VPEConf0";
ead9360e 4733 break;
7a387fff 4734 case 3:
d75c135e 4735 check_insn(ctx, ASE_MT);
895c2d04 4736 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4737 rn = "VPEConf1";
ead9360e 4738 break;
7a387fff 4739 case 4:
d75c135e 4740 check_insn(ctx, ASE_MT);
895c2d04 4741 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4742 rn = "YQMask";
ead9360e 4743 break;
7a387fff 4744 case 5:
d75c135e 4745 check_insn(ctx, ASE_MT);
7db13fae 4746 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4747 rn = "VPESchedule";
ead9360e 4748 break;
7a387fff 4749 case 6:
d75c135e 4750 check_insn(ctx, ASE_MT);
7db13fae 4751 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4752 rn = "VPEScheFBack";
ead9360e 4753 break;
7a387fff 4754 case 7:
d75c135e 4755 check_insn(ctx, ASE_MT);
895c2d04 4756 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4757 rn = "VPEOpt";
ead9360e 4758 break;
7a387fff
TS
4759 default:
4760 goto die;
4761 }
8c0fdd85
TS
4762 break;
4763 case 2:
7a387fff
TS
4764 switch (sel) {
4765 case 0:
895c2d04 4766 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4767 rn = "EntryLo0";
4768 break;
7a387fff 4769 case 1:
d75c135e 4770 check_insn(ctx, ASE_MT);
895c2d04 4771 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4772 rn = "TCStatus";
ead9360e 4773 break;
7a387fff 4774 case 2:
d75c135e 4775 check_insn(ctx, ASE_MT);
895c2d04 4776 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4777 rn = "TCBind";
ead9360e 4778 break;
7a387fff 4779 case 3:
d75c135e 4780 check_insn(ctx, ASE_MT);
895c2d04 4781 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4782 rn = "TCRestart";
ead9360e 4783 break;
7a387fff 4784 case 4:
d75c135e 4785 check_insn(ctx, ASE_MT);
895c2d04 4786 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4787 rn = "TCHalt";
ead9360e 4788 break;
7a387fff 4789 case 5:
d75c135e 4790 check_insn(ctx, ASE_MT);
895c2d04 4791 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4792 rn = "TCContext";
ead9360e 4793 break;
7a387fff 4794 case 6:
d75c135e 4795 check_insn(ctx, ASE_MT);
895c2d04 4796 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4797 rn = "TCSchedule";
ead9360e 4798 break;
7a387fff 4799 case 7:
d75c135e 4800 check_insn(ctx, ASE_MT);
895c2d04 4801 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4802 rn = "TCScheFBack";
ead9360e 4803 break;
7a387fff
TS
4804 default:
4805 goto die;
4806 }
8c0fdd85
TS
4807 break;
4808 case 3:
7a387fff
TS
4809 switch (sel) {
4810 case 0:
895c2d04 4811 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4812 rn = "EntryLo1";
4813 break;
7a387fff
TS
4814 default:
4815 goto die;
876d4b07 4816 }
8c0fdd85
TS
4817 break;
4818 case 4:
7a387fff
TS
4819 switch (sel) {
4820 case 0:
895c2d04 4821 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4822 rn = "Context";
4823 break;
7a387fff 4824 case 1:
895c2d04 4825// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4826 rn = "ContextConfig";
4827// break;
7a387fff
TS
4828 default:
4829 goto die;
876d4b07 4830 }
8c0fdd85
TS
4831 break;
4832 case 5:
7a387fff
TS
4833 switch (sel) {
4834 case 0:
895c2d04 4835 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4836 rn = "PageMask";
4837 break;
7a387fff 4838 case 1:
d75c135e 4839 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4840 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4841 rn = "PageGrain";
4842 break;
7a387fff
TS
4843 default:
4844 goto die;
876d4b07 4845 }
8c0fdd85
TS
4846 break;
4847 case 6:
7a387fff
TS
4848 switch (sel) {
4849 case 0:
895c2d04 4850 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4851 rn = "Wired";
4852 break;
7a387fff 4853 case 1:
d75c135e 4854 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4855 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4856 rn = "SRSConf0";
ead9360e 4857 break;
7a387fff 4858 case 2:
d75c135e 4859 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4860 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4861 rn = "SRSConf1";
ead9360e 4862 break;
7a387fff 4863 case 3:
d75c135e 4864 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4865 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4866 rn = "SRSConf2";
ead9360e 4867 break;
7a387fff 4868 case 4:
d75c135e 4869 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4870 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4871 rn = "SRSConf3";
ead9360e 4872 break;
7a387fff 4873 case 5:
d75c135e 4874 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4875 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4876 rn = "SRSConf4";
ead9360e 4877 break;
7a387fff
TS
4878 default:
4879 goto die;
876d4b07 4880 }
8c0fdd85
TS
4881 break;
4882 case 7:
7a387fff
TS
4883 switch (sel) {
4884 case 0:
d75c135e 4885 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4886 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4887 rn = "HWREna";
4888 break;
7a387fff
TS
4889 default:
4890 goto die;
876d4b07 4891 }
8c0fdd85
TS
4892 break;
4893 case 8:
7a387fff 4894 /* ignored */
f0b3f3ae 4895 rn = "BadVAddr";
8c0fdd85
TS
4896 break;
4897 case 9:
7a387fff
TS
4898 switch (sel) {
4899 case 0:
895c2d04 4900 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4901 rn = "Count";
4902 break;
876d4b07 4903 /* 6,7 are implementation dependent */
7a387fff
TS
4904 default:
4905 goto die;
876d4b07 4906 }
8c0fdd85
TS
4907 break;
4908 case 10:
7a387fff
TS
4909 switch (sel) {
4910 case 0:
895c2d04 4911 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4912 rn = "EntryHi";
4913 break;
7a387fff
TS
4914 default:
4915 goto die;
876d4b07 4916 }
8c0fdd85
TS
4917 break;
4918 case 11:
7a387fff
TS
4919 switch (sel) {
4920 case 0:
895c2d04 4921 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4922 rn = "Compare";
4923 break;
4924 /* 6,7 are implementation dependent */
7a387fff
TS
4925 default:
4926 goto die;
876d4b07 4927 }
8c0fdd85
TS
4928 break;
4929 case 12:
7a387fff
TS
4930 switch (sel) {
4931 case 0:
867abc7e 4932 save_cpu_state(ctx, 1);
895c2d04 4933 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4934 /* BS_STOP isn't good enough here, hflags may have changed. */
4935 gen_save_pc(ctx->pc + 4);
4936 ctx->bstate = BS_EXCP;
2423f660
TS
4937 rn = "Status";
4938 break;
7a387fff 4939 case 1:
d75c135e 4940 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4941 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4942 /* Stop translation as we may have switched the execution mode */
4943 ctx->bstate = BS_STOP;
2423f660
TS
4944 rn = "IntCtl";
4945 break;
7a387fff 4946 case 2:
d75c135e 4947 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4948 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4949 /* Stop translation as we may have switched the execution mode */
4950 ctx->bstate = BS_STOP;
2423f660
TS
4951 rn = "SRSCtl";
4952 break;
7a387fff 4953 case 3:
d75c135e 4954 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4955 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4956 /* Stop translation as we may have switched the execution mode */
4957 ctx->bstate = BS_STOP;
2423f660 4958 rn = "SRSMap";
fd88b6ab 4959 break;
7a387fff
TS
4960 default:
4961 goto die;
876d4b07 4962 }
8c0fdd85
TS
4963 break;
4964 case 13:
7a387fff
TS
4965 switch (sel) {
4966 case 0:
867abc7e 4967 save_cpu_state(ctx, 1);
895c2d04 4968 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4969 rn = "Cause";
4970 break;
7a387fff
TS
4971 default:
4972 goto die;
876d4b07 4973 }
8c0fdd85
TS
4974 break;
4975 case 14:
7a387fff
TS
4976 switch (sel) {
4977 case 0:
7db13fae 4978 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4979 rn = "EPC";
4980 break;
7a387fff
TS
4981 default:
4982 goto die;
876d4b07 4983 }
8c0fdd85
TS
4984 break;
4985 case 15:
7a387fff
TS
4986 switch (sel) {
4987 case 0:
2423f660
TS
4988 /* ignored */
4989 rn = "PRid";
4990 break;
7a387fff 4991 case 1:
d75c135e 4992 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4993 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
4994 rn = "EBase";
4995 break;
7a387fff
TS
4996 default:
4997 goto die;
1579a72e 4998 }
8c0fdd85
TS
4999 break;
5000 case 16:
5001 switch (sel) {
5002 case 0:
895c2d04 5003 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5004 rn = "Config";
2423f660
TS
5005 /* Stop translation as we may have switched the execution mode */
5006 ctx->bstate = BS_STOP;
7a387fff
TS
5007 break;
5008 case 1:
e397ee33 5009 /* ignored, read only */
7a387fff
TS
5010 rn = "Config1";
5011 break;
5012 case 2:
895c2d04 5013 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5014 rn = "Config2";
2423f660
TS
5015 /* Stop translation as we may have switched the execution mode */
5016 ctx->bstate = BS_STOP;
8c0fdd85 5017 break;
7a387fff 5018 case 3:
e397ee33 5019 /* ignored, read only */
7a387fff
TS
5020 rn = "Config3";
5021 break;
e397ee33
TS
5022 /* 4,5 are reserved */
5023 /* 6,7 are implementation dependent */
5024 case 6:
5025 /* ignored */
5026 rn = "Config6";
5027 break;
5028 case 7:
5029 /* ignored */
5030 rn = "Config7";
5031 break;
8c0fdd85
TS
5032 default:
5033 rn = "Invalid config selector";
5034 goto die;
5035 }
5036 break;
5037 case 17:
7a387fff
TS
5038 switch (sel) {
5039 case 0:
895c2d04 5040 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5041 rn = "LLAddr";
5042 break;
7a387fff
TS
5043 default:
5044 goto die;
5045 }
8c0fdd85
TS
5046 break;
5047 case 18:
7a387fff 5048 switch (sel) {
fd88b6ab 5049 case 0 ... 7:
895c2d04 5050 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5051 rn = "WatchLo";
5052 break;
7a387fff
TS
5053 default:
5054 goto die;
5055 }
8c0fdd85
TS
5056 break;
5057 case 19:
7a387fff 5058 switch (sel) {
fd88b6ab 5059 case 0 ... 7:
895c2d04 5060 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5061 rn = "WatchHi";
5062 break;
7a387fff
TS
5063 default:
5064 goto die;
5065 }
8c0fdd85
TS
5066 break;
5067 case 20:
7a387fff
TS
5068 switch (sel) {
5069 case 0:
d26bc211 5070#if defined(TARGET_MIPS64)
d75c135e 5071 check_insn(ctx, ISA_MIPS3);
895c2d04 5072 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5073 rn = "XContext";
5074 break;
703eaf37 5075#endif
7a387fff
TS
5076 default:
5077 goto die;
5078 }
8c0fdd85
TS
5079 break;
5080 case 21:
7a387fff
TS
5081 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5082 switch (sel) {
5083 case 0:
895c2d04 5084 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5085 rn = "Framemask";
5086 break;
7a387fff
TS
5087 default:
5088 goto die;
5089 }
5090 break;
8c0fdd85 5091 case 22:
7a387fff
TS
5092 /* ignored */
5093 rn = "Diagnostic"; /* implementation dependent */
2423f660 5094 break;
8c0fdd85 5095 case 23:
7a387fff
TS
5096 switch (sel) {
5097 case 0:
895c2d04 5098 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5099 /* BS_STOP isn't good enough here, hflags may have changed. */
5100 gen_save_pc(ctx->pc + 4);
5101 ctx->bstate = BS_EXCP;
2423f660
TS
5102 rn = "Debug";
5103 break;
7a387fff 5104 case 1:
895c2d04 5105// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5106 rn = "TraceControl";
8487327a
TS
5107 /* Stop translation as we may have switched the execution mode */
5108 ctx->bstate = BS_STOP;
2423f660 5109// break;
7a387fff 5110 case 2:
895c2d04 5111// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5112 rn = "TraceControl2";
8487327a
TS
5113 /* Stop translation as we may have switched the execution mode */
5114 ctx->bstate = BS_STOP;
2423f660 5115// break;
7a387fff 5116 case 3:
8487327a
TS
5117 /* Stop translation as we may have switched the execution mode */
5118 ctx->bstate = BS_STOP;
895c2d04 5119// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5120 rn = "UserTraceData";
8487327a
TS
5121 /* Stop translation as we may have switched the execution mode */
5122 ctx->bstate = BS_STOP;
2423f660 5123// break;
7a387fff 5124 case 4:
895c2d04 5125// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5126 /* Stop translation as we may have switched the execution mode */
5127 ctx->bstate = BS_STOP;
2423f660
TS
5128 rn = "TraceBPC";
5129// break;
7a387fff
TS
5130 default:
5131 goto die;
5132 }
8c0fdd85
TS
5133 break;
5134 case 24:
7a387fff
TS
5135 switch (sel) {
5136 case 0:
f1aa6320 5137 /* EJTAG support */
7db13fae 5138 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5139 rn = "DEPC";
5140 break;
7a387fff
TS
5141 default:
5142 goto die;
5143 }
8c0fdd85
TS
5144 break;
5145 case 25:
7a387fff
TS
5146 switch (sel) {
5147 case 0:
895c2d04 5148 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5149 rn = "Performance0";
5150 break;
7a387fff 5151 case 1:
d9bea114 5152// gen_helper_mtc0_performance1(arg);
2423f660
TS
5153 rn = "Performance1";
5154// break;
7a387fff 5155 case 2:
d9bea114 5156// gen_helper_mtc0_performance2(arg);
2423f660
TS
5157 rn = "Performance2";
5158// break;
7a387fff 5159 case 3:
d9bea114 5160// gen_helper_mtc0_performance3(arg);
2423f660
TS
5161 rn = "Performance3";
5162// break;
7a387fff 5163 case 4:
d9bea114 5164// gen_helper_mtc0_performance4(arg);
2423f660
TS
5165 rn = "Performance4";
5166// break;
7a387fff 5167 case 5:
d9bea114 5168// gen_helper_mtc0_performance5(arg);
2423f660
TS
5169 rn = "Performance5";
5170// break;
7a387fff 5171 case 6:
d9bea114 5172// gen_helper_mtc0_performance6(arg);
2423f660
TS
5173 rn = "Performance6";
5174// break;
7a387fff 5175 case 7:
d9bea114 5176// gen_helper_mtc0_performance7(arg);
2423f660
TS
5177 rn = "Performance7";
5178// break;
7a387fff
TS
5179 default:
5180 goto die;
5181 }
8c0fdd85
TS
5182 break;
5183 case 26:
2423f660 5184 /* ignored */
8c0fdd85 5185 rn = "ECC";
2423f660 5186 break;
8c0fdd85 5187 case 27:
7a387fff
TS
5188 switch (sel) {
5189 case 0 ... 3:
2423f660
TS
5190 /* ignored */
5191 rn = "CacheErr";
5192 break;
7a387fff
TS
5193 default:
5194 goto die;
5195 }
8c0fdd85
TS
5196 break;
5197 case 28:
5198 switch (sel) {
5199 case 0:
7a387fff
TS
5200 case 2:
5201 case 4:
5202 case 6:
895c2d04 5203 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5204 rn = "TagLo";
5205 break;
7a387fff
TS
5206 case 1:
5207 case 3:
5208 case 5:
5209 case 7:
895c2d04 5210 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5211 rn = "DataLo";
5212 break;
8c0fdd85 5213 default:
8c0fdd85
TS
5214 goto die;
5215 }
5216 break;
5217 case 29:
7a387fff
TS
5218 switch (sel) {
5219 case 0:
5220 case 2:
5221 case 4:
5222 case 6:
895c2d04 5223 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5224 rn = "TagHi";
5225 break;
5226 case 1:
5227 case 3:
5228 case 5:
5229 case 7:
895c2d04 5230 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5231 rn = "DataHi";
5232 break;
5233 default:
5234 rn = "invalid sel";
5235 goto die;
5236 }
8c0fdd85
TS
5237 break;
5238 case 30:
7a387fff
TS
5239 switch (sel) {
5240 case 0:
7db13fae 5241 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5242 rn = "ErrorEPC";
5243 break;
7a387fff
TS
5244 default:
5245 goto die;
5246 }
8c0fdd85
TS
5247 break;
5248 case 31:
7a387fff
TS
5249 switch (sel) {
5250 case 0:
f1aa6320 5251 /* EJTAG support */
7db13fae 5252 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5253 rn = "DESAVE";
5254 break;
7a387fff
TS
5255 default:
5256 goto die;
5257 }
2423f660
TS
5258 /* Stop translation as we may have switched the execution mode */
5259 ctx->bstate = BS_STOP;
8c0fdd85
TS
5260 break;
5261 default:
8c0fdd85
TS
5262 goto die;
5263 }
2abf314d 5264 (void)rn; /* avoid a compiler warning */
d12d51d5 5265 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5266 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5267 if (use_icount) {
5268 gen_io_end();
5269 ctx->bstate = BS_STOP;
5270 }
8c0fdd85
TS
5271 return;
5272
5273die:
d12d51d5 5274 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5275 generate_exception(ctx, EXCP_RI);
5276}
5277
d26bc211 5278#if defined(TARGET_MIPS64)
d75c135e 5279static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5280{
5281 const char *rn = "invalid";
5282
e189e748 5283 if (sel != 0)
d75c135e 5284 check_insn(ctx, ISA_MIPS64);
e189e748 5285
9c2149c8
TS
5286 switch (reg) {
5287 case 0:
5288 switch (sel) {
5289 case 0:
7db13fae 5290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5291 rn = "Index";
5292 break;
5293 case 1:
d75c135e 5294 check_insn(ctx, ASE_MT);
895c2d04 5295 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5296 rn = "MVPControl";
ead9360e 5297 break;
9c2149c8 5298 case 2:
d75c135e 5299 check_insn(ctx, ASE_MT);
895c2d04 5300 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5301 rn = "MVPConf0";
ead9360e 5302 break;
9c2149c8 5303 case 3:
d75c135e 5304 check_insn(ctx, ASE_MT);
895c2d04 5305 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5306 rn = "MVPConf1";
ead9360e 5307 break;
9c2149c8
TS
5308 default:
5309 goto die;
5310 }
5311 break;
5312 case 1:
5313 switch (sel) {
5314 case 0:
895c2d04 5315 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5316 rn = "Random";
2423f660 5317 break;
9c2149c8 5318 case 1:
d75c135e 5319 check_insn(ctx, ASE_MT);
7db13fae 5320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5321 rn = "VPEControl";
ead9360e 5322 break;
9c2149c8 5323 case 2:
d75c135e 5324 check_insn(ctx, ASE_MT);
7db13fae 5325 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5326 rn = "VPEConf0";
ead9360e 5327 break;
9c2149c8 5328 case 3:
d75c135e 5329 check_insn(ctx, ASE_MT);
7db13fae 5330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5331 rn = "VPEConf1";
ead9360e 5332 break;
9c2149c8 5333 case 4:
d75c135e 5334 check_insn(ctx, ASE_MT);
7db13fae 5335 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5336 rn = "YQMask";
ead9360e 5337 break;
9c2149c8 5338 case 5:
d75c135e 5339 check_insn(ctx, ASE_MT);
7db13fae 5340 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5341 rn = "VPESchedule";
ead9360e 5342 break;
9c2149c8 5343 case 6:
d75c135e 5344 check_insn(ctx, ASE_MT);
7db13fae 5345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5346 rn = "VPEScheFBack";
ead9360e 5347 break;
9c2149c8 5348 case 7:
d75c135e 5349 check_insn(ctx, ASE_MT);
7db13fae 5350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5351 rn = "VPEOpt";
ead9360e 5352 break;
9c2149c8
TS
5353 default:
5354 goto die;
5355 }
5356 break;
5357 case 2:
5358 switch (sel) {
5359 case 0:
7db13fae 5360 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5361 rn = "EntryLo0";
5362 break;
9c2149c8 5363 case 1:
d75c135e 5364 check_insn(ctx, ASE_MT);
895c2d04 5365 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5366 rn = "TCStatus";
ead9360e 5367 break;
9c2149c8 5368 case 2:
d75c135e 5369 check_insn(ctx, ASE_MT);
895c2d04 5370 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5371 rn = "TCBind";
ead9360e 5372 break;
9c2149c8 5373 case 3:
d75c135e 5374 check_insn(ctx, ASE_MT);
895c2d04 5375 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5376 rn = "TCRestart";
ead9360e 5377 break;
9c2149c8 5378 case 4:
d75c135e 5379 check_insn(ctx, ASE_MT);
895c2d04 5380 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5381 rn = "TCHalt";
ead9360e 5382 break;
9c2149c8 5383 case 5:
d75c135e 5384 check_insn(ctx, ASE_MT);
895c2d04 5385 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5386 rn = "TCContext";
ead9360e 5387 break;
9c2149c8 5388 case 6:
d75c135e 5389 check_insn(ctx, ASE_MT);
895c2d04 5390 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5391 rn = "TCSchedule";
ead9360e 5392 break;
9c2149c8 5393 case 7:
d75c135e 5394 check_insn(ctx, ASE_MT);
895c2d04 5395 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5396 rn = "TCScheFBack";
ead9360e 5397 break;
9c2149c8
TS
5398 default:
5399 goto die;
5400 }
5401 break;
5402 case 3:
5403 switch (sel) {
5404 case 0:
7db13fae 5405 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5406 rn = "EntryLo1";
5407 break;
9c2149c8
TS
5408 default:
5409 goto die;
1579a72e 5410 }
9c2149c8
TS
5411 break;
5412 case 4:
5413 switch (sel) {
5414 case 0:
7db13fae 5415 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5416 rn = "Context";
5417 break;
9c2149c8 5418 case 1:
d9bea114 5419// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5420 rn = "ContextConfig";
5421// break;
9c2149c8
TS
5422 default:
5423 goto die;
876d4b07 5424 }
9c2149c8
TS
5425 break;
5426 case 5:
5427 switch (sel) {
5428 case 0:
7db13fae 5429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5430 rn = "PageMask";
5431 break;
9c2149c8 5432 case 1:
d75c135e 5433 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5435 rn = "PageGrain";
5436 break;
9c2149c8
TS
5437 default:
5438 goto die;
876d4b07 5439 }
9c2149c8
TS
5440 break;
5441 case 6:
5442 switch (sel) {
5443 case 0:
7db13fae 5444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5445 rn = "Wired";
5446 break;
9c2149c8 5447 case 1:
d75c135e 5448 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5450 rn = "SRSConf0";
ead9360e 5451 break;
9c2149c8 5452 case 2:
d75c135e 5453 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5454 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5455 rn = "SRSConf1";
ead9360e 5456 break;
9c2149c8 5457 case 3:
d75c135e 5458 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5460 rn = "SRSConf2";
ead9360e 5461 break;
9c2149c8 5462 case 4:
d75c135e 5463 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5465 rn = "SRSConf3";
ead9360e 5466 break;
9c2149c8 5467 case 5:
d75c135e 5468 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5470 rn = "SRSConf4";
ead9360e 5471 break;
9c2149c8
TS
5472 default:
5473 goto die;
876d4b07 5474 }
9c2149c8
TS
5475 break;
5476 case 7:
5477 switch (sel) {
5478 case 0:
d75c135e 5479 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5481 rn = "HWREna";
5482 break;
9c2149c8
TS
5483 default:
5484 goto die;
876d4b07 5485 }
9c2149c8
TS
5486 break;
5487 case 8:
5488 switch (sel) {
5489 case 0:
7db13fae 5490 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5491 rn = "BadVAddr";
2423f660 5492 break;
9c2149c8
TS
5493 default:
5494 goto die;
876d4b07 5495 }
9c2149c8
TS
5496 break;
5497 case 9:
5498 switch (sel) {
5499 case 0:
2e70f6ef
PB
5500 /* Mark as an IO operation because we read the time. */
5501 if (use_icount)
5502 gen_io_start();
895c2d04 5503 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5504 if (use_icount) {
5505 gen_io_end();
2e70f6ef 5506 }
55807224
EI
5507 /* Break the TB to be able to take timer interrupts immediately
5508 after reading count. */
5509 ctx->bstate = BS_STOP;
2423f660
TS
5510 rn = "Count";
5511 break;
5512 /* 6,7 are implementation dependent */
9c2149c8
TS
5513 default:
5514 goto die;
876d4b07 5515 }
9c2149c8
TS
5516 break;
5517 case 10:
5518 switch (sel) {
5519 case 0:
7db13fae 5520 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5521 rn = "EntryHi";
5522 break;
9c2149c8
TS
5523 default:
5524 goto die;
876d4b07 5525 }
9c2149c8
TS
5526 break;
5527 case 11:
5528 switch (sel) {
5529 case 0:
7db13fae 5530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5531 rn = "Compare";
5532 break;
876d4b07 5533 /* 6,7 are implementation dependent */
9c2149c8
TS
5534 default:
5535 goto die;
876d4b07 5536 }
9c2149c8
TS
5537 break;
5538 case 12:
5539 switch (sel) {
5540 case 0:
7db13fae 5541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5542 rn = "Status";
5543 break;
9c2149c8 5544 case 1:
d75c135e 5545 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5547 rn = "IntCtl";
5548 break;
9c2149c8 5549 case 2:
d75c135e 5550 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5552 rn = "SRSCtl";
5553 break;
9c2149c8 5554 case 3:
d75c135e 5555 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5557 rn = "SRSMap";
5558 break;
9c2149c8
TS
5559 default:
5560 goto die;
876d4b07 5561 }
9c2149c8
TS
5562 break;
5563 case 13:
5564 switch (sel) {
5565 case 0:
7db13fae 5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5567 rn = "Cause";
5568 break;
9c2149c8
TS
5569 default:
5570 goto die;
876d4b07 5571 }
9c2149c8
TS
5572 break;
5573 case 14:
5574 switch (sel) {
5575 case 0:
7db13fae 5576 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5577 rn = "EPC";
5578 break;
9c2149c8
TS
5579 default:
5580 goto die;
876d4b07 5581 }
9c2149c8
TS
5582 break;
5583 case 15:
5584 switch (sel) {
5585 case 0:
7db13fae 5586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5587 rn = "PRid";
5588 break;
9c2149c8 5589 case 1:
d75c135e 5590 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5592 rn = "EBase";
5593 break;
9c2149c8
TS
5594 default:
5595 goto die;
876d4b07 5596 }
9c2149c8
TS
5597 break;
5598 case 16:
5599 switch (sel) {
5600 case 0:
7db13fae 5601 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5602 rn = "Config";
5603 break;
5604 case 1:
7db13fae 5605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5606 rn = "Config1";
5607 break;
5608 case 2:
7db13fae 5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5610 rn = "Config2";
5611 break;
5612 case 3:
7db13fae 5613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5614 rn = "Config3";
5615 break;
5616 /* 6,7 are implementation dependent */
f0b3f3ae 5617 case 6:
7db13fae 5618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5619 rn = "Config6";
5620 break;
5621 case 7:
7db13fae 5622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5623 rn = "Config7";
5624 break;
9c2149c8
TS
5625 default:
5626 goto die;
5627 }
5628 break;
5629 case 17:
5630 switch (sel) {
5631 case 0:
895c2d04 5632 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5633 rn = "LLAddr";
5634 break;
9c2149c8
TS
5635 default:
5636 goto die;
5637 }
5638 break;
5639 case 18:
5640 switch (sel) {
fd88b6ab 5641 case 0 ... 7:
895c2d04 5642 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5643 rn = "WatchLo";
5644 break;
9c2149c8
TS
5645 default:
5646 goto die;
5647 }
5648 break;
5649 case 19:
5650 switch (sel) {
fd88b6ab 5651 case 0 ... 7:
895c2d04 5652 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5653 rn = "WatchHi";
5654 break;
9c2149c8
TS
5655 default:
5656 goto die;
5657 }
5658 break;
5659 case 20:
5660 switch (sel) {
5661 case 0:
d75c135e 5662 check_insn(ctx, ISA_MIPS3);
7db13fae 5663 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5664 rn = "XContext";
5665 break;
9c2149c8
TS
5666 default:
5667 goto die;
5668 }
5669 break;
5670 case 21:
5671 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5672 switch (sel) {
5673 case 0:
7db13fae 5674 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5675 rn = "Framemask";
5676 break;
9c2149c8
TS
5677 default:
5678 goto die;
5679 }
5680 break;
5681 case 22:
d9bea114 5682 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5683 rn = "'Diagnostic"; /* implementation dependent */
5684 break;
9c2149c8
TS
5685 case 23:
5686 switch (sel) {
5687 case 0:
895c2d04 5688 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5689 rn = "Debug";
5690 break;
9c2149c8 5691 case 1:
895c2d04 5692// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5693 rn = "TraceControl";
5694// break;
9c2149c8 5695 case 2:
895c2d04 5696// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5697 rn = "TraceControl2";
5698// break;
9c2149c8 5699 case 3:
895c2d04 5700// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5701 rn = "UserTraceData";
5702// break;
9c2149c8 5703 case 4:
895c2d04 5704// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5705 rn = "TraceBPC";
5706// break;
9c2149c8
TS
5707 default:
5708 goto die;
5709 }
5710 break;
5711 case 24:
5712 switch (sel) {
5713 case 0:
f0b3f3ae 5714 /* EJTAG support */
7db13fae 5715 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5716 rn = "DEPC";
5717 break;
9c2149c8
TS
5718 default:
5719 goto die;
5720 }
5721 break;
5722 case 25:
5723 switch (sel) {
5724 case 0:
7db13fae 5725 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5726 rn = "Performance0";
9c2149c8
TS
5727 break;
5728 case 1:
d9bea114 5729// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5730 rn = "Performance1";
5731// break;
9c2149c8 5732 case 2:
d9bea114 5733// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5734 rn = "Performance2";
5735// break;
9c2149c8 5736 case 3:
d9bea114 5737// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5738 rn = "Performance3";
5739// break;
9c2149c8 5740 case 4:
d9bea114 5741// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5742 rn = "Performance4";
5743// break;
9c2149c8 5744 case 5:
d9bea114 5745// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5746 rn = "Performance5";
5747// break;
9c2149c8 5748 case 6:
d9bea114 5749// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5750 rn = "Performance6";
5751// break;
9c2149c8 5752 case 7:
d9bea114 5753// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5754 rn = "Performance7";
5755// break;
9c2149c8
TS
5756 default:
5757 goto die;
5758 }
5759 break;
5760 case 26:
d9bea114 5761 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5762 rn = "ECC";
5763 break;
9c2149c8
TS
5764 case 27:
5765 switch (sel) {
5766 /* ignored */
5767 case 0 ... 3:
d9bea114 5768 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5769 rn = "CacheErr";
5770 break;
9c2149c8
TS
5771 default:
5772 goto die;
5773 }
5774 break;
5775 case 28:
5776 switch (sel) {
5777 case 0:
5778 case 2:
5779 case 4:
5780 case 6:
7db13fae 5781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5782 rn = "TagLo";
5783 break;
5784 case 1:
5785 case 3:
5786 case 5:
5787 case 7:
7db13fae 5788 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5789 rn = "DataLo";
5790 break;
5791 default:
5792 goto die;
5793 }
5794 break;
5795 case 29:
5796 switch (sel) {
5797 case 0:
5798 case 2:
5799 case 4:
5800 case 6:
7db13fae 5801 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5802 rn = "TagHi";
5803 break;
5804 case 1:
5805 case 3:
5806 case 5:
5807 case 7:
7db13fae 5808 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5809 rn = "DataHi";
5810 break;
5811 default:
5812 goto die;
5813 }
5814 break;
5815 case 30:
5816 switch (sel) {
5817 case 0:
7db13fae 5818 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5819 rn = "ErrorEPC";
5820 break;
9c2149c8
TS
5821 default:
5822 goto die;
5823 }
5824 break;
5825 case 31:
5826 switch (sel) {
5827 case 0:
f0b3f3ae 5828 /* EJTAG support */
7db13fae 5829 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5830 rn = "DESAVE";
5831 break;
9c2149c8
TS
5832 default:
5833 goto die;
5834 }
5835 break;
5836 default:
876d4b07 5837 goto die;
9c2149c8 5838 }
2abf314d 5839 (void)rn; /* avoid a compiler warning */
d12d51d5 5840 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5841 return;
5842
5843die:
d12d51d5 5844 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5845 generate_exception(ctx, EXCP_RI);
5846}
5847
d75c135e 5848static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5849{
5850 const char *rn = "invalid";
5851
e189e748 5852 if (sel != 0)
d75c135e 5853 check_insn(ctx, ISA_MIPS64);
e189e748 5854
2e70f6ef
PB
5855 if (use_icount)
5856 gen_io_start();
5857
9c2149c8
TS
5858 switch (reg) {
5859 case 0:
5860 switch (sel) {
5861 case 0:
895c2d04 5862 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5863 rn = "Index";
5864 break;
5865 case 1:
d75c135e 5866 check_insn(ctx, ASE_MT);
895c2d04 5867 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5868 rn = "MVPControl";
ead9360e 5869 break;
9c2149c8 5870 case 2:
d75c135e 5871 check_insn(ctx, ASE_MT);
ead9360e 5872 /* ignored */
9c2149c8 5873 rn = "MVPConf0";
ead9360e 5874 break;
9c2149c8 5875 case 3:
d75c135e 5876 check_insn(ctx, ASE_MT);
ead9360e 5877 /* ignored */
9c2149c8 5878 rn = "MVPConf1";
ead9360e 5879 break;
9c2149c8
TS
5880 default:
5881 goto die;
5882 }
5883 break;
5884 case 1:
5885 switch (sel) {
5886 case 0:
2423f660 5887 /* ignored */
9c2149c8 5888 rn = "Random";
2423f660 5889 break;
9c2149c8 5890 case 1:
d75c135e 5891 check_insn(ctx, ASE_MT);
895c2d04 5892 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5893 rn = "VPEControl";
ead9360e 5894 break;
9c2149c8 5895 case 2:
d75c135e 5896 check_insn(ctx, ASE_MT);
895c2d04 5897 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5898 rn = "VPEConf0";
ead9360e 5899 break;
9c2149c8 5900 case 3:
d75c135e 5901 check_insn(ctx, ASE_MT);
895c2d04 5902 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5903 rn = "VPEConf1";
ead9360e 5904 break;
9c2149c8 5905 case 4:
d75c135e 5906 check_insn(ctx, ASE_MT);
895c2d04 5907 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5908 rn = "YQMask";
ead9360e 5909 break;
9c2149c8 5910 case 5:
d75c135e 5911 check_insn(ctx, ASE_MT);
7db13fae 5912 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5913 rn = "VPESchedule";
ead9360e 5914 break;
9c2149c8 5915 case 6:
d75c135e 5916 check_insn(ctx, ASE_MT);
7db13fae 5917 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5918 rn = "VPEScheFBack";
ead9360e 5919 break;
9c2149c8 5920 case 7:
d75c135e 5921 check_insn(ctx, ASE_MT);
895c2d04 5922 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5923 rn = "VPEOpt";
ead9360e 5924 break;
9c2149c8
TS
5925 default:
5926 goto die;
5927 }
5928 break;
5929 case 2:
5930 switch (sel) {
5931 case 0:
895c2d04 5932 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5933 rn = "EntryLo0";
5934 break;
9c2149c8 5935 case 1:
d75c135e 5936 check_insn(ctx, ASE_MT);
895c2d04 5937 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5938 rn = "TCStatus";
ead9360e 5939 break;
9c2149c8 5940 case 2:
d75c135e 5941 check_insn(ctx, ASE_MT);
895c2d04 5942 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5943 rn = "TCBind";
ead9360e 5944 break;
9c2149c8 5945 case 3:
d75c135e 5946 check_insn(ctx, ASE_MT);
895c2d04 5947 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5948 rn = "TCRestart";
ead9360e 5949 break;
9c2149c8 5950 case 4:
d75c135e 5951 check_insn(ctx, ASE_MT);
895c2d04 5952 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5953 rn = "TCHalt";
ead9360e 5954 break;
9c2149c8 5955 case 5:
d75c135e 5956 check_insn(ctx, ASE_MT);
895c2d04 5957 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5958 rn = "TCContext";
ead9360e 5959 break;
9c2149c8 5960 case 6:
d75c135e 5961 check_insn(ctx, ASE_MT);
895c2d04 5962 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5963 rn = "TCSchedule";
ead9360e 5964 break;
9c2149c8 5965 case 7:
d75c135e 5966 check_insn(ctx, ASE_MT);
895c2d04 5967 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5968 rn = "TCScheFBack";
ead9360e 5969 break;
9c2149c8
TS
5970 default:
5971 goto die;
5972 }
5973 break;
5974 case 3:
5975 switch (sel) {
5976 case 0:
895c2d04 5977 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5978 rn = "EntryLo1";
5979 break;
9c2149c8
TS
5980 default:
5981 goto die;
876d4b07 5982 }
9c2149c8
TS
5983 break;
5984 case 4:
5985 switch (sel) {
5986 case 0:
895c2d04 5987 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5988 rn = "Context";
5989 break;
9c2149c8 5990 case 1:
895c2d04 5991// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
5992 rn = "ContextConfig";
5993// break;
9c2149c8
TS
5994 default:
5995 goto die;
876d4b07 5996 }
9c2149c8
TS
5997 break;
5998 case 5:
5999 switch (sel) {
6000 case 0:
895c2d04 6001 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6002 rn = "PageMask";
6003 break;
9c2149c8 6004 case 1:
d75c135e 6005 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6006 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6007 rn = "PageGrain";
6008 break;
9c2149c8
TS
6009 default:
6010 goto die;
876d4b07 6011 }
9c2149c8
TS
6012 break;
6013 case 6:
6014 switch (sel) {
6015 case 0:
895c2d04 6016 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6017 rn = "Wired";
6018 break;
9c2149c8 6019 case 1:
d75c135e 6020 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6021 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6022 rn = "SRSConf0";
ead9360e 6023 break;
9c2149c8 6024 case 2:
d75c135e 6025 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6026 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6027 rn = "SRSConf1";
ead9360e 6028 break;
9c2149c8 6029 case 3:
d75c135e 6030 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6031 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6032 rn = "SRSConf2";
ead9360e 6033 break;
9c2149c8 6034 case 4:
d75c135e 6035 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6036 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6037 rn = "SRSConf3";
ead9360e 6038 break;
9c2149c8 6039 case 5:
d75c135e 6040 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6041 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6042 rn = "SRSConf4";
ead9360e 6043 break;
9c2149c8
TS
6044 default:
6045 goto die;
876d4b07 6046 }
9c2149c8
TS
6047 break;
6048 case 7:
6049 switch (sel) {
6050 case 0:
d75c135e 6051 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6052 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6053 rn = "HWREna";
6054 break;
9c2149c8
TS
6055 default:
6056 goto die;
876d4b07 6057 }
9c2149c8
TS
6058 break;
6059 case 8:
6060 /* ignored */
f0b3f3ae 6061 rn = "BadVAddr";
9c2149c8
TS
6062 break;
6063 case 9:
6064 switch (sel) {
6065 case 0:
895c2d04 6066 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6067 rn = "Count";
6068 break;
876d4b07 6069 /* 6,7 are implementation dependent */
9c2149c8
TS
6070 default:
6071 goto die;
876d4b07
TS
6072 }
6073 /* Stop translation as we may have switched the execution mode */
6074 ctx->bstate = BS_STOP;
9c2149c8
TS
6075 break;
6076 case 10:
6077 switch (sel) {
6078 case 0:
895c2d04 6079 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6080 rn = "EntryHi";
6081 break;
9c2149c8
TS
6082 default:
6083 goto die;
876d4b07 6084 }
9c2149c8
TS
6085 break;
6086 case 11:
6087 switch (sel) {
6088 case 0:
895c2d04 6089 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6090 rn = "Compare";
6091 break;
876d4b07 6092 /* 6,7 are implementation dependent */
9c2149c8
TS
6093 default:
6094 goto die;
876d4b07 6095 }
de9a95f0
AJ
6096 /* Stop translation as we may have switched the execution mode */
6097 ctx->bstate = BS_STOP;
9c2149c8
TS
6098 break;
6099 case 12:
6100 switch (sel) {
6101 case 0:
867abc7e 6102 save_cpu_state(ctx, 1);
895c2d04 6103 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6104 /* BS_STOP isn't good enough here, hflags may have changed. */
6105 gen_save_pc(ctx->pc + 4);
6106 ctx->bstate = BS_EXCP;
2423f660
TS
6107 rn = "Status";
6108 break;
9c2149c8 6109 case 1:
d75c135e 6110 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6111 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6112 /* Stop translation as we may have switched the execution mode */
6113 ctx->bstate = BS_STOP;
2423f660
TS
6114 rn = "IntCtl";
6115 break;
9c2149c8 6116 case 2:
d75c135e 6117 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6118 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6119 /* Stop translation as we may have switched the execution mode */
6120 ctx->bstate = BS_STOP;
2423f660
TS
6121 rn = "SRSCtl";
6122 break;
9c2149c8 6123 case 3:
d75c135e 6124 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6125 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6126 /* Stop translation as we may have switched the execution mode */
6127 ctx->bstate = BS_STOP;
2423f660
TS
6128 rn = "SRSMap";
6129 break;
6130 default:
9c2149c8 6131 goto die;
876d4b07 6132 }
9c2149c8
TS
6133 break;
6134 case 13:
6135 switch (sel) {
6136 case 0:
867abc7e 6137 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6138 /* Mark as an IO operation because we may trigger a software
6139 interrupt. */
6140 if (use_icount) {
6141 gen_io_start();
6142 }
895c2d04 6143 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6144 if (use_icount) {
6145 gen_io_end();
6146 }
6147 /* Stop translation as we may have triggered an intetrupt */
6148 ctx->bstate = BS_STOP;
2423f660
TS
6149 rn = "Cause";
6150 break;
9c2149c8
TS
6151 default:
6152 goto die;
876d4b07 6153 }
9c2149c8
TS
6154 break;
6155 case 14:
6156 switch (sel) {
6157 case 0:
7db13fae 6158 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6159 rn = "EPC";
6160 break;
9c2149c8
TS
6161 default:
6162 goto die;
876d4b07 6163 }
9c2149c8
TS
6164 break;
6165 case 15:
6166 switch (sel) {
6167 case 0:
2423f660
TS
6168 /* ignored */
6169 rn = "PRid";
6170 break;
9c2149c8 6171 case 1:
d75c135e 6172 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6173 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6174 rn = "EBase";
6175 break;
9c2149c8
TS
6176 default:
6177 goto die;
876d4b07 6178 }
9c2149c8
TS
6179 break;
6180 case 16:
6181 switch (sel) {
6182 case 0:
895c2d04 6183 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6184 rn = "Config";
2423f660
TS
6185 /* Stop translation as we may have switched the execution mode */
6186 ctx->bstate = BS_STOP;
9c2149c8
TS
6187 break;
6188 case 1:
1fc7bf6e 6189 /* ignored, read only */
9c2149c8
TS
6190 rn = "Config1";
6191 break;
6192 case 2:
895c2d04 6193 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6194 rn = "Config2";
2423f660
TS
6195 /* Stop translation as we may have switched the execution mode */
6196 ctx->bstate = BS_STOP;
9c2149c8
TS
6197 break;
6198 case 3:
2423f660 6199 /* ignored */
9c2149c8
TS
6200 rn = "Config3";
6201 break;
6202 /* 6,7 are implementation dependent */
6203 default:
6204 rn = "Invalid config selector";
6205 goto die;
6206 }
9c2149c8
TS
6207 break;
6208 case 17:
6209 switch (sel) {
6210 case 0:
895c2d04 6211 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6212 rn = "LLAddr";
6213 break;
9c2149c8
TS
6214 default:
6215 goto die;
6216 }
6217 break;
6218 case 18:
6219 switch (sel) {
fd88b6ab 6220 case 0 ... 7:
895c2d04 6221 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6222 rn = "WatchLo";
6223 break;
9c2149c8
TS
6224 default:
6225 goto die;
6226 }
6227 break;
6228 case 19:
6229 switch (sel) {
fd88b6ab 6230 case 0 ... 7:
895c2d04 6231 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6232 rn = "WatchHi";
6233 break;
9c2149c8
TS
6234 default:
6235 goto die;
6236 }
6237 break;
6238 case 20:
6239 switch (sel) {
6240 case 0:
d75c135e 6241 check_insn(ctx, ISA_MIPS3);
895c2d04 6242 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6243 rn = "XContext";
6244 break;
9c2149c8
TS
6245 default:
6246 goto die;
6247 }
6248 break;
6249 case 21:
6250 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6251 switch (sel) {
6252 case 0:
895c2d04 6253 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6254 rn = "Framemask";
6255 break;
9c2149c8
TS
6256 default:
6257 goto die;
6258 }
6259 break;
6260 case 22:
6261 /* ignored */
6262 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6263 break;
9c2149c8
TS
6264 case 23:
6265 switch (sel) {
6266 case 0:
895c2d04 6267 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6268 /* BS_STOP isn't good enough here, hflags may have changed. */
6269 gen_save_pc(ctx->pc + 4);
6270 ctx->bstate = BS_EXCP;
2423f660
TS
6271 rn = "Debug";
6272 break;
9c2149c8 6273 case 1:
895c2d04 6274// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6275 /* Stop translation as we may have switched the execution mode */
6276 ctx->bstate = BS_STOP;
2423f660
TS
6277 rn = "TraceControl";
6278// break;
9c2149c8 6279 case 2:
895c2d04 6280// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6281 /* Stop translation as we may have switched the execution mode */
6282 ctx->bstate = BS_STOP;
2423f660
TS
6283 rn = "TraceControl2";
6284// break;
9c2149c8 6285 case 3:
895c2d04 6286// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6287 /* Stop translation as we may have switched the execution mode */
6288 ctx->bstate = BS_STOP;
2423f660
TS
6289 rn = "UserTraceData";
6290// break;
9c2149c8 6291 case 4:
895c2d04 6292// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6293 /* Stop translation as we may have switched the execution mode */
6294 ctx->bstate = BS_STOP;
2423f660
TS
6295 rn = "TraceBPC";
6296// break;
9c2149c8
TS
6297 default:
6298 goto die;
6299 }
9c2149c8
TS
6300 break;
6301 case 24:
6302 switch (sel) {
6303 case 0:
f1aa6320 6304 /* EJTAG support */
7db13fae 6305 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6306 rn = "DEPC";
6307 break;
9c2149c8
TS
6308 default:
6309 goto die;
6310 }
6311 break;
6312 case 25:
6313 switch (sel) {
6314 case 0:
895c2d04 6315 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6316 rn = "Performance0";
6317 break;
9c2149c8 6318 case 1:
895c2d04 6319// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6320 rn = "Performance1";
6321// break;
9c2149c8 6322 case 2:
895c2d04 6323// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6324 rn = "Performance2";
6325// break;
9c2149c8 6326 case 3:
895c2d04 6327// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6328 rn = "Performance3";
6329// break;
9c2149c8 6330 case 4:
895c2d04 6331// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6332 rn = "Performance4";
6333// break;
9c2149c8 6334 case 5:
895c2d04 6335// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6336 rn = "Performance5";
6337// break;
9c2149c8 6338 case 6:
895c2d04 6339// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6340 rn = "Performance6";
6341// break;
9c2149c8 6342 case 7:
895c2d04 6343// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6344 rn = "Performance7";
6345// break;
9c2149c8
TS
6346 default:
6347 goto die;
6348 }
876d4b07 6349 break;
9c2149c8 6350 case 26:
876d4b07 6351 /* ignored */
9c2149c8 6352 rn = "ECC";
876d4b07 6353 break;
9c2149c8
TS
6354 case 27:
6355 switch (sel) {
6356 case 0 ... 3:
2423f660
TS
6357 /* ignored */
6358 rn = "CacheErr";
6359 break;
9c2149c8
TS
6360 default:
6361 goto die;
6362 }
876d4b07 6363 break;
9c2149c8
TS
6364 case 28:
6365 switch (sel) {
6366 case 0:
6367 case 2:
6368 case 4:
6369 case 6:
895c2d04 6370 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6371 rn = "TagLo";
6372 break;
6373 case 1:
6374 case 3:
6375 case 5:
6376 case 7:
895c2d04 6377 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6378 rn = "DataLo";
6379 break;
6380 default:
6381 goto die;
6382 }
6383 break;
6384 case 29:
6385 switch (sel) {
6386 case 0:
6387 case 2:
6388 case 4:
6389 case 6:
895c2d04 6390 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6391 rn = "TagHi";
6392 break;
6393 case 1:
6394 case 3:
6395 case 5:
6396 case 7:
895c2d04 6397 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6398 rn = "DataHi";
6399 break;
6400 default:
6401 rn = "invalid sel";
6402 goto die;
6403 }
876d4b07 6404 break;
9c2149c8
TS
6405 case 30:
6406 switch (sel) {
6407 case 0:
7db13fae 6408 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6409 rn = "ErrorEPC";
6410 break;
9c2149c8
TS
6411 default:
6412 goto die;
6413 }
6414 break;
6415 case 31:
6416 switch (sel) {
6417 case 0:
f1aa6320 6418 /* EJTAG support */
7db13fae 6419 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6420 rn = "DESAVE";
6421 break;
9c2149c8
TS
6422 default:
6423 goto die;
6424 }
876d4b07
TS
6425 /* Stop translation as we may have switched the execution mode */
6426 ctx->bstate = BS_STOP;
9c2149c8
TS
6427 break;
6428 default:
876d4b07 6429 goto die;
9c2149c8 6430 }
2abf314d 6431 (void)rn; /* avoid a compiler warning */
d12d51d5 6432 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6433 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6434 if (use_icount) {
6435 gen_io_end();
6436 ctx->bstate = BS_STOP;
6437 }
9c2149c8
TS
6438 return;
6439
6440die:
d12d51d5 6441 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6442 generate_exception(ctx, EXCP_RI);
6443}
d26bc211 6444#endif /* TARGET_MIPS64 */
9c2149c8 6445
7db13fae 6446static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6447 int u, int sel, int h)
6448{
6449 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6450 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6451
6452 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6453 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6454 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6455 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6456 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6457 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6458 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6459 else if (u == 0) {
6460 switch (rt) {
5a25ce94
EI
6461 case 1:
6462 switch (sel) {
6463 case 1:
895c2d04 6464 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6465 break;
6466 case 2:
895c2d04 6467 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6468 break;
6469 default:
6470 goto die;
6471 break;
6472 }
6473 break;
ead9360e
TS
6474 case 2:
6475 switch (sel) {
6476 case 1:
895c2d04 6477 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6478 break;
6479 case 2:
895c2d04 6480 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6481 break;
6482 case 3:
895c2d04 6483 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6484 break;
6485 case 4:
895c2d04 6486 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6487 break;
6488 case 5:
895c2d04 6489 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6490 break;
6491 case 6:
895c2d04 6492 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6493 break;
6494 case 7:
895c2d04 6495 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6496 break;
6497 default:
d75c135e 6498 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6499 break;
6500 }
6501 break;
6502 case 10:
6503 switch (sel) {
6504 case 0:
895c2d04 6505 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6506 break;
6507 default:
d75c135e 6508 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6509 break;
6510 }
6511 case 12:
6512 switch (sel) {
6513 case 0:
895c2d04 6514 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6515 break;
6516 default:
d75c135e 6517 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6518 break;
6519 }
5a25ce94
EI
6520 case 13:
6521 switch (sel) {
6522 case 0:
895c2d04 6523 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6524 break;
6525 default:
6526 goto die;
6527 break;
6528 }
6529 break;
6530 case 14:
6531 switch (sel) {
6532 case 0:
895c2d04 6533 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6534 break;
6535 default:
6536 goto die;
6537 break;
6538 }
6539 break;
6540 case 15:
6541 switch (sel) {
6542 case 1:
895c2d04 6543 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6544 break;
6545 default:
6546 goto die;
6547 break;
6548 }
6549 break;
6550 case 16:
6551 switch (sel) {
6552 case 0 ... 7:
895c2d04 6553 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6554 break;
6555 default:
6556 goto die;
6557 break;
6558 }
6559 break;
ead9360e
TS
6560 case 23:
6561 switch (sel) {
6562 case 0:
895c2d04 6563 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6564 break;
6565 default:
d75c135e 6566 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6567 break;
6568 }
6569 break;
6570 default:
d75c135e 6571 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6572 }
6573 } else switch (sel) {
6574 /* GPR registers. */
6575 case 0:
895c2d04 6576 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6577 break;
6578 /* Auxiliary CPU registers */
6579 case 1:
6580 switch (rt) {
6581 case 0:
895c2d04 6582 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6583 break;
6584 case 1:
895c2d04 6585 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6586 break;
6587 case 2:
895c2d04 6588 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6589 break;
6590 case 4:
895c2d04 6591 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6592 break;
6593 case 5:
895c2d04 6594 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6595 break;
6596 case 6:
895c2d04 6597 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6598 break;
6599 case 8:
895c2d04 6600 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6601 break;
6602 case 9:
895c2d04 6603 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6604 break;
6605 case 10:
895c2d04 6606 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6607 break;
6608 case 12:
895c2d04 6609 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6610 break;
6611 case 13:
895c2d04 6612 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6613 break;
6614 case 14:
895c2d04 6615 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6616 break;
6617 case 16:
895c2d04 6618 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6619 break;
6620 default:
6621 goto die;
6622 }
6623 break;
6624 /* Floating point (COP1). */
6625 case 2:
6626 /* XXX: For now we support only a single FPU context. */
6627 if (h == 0) {
a7812ae4 6628 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6629
6630 gen_load_fpr32(fp0, rt);
6631 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6632 tcg_temp_free_i32(fp0);
ead9360e 6633 } else {
a7812ae4 6634 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6635
6636 gen_load_fpr32h(fp0, rt);
6637 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6638 tcg_temp_free_i32(fp0);
ead9360e
TS
6639 }
6640 break;
6641 case 3:
6642 /* XXX: For now we support only a single FPU context. */
895c2d04 6643 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6644 break;
6645 /* COP2: Not implemented. */
6646 case 4:
6647 case 5:
6648 /* fall through */
6649 default:
6650 goto die;
6651 }
d12d51d5 6652 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6653 gen_store_gpr(t0, rd);
6654 tcg_temp_free(t0);
ead9360e
TS
6655 return;
6656
6657die:
1a3fd9c3 6658 tcg_temp_free(t0);
d12d51d5 6659 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6660 generate_exception(ctx, EXCP_RI);
6661}
6662
7db13fae 6663static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6664 int u, int sel, int h)
6665{
6666 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6667 TCGv t0 = tcg_temp_local_new();
ead9360e 6668
1a3fd9c3 6669 gen_load_gpr(t0, rt);
ead9360e 6670 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6671 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6672 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6673 /* NOP */ ;
6674 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6675 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6676 /* NOP */ ;
6677 else if (u == 0) {
6678 switch (rd) {
5a25ce94
EI
6679 case 1:
6680 switch (sel) {
6681 case 1:
895c2d04 6682 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6683 break;
6684 case 2:
895c2d04 6685 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6686 break;
6687 default:
6688 goto die;
6689 break;
6690 }
6691 break;
ead9360e
TS
6692 case 2:
6693 switch (sel) {
6694 case 1:
895c2d04 6695 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6696 break;
6697 case 2:
895c2d04 6698 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6699 break;
6700 case 3:
895c2d04 6701 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6702 break;
6703 case 4:
895c2d04 6704 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6705 break;
6706 case 5:
895c2d04 6707 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6708 break;
6709 case 6:
895c2d04 6710 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6711 break;
6712 case 7:
895c2d04 6713 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6714 break;
6715 default:
d75c135e 6716 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6717 break;
6718 }
6719 break;
6720 case 10:
6721 switch (sel) {
6722 case 0:
895c2d04 6723 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6724 break;
6725 default:
d75c135e 6726 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6727 break;
6728 }
6729 case 12:
6730 switch (sel) {
6731 case 0:
895c2d04 6732 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6733 break;
6734 default:
d75c135e 6735 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6736 break;
6737 }
5a25ce94
EI
6738 case 13:
6739 switch (sel) {
6740 case 0:
895c2d04 6741 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6742 break;
6743 default:
6744 goto die;
6745 break;
6746 }
6747 break;
6748 case 15:
6749 switch (sel) {
6750 case 1:
895c2d04 6751 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6752 break;
6753 default:
6754 goto die;
6755 break;
6756 }
6757 break;
ead9360e
TS
6758 case 23:
6759 switch (sel) {
6760 case 0:
895c2d04 6761 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6762 break;
6763 default:
d75c135e 6764 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6765 break;
6766 }
6767 break;
6768 default:
d75c135e 6769 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6770 }
6771 } else switch (sel) {
6772 /* GPR registers. */
6773 case 0:
895c2d04 6774 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6775 break;
6776 /* Auxiliary CPU registers */
6777 case 1:
6778 switch (rd) {
6779 case 0:
895c2d04 6780 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6781 break;
6782 case 1:
895c2d04 6783 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6784 break;
6785 case 2:
895c2d04 6786 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6787 break;
6788 case 4:
895c2d04 6789 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6790 break;
6791 case 5:
895c2d04 6792 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6793 break;
6794 case 6:
895c2d04 6795 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6796 break;
6797 case 8:
895c2d04 6798 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6799 break;
6800 case 9:
895c2d04 6801 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6802 break;
6803 case 10:
895c2d04 6804 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6805 break;
6806 case 12:
895c2d04 6807 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6808 break;
6809 case 13:
895c2d04 6810 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6811 break;
6812 case 14:
895c2d04 6813 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6814 break;
6815 case 16:
895c2d04 6816 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6817 break;
6818 default:
6819 goto die;
6820 }
6821 break;
6822 /* Floating point (COP1). */
6823 case 2:
6824 /* XXX: For now we support only a single FPU context. */
6825 if (h == 0) {
a7812ae4 6826 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6827
6828 tcg_gen_trunc_tl_i32(fp0, t0);
6829 gen_store_fpr32(fp0, rd);
a7812ae4 6830 tcg_temp_free_i32(fp0);
ead9360e 6831 } else {
a7812ae4 6832 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6833
6834 tcg_gen_trunc_tl_i32(fp0, t0);
6835 gen_store_fpr32h(fp0, rd);
a7812ae4 6836 tcg_temp_free_i32(fp0);
ead9360e
TS
6837 }
6838 break;
6839 case 3:
6840 /* XXX: For now we support only a single FPU context. */
895c2d04 6841 gen_helper_0e1i(ctc1, t0, rd);
ead9360e
TS
6842 break;
6843 /* COP2: Not implemented. */
6844 case 4:
6845 case 5:
6846 /* fall through */
6847 default:
6848 goto die;
6849 }
d12d51d5 6850 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6851 tcg_temp_free(t0);
ead9360e
TS
6852 return;
6853
6854die:
1a3fd9c3 6855 tcg_temp_free(t0);
d12d51d5 6856 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6857 generate_exception(ctx, EXCP_RI);
6858}
6859
7db13fae 6860static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6861{
287c4b84 6862 const char *opn = "ldst";
6af0bf9c 6863
2e15497c 6864 check_cp0_enabled(ctx);
6af0bf9c
FB
6865 switch (opc) {
6866 case OPC_MFC0:
6867 if (rt == 0) {
ead9360e 6868 /* Treat as NOP. */
6af0bf9c
FB
6869 return;
6870 }
d75c135e 6871 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6872 opn = "mfc0";
6873 break;
6874 case OPC_MTC0:
1a3fd9c3 6875 {
1fc7bf6e 6876 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6877
6878 gen_load_gpr(t0, rt);
d75c135e 6879 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6880 tcg_temp_free(t0);
6881 }
6af0bf9c
FB
6882 opn = "mtc0";
6883 break;
d26bc211 6884#if defined(TARGET_MIPS64)
9c2149c8 6885 case OPC_DMFC0:
d75c135e 6886 check_insn(ctx, ISA_MIPS3);
9c2149c8 6887 if (rt == 0) {
ead9360e 6888 /* Treat as NOP. */
9c2149c8
TS
6889 return;
6890 }
d75c135e 6891 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6892 opn = "dmfc0";
6893 break;
6894 case OPC_DMTC0:
d75c135e 6895 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 6896 {
1fc7bf6e 6897 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6898
6899 gen_load_gpr(t0, rt);
d75c135e 6900 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6901 tcg_temp_free(t0);
6902 }
9c2149c8
TS
6903 opn = "dmtc0";
6904 break;
534ce69f 6905#endif
ead9360e 6906 case OPC_MFTR:
d75c135e 6907 check_insn(ctx, ASE_MT);
ead9360e
TS
6908 if (rd == 0) {
6909 /* Treat as NOP. */
6910 return;
6911 }
6c5c1e20 6912 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6913 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6914 opn = "mftr";
6915 break;
6916 case OPC_MTTR:
d75c135e 6917 check_insn(ctx, ASE_MT);
6c5c1e20 6918 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6919 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6920 opn = "mttr";
6921 break;
6af0bf9c 6922 case OPC_TLBWI:
6af0bf9c 6923 opn = "tlbwi";
c01fccd2 6924 if (!env->tlb->helper_tlbwi)
29929e34 6925 goto die;
895c2d04 6926 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6927 break;
6928 case OPC_TLBWR:
6af0bf9c 6929 opn = "tlbwr";
c01fccd2 6930 if (!env->tlb->helper_tlbwr)
29929e34 6931 goto die;
895c2d04 6932 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6933 break;
6934 case OPC_TLBP:
6af0bf9c 6935 opn = "tlbp";
c01fccd2 6936 if (!env->tlb->helper_tlbp)
29929e34 6937 goto die;
895c2d04 6938 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6939 break;
6940 case OPC_TLBR:
6af0bf9c 6941 opn = "tlbr";
c01fccd2 6942 if (!env->tlb->helper_tlbr)
29929e34 6943 goto die;
895c2d04 6944 gen_helper_tlbr(cpu_env);
6af0bf9c 6945 break;
6af0bf9c
FB
6946 case OPC_ERET:
6947 opn = "eret";
d75c135e 6948 check_insn(ctx, ISA_MIPS2);
895c2d04 6949 gen_helper_eret(cpu_env);
6af0bf9c
FB
6950 ctx->bstate = BS_EXCP;
6951 break;
6952 case OPC_DERET:
6953 opn = "deret";
d75c135e 6954 check_insn(ctx, ISA_MIPS32);
6af0bf9c 6955 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6956 MIPS_INVAL(opn);
6af0bf9c
FB
6957 generate_exception(ctx, EXCP_RI);
6958 } else {
895c2d04 6959 gen_helper_deret(cpu_env);
6af0bf9c
FB
6960 ctx->bstate = BS_EXCP;
6961 }
6962 break;
4ad40f36
FB
6963 case OPC_WAIT:
6964 opn = "wait";
d75c135e 6965 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6966 /* If we get an exception, we want to restart at next instruction */
6967 ctx->pc += 4;
6968 save_cpu_state(ctx, 1);
6969 ctx->pc -= 4;
895c2d04 6970 gen_helper_wait(cpu_env);
4ad40f36
FB
6971 ctx->bstate = BS_EXCP;
6972 break;
6af0bf9c 6973 default:
29929e34 6974 die:
923617a3 6975 MIPS_INVAL(opn);
6af0bf9c
FB
6976 generate_exception(ctx, EXCP_RI);
6977 return;
6978 }
2abf314d 6979 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
6980 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6981}
f1aa6320 6982#endif /* !CONFIG_USER_ONLY */
6af0bf9c 6983
6ea83fed 6984/* CP1 Branches (before delay slot) */
d75c135e
AJ
6985static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6986 int32_t cc, int32_t offset)
6ea83fed
FB
6987{
6988 target_ulong btarget;
923617a3 6989 const char *opn = "cp1 cond branch";
a7812ae4 6990 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 6991
e189e748 6992 if (cc != 0)
d75c135e 6993 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 6994
6ea83fed
FB
6995 btarget = ctx->pc + 4 + offset;
6996
7a387fff
TS
6997 switch (op) {
6998 case OPC_BC1F:
d94536f4
AJ
6999 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7000 tcg_gen_not_i32(t0, t0);
7001 tcg_gen_andi_i32(t0, t0, 1);
7002 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7003 opn = "bc1f";
6ea83fed 7004 goto not_likely;
7a387fff 7005 case OPC_BC1FL:
d94536f4
AJ
7006 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7007 tcg_gen_not_i32(t0, t0);
7008 tcg_gen_andi_i32(t0, t0, 1);
7009 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7010 opn = "bc1fl";
6ea83fed 7011 goto likely;
7a387fff 7012 case OPC_BC1T:
d94536f4
AJ
7013 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7014 tcg_gen_andi_i32(t0, t0, 1);
7015 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7016 opn = "bc1t";
5a5012ec 7017 goto not_likely;
7a387fff 7018 case OPC_BC1TL:
d94536f4
AJ
7019 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7020 tcg_gen_andi_i32(t0, t0, 1);
7021 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7022 opn = "bc1tl";
6ea83fed
FB
7023 likely:
7024 ctx->hflags |= MIPS_HFLAG_BL;
7025 break;
5a5012ec 7026 case OPC_BC1FANY2:
a16336e4 7027 {
d94536f4
AJ
7028 TCGv_i32 t1 = tcg_temp_new_i32();
7029 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7030 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7031 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7032 tcg_temp_free_i32(t1);
d94536f4
AJ
7033 tcg_gen_andi_i32(t0, t0, 1);
7034 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7035 }
fd4a04eb 7036 opn = "bc1any2f";
5a5012ec
TS
7037 goto not_likely;
7038 case OPC_BC1TANY2:
a16336e4 7039 {
d94536f4
AJ
7040 TCGv_i32 t1 = tcg_temp_new_i32();
7041 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7042 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7043 tcg_gen_or_i32(t0, t0, t1);
7044 tcg_temp_free_i32(t1);
7045 tcg_gen_andi_i32(t0, t0, 1);
7046 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7047 }
fd4a04eb 7048 opn = "bc1any2t";
5a5012ec
TS
7049 goto not_likely;
7050 case OPC_BC1FANY4:
a16336e4 7051 {
d94536f4
AJ
7052 TCGv_i32 t1 = tcg_temp_new_i32();
7053 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7054 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7055 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7056 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7057 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7058 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7059 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7060 tcg_temp_free_i32(t1);
d94536f4
AJ
7061 tcg_gen_andi_i32(t0, t0, 1);
7062 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7063 }
fd4a04eb 7064 opn = "bc1any4f";
5a5012ec
TS
7065 goto not_likely;
7066 case OPC_BC1TANY4:
a16336e4 7067 {
d94536f4
AJ
7068 TCGv_i32 t1 = tcg_temp_new_i32();
7069 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7070 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7071 tcg_gen_or_i32(t0, t0, t1);
7072 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7073 tcg_gen_or_i32(t0, t0, t1);
7074 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7075 tcg_gen_or_i32(t0, t0, t1);
7076 tcg_temp_free_i32(t1);
7077 tcg_gen_andi_i32(t0, t0, 1);
7078 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7079 }
fd4a04eb 7080 opn = "bc1any4t";
5a5012ec
TS
7081 not_likely:
7082 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7083 break;
7084 default:
923617a3 7085 MIPS_INVAL(opn);
e397ee33 7086 generate_exception (ctx, EXCP_RI);
6c5c1e20 7087 goto out;
6ea83fed 7088 }
2abf314d 7089 (void)opn; /* avoid a compiler warning */
923617a3 7090 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7091 ctx->hflags, btarget);
7092 ctx->btarget = btarget;
6c5c1e20
TS
7093
7094 out:
a7812ae4 7095 tcg_temp_free_i32(t0);
6ea83fed
FB
7096}
7097
6af0bf9c 7098/* Coprocessor 1 (FPU) */
5a5012ec 7099
5a5012ec
TS
7100#define FOP(func, fmt) (((fmt) << 21) | (func))
7101
bf4120ad
NF
7102enum fopcode {
7103 OPC_ADD_S = FOP(0, FMT_S),
7104 OPC_SUB_S = FOP(1, FMT_S),
7105 OPC_MUL_S = FOP(2, FMT_S),
7106 OPC_DIV_S = FOP(3, FMT_S),
7107 OPC_SQRT_S = FOP(4, FMT_S),
7108 OPC_ABS_S = FOP(5, FMT_S),
7109 OPC_MOV_S = FOP(6, FMT_S),
7110 OPC_NEG_S = FOP(7, FMT_S),
7111 OPC_ROUND_L_S = FOP(8, FMT_S),
7112 OPC_TRUNC_L_S = FOP(9, FMT_S),
7113 OPC_CEIL_L_S = FOP(10, FMT_S),
7114 OPC_FLOOR_L_S = FOP(11, FMT_S),
7115 OPC_ROUND_W_S = FOP(12, FMT_S),
7116 OPC_TRUNC_W_S = FOP(13, FMT_S),
7117 OPC_CEIL_W_S = FOP(14, FMT_S),
7118 OPC_FLOOR_W_S = FOP(15, FMT_S),
7119 OPC_MOVCF_S = FOP(17, FMT_S),
7120 OPC_MOVZ_S = FOP(18, FMT_S),
7121 OPC_MOVN_S = FOP(19, FMT_S),
7122 OPC_RECIP_S = FOP(21, FMT_S),
7123 OPC_RSQRT_S = FOP(22, FMT_S),
7124 OPC_RECIP2_S = FOP(28, FMT_S),
7125 OPC_RECIP1_S = FOP(29, FMT_S),
7126 OPC_RSQRT1_S = FOP(30, FMT_S),
7127 OPC_RSQRT2_S = FOP(31, FMT_S),
7128 OPC_CVT_D_S = FOP(33, FMT_S),
7129 OPC_CVT_W_S = FOP(36, FMT_S),
7130 OPC_CVT_L_S = FOP(37, FMT_S),
7131 OPC_CVT_PS_S = FOP(38, FMT_S),
7132 OPC_CMP_F_S = FOP (48, FMT_S),
7133 OPC_CMP_UN_S = FOP (49, FMT_S),
7134 OPC_CMP_EQ_S = FOP (50, FMT_S),
7135 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7136 OPC_CMP_OLT_S = FOP (52, FMT_S),
7137 OPC_CMP_ULT_S = FOP (53, FMT_S),
7138 OPC_CMP_OLE_S = FOP (54, FMT_S),
7139 OPC_CMP_ULE_S = FOP (55, FMT_S),
7140 OPC_CMP_SF_S = FOP (56, FMT_S),
7141 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7142 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7143 OPC_CMP_NGL_S = FOP (59, FMT_S),
7144 OPC_CMP_LT_S = FOP (60, FMT_S),
7145 OPC_CMP_NGE_S = FOP (61, FMT_S),
7146 OPC_CMP_LE_S = FOP (62, FMT_S),
7147 OPC_CMP_NGT_S = FOP (63, FMT_S),
7148
7149 OPC_ADD_D = FOP(0, FMT_D),
7150 OPC_SUB_D = FOP(1, FMT_D),
7151 OPC_MUL_D = FOP(2, FMT_D),
7152 OPC_DIV_D = FOP(3, FMT_D),
7153 OPC_SQRT_D = FOP(4, FMT_D),
7154 OPC_ABS_D = FOP(5, FMT_D),
7155 OPC_MOV_D = FOP(6, FMT_D),
7156 OPC_NEG_D = FOP(7, FMT_D),
7157 OPC_ROUND_L_D = FOP(8, FMT_D),
7158 OPC_TRUNC_L_D = FOP(9, FMT_D),
7159 OPC_CEIL_L_D = FOP(10, FMT_D),
7160 OPC_FLOOR_L_D = FOP(11, FMT_D),
7161 OPC_ROUND_W_D = FOP(12, FMT_D),
7162 OPC_TRUNC_W_D = FOP(13, FMT_D),
7163 OPC_CEIL_W_D = FOP(14, FMT_D),
7164 OPC_FLOOR_W_D = FOP(15, FMT_D),
7165 OPC_MOVCF_D = FOP(17, FMT_D),
7166 OPC_MOVZ_D = FOP(18, FMT_D),
7167 OPC_MOVN_D = FOP(19, FMT_D),
7168 OPC_RECIP_D = FOP(21, FMT_D),
7169 OPC_RSQRT_D = FOP(22, FMT_D),
7170 OPC_RECIP2_D = FOP(28, FMT_D),
7171 OPC_RECIP1_D = FOP(29, FMT_D),
7172 OPC_RSQRT1_D = FOP(30, FMT_D),
7173 OPC_RSQRT2_D = FOP(31, FMT_D),
7174 OPC_CVT_S_D = FOP(32, FMT_D),
7175 OPC_CVT_W_D = FOP(36, FMT_D),
7176 OPC_CVT_L_D = FOP(37, FMT_D),
7177 OPC_CMP_F_D = FOP (48, FMT_D),
7178 OPC_CMP_UN_D = FOP (49, FMT_D),
7179 OPC_CMP_EQ_D = FOP (50, FMT_D),
7180 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7181 OPC_CMP_OLT_D = FOP (52, FMT_D),
7182 OPC_CMP_ULT_D = FOP (53, FMT_D),
7183 OPC_CMP_OLE_D = FOP (54, FMT_D),
7184 OPC_CMP_ULE_D = FOP (55, FMT_D),
7185 OPC_CMP_SF_D = FOP (56, FMT_D),
7186 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7187 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7188 OPC_CMP_NGL_D = FOP (59, FMT_D),
7189 OPC_CMP_LT_D = FOP (60, FMT_D),
7190 OPC_CMP_NGE_D = FOP (61, FMT_D),
7191 OPC_CMP_LE_D = FOP (62, FMT_D),
7192 OPC_CMP_NGT_D = FOP (63, FMT_D),
7193
7194 OPC_CVT_S_W = FOP(32, FMT_W),
7195 OPC_CVT_D_W = FOP(33, FMT_W),
7196 OPC_CVT_S_L = FOP(32, FMT_L),
7197 OPC_CVT_D_L = FOP(33, FMT_L),
7198 OPC_CVT_PS_PW = FOP(38, FMT_W),
7199
7200 OPC_ADD_PS = FOP(0, FMT_PS),
7201 OPC_SUB_PS = FOP(1, FMT_PS),
7202 OPC_MUL_PS = FOP(2, FMT_PS),
7203 OPC_DIV_PS = FOP(3, FMT_PS),
7204 OPC_ABS_PS = FOP(5, FMT_PS),
7205 OPC_MOV_PS = FOP(6, FMT_PS),
7206 OPC_NEG_PS = FOP(7, FMT_PS),
7207 OPC_MOVCF_PS = FOP(17, FMT_PS),
7208 OPC_MOVZ_PS = FOP(18, FMT_PS),
7209 OPC_MOVN_PS = FOP(19, FMT_PS),
7210 OPC_ADDR_PS = FOP(24, FMT_PS),
7211 OPC_MULR_PS = FOP(26, FMT_PS),
7212 OPC_RECIP2_PS = FOP(28, FMT_PS),
7213 OPC_RECIP1_PS = FOP(29, FMT_PS),
7214 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7215 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7216
7217 OPC_CVT_S_PU = FOP(32, FMT_PS),
7218 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7219 OPC_CVT_S_PL = FOP(40, FMT_PS),
7220 OPC_PLL_PS = FOP(44, FMT_PS),
7221 OPC_PLU_PS = FOP(45, FMT_PS),
7222 OPC_PUL_PS = FOP(46, FMT_PS),
7223 OPC_PUU_PS = FOP(47, FMT_PS),
7224 OPC_CMP_F_PS = FOP (48, FMT_PS),
7225 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7226 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7227 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7228 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7229 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7230 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7231 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7232 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7233 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7234 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7235 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7236 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7237 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7238 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7239 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7240};
7241
7a387fff 7242static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7243{
923617a3 7244 const char *opn = "cp1 move";
72c3a3ee 7245 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7246
7247 switch (opc) {
7248 case OPC_MFC1:
b6d96bed 7249 {
a7812ae4 7250 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7251
7252 gen_load_fpr32(fp0, fs);
7253 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7254 tcg_temp_free_i32(fp0);
6958549d 7255 }
6c5c1e20 7256 gen_store_gpr(t0, rt);
6ea83fed
FB
7257 opn = "mfc1";
7258 break;
7259 case OPC_MTC1:
6c5c1e20 7260 gen_load_gpr(t0, rt);
b6d96bed 7261 {
a7812ae4 7262 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7263
7264 tcg_gen_trunc_tl_i32(fp0, t0);
7265 gen_store_fpr32(fp0, fs);
a7812ae4 7266 tcg_temp_free_i32(fp0);
6958549d 7267 }
6ea83fed
FB
7268 opn = "mtc1";
7269 break;
7270 case OPC_CFC1:
895c2d04 7271 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7272 gen_store_gpr(t0, rt);
6ea83fed
FB
7273 opn = "cfc1";
7274 break;
7275 case OPC_CTC1:
6c5c1e20 7276 gen_load_gpr(t0, rt);
895c2d04 7277 gen_helper_0e1i(ctc1, t0, fs);
6ea83fed
FB
7278 opn = "ctc1";
7279 break;
72c3a3ee 7280#if defined(TARGET_MIPS64)
9c2149c8 7281 case OPC_DMFC1:
72c3a3ee 7282 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7283 gen_store_gpr(t0, rt);
5a5012ec
TS
7284 opn = "dmfc1";
7285 break;
9c2149c8 7286 case OPC_DMTC1:
6c5c1e20 7287 gen_load_gpr(t0, rt);
72c3a3ee 7288 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7289 opn = "dmtc1";
7290 break;
72c3a3ee 7291#endif
5a5012ec 7292 case OPC_MFHC1:
b6d96bed 7293 {
a7812ae4 7294 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7295
7296 gen_load_fpr32h(fp0, fs);
7297 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7298 tcg_temp_free_i32(fp0);
6958549d 7299 }
6c5c1e20 7300 gen_store_gpr(t0, rt);
5a5012ec
TS
7301 opn = "mfhc1";
7302 break;
7303 case OPC_MTHC1:
6c5c1e20 7304 gen_load_gpr(t0, rt);
b6d96bed 7305 {
a7812ae4 7306 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7307
7308 tcg_gen_trunc_tl_i32(fp0, t0);
7309 gen_store_fpr32h(fp0, fs);
a7812ae4 7310 tcg_temp_free_i32(fp0);
6958549d 7311 }
5a5012ec
TS
7312 opn = "mthc1";
7313 break;
6ea83fed 7314 default:
923617a3 7315 MIPS_INVAL(opn);
e397ee33 7316 generate_exception (ctx, EXCP_RI);
6c5c1e20 7317 goto out;
6ea83fed 7318 }
2abf314d 7319 (void)opn; /* avoid a compiler warning */
6ea83fed 7320 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7321
7322 out:
7323 tcg_temp_free(t0);
6ea83fed
FB
7324}
7325
5a5012ec
TS
7326static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7327{
af58f9ca 7328 int l1;
e214b9bb 7329 TCGCond cond;
af58f9ca
AJ
7330 TCGv_i32 t0;
7331
7332 if (rd == 0) {
7333 /* Treat as NOP. */
7334 return;
7335 }
6ea83fed 7336
e214b9bb 7337 if (tf)
e214b9bb 7338 cond = TCG_COND_EQ;
27848470
TS
7339 else
7340 cond = TCG_COND_NE;
7341
af58f9ca
AJ
7342 l1 = gen_new_label();
7343 t0 = tcg_temp_new_i32();
fa31af0e 7344 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7345 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7346 tcg_temp_free_i32(t0);
af58f9ca
AJ
7347 if (rs == 0) {
7348 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7349 } else {
7350 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7351 }
e214b9bb 7352 gen_set_label(l1);
5a5012ec
TS
7353}
7354
b6d96bed 7355static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7356{
a16336e4 7357 int cond;
cbc37b28 7358 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7359 int l1 = gen_new_label();
7360
a16336e4
TS
7361 if (tf)
7362 cond = TCG_COND_EQ;
7363 else
7364 cond = TCG_COND_NE;
7365
fa31af0e 7366 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7367 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7368 gen_load_fpr32(t0, fs);
7369 gen_store_fpr32(t0, fd);
a16336e4 7370 gen_set_label(l1);
cbc37b28 7371 tcg_temp_free_i32(t0);
5a5012ec 7372}
a16336e4 7373
b6d96bed 7374static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7375{
a16336e4 7376 int cond;
cbc37b28
AJ
7377 TCGv_i32 t0 = tcg_temp_new_i32();
7378 TCGv_i64 fp0;
a16336e4
TS
7379 int l1 = gen_new_label();
7380
a16336e4
TS
7381 if (tf)
7382 cond = TCG_COND_EQ;
7383 else
7384 cond = TCG_COND_NE;
7385
fa31af0e 7386 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7387 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7388 tcg_temp_free_i32(t0);
11f94258 7389 fp0 = tcg_temp_new_i64();
9bf3eb2c 7390 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7391 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7392 tcg_temp_free_i64(fp0);
cbc37b28 7393 gen_set_label(l1);
a16336e4
TS
7394}
7395
b6d96bed 7396static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
a16336e4
TS
7397{
7398 int cond;
cbc37b28 7399 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7400 int l1 = gen_new_label();
7401 int l2 = gen_new_label();
7402
7403 if (tf)
7404 cond = TCG_COND_EQ;
7405 else
7406 cond = TCG_COND_NE;
7407
fa31af0e 7408 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7409 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7410 gen_load_fpr32(t0, fs);
7411 gen_store_fpr32(t0, fd);
a16336e4 7412 gen_set_label(l1);
9bf3eb2c 7413
fa31af0e 7414 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28
AJ
7415 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7416 gen_load_fpr32h(t0, fs);
7417 gen_store_fpr32h(t0, fd);
52a0e9eb 7418 tcg_temp_free_i32(t0);
a16336e4 7419 gen_set_label(l2);
a16336e4
TS
7420}
7421
6ea83fed 7422
bf4120ad 7423static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7424 int ft, int fs, int fd, int cc)
6ea83fed 7425{
923617a3 7426 const char *opn = "farith";
6ea83fed
FB
7427 const char *condnames[] = {
7428 "c.f",
7429 "c.un",
7430 "c.eq",
7431 "c.ueq",
7432 "c.olt",
7433 "c.ult",
7434 "c.ole",
7435 "c.ule",
7436 "c.sf",
7437 "c.ngle",
7438 "c.seq",
7439 "c.ngl",
7440 "c.lt",
7441 "c.nge",
7442 "c.le",
7443 "c.ngt",
7444 };
5a1e8ffb
TS
7445 const char *condnames_abs[] = {
7446 "cabs.f",
7447 "cabs.un",
7448 "cabs.eq",
7449 "cabs.ueq",
7450 "cabs.olt",
7451 "cabs.ult",
7452 "cabs.ole",
7453 "cabs.ule",
7454 "cabs.sf",
7455 "cabs.ngle",
7456 "cabs.seq",
7457 "cabs.ngl",
7458 "cabs.lt",
7459 "cabs.nge",
7460 "cabs.le",
7461 "cabs.ngt",
7462 };
7463 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7464 uint32_t func = ctx->opcode & 0x3f;
7465
bf4120ad
NF
7466 switch (op1) {
7467 case OPC_ADD_S:
b6d96bed 7468 {
a7812ae4
PB
7469 TCGv_i32 fp0 = tcg_temp_new_i32();
7470 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7471
7472 gen_load_fpr32(fp0, fs);
7473 gen_load_fpr32(fp1, ft);
895c2d04 7474 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7475 tcg_temp_free_i32(fp1);
b6d96bed 7476 gen_store_fpr32(fp0, fd);
a7812ae4 7477 tcg_temp_free_i32(fp0);
b6d96bed 7478 }
5a5012ec 7479 opn = "add.s";
5a1e8ffb 7480 optype = BINOP;
5a5012ec 7481 break;
bf4120ad 7482 case OPC_SUB_S:
b6d96bed 7483 {
a7812ae4
PB
7484 TCGv_i32 fp0 = tcg_temp_new_i32();
7485 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7486
7487 gen_load_fpr32(fp0, fs);
7488 gen_load_fpr32(fp1, ft);
895c2d04 7489 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7490 tcg_temp_free_i32(fp1);
b6d96bed 7491 gen_store_fpr32(fp0, fd);
a7812ae4 7492 tcg_temp_free_i32(fp0);
b6d96bed 7493 }
5a5012ec 7494 opn = "sub.s";
5a1e8ffb 7495 optype = BINOP;
5a5012ec 7496 break;
bf4120ad 7497 case OPC_MUL_S:
b6d96bed 7498 {
a7812ae4
PB
7499 TCGv_i32 fp0 = tcg_temp_new_i32();
7500 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7501
7502 gen_load_fpr32(fp0, fs);
7503 gen_load_fpr32(fp1, ft);
895c2d04 7504 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7505 tcg_temp_free_i32(fp1);
b6d96bed 7506 gen_store_fpr32(fp0, fd);
a7812ae4 7507 tcg_temp_free_i32(fp0);
b6d96bed 7508 }
5a5012ec 7509 opn = "mul.s";
5a1e8ffb 7510 optype = BINOP;
5a5012ec 7511 break;
bf4120ad 7512 case OPC_DIV_S:
b6d96bed 7513 {
a7812ae4
PB
7514 TCGv_i32 fp0 = tcg_temp_new_i32();
7515 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7516
7517 gen_load_fpr32(fp0, fs);
7518 gen_load_fpr32(fp1, ft);
895c2d04 7519 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7520 tcg_temp_free_i32(fp1);
b6d96bed 7521 gen_store_fpr32(fp0, fd);
a7812ae4 7522 tcg_temp_free_i32(fp0);
b6d96bed 7523 }
5a5012ec 7524 opn = "div.s";
5a1e8ffb 7525 optype = BINOP;
5a5012ec 7526 break;
bf4120ad 7527 case OPC_SQRT_S:
b6d96bed 7528 {
a7812ae4 7529 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7530
7531 gen_load_fpr32(fp0, fs);
895c2d04 7532 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7533 gen_store_fpr32(fp0, fd);
a7812ae4 7534 tcg_temp_free_i32(fp0);
b6d96bed 7535 }
5a5012ec
TS
7536 opn = "sqrt.s";
7537 break;
bf4120ad 7538 case OPC_ABS_S:
b6d96bed 7539 {
a7812ae4 7540 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7541
7542 gen_load_fpr32(fp0, fs);
a7812ae4 7543 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7544 gen_store_fpr32(fp0, fd);
a7812ae4 7545 tcg_temp_free_i32(fp0);
b6d96bed 7546 }
5a5012ec
TS
7547 opn = "abs.s";
7548 break;
bf4120ad 7549 case OPC_MOV_S:
b6d96bed 7550 {
a7812ae4 7551 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7552
7553 gen_load_fpr32(fp0, fs);
7554 gen_store_fpr32(fp0, fd);
a7812ae4 7555 tcg_temp_free_i32(fp0);
b6d96bed 7556 }
5a5012ec
TS
7557 opn = "mov.s";
7558 break;
bf4120ad 7559 case OPC_NEG_S:
b6d96bed 7560 {
a7812ae4 7561 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7562
7563 gen_load_fpr32(fp0, fs);
a7812ae4 7564 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7565 gen_store_fpr32(fp0, fd);
a7812ae4 7566 tcg_temp_free_i32(fp0);
b6d96bed 7567 }
5a5012ec
TS
7568 opn = "neg.s";
7569 break;
bf4120ad 7570 case OPC_ROUND_L_S:
5e755519 7571 check_cp1_64bitmode(ctx);
b6d96bed 7572 {
a7812ae4
PB
7573 TCGv_i32 fp32 = tcg_temp_new_i32();
7574 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7575
7576 gen_load_fpr32(fp32, fs);
895c2d04 7577 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7578 tcg_temp_free_i32(fp32);
b6d96bed 7579 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7580 tcg_temp_free_i64(fp64);
b6d96bed 7581 }
5a5012ec
TS
7582 opn = "round.l.s";
7583 break;
bf4120ad 7584 case OPC_TRUNC_L_S:
5e755519 7585 check_cp1_64bitmode(ctx);
b6d96bed 7586 {
a7812ae4
PB
7587 TCGv_i32 fp32 = tcg_temp_new_i32();
7588 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7589
7590 gen_load_fpr32(fp32, fs);
895c2d04 7591 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7592 tcg_temp_free_i32(fp32);
b6d96bed 7593 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7594 tcg_temp_free_i64(fp64);
b6d96bed 7595 }
5a5012ec
TS
7596 opn = "trunc.l.s";
7597 break;
bf4120ad 7598 case OPC_CEIL_L_S:
5e755519 7599 check_cp1_64bitmode(ctx);
b6d96bed 7600 {
a7812ae4
PB
7601 TCGv_i32 fp32 = tcg_temp_new_i32();
7602 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7603
7604 gen_load_fpr32(fp32, fs);
895c2d04 7605 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7606 tcg_temp_free_i32(fp32);
b6d96bed 7607 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7608 tcg_temp_free_i64(fp64);
b6d96bed 7609 }
5a5012ec
TS
7610 opn = "ceil.l.s";
7611 break;
bf4120ad 7612 case OPC_FLOOR_L_S:
5e755519 7613 check_cp1_64bitmode(ctx);
b6d96bed 7614 {
a7812ae4
PB
7615 TCGv_i32 fp32 = tcg_temp_new_i32();
7616 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7617
7618 gen_load_fpr32(fp32, fs);
895c2d04 7619 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7620 tcg_temp_free_i32(fp32);
b6d96bed 7621 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7622 tcg_temp_free_i64(fp64);
b6d96bed 7623 }
5a5012ec
TS
7624 opn = "floor.l.s";
7625 break;
bf4120ad 7626 case OPC_ROUND_W_S:
b6d96bed 7627 {
a7812ae4 7628 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7629
7630 gen_load_fpr32(fp0, fs);
895c2d04 7631 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7632 gen_store_fpr32(fp0, fd);
a7812ae4 7633 tcg_temp_free_i32(fp0);
b6d96bed 7634 }
5a5012ec
TS
7635 opn = "round.w.s";
7636 break;
bf4120ad 7637 case OPC_TRUNC_W_S:
b6d96bed 7638 {
a7812ae4 7639 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7640
7641 gen_load_fpr32(fp0, fs);
895c2d04 7642 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7643 gen_store_fpr32(fp0, fd);
a7812ae4 7644 tcg_temp_free_i32(fp0);
b6d96bed 7645 }
5a5012ec
TS
7646 opn = "trunc.w.s";
7647 break;
bf4120ad 7648 case OPC_CEIL_W_S:
b6d96bed 7649 {
a7812ae4 7650 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7651
7652 gen_load_fpr32(fp0, fs);
895c2d04 7653 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7654 gen_store_fpr32(fp0, fd);
a7812ae4 7655 tcg_temp_free_i32(fp0);
b6d96bed 7656 }
5a5012ec
TS
7657 opn = "ceil.w.s";
7658 break;
bf4120ad 7659 case OPC_FLOOR_W_S:
b6d96bed 7660 {
a7812ae4 7661 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7662
7663 gen_load_fpr32(fp0, fs);
895c2d04 7664 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7665 gen_store_fpr32(fp0, fd);
a7812ae4 7666 tcg_temp_free_i32(fp0);
b6d96bed 7667 }
5a5012ec
TS
7668 opn = "floor.w.s";
7669 break;
bf4120ad 7670 case OPC_MOVCF_S:
b6d96bed 7671 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7672 opn = "movcf.s";
7673 break;
bf4120ad 7674 case OPC_MOVZ_S:
a16336e4
TS
7675 {
7676 int l1 = gen_new_label();
c9297f4d 7677 TCGv_i32 fp0;
a16336e4 7678
c9297f4d
AJ
7679 if (ft != 0) {
7680 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7681 }
7682 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7683 gen_load_fpr32(fp0, fs);
7684 gen_store_fpr32(fp0, fd);
a7812ae4 7685 tcg_temp_free_i32(fp0);
a16336e4
TS
7686 gen_set_label(l1);
7687 }
5a5012ec
TS
7688 opn = "movz.s";
7689 break;
bf4120ad 7690 case OPC_MOVN_S:
a16336e4
TS
7691 {
7692 int l1 = gen_new_label();
c9297f4d
AJ
7693 TCGv_i32 fp0;
7694
7695 if (ft != 0) {
7696 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7697 fp0 = tcg_temp_new_i32();
7698 gen_load_fpr32(fp0, fs);
7699 gen_store_fpr32(fp0, fd);
7700 tcg_temp_free_i32(fp0);
7701 gen_set_label(l1);
7702 }
a16336e4 7703 }
5a5012ec
TS
7704 opn = "movn.s";
7705 break;
bf4120ad 7706 case OPC_RECIP_S:
b8aa4598 7707 check_cop1x(ctx);
b6d96bed 7708 {
a7812ae4 7709 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7710
7711 gen_load_fpr32(fp0, fs);
895c2d04 7712 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7713 gen_store_fpr32(fp0, fd);
a7812ae4 7714 tcg_temp_free_i32(fp0);
b6d96bed 7715 }
57fa1fb3
TS
7716 opn = "recip.s";
7717 break;
bf4120ad 7718 case OPC_RSQRT_S:
b8aa4598 7719 check_cop1x(ctx);
b6d96bed 7720 {
a7812ae4 7721 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7722
7723 gen_load_fpr32(fp0, fs);
895c2d04 7724 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7725 gen_store_fpr32(fp0, fd);
a7812ae4 7726 tcg_temp_free_i32(fp0);
b6d96bed 7727 }
57fa1fb3
TS
7728 opn = "rsqrt.s";
7729 break;
bf4120ad 7730 case OPC_RECIP2_S:
5e755519 7731 check_cp1_64bitmode(ctx);
b6d96bed 7732 {
a7812ae4
PB
7733 TCGv_i32 fp0 = tcg_temp_new_i32();
7734 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7735
7736 gen_load_fpr32(fp0, fs);
d22d7289 7737 gen_load_fpr32(fp1, ft);
895c2d04 7738 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7739 tcg_temp_free_i32(fp1);
b6d96bed 7740 gen_store_fpr32(fp0, fd);
a7812ae4 7741 tcg_temp_free_i32(fp0);
b6d96bed 7742 }
57fa1fb3
TS
7743 opn = "recip2.s";
7744 break;
bf4120ad 7745 case OPC_RECIP1_S:
5e755519 7746 check_cp1_64bitmode(ctx);
b6d96bed 7747 {
a7812ae4 7748 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7749
7750 gen_load_fpr32(fp0, fs);
895c2d04 7751 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7752 gen_store_fpr32(fp0, fd);
a7812ae4 7753 tcg_temp_free_i32(fp0);
b6d96bed 7754 }
57fa1fb3
TS
7755 opn = "recip1.s";
7756 break;
bf4120ad 7757 case OPC_RSQRT1_S:
5e755519 7758 check_cp1_64bitmode(ctx);
b6d96bed 7759 {
a7812ae4 7760 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7761
7762 gen_load_fpr32(fp0, fs);
895c2d04 7763 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7764 gen_store_fpr32(fp0, fd);
a7812ae4 7765 tcg_temp_free_i32(fp0);
b6d96bed 7766 }
57fa1fb3
TS
7767 opn = "rsqrt1.s";
7768 break;
bf4120ad 7769 case OPC_RSQRT2_S:
5e755519 7770 check_cp1_64bitmode(ctx);
b6d96bed 7771 {
a7812ae4
PB
7772 TCGv_i32 fp0 = tcg_temp_new_i32();
7773 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7774
7775 gen_load_fpr32(fp0, fs);
7776 gen_load_fpr32(fp1, ft);
895c2d04 7777 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7778 tcg_temp_free_i32(fp1);
b6d96bed 7779 gen_store_fpr32(fp0, fd);
a7812ae4 7780 tcg_temp_free_i32(fp0);
b6d96bed 7781 }
57fa1fb3
TS
7782 opn = "rsqrt2.s";
7783 break;
bf4120ad 7784 case OPC_CVT_D_S:
5e755519 7785 check_cp1_registers(ctx, fd);
b6d96bed 7786 {
a7812ae4
PB
7787 TCGv_i32 fp32 = tcg_temp_new_i32();
7788 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7789
7790 gen_load_fpr32(fp32, fs);
895c2d04 7791 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7792 tcg_temp_free_i32(fp32);
b6d96bed 7793 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7794 tcg_temp_free_i64(fp64);
b6d96bed 7795 }
5a5012ec
TS
7796 opn = "cvt.d.s";
7797 break;
bf4120ad 7798 case OPC_CVT_W_S:
b6d96bed 7799 {
a7812ae4 7800 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7801
7802 gen_load_fpr32(fp0, fs);
895c2d04 7803 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7804 gen_store_fpr32(fp0, fd);
a7812ae4 7805 tcg_temp_free_i32(fp0);
b6d96bed 7806 }
5a5012ec
TS
7807 opn = "cvt.w.s";
7808 break;
bf4120ad 7809 case OPC_CVT_L_S:
5e755519 7810 check_cp1_64bitmode(ctx);
b6d96bed 7811 {
a7812ae4
PB
7812 TCGv_i32 fp32 = tcg_temp_new_i32();
7813 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7814
7815 gen_load_fpr32(fp32, fs);
895c2d04 7816 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7817 tcg_temp_free_i32(fp32);
b6d96bed 7818 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7819 tcg_temp_free_i64(fp64);
b6d96bed 7820 }
5a5012ec
TS
7821 opn = "cvt.l.s";
7822 break;
bf4120ad 7823 case OPC_CVT_PS_S:
5e755519 7824 check_cp1_64bitmode(ctx);
b6d96bed 7825 {
a7812ae4
PB
7826 TCGv_i64 fp64 = tcg_temp_new_i64();
7827 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7828 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7829
7830 gen_load_fpr32(fp32_0, fs);
7831 gen_load_fpr32(fp32_1, ft);
13d24f49 7832 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7833 tcg_temp_free_i32(fp32_1);
7834 tcg_temp_free_i32(fp32_0);
36aa55dc 7835 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7836 tcg_temp_free_i64(fp64);
b6d96bed 7837 }
5a5012ec
TS
7838 opn = "cvt.ps.s";
7839 break;
bf4120ad
NF
7840 case OPC_CMP_F_S:
7841 case OPC_CMP_UN_S:
7842 case OPC_CMP_EQ_S:
7843 case OPC_CMP_UEQ_S:
7844 case OPC_CMP_OLT_S:
7845 case OPC_CMP_ULT_S:
7846 case OPC_CMP_OLE_S:
7847 case OPC_CMP_ULE_S:
7848 case OPC_CMP_SF_S:
7849 case OPC_CMP_NGLE_S:
7850 case OPC_CMP_SEQ_S:
7851 case OPC_CMP_NGL_S:
7852 case OPC_CMP_LT_S:
7853 case OPC_CMP_NGE_S:
7854 case OPC_CMP_LE_S:
7855 case OPC_CMP_NGT_S:
8153667c
NF
7856 if (ctx->opcode & (1 << 6)) {
7857 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7858 opn = condnames_abs[func-48];
7859 } else {
7860 gen_cmp_s(ctx, func-48, ft, fs, cc);
7861 opn = condnames[func-48];
5a1e8ffb 7862 }
5a5012ec 7863 break;
bf4120ad 7864 case OPC_ADD_D:
5e755519 7865 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7866 {
a7812ae4
PB
7867 TCGv_i64 fp0 = tcg_temp_new_i64();
7868 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7869
7870 gen_load_fpr64(ctx, fp0, fs);
7871 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7872 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7873 tcg_temp_free_i64(fp1);
b6d96bed 7874 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7875 tcg_temp_free_i64(fp0);
b6d96bed 7876 }
6ea83fed 7877 opn = "add.d";
5a1e8ffb 7878 optype = BINOP;
6ea83fed 7879 break;
bf4120ad 7880 case OPC_SUB_D:
5e755519 7881 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7882 {
a7812ae4
PB
7883 TCGv_i64 fp0 = tcg_temp_new_i64();
7884 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7885
7886 gen_load_fpr64(ctx, fp0, fs);
7887 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7888 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7889 tcg_temp_free_i64(fp1);
b6d96bed 7890 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7891 tcg_temp_free_i64(fp0);
b6d96bed 7892 }
6ea83fed 7893 opn = "sub.d";
5a1e8ffb 7894 optype = BINOP;
6ea83fed 7895 break;
bf4120ad 7896 case OPC_MUL_D:
5e755519 7897 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7898 {
a7812ae4
PB
7899 TCGv_i64 fp0 = tcg_temp_new_i64();
7900 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7901
7902 gen_load_fpr64(ctx, fp0, fs);
7903 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7904 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7905 tcg_temp_free_i64(fp1);
b6d96bed 7906 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7907 tcg_temp_free_i64(fp0);
b6d96bed 7908 }
6ea83fed 7909 opn = "mul.d";
5a1e8ffb 7910 optype = BINOP;
6ea83fed 7911 break;
bf4120ad 7912 case OPC_DIV_D:
5e755519 7913 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7914 {
a7812ae4
PB
7915 TCGv_i64 fp0 = tcg_temp_new_i64();
7916 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7917
7918 gen_load_fpr64(ctx, fp0, fs);
7919 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7920 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7921 tcg_temp_free_i64(fp1);
b6d96bed 7922 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7923 tcg_temp_free_i64(fp0);
b6d96bed 7924 }
6ea83fed 7925 opn = "div.d";
5a1e8ffb 7926 optype = BINOP;
6ea83fed 7927 break;
bf4120ad 7928 case OPC_SQRT_D:
5e755519 7929 check_cp1_registers(ctx, fs | fd);
b6d96bed 7930 {
a7812ae4 7931 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7932
7933 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7934 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7935 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7936 tcg_temp_free_i64(fp0);
b6d96bed 7937 }
6ea83fed
FB
7938 opn = "sqrt.d";
7939 break;
bf4120ad 7940 case OPC_ABS_D:
5e755519 7941 check_cp1_registers(ctx, fs | fd);
b6d96bed 7942 {
a7812ae4 7943 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7944
7945 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7946 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7947 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7948 tcg_temp_free_i64(fp0);
b6d96bed 7949 }
6ea83fed
FB
7950 opn = "abs.d";
7951 break;
bf4120ad 7952 case OPC_MOV_D:
5e755519 7953 check_cp1_registers(ctx, fs | fd);
b6d96bed 7954 {
a7812ae4 7955 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7956
7957 gen_load_fpr64(ctx, fp0, fs);
7958 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7959 tcg_temp_free_i64(fp0);
b6d96bed 7960 }
6ea83fed
FB
7961 opn = "mov.d";
7962 break;
bf4120ad 7963 case OPC_NEG_D:
5e755519 7964 check_cp1_registers(ctx, fs | fd);
b6d96bed 7965 {
a7812ae4 7966 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7967
7968 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7969 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7970 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7971 tcg_temp_free_i64(fp0);
b6d96bed 7972 }
6ea83fed
FB
7973 opn = "neg.d";
7974 break;
bf4120ad 7975 case OPC_ROUND_L_D:
5e755519 7976 check_cp1_64bitmode(ctx);
b6d96bed 7977 {
a7812ae4 7978 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7979
7980 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7981 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 7982 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7983 tcg_temp_free_i64(fp0);
b6d96bed 7984 }
5a5012ec
TS
7985 opn = "round.l.d";
7986 break;
bf4120ad 7987 case OPC_TRUNC_L_D:
5e755519 7988 check_cp1_64bitmode(ctx);
b6d96bed 7989 {
a7812ae4 7990 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7991
7992 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7993 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 7994 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7995 tcg_temp_free_i64(fp0);
b6d96bed 7996 }
5a5012ec
TS
7997 opn = "trunc.l.d";
7998 break;
bf4120ad 7999 case OPC_CEIL_L_D:
5e755519 8000 check_cp1_64bitmode(ctx);
b6d96bed 8001 {
a7812ae4 8002 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8003
8004 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8005 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8006 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8007 tcg_temp_free_i64(fp0);
b6d96bed 8008 }
5a5012ec
TS
8009 opn = "ceil.l.d";
8010 break;
bf4120ad 8011 case OPC_FLOOR_L_D:
5e755519 8012 check_cp1_64bitmode(ctx);
b6d96bed 8013 {
a7812ae4 8014 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8015
8016 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8017 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8018 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8019 tcg_temp_free_i64(fp0);
b6d96bed 8020 }
5a5012ec
TS
8021 opn = "floor.l.d";
8022 break;
bf4120ad 8023 case OPC_ROUND_W_D:
5e755519 8024 check_cp1_registers(ctx, fs);
b6d96bed 8025 {
a7812ae4
PB
8026 TCGv_i32 fp32 = tcg_temp_new_i32();
8027 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8028
8029 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8030 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8031 tcg_temp_free_i64(fp64);
b6d96bed 8032 gen_store_fpr32(fp32, fd);
a7812ae4 8033 tcg_temp_free_i32(fp32);
b6d96bed 8034 }
6ea83fed
FB
8035 opn = "round.w.d";
8036 break;
bf4120ad 8037 case OPC_TRUNC_W_D:
5e755519 8038 check_cp1_registers(ctx, fs);
b6d96bed 8039 {
a7812ae4
PB
8040 TCGv_i32 fp32 = tcg_temp_new_i32();
8041 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8042
8043 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8044 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8045 tcg_temp_free_i64(fp64);
b6d96bed 8046 gen_store_fpr32(fp32, fd);
a7812ae4 8047 tcg_temp_free_i32(fp32);
b6d96bed 8048 }
6ea83fed
FB
8049 opn = "trunc.w.d";
8050 break;
bf4120ad 8051 case OPC_CEIL_W_D:
5e755519 8052 check_cp1_registers(ctx, fs);
b6d96bed 8053 {
a7812ae4
PB
8054 TCGv_i32 fp32 = tcg_temp_new_i32();
8055 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8056
8057 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8058 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8059 tcg_temp_free_i64(fp64);
b6d96bed 8060 gen_store_fpr32(fp32, fd);
a7812ae4 8061 tcg_temp_free_i32(fp32);
b6d96bed 8062 }
6ea83fed
FB
8063 opn = "ceil.w.d";
8064 break;
bf4120ad 8065 case OPC_FLOOR_W_D:
5e755519 8066 check_cp1_registers(ctx, fs);
b6d96bed 8067 {
a7812ae4
PB
8068 TCGv_i32 fp32 = tcg_temp_new_i32();
8069 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8070
8071 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8072 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8073 tcg_temp_free_i64(fp64);
b6d96bed 8074 gen_store_fpr32(fp32, fd);
a7812ae4 8075 tcg_temp_free_i32(fp32);
b6d96bed 8076 }
7a387fff 8077 opn = "floor.w.d";
6ea83fed 8078 break;
bf4120ad 8079 case OPC_MOVCF_D:
b6d96bed 8080 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8081 opn = "movcf.d";
dd016883 8082 break;
bf4120ad 8083 case OPC_MOVZ_D:
a16336e4
TS
8084 {
8085 int l1 = gen_new_label();
c9297f4d 8086 TCGv_i64 fp0;
a16336e4 8087
c9297f4d
AJ
8088 if (ft != 0) {
8089 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8090 }
8091 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8092 gen_load_fpr64(ctx, fp0, fs);
8093 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8094 tcg_temp_free_i64(fp0);
a16336e4
TS
8095 gen_set_label(l1);
8096 }
5a5012ec
TS
8097 opn = "movz.d";
8098 break;
bf4120ad 8099 case OPC_MOVN_D:
a16336e4
TS
8100 {
8101 int l1 = gen_new_label();
c9297f4d
AJ
8102 TCGv_i64 fp0;
8103
8104 if (ft != 0) {
8105 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8106 fp0 = tcg_temp_new_i64();
8107 gen_load_fpr64(ctx, fp0, fs);
8108 gen_store_fpr64(ctx, fp0, fd);
8109 tcg_temp_free_i64(fp0);
8110 gen_set_label(l1);
8111 }
a16336e4 8112 }
5a5012ec 8113 opn = "movn.d";
6ea83fed 8114 break;
bf4120ad 8115 case OPC_RECIP_D:
b8aa4598 8116 check_cp1_64bitmode(ctx);
b6d96bed 8117 {
a7812ae4 8118 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8119
8120 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8121 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8122 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8123 tcg_temp_free_i64(fp0);
b6d96bed 8124 }
57fa1fb3
TS
8125 opn = "recip.d";
8126 break;
bf4120ad 8127 case OPC_RSQRT_D:
b8aa4598 8128 check_cp1_64bitmode(ctx);
b6d96bed 8129 {
a7812ae4 8130 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8131
8132 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8133 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8134 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8135 tcg_temp_free_i64(fp0);
b6d96bed 8136 }
57fa1fb3
TS
8137 opn = "rsqrt.d";
8138 break;
bf4120ad 8139 case OPC_RECIP2_D:
5e755519 8140 check_cp1_64bitmode(ctx);
b6d96bed 8141 {
a7812ae4
PB
8142 TCGv_i64 fp0 = tcg_temp_new_i64();
8143 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8144
8145 gen_load_fpr64(ctx, fp0, fs);
8146 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8147 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8148 tcg_temp_free_i64(fp1);
b6d96bed 8149 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8150 tcg_temp_free_i64(fp0);
b6d96bed 8151 }
57fa1fb3
TS
8152 opn = "recip2.d";
8153 break;
bf4120ad 8154 case OPC_RECIP1_D:
5e755519 8155 check_cp1_64bitmode(ctx);
b6d96bed 8156 {
a7812ae4 8157 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8158
8159 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8160 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8161 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8162 tcg_temp_free_i64(fp0);
b6d96bed 8163 }
57fa1fb3
TS
8164 opn = "recip1.d";
8165 break;
bf4120ad 8166 case OPC_RSQRT1_D:
5e755519 8167 check_cp1_64bitmode(ctx);
b6d96bed 8168 {
a7812ae4 8169 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8170
8171 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8172 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8173 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8174 tcg_temp_free_i64(fp0);
b6d96bed 8175 }
57fa1fb3
TS
8176 opn = "rsqrt1.d";
8177 break;
bf4120ad 8178 case OPC_RSQRT2_D:
5e755519 8179 check_cp1_64bitmode(ctx);
b6d96bed 8180 {
a7812ae4
PB
8181 TCGv_i64 fp0 = tcg_temp_new_i64();
8182 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8183
8184 gen_load_fpr64(ctx, fp0, fs);
8185 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8186 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8187 tcg_temp_free_i64(fp1);
b6d96bed 8188 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8189 tcg_temp_free_i64(fp0);
b6d96bed 8190 }
57fa1fb3
TS
8191 opn = "rsqrt2.d";
8192 break;
bf4120ad
NF
8193 case OPC_CMP_F_D:
8194 case OPC_CMP_UN_D:
8195 case OPC_CMP_EQ_D:
8196 case OPC_CMP_UEQ_D:
8197 case OPC_CMP_OLT_D:
8198 case OPC_CMP_ULT_D:
8199 case OPC_CMP_OLE_D:
8200 case OPC_CMP_ULE_D:
8201 case OPC_CMP_SF_D:
8202 case OPC_CMP_NGLE_D:
8203 case OPC_CMP_SEQ_D:
8204 case OPC_CMP_NGL_D:
8205 case OPC_CMP_LT_D:
8206 case OPC_CMP_NGE_D:
8207 case OPC_CMP_LE_D:
8208 case OPC_CMP_NGT_D:
8153667c
NF
8209 if (ctx->opcode & (1 << 6)) {
8210 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8211 opn = condnames_abs[func-48];
8212 } else {
8213 gen_cmp_d(ctx, func-48, ft, fs, cc);
8214 opn = condnames[func-48];
5a1e8ffb 8215 }
6ea83fed 8216 break;
bf4120ad 8217 case OPC_CVT_S_D:
5e755519 8218 check_cp1_registers(ctx, fs);
b6d96bed 8219 {
a7812ae4
PB
8220 TCGv_i32 fp32 = tcg_temp_new_i32();
8221 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8222
8223 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8224 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8225 tcg_temp_free_i64(fp64);
b6d96bed 8226 gen_store_fpr32(fp32, fd);
a7812ae4 8227 tcg_temp_free_i32(fp32);
b6d96bed 8228 }
5a5012ec
TS
8229 opn = "cvt.s.d";
8230 break;
bf4120ad 8231 case OPC_CVT_W_D:
5e755519 8232 check_cp1_registers(ctx, fs);
b6d96bed 8233 {
a7812ae4
PB
8234 TCGv_i32 fp32 = tcg_temp_new_i32();
8235 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8236
8237 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8238 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8239 tcg_temp_free_i64(fp64);
b6d96bed 8240 gen_store_fpr32(fp32, fd);
a7812ae4 8241 tcg_temp_free_i32(fp32);
b6d96bed 8242 }
5a5012ec
TS
8243 opn = "cvt.w.d";
8244 break;
bf4120ad 8245 case OPC_CVT_L_D:
5e755519 8246 check_cp1_64bitmode(ctx);
b6d96bed 8247 {
a7812ae4 8248 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8249
8250 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8251 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8252 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8253 tcg_temp_free_i64(fp0);
b6d96bed 8254 }
5a5012ec
TS
8255 opn = "cvt.l.d";
8256 break;
bf4120ad 8257 case OPC_CVT_S_W:
b6d96bed 8258 {
a7812ae4 8259 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8260
8261 gen_load_fpr32(fp0, fs);
895c2d04 8262 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8263 gen_store_fpr32(fp0, fd);
a7812ae4 8264 tcg_temp_free_i32(fp0);
b6d96bed 8265 }
5a5012ec 8266 opn = "cvt.s.w";
6ea83fed 8267 break;
bf4120ad 8268 case OPC_CVT_D_W:
5e755519 8269 check_cp1_registers(ctx, fd);
b6d96bed 8270 {
a7812ae4
PB
8271 TCGv_i32 fp32 = tcg_temp_new_i32();
8272 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8273
8274 gen_load_fpr32(fp32, fs);
895c2d04 8275 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8276 tcg_temp_free_i32(fp32);
b6d96bed 8277 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8278 tcg_temp_free_i64(fp64);
b6d96bed 8279 }
5a5012ec
TS
8280 opn = "cvt.d.w";
8281 break;
bf4120ad 8282 case OPC_CVT_S_L:
5e755519 8283 check_cp1_64bitmode(ctx);
b6d96bed 8284 {
a7812ae4
PB
8285 TCGv_i32 fp32 = tcg_temp_new_i32();
8286 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8287
8288 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8289 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8290 tcg_temp_free_i64(fp64);
b6d96bed 8291 gen_store_fpr32(fp32, fd);
a7812ae4 8292 tcg_temp_free_i32(fp32);
b6d96bed 8293 }
5a5012ec
TS
8294 opn = "cvt.s.l";
8295 break;
bf4120ad 8296 case OPC_CVT_D_L:
5e755519 8297 check_cp1_64bitmode(ctx);
b6d96bed 8298 {
a7812ae4 8299 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8300
8301 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8302 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8303 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8304 tcg_temp_free_i64(fp0);
b6d96bed 8305 }
5a5012ec
TS
8306 opn = "cvt.d.l";
8307 break;
bf4120ad 8308 case OPC_CVT_PS_PW:
5e755519 8309 check_cp1_64bitmode(ctx);
b6d96bed 8310 {
a7812ae4 8311 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8312
8313 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8314 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8315 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8316 tcg_temp_free_i64(fp0);
b6d96bed 8317 }
5a5012ec
TS
8318 opn = "cvt.ps.pw";
8319 break;
bf4120ad 8320 case OPC_ADD_PS:
5e755519 8321 check_cp1_64bitmode(ctx);
b6d96bed 8322 {
a7812ae4
PB
8323 TCGv_i64 fp0 = tcg_temp_new_i64();
8324 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8325
8326 gen_load_fpr64(ctx, fp0, fs);
8327 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8328 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8329 tcg_temp_free_i64(fp1);
b6d96bed 8330 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8331 tcg_temp_free_i64(fp0);
b6d96bed 8332 }
5a5012ec 8333 opn = "add.ps";
6ea83fed 8334 break;
bf4120ad 8335 case OPC_SUB_PS:
5e755519 8336 check_cp1_64bitmode(ctx);
b6d96bed 8337 {
a7812ae4
PB
8338 TCGv_i64 fp0 = tcg_temp_new_i64();
8339 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8340
8341 gen_load_fpr64(ctx, fp0, fs);
8342 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8343 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8344 tcg_temp_free_i64(fp1);
b6d96bed 8345 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8346 tcg_temp_free_i64(fp0);
b6d96bed 8347 }
5a5012ec 8348 opn = "sub.ps";
6ea83fed 8349 break;
bf4120ad 8350 case OPC_MUL_PS:
5e755519 8351 check_cp1_64bitmode(ctx);
b6d96bed 8352 {
a7812ae4
PB
8353 TCGv_i64 fp0 = tcg_temp_new_i64();
8354 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8355
8356 gen_load_fpr64(ctx, fp0, fs);
8357 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8358 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8359 tcg_temp_free_i64(fp1);
b6d96bed 8360 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8361 tcg_temp_free_i64(fp0);
b6d96bed 8362 }
5a5012ec 8363 opn = "mul.ps";
6ea83fed 8364 break;
bf4120ad 8365 case OPC_ABS_PS:
5e755519 8366 check_cp1_64bitmode(ctx);
b6d96bed 8367 {
a7812ae4 8368 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8369
8370 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8371 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8372 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8373 tcg_temp_free_i64(fp0);
b6d96bed 8374 }
5a5012ec 8375 opn = "abs.ps";
6ea83fed 8376 break;
bf4120ad 8377 case OPC_MOV_PS:
5e755519 8378 check_cp1_64bitmode(ctx);
b6d96bed 8379 {
a7812ae4 8380 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8381
8382 gen_load_fpr64(ctx, fp0, fs);
8383 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8384 tcg_temp_free_i64(fp0);
b6d96bed 8385 }
5a5012ec 8386 opn = "mov.ps";
6ea83fed 8387 break;
bf4120ad 8388 case OPC_NEG_PS:
5e755519 8389 check_cp1_64bitmode(ctx);
b6d96bed 8390 {
a7812ae4 8391 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8392
8393 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8394 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8395 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8396 tcg_temp_free_i64(fp0);
b6d96bed 8397 }
5a5012ec 8398 opn = "neg.ps";
6ea83fed 8399 break;
bf4120ad 8400 case OPC_MOVCF_PS:
5e755519 8401 check_cp1_64bitmode(ctx);
b6d96bed 8402 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8403 opn = "movcf.ps";
6ea83fed 8404 break;
bf4120ad 8405 case OPC_MOVZ_PS:
5e755519 8406 check_cp1_64bitmode(ctx);
a16336e4
TS
8407 {
8408 int l1 = gen_new_label();
30a3848b 8409 TCGv_i64 fp0;
a16336e4 8410
c9297f4d
AJ
8411 if (ft != 0)
8412 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8413 fp0 = tcg_temp_new_i64();
8414 gen_load_fpr64(ctx, fp0, fs);
8415 gen_store_fpr64(ctx, fp0, fd);
8416 tcg_temp_free_i64(fp0);
a16336e4
TS
8417 gen_set_label(l1);
8418 }
5a5012ec 8419 opn = "movz.ps";
6ea83fed 8420 break;
bf4120ad 8421 case OPC_MOVN_PS:
5e755519 8422 check_cp1_64bitmode(ctx);
a16336e4
TS
8423 {
8424 int l1 = gen_new_label();
30a3848b 8425 TCGv_i64 fp0;
c9297f4d
AJ
8426
8427 if (ft != 0) {
8428 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8429 fp0 = tcg_temp_new_i64();
8430 gen_load_fpr64(ctx, fp0, fs);
8431 gen_store_fpr64(ctx, fp0, fd);
8432 tcg_temp_free_i64(fp0);
8433 gen_set_label(l1);
8434 }
a16336e4 8435 }
5a5012ec 8436 opn = "movn.ps";
6ea83fed 8437 break;
bf4120ad 8438 case OPC_ADDR_PS:
5e755519 8439 check_cp1_64bitmode(ctx);
b6d96bed 8440 {
a7812ae4
PB
8441 TCGv_i64 fp0 = tcg_temp_new_i64();
8442 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8443
8444 gen_load_fpr64(ctx, fp0, ft);
8445 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8446 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8447 tcg_temp_free_i64(fp1);
b6d96bed 8448 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8449 tcg_temp_free_i64(fp0);
b6d96bed 8450 }
fbcc6828
TS
8451 opn = "addr.ps";
8452 break;
bf4120ad 8453 case OPC_MULR_PS:
5e755519 8454 check_cp1_64bitmode(ctx);
b6d96bed 8455 {
a7812ae4
PB
8456 TCGv_i64 fp0 = tcg_temp_new_i64();
8457 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8458
8459 gen_load_fpr64(ctx, fp0, ft);
8460 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8461 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8462 tcg_temp_free_i64(fp1);
b6d96bed 8463 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8464 tcg_temp_free_i64(fp0);
b6d96bed 8465 }
57fa1fb3
TS
8466 opn = "mulr.ps";
8467 break;
bf4120ad 8468 case OPC_RECIP2_PS:
5e755519 8469 check_cp1_64bitmode(ctx);
b6d96bed 8470 {
a7812ae4
PB
8471 TCGv_i64 fp0 = tcg_temp_new_i64();
8472 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8473
8474 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8475 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8476 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8477 tcg_temp_free_i64(fp1);
b6d96bed 8478 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8479 tcg_temp_free_i64(fp0);
b6d96bed 8480 }
57fa1fb3
TS
8481 opn = "recip2.ps";
8482 break;
bf4120ad 8483 case OPC_RECIP1_PS:
5e755519 8484 check_cp1_64bitmode(ctx);
b6d96bed 8485 {
a7812ae4 8486 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8487
8488 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8489 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8490 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8491 tcg_temp_free_i64(fp0);
b6d96bed 8492 }
57fa1fb3
TS
8493 opn = "recip1.ps";
8494 break;
bf4120ad 8495 case OPC_RSQRT1_PS:
5e755519 8496 check_cp1_64bitmode(ctx);
b6d96bed 8497 {
a7812ae4 8498 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8499
8500 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8501 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8502 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8503 tcg_temp_free_i64(fp0);
b6d96bed 8504 }
57fa1fb3
TS
8505 opn = "rsqrt1.ps";
8506 break;
bf4120ad 8507 case OPC_RSQRT2_PS:
5e755519 8508 check_cp1_64bitmode(ctx);
b6d96bed 8509 {
a7812ae4
PB
8510 TCGv_i64 fp0 = tcg_temp_new_i64();
8511 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8512
8513 gen_load_fpr64(ctx, fp0, fs);
8514 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8515 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8516 tcg_temp_free_i64(fp1);
b6d96bed 8517 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8518 tcg_temp_free_i64(fp0);
b6d96bed 8519 }
57fa1fb3
TS
8520 opn = "rsqrt2.ps";
8521 break;
bf4120ad 8522 case OPC_CVT_S_PU:
5e755519 8523 check_cp1_64bitmode(ctx);
b6d96bed 8524 {
a7812ae4 8525 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8526
8527 gen_load_fpr32h(fp0, fs);
895c2d04 8528 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8529 gen_store_fpr32(fp0, fd);
a7812ae4 8530 tcg_temp_free_i32(fp0);
b6d96bed 8531 }
5a5012ec 8532 opn = "cvt.s.pu";
dd016883 8533 break;
bf4120ad 8534 case OPC_CVT_PW_PS:
5e755519 8535 check_cp1_64bitmode(ctx);
b6d96bed 8536 {
a7812ae4 8537 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8538
8539 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8540 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8541 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8542 tcg_temp_free_i64(fp0);
b6d96bed 8543 }
5a5012ec 8544 opn = "cvt.pw.ps";
6ea83fed 8545 break;
bf4120ad 8546 case OPC_CVT_S_PL:
5e755519 8547 check_cp1_64bitmode(ctx);
b6d96bed 8548 {
a7812ae4 8549 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8550
8551 gen_load_fpr32(fp0, fs);
895c2d04 8552 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8553 gen_store_fpr32(fp0, fd);
a7812ae4 8554 tcg_temp_free_i32(fp0);
b6d96bed 8555 }
5a5012ec 8556 opn = "cvt.s.pl";
6ea83fed 8557 break;
bf4120ad 8558 case OPC_PLL_PS:
5e755519 8559 check_cp1_64bitmode(ctx);
b6d96bed 8560 {
a7812ae4
PB
8561 TCGv_i32 fp0 = tcg_temp_new_i32();
8562 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8563
8564 gen_load_fpr32(fp0, fs);
8565 gen_load_fpr32(fp1, ft);
8566 gen_store_fpr32h(fp0, fd);
8567 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8568 tcg_temp_free_i32(fp0);
8569 tcg_temp_free_i32(fp1);
b6d96bed 8570 }
5a5012ec 8571 opn = "pll.ps";
6ea83fed 8572 break;
bf4120ad 8573 case OPC_PLU_PS:
5e755519 8574 check_cp1_64bitmode(ctx);
b6d96bed 8575 {
a7812ae4
PB
8576 TCGv_i32 fp0 = tcg_temp_new_i32();
8577 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8578
8579 gen_load_fpr32(fp0, fs);
8580 gen_load_fpr32h(fp1, ft);
8581 gen_store_fpr32(fp1, fd);
8582 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8583 tcg_temp_free_i32(fp0);
8584 tcg_temp_free_i32(fp1);
b6d96bed 8585 }
5a5012ec
TS
8586 opn = "plu.ps";
8587 break;
bf4120ad 8588 case OPC_PUL_PS:
5e755519 8589 check_cp1_64bitmode(ctx);
b6d96bed 8590 {
a7812ae4
PB
8591 TCGv_i32 fp0 = tcg_temp_new_i32();
8592 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8593
8594 gen_load_fpr32h(fp0, fs);
8595 gen_load_fpr32(fp1, ft);
8596 gen_store_fpr32(fp1, fd);
8597 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8598 tcg_temp_free_i32(fp0);
8599 tcg_temp_free_i32(fp1);
b6d96bed 8600 }
5a5012ec
TS
8601 opn = "pul.ps";
8602 break;
bf4120ad 8603 case OPC_PUU_PS:
5e755519 8604 check_cp1_64bitmode(ctx);
b6d96bed 8605 {
a7812ae4
PB
8606 TCGv_i32 fp0 = tcg_temp_new_i32();
8607 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8608
8609 gen_load_fpr32h(fp0, fs);
8610 gen_load_fpr32h(fp1, ft);
8611 gen_store_fpr32(fp1, fd);
8612 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8613 tcg_temp_free_i32(fp0);
8614 tcg_temp_free_i32(fp1);
b6d96bed 8615 }
5a5012ec
TS
8616 opn = "puu.ps";
8617 break;
bf4120ad
NF
8618 case OPC_CMP_F_PS:
8619 case OPC_CMP_UN_PS:
8620 case OPC_CMP_EQ_PS:
8621 case OPC_CMP_UEQ_PS:
8622 case OPC_CMP_OLT_PS:
8623 case OPC_CMP_ULT_PS:
8624 case OPC_CMP_OLE_PS:
8625 case OPC_CMP_ULE_PS:
8626 case OPC_CMP_SF_PS:
8627 case OPC_CMP_NGLE_PS:
8628 case OPC_CMP_SEQ_PS:
8629 case OPC_CMP_NGL_PS:
8630 case OPC_CMP_LT_PS:
8631 case OPC_CMP_NGE_PS:
8632 case OPC_CMP_LE_PS:
8633 case OPC_CMP_NGT_PS:
8153667c
NF
8634 if (ctx->opcode & (1 << 6)) {
8635 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8636 opn = condnames_abs[func-48];
8637 } else {
8638 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8639 opn = condnames[func-48];
5a1e8ffb 8640 }
6ea83fed 8641 break;
5a5012ec 8642 default:
923617a3 8643 MIPS_INVAL(opn);
e397ee33 8644 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8645 return;
8646 }
2abf314d 8647 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8648 switch (optype) {
8649 case BINOP:
6ea83fed 8650 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8651 break;
8652 case CMPOP:
8653 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8654 break;
8655 default:
6ea83fed 8656 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8657 break;
8658 }
6ea83fed 8659}
6af0bf9c 8660
5a5012ec 8661/* Coprocessor 3 (FPU) */
5e755519
TS
8662static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8663 int fd, int fs, int base, int index)
7a387fff 8664{
923617a3 8665 const char *opn = "extended float load/store";
93b12ccc 8666 int store = 0;
4e2474d6 8667 TCGv t0 = tcg_temp_new();
7a387fff 8668
93b12ccc 8669 if (base == 0) {
6c5c1e20 8670 gen_load_gpr(t0, index);
93b12ccc 8671 } else if (index == 0) {
6c5c1e20 8672 gen_load_gpr(t0, base);
93b12ccc 8673 } else {
05168674 8674 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8675 }
5a5012ec 8676 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8677 memory access. */
5a5012ec
TS
8678 switch (opc) {
8679 case OPC_LWXC1:
8c0ab41f 8680 check_cop1x(ctx);
b6d96bed 8681 {
a7812ae4 8682 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8683
585c88d5
AJ
8684 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8685 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8686 gen_store_fpr32(fp0, fd);
a7812ae4 8687 tcg_temp_free_i32(fp0);
b6d96bed 8688 }
5a5012ec
TS
8689 opn = "lwxc1";
8690 break;
8691 case OPC_LDXC1:
8c0ab41f
AJ
8692 check_cop1x(ctx);
8693 check_cp1_registers(ctx, fd);
b6d96bed 8694 {
a7812ae4 8695 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8696
8697 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8698 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8699 tcg_temp_free_i64(fp0);
b6d96bed 8700 }
5a5012ec
TS
8701 opn = "ldxc1";
8702 break;
8703 case OPC_LUXC1:
8c0ab41f 8704 check_cp1_64bitmode(ctx);
6c5c1e20 8705 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8706 {
a7812ae4 8707 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8708
8709 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8710 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8711 tcg_temp_free_i64(fp0);
b6d96bed 8712 }
5a5012ec
TS
8713 opn = "luxc1";
8714 break;
8715 case OPC_SWXC1:
8c0ab41f 8716 check_cop1x(ctx);
b6d96bed 8717 {
a7812ae4 8718 TCGv_i32 fp0 = tcg_temp_new_i32();
585c88d5 8719 TCGv t1 = tcg_temp_new();
b6d96bed
TS
8720
8721 gen_load_fpr32(fp0, fs);
a7812ae4
PB
8722 tcg_gen_extu_i32_tl(t1, fp0);
8723 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8724 tcg_temp_free_i32(fp0);
a6035857 8725 tcg_temp_free(t1);
b6d96bed 8726 }
5a5012ec 8727 opn = "swxc1";
93b12ccc 8728 store = 1;
5a5012ec
TS
8729 break;
8730 case OPC_SDXC1:
8c0ab41f
AJ
8731 check_cop1x(ctx);
8732 check_cp1_registers(ctx, fs);
b6d96bed 8733 {
a7812ae4 8734 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8735
8736 gen_load_fpr64(ctx, fp0, fs);
8737 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8738 tcg_temp_free_i64(fp0);
b6d96bed 8739 }
5a5012ec 8740 opn = "sdxc1";
93b12ccc 8741 store = 1;
5a5012ec
TS
8742 break;
8743 case OPC_SUXC1:
8c0ab41f 8744 check_cp1_64bitmode(ctx);
6c5c1e20 8745 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8746 {
a7812ae4 8747 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8748
8749 gen_load_fpr64(ctx, fp0, fs);
8750 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8751 tcg_temp_free_i64(fp0);
b6d96bed 8752 }
5a5012ec 8753 opn = "suxc1";
93b12ccc 8754 store = 1;
5a5012ec 8755 break;
5a5012ec 8756 }
6c5c1e20 8757 tcg_temp_free(t0);
2abf314d 8758 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8759 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8760 regnames[index], regnames[base]);
5a5012ec
TS
8761}
8762
5e755519
TS
8763static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8764 int fd, int fr, int fs, int ft)
5a5012ec 8765{
923617a3 8766 const char *opn = "flt3_arith";
5a5012ec 8767
5a5012ec
TS
8768 switch (opc) {
8769 case OPC_ALNV_PS:
b8aa4598 8770 check_cp1_64bitmode(ctx);
a16336e4 8771 {
a7812ae4 8772 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8773 TCGv_i32 fp = tcg_temp_new_i32();
8774 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8775 int l1 = gen_new_label();
8776 int l2 = gen_new_label();
8777
6c5c1e20
TS
8778 gen_load_gpr(t0, fr);
8779 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8780
8781 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac
AJ
8782 gen_load_fpr32(fp, fs);
8783 gen_load_fpr32h(fph, fs);
8784 gen_store_fpr32(fp, fd);
8785 gen_store_fpr32h(fph, fd);
a16336e4
TS
8786 tcg_gen_br(l2);
8787 gen_set_label(l1);
6c5c1e20
TS
8788 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8789 tcg_temp_free(t0);
a16336e4 8790#ifdef TARGET_WORDS_BIGENDIAN
c905fdac
AJ
8791 gen_load_fpr32(fp, fs);
8792 gen_load_fpr32h(fph, ft);
8793 gen_store_fpr32h(fp, fd);
8794 gen_store_fpr32(fph, fd);
a16336e4 8795#else
c905fdac
AJ
8796 gen_load_fpr32h(fph, fs);
8797 gen_load_fpr32(fp, ft);
8798 gen_store_fpr32(fph, fd);
8799 gen_store_fpr32h(fp, fd);
a16336e4
TS
8800#endif
8801 gen_set_label(l2);
c905fdac
AJ
8802 tcg_temp_free_i32(fp);
8803 tcg_temp_free_i32(fph);
a16336e4 8804 }
5a5012ec
TS
8805 opn = "alnv.ps";
8806 break;
8807 case OPC_MADD_S:
b8aa4598 8808 check_cop1x(ctx);
b6d96bed 8809 {
a7812ae4
PB
8810 TCGv_i32 fp0 = tcg_temp_new_i32();
8811 TCGv_i32 fp1 = tcg_temp_new_i32();
8812 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8813
8814 gen_load_fpr32(fp0, fs);
8815 gen_load_fpr32(fp1, ft);
8816 gen_load_fpr32(fp2, fr);
b3d6cd44 8817 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8818 tcg_temp_free_i32(fp0);
8819 tcg_temp_free_i32(fp1);
b6d96bed 8820 gen_store_fpr32(fp2, fd);
a7812ae4 8821 tcg_temp_free_i32(fp2);
b6d96bed 8822 }
5a5012ec
TS
8823 opn = "madd.s";
8824 break;
8825 case OPC_MADD_D:
b8aa4598
TS
8826 check_cop1x(ctx);
8827 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8828 {
a7812ae4
PB
8829 TCGv_i64 fp0 = tcg_temp_new_i64();
8830 TCGv_i64 fp1 = tcg_temp_new_i64();
8831 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8832
8833 gen_load_fpr64(ctx, fp0, fs);
8834 gen_load_fpr64(ctx, fp1, ft);
8835 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8836 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8837 tcg_temp_free_i64(fp0);
8838 tcg_temp_free_i64(fp1);
b6d96bed 8839 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8840 tcg_temp_free_i64(fp2);
b6d96bed 8841 }
5a5012ec
TS
8842 opn = "madd.d";
8843 break;
8844 case OPC_MADD_PS:
b8aa4598 8845 check_cp1_64bitmode(ctx);
b6d96bed 8846 {
a7812ae4
PB
8847 TCGv_i64 fp0 = tcg_temp_new_i64();
8848 TCGv_i64 fp1 = tcg_temp_new_i64();
8849 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8850
8851 gen_load_fpr64(ctx, fp0, fs);
8852 gen_load_fpr64(ctx, fp1, ft);
8853 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8854 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8855 tcg_temp_free_i64(fp0);
8856 tcg_temp_free_i64(fp1);
b6d96bed 8857 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8858 tcg_temp_free_i64(fp2);
b6d96bed 8859 }
5a5012ec
TS
8860 opn = "madd.ps";
8861 break;
8862 case OPC_MSUB_S:
b8aa4598 8863 check_cop1x(ctx);
b6d96bed 8864 {
a7812ae4
PB
8865 TCGv_i32 fp0 = tcg_temp_new_i32();
8866 TCGv_i32 fp1 = tcg_temp_new_i32();
8867 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8868
8869 gen_load_fpr32(fp0, fs);
8870 gen_load_fpr32(fp1, ft);
8871 gen_load_fpr32(fp2, fr);
b3d6cd44 8872 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8873 tcg_temp_free_i32(fp0);
8874 tcg_temp_free_i32(fp1);
b6d96bed 8875 gen_store_fpr32(fp2, fd);
a7812ae4 8876 tcg_temp_free_i32(fp2);
b6d96bed 8877 }
5a5012ec
TS
8878 opn = "msub.s";
8879 break;
8880 case OPC_MSUB_D:
b8aa4598
TS
8881 check_cop1x(ctx);
8882 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8883 {
a7812ae4
PB
8884 TCGv_i64 fp0 = tcg_temp_new_i64();
8885 TCGv_i64 fp1 = tcg_temp_new_i64();
8886 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8887
8888 gen_load_fpr64(ctx, fp0, fs);
8889 gen_load_fpr64(ctx, fp1, ft);
8890 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8891 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8892 tcg_temp_free_i64(fp0);
8893 tcg_temp_free_i64(fp1);
b6d96bed 8894 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8895 tcg_temp_free_i64(fp2);
b6d96bed 8896 }
5a5012ec
TS
8897 opn = "msub.d";
8898 break;
8899 case OPC_MSUB_PS:
b8aa4598 8900 check_cp1_64bitmode(ctx);
b6d96bed 8901 {
a7812ae4
PB
8902 TCGv_i64 fp0 = tcg_temp_new_i64();
8903 TCGv_i64 fp1 = tcg_temp_new_i64();
8904 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8905
8906 gen_load_fpr64(ctx, fp0, fs);
8907 gen_load_fpr64(ctx, fp1, ft);
8908 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8909 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8910 tcg_temp_free_i64(fp0);
8911 tcg_temp_free_i64(fp1);
b6d96bed 8912 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8913 tcg_temp_free_i64(fp2);
b6d96bed 8914 }
5a5012ec
TS
8915 opn = "msub.ps";
8916 break;
8917 case OPC_NMADD_S:
b8aa4598 8918 check_cop1x(ctx);
b6d96bed 8919 {
a7812ae4
PB
8920 TCGv_i32 fp0 = tcg_temp_new_i32();
8921 TCGv_i32 fp1 = tcg_temp_new_i32();
8922 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8923
8924 gen_load_fpr32(fp0, fs);
8925 gen_load_fpr32(fp1, ft);
8926 gen_load_fpr32(fp2, fr);
b3d6cd44 8927 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8928 tcg_temp_free_i32(fp0);
8929 tcg_temp_free_i32(fp1);
b6d96bed 8930 gen_store_fpr32(fp2, fd);
a7812ae4 8931 tcg_temp_free_i32(fp2);
b6d96bed 8932 }
5a5012ec
TS
8933 opn = "nmadd.s";
8934 break;
8935 case OPC_NMADD_D:
b8aa4598
TS
8936 check_cop1x(ctx);
8937 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8938 {
a7812ae4
PB
8939 TCGv_i64 fp0 = tcg_temp_new_i64();
8940 TCGv_i64 fp1 = tcg_temp_new_i64();
8941 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8942
8943 gen_load_fpr64(ctx, fp0, fs);
8944 gen_load_fpr64(ctx, fp1, ft);
8945 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8946 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8947 tcg_temp_free_i64(fp0);
8948 tcg_temp_free_i64(fp1);
b6d96bed 8949 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8950 tcg_temp_free_i64(fp2);
b6d96bed 8951 }
5a5012ec
TS
8952 opn = "nmadd.d";
8953 break;
8954 case OPC_NMADD_PS:
b8aa4598 8955 check_cp1_64bitmode(ctx);
b6d96bed 8956 {
a7812ae4
PB
8957 TCGv_i64 fp0 = tcg_temp_new_i64();
8958 TCGv_i64 fp1 = tcg_temp_new_i64();
8959 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8960
8961 gen_load_fpr64(ctx, fp0, fs);
8962 gen_load_fpr64(ctx, fp1, ft);
8963 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8964 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8965 tcg_temp_free_i64(fp0);
8966 tcg_temp_free_i64(fp1);
b6d96bed 8967 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8968 tcg_temp_free_i64(fp2);
b6d96bed 8969 }
5a5012ec
TS
8970 opn = "nmadd.ps";
8971 break;
8972 case OPC_NMSUB_S:
b8aa4598 8973 check_cop1x(ctx);
b6d96bed 8974 {
a7812ae4
PB
8975 TCGv_i32 fp0 = tcg_temp_new_i32();
8976 TCGv_i32 fp1 = tcg_temp_new_i32();
8977 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8978
8979 gen_load_fpr32(fp0, fs);
8980 gen_load_fpr32(fp1, ft);
8981 gen_load_fpr32(fp2, fr);
b3d6cd44 8982 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8983 tcg_temp_free_i32(fp0);
8984 tcg_temp_free_i32(fp1);
b6d96bed 8985 gen_store_fpr32(fp2, fd);
a7812ae4 8986 tcg_temp_free_i32(fp2);
b6d96bed 8987 }
5a5012ec
TS
8988 opn = "nmsub.s";
8989 break;
8990 case OPC_NMSUB_D:
b8aa4598
TS
8991 check_cop1x(ctx);
8992 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8993 {
a7812ae4
PB
8994 TCGv_i64 fp0 = tcg_temp_new_i64();
8995 TCGv_i64 fp1 = tcg_temp_new_i64();
8996 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8997
8998 gen_load_fpr64(ctx, fp0, fs);
8999 gen_load_fpr64(ctx, fp1, ft);
9000 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9001 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9002 tcg_temp_free_i64(fp0);
9003 tcg_temp_free_i64(fp1);
b6d96bed 9004 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9005 tcg_temp_free_i64(fp2);
b6d96bed 9006 }
5a5012ec
TS
9007 opn = "nmsub.d";
9008 break;
9009 case OPC_NMSUB_PS:
b8aa4598 9010 check_cp1_64bitmode(ctx);
b6d96bed 9011 {
a7812ae4
PB
9012 TCGv_i64 fp0 = tcg_temp_new_i64();
9013 TCGv_i64 fp1 = tcg_temp_new_i64();
9014 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9015
9016 gen_load_fpr64(ctx, fp0, fs);
9017 gen_load_fpr64(ctx, fp1, ft);
9018 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9019 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9020 tcg_temp_free_i64(fp0);
9021 tcg_temp_free_i64(fp1);
b6d96bed 9022 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9023 tcg_temp_free_i64(fp2);
b6d96bed 9024 }
5a5012ec
TS
9025 opn = "nmsub.ps";
9026 break;
923617a3
TS
9027 default:
9028 MIPS_INVAL(opn);
5a5012ec
TS
9029 generate_exception (ctx, EXCP_RI);
9030 return;
9031 }
2abf314d 9032 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9033 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9034 fregnames[fs], fregnames[ft]);
7a387fff
TS
9035}
9036
d75c135e 9037static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9038{
9039 TCGv t0;
9040
b3167288
RH
9041#if !defined(CONFIG_USER_ONLY)
9042 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9043 Therefore only check the ISA in system mode. */
d75c135e 9044 check_insn(ctx, ISA_MIPS32R2);
b3167288 9045#endif
26ebe468
NF
9046 t0 = tcg_temp_new();
9047
9048 switch (rd) {
9049 case 0:
9050 save_cpu_state(ctx, 1);
895c2d04 9051 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9052 gen_store_gpr(t0, rt);
9053 break;
9054 case 1:
9055 save_cpu_state(ctx, 1);
895c2d04 9056 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9057 gen_store_gpr(t0, rt);
9058 break;
9059 case 2:
9060 save_cpu_state(ctx, 1);
895c2d04 9061 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9062 gen_store_gpr(t0, rt);
9063 break;
9064 case 3:
9065 save_cpu_state(ctx, 1);
895c2d04 9066 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9067 gen_store_gpr(t0, rt);
9068 break;
9069 case 29:
9070#if defined(CONFIG_USER_ONLY)
7db13fae 9071 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9072 gen_store_gpr(t0, rt);
9073 break;
9074#else
9075 /* XXX: Some CPUs implement this in hardware.
9076 Not supported yet. */
9077#endif
9078 default: /* Invalid */
9079 MIPS_INVAL("rdhwr");
9080 generate_exception(ctx, EXCP_RI);
9081 break;
9082 }
9083 tcg_temp_free(t0);
9084}
9085
d75c135e 9086static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9087{
9088 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9089 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9090 /* Branches completion */
9091 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9092 ctx->bstate = BS_BRANCH;
9093 save_cpu_state(ctx, 0);
9094 /* FIXME: Need to clear can_do_io. */
364d4831 9095 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9096 case MIPS_HFLAG_B:
9097 /* unconditional branch */
9098 MIPS_DEBUG("unconditional branch");
364d4831
NF
9099 if (proc_hflags & MIPS_HFLAG_BX) {
9100 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9101 }
c9602061
NF
9102 gen_goto_tb(ctx, 0, ctx->btarget);
9103 break;
9104 case MIPS_HFLAG_BL:
9105 /* blikely taken case */
9106 MIPS_DEBUG("blikely branch taken");
9107 gen_goto_tb(ctx, 0, ctx->btarget);
9108 break;
9109 case MIPS_HFLAG_BC:
9110 /* Conditional branch */
9111 MIPS_DEBUG("conditional branch");
9112 {
9113 int l1 = gen_new_label();
9114
9115 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9116 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9117 gen_set_label(l1);
9118 gen_goto_tb(ctx, 0, ctx->btarget);
9119 }
9120 break;
9121 case MIPS_HFLAG_BR:
9122 /* unconditional branch to register */
9123 MIPS_DEBUG("branch to register");
d75c135e 9124 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9125 TCGv t0 = tcg_temp_new();
9126 TCGv_i32 t1 = tcg_temp_new_i32();
9127
9128 tcg_gen_andi_tl(t0, btarget, 0x1);
9129 tcg_gen_trunc_tl_i32(t1, t0);
9130 tcg_temp_free(t0);
9131 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9132 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9133 tcg_gen_or_i32(hflags, hflags, t1);
9134 tcg_temp_free_i32(t1);
9135
9136 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9137 } else {
9138 tcg_gen_mov_tl(cpu_PC, btarget);
9139 }
c9602061
NF
9140 if (ctx->singlestep_enabled) {
9141 save_cpu_state(ctx, 0);
895c2d04 9142 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9143 }
9144 tcg_gen_exit_tb(0);
9145 break;
9146 default:
9147 MIPS_DEBUG("unknown branch");
9148 break;
9149 }
9150 }
9151}
9152
7a387fff 9153/* ISA extensions (ASEs) */
6af0bf9c 9154/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9155
9156/* MIPS16 major opcodes */
9157enum {
9158 M16_OPC_ADDIUSP = 0x00,
9159 M16_OPC_ADDIUPC = 0x01,
9160 M16_OPC_B = 0x02,
9161 M16_OPC_JAL = 0x03,
9162 M16_OPC_BEQZ = 0x04,
9163 M16_OPC_BNEQZ = 0x05,
9164 M16_OPC_SHIFT = 0x06,
9165 M16_OPC_LD = 0x07,
9166 M16_OPC_RRIA = 0x08,
9167 M16_OPC_ADDIU8 = 0x09,
9168 M16_OPC_SLTI = 0x0a,
9169 M16_OPC_SLTIU = 0x0b,
9170 M16_OPC_I8 = 0x0c,
9171 M16_OPC_LI = 0x0d,
9172 M16_OPC_CMPI = 0x0e,
9173 M16_OPC_SD = 0x0f,
9174 M16_OPC_LB = 0x10,
9175 M16_OPC_LH = 0x11,
9176 M16_OPC_LWSP = 0x12,
9177 M16_OPC_LW = 0x13,
9178 M16_OPC_LBU = 0x14,
9179 M16_OPC_LHU = 0x15,
9180 M16_OPC_LWPC = 0x16,
9181 M16_OPC_LWU = 0x17,
9182 M16_OPC_SB = 0x18,
9183 M16_OPC_SH = 0x19,
9184 M16_OPC_SWSP = 0x1a,
9185 M16_OPC_SW = 0x1b,
9186 M16_OPC_RRR = 0x1c,
9187 M16_OPC_RR = 0x1d,
9188 M16_OPC_EXTEND = 0x1e,
9189 M16_OPC_I64 = 0x1f
9190};
9191
9192/* I8 funct field */
9193enum {
9194 I8_BTEQZ = 0x0,
9195 I8_BTNEZ = 0x1,
9196 I8_SWRASP = 0x2,
9197 I8_ADJSP = 0x3,
9198 I8_SVRS = 0x4,
9199 I8_MOV32R = 0x5,
9200 I8_MOVR32 = 0x7
9201};
9202
9203/* RRR f field */
9204enum {
9205 RRR_DADDU = 0x0,
9206 RRR_ADDU = 0x1,
9207 RRR_DSUBU = 0x2,
9208 RRR_SUBU = 0x3
9209};
9210
9211/* RR funct field */
9212enum {
9213 RR_JR = 0x00,
9214 RR_SDBBP = 0x01,
9215 RR_SLT = 0x02,
9216 RR_SLTU = 0x03,
9217 RR_SLLV = 0x04,
9218 RR_BREAK = 0x05,
9219 RR_SRLV = 0x06,
9220 RR_SRAV = 0x07,
9221 RR_DSRL = 0x08,
9222 RR_CMP = 0x0a,
9223 RR_NEG = 0x0b,
9224 RR_AND = 0x0c,
9225 RR_OR = 0x0d,
9226 RR_XOR = 0x0e,
9227 RR_NOT = 0x0f,
9228 RR_MFHI = 0x10,
9229 RR_CNVT = 0x11,
9230 RR_MFLO = 0x12,
9231 RR_DSRA = 0x13,
9232 RR_DSLLV = 0x14,
9233 RR_DSRLV = 0x16,
9234 RR_DSRAV = 0x17,
9235 RR_MULT = 0x18,
9236 RR_MULTU = 0x19,
9237 RR_DIV = 0x1a,
9238 RR_DIVU = 0x1b,
9239 RR_DMULT = 0x1c,
9240 RR_DMULTU = 0x1d,
9241 RR_DDIV = 0x1e,
9242 RR_DDIVU = 0x1f
9243};
9244
9245/* I64 funct field */
9246enum {
9247 I64_LDSP = 0x0,
9248 I64_SDSP = 0x1,
9249 I64_SDRASP = 0x2,
9250 I64_DADJSP = 0x3,
9251 I64_LDPC = 0x4,
364d4831 9252 I64_DADDIU5 = 0x5,
6ea219d0
NF
9253 I64_DADDIUPC = 0x6,
9254 I64_DADDIUSP = 0x7
9255};
9256
9257/* RR ry field for CNVT */
9258enum {
9259 RR_RY_CNVT_ZEB = 0x0,
9260 RR_RY_CNVT_ZEH = 0x1,
9261 RR_RY_CNVT_ZEW = 0x2,
9262 RR_RY_CNVT_SEB = 0x4,
9263 RR_RY_CNVT_SEH = 0x5,
9264 RR_RY_CNVT_SEW = 0x6,
9265};
9266
364d4831
NF
9267static int xlat (int r)
9268{
9269 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9270
9271 return map[r];
9272}
9273
9274static void gen_mips16_save (DisasContext *ctx,
9275 int xsregs, int aregs,
9276 int do_ra, int do_s0, int do_s1,
9277 int framesize)
9278{
9279 TCGv t0 = tcg_temp_new();
9280 TCGv t1 = tcg_temp_new();
9281 int args, astatic;
9282
9283 switch (aregs) {
9284 case 0:
9285 case 1:
9286 case 2:
9287 case 3:
9288 case 11:
9289 args = 0;
9290 break;
9291 case 4:
9292 case 5:
9293 case 6:
9294 case 7:
9295 args = 1;
9296 break;
9297 case 8:
9298 case 9:
9299 case 10:
9300 args = 2;
9301 break;
9302 case 12:
9303 case 13:
9304 args = 3;
9305 break;
9306 case 14:
9307 args = 4;
9308 break;
9309 default:
9310 generate_exception(ctx, EXCP_RI);
9311 return;
9312 }
9313
9314 switch (args) {
9315 case 4:
9316 gen_base_offset_addr(ctx, t0, 29, 12);
9317 gen_load_gpr(t1, 7);
2910c6cb 9318 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9319 /* Fall through */
9320 case 3:
9321 gen_base_offset_addr(ctx, t0, 29, 8);
9322 gen_load_gpr(t1, 6);
2910c6cb 9323 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9324 /* Fall through */
9325 case 2:
9326 gen_base_offset_addr(ctx, t0, 29, 4);
9327 gen_load_gpr(t1, 5);
2910c6cb 9328 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9329 /* Fall through */
9330 case 1:
9331 gen_base_offset_addr(ctx, t0, 29, 0);
9332 gen_load_gpr(t1, 4);
2910c6cb 9333 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9334 }
9335
9336 gen_load_gpr(t0, 29);
9337
9338#define DECR_AND_STORE(reg) do { \
9339 tcg_gen_subi_tl(t0, t0, 4); \
9340 gen_load_gpr(t1, reg); \
2910c6cb 9341 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
364d4831
NF
9342 } while (0)
9343
9344 if (do_ra) {
9345 DECR_AND_STORE(31);
9346 }
9347
9348 switch (xsregs) {
9349 case 7:
9350 DECR_AND_STORE(30);
9351 /* Fall through */
9352 case 6:
9353 DECR_AND_STORE(23);
9354 /* Fall through */
9355 case 5:
9356 DECR_AND_STORE(22);
9357 /* Fall through */
9358 case 4:
9359 DECR_AND_STORE(21);
9360 /* Fall through */
9361 case 3:
9362 DECR_AND_STORE(20);
9363 /* Fall through */
9364 case 2:
9365 DECR_AND_STORE(19);
9366 /* Fall through */
9367 case 1:
9368 DECR_AND_STORE(18);
9369 }
9370
9371 if (do_s1) {
9372 DECR_AND_STORE(17);
9373 }
9374 if (do_s0) {
9375 DECR_AND_STORE(16);
9376 }
9377
9378 switch (aregs) {
9379 case 0:
9380 case 4:
9381 case 8:
9382 case 12:
9383 case 14:
9384 astatic = 0;
9385 break;
9386 case 1:
9387 case 5:
9388 case 9:
9389 case 13:
9390 astatic = 1;
9391 break;
9392 case 2:
9393 case 6:
9394 case 10:
9395 astatic = 2;
9396 break;
9397 case 3:
9398 case 7:
9399 astatic = 3;
9400 break;
9401 case 11:
9402 astatic = 4;
9403 break;
9404 default:
9405 generate_exception(ctx, EXCP_RI);
9406 return;
9407 }
9408
9409 if (astatic > 0) {
9410 DECR_AND_STORE(7);
9411 if (astatic > 1) {
9412 DECR_AND_STORE(6);
9413 if (astatic > 2) {
9414 DECR_AND_STORE(5);
9415 if (astatic > 3) {
9416 DECR_AND_STORE(4);
9417 }
9418 }
9419 }
9420 }
9421#undef DECR_AND_STORE
9422
9423 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9424 tcg_temp_free(t0);
9425 tcg_temp_free(t1);
9426}
9427
9428static void gen_mips16_restore (DisasContext *ctx,
9429 int xsregs, int aregs,
9430 int do_ra, int do_s0, int do_s1,
9431 int framesize)
9432{
9433 int astatic;
9434 TCGv t0 = tcg_temp_new();
9435 TCGv t1 = tcg_temp_new();
9436
9437 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9438
2910c6cb
AJ
9439#define DECR_AND_LOAD(reg) do { \
9440 tcg_gen_subi_tl(t0, t0, 4); \
9441 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9442 gen_store_gpr(t1, reg); \
364d4831
NF
9443 } while (0)
9444
9445 if (do_ra) {
9446 DECR_AND_LOAD(31);
9447 }
9448
9449 switch (xsregs) {
9450 case 7:
9451 DECR_AND_LOAD(30);
9452 /* Fall through */
9453 case 6:
9454 DECR_AND_LOAD(23);
9455 /* Fall through */
9456 case 5:
9457 DECR_AND_LOAD(22);
9458 /* Fall through */
9459 case 4:
9460 DECR_AND_LOAD(21);
9461 /* Fall through */
9462 case 3:
9463 DECR_AND_LOAD(20);
9464 /* Fall through */
9465 case 2:
9466 DECR_AND_LOAD(19);
9467 /* Fall through */
9468 case 1:
9469 DECR_AND_LOAD(18);
9470 }
9471
9472 if (do_s1) {
9473 DECR_AND_LOAD(17);
9474 }
9475 if (do_s0) {
9476 DECR_AND_LOAD(16);
9477 }
9478
9479 switch (aregs) {
9480 case 0:
9481 case 4:
9482 case 8:
9483 case 12:
9484 case 14:
9485 astatic = 0;
9486 break;
9487 case 1:
9488 case 5:
9489 case 9:
9490 case 13:
9491 astatic = 1;
9492 break;
9493 case 2:
9494 case 6:
9495 case 10:
9496 astatic = 2;
9497 break;
9498 case 3:
9499 case 7:
9500 astatic = 3;
9501 break;
9502 case 11:
9503 astatic = 4;
9504 break;
9505 default:
9506 generate_exception(ctx, EXCP_RI);
9507 return;
9508 }
9509
9510 if (astatic > 0) {
9511 DECR_AND_LOAD(7);
9512 if (astatic > 1) {
9513 DECR_AND_LOAD(6);
9514 if (astatic > 2) {
9515 DECR_AND_LOAD(5);
9516 if (astatic > 3) {
9517 DECR_AND_LOAD(4);
9518 }
9519 }
9520 }
9521 }
9522#undef DECR_AND_LOAD
9523
9524 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9525 tcg_temp_free(t0);
9526 tcg_temp_free(t1);
9527}
9528
9529static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9530 int is_64_bit, int extended)
9531{
9532 TCGv t0;
9533
9534 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9535 generate_exception(ctx, EXCP_RI);
9536 return;
9537 }
9538
9539 t0 = tcg_temp_new();
9540
9541 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9542 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9543 if (!is_64_bit) {
9544 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9545 }
9546
9547 tcg_temp_free(t0);
9548}
9549
9550#if defined(TARGET_MIPS64)
d75c135e 9551static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9552 int ry, int funct, int16_t offset,
9553 int extended)
9554{
9555 switch (funct) {
9556 case I64_LDSP:
9557 check_mips_64(ctx);
9558 offset = extended ? offset : offset << 3;
d75c135e 9559 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9560 break;
9561 case I64_SDSP:
9562 check_mips_64(ctx);
9563 offset = extended ? offset : offset << 3;
5c13fdfd 9564 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9565 break;
9566 case I64_SDRASP:
9567 check_mips_64(ctx);
9568 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9569 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9570 break;
9571 case I64_DADJSP:
9572 check_mips_64(ctx);
9573 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9574 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9575 break;
9576 case I64_LDPC:
9577 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9578 generate_exception(ctx, EXCP_RI);
9579 } else {
9580 offset = extended ? offset : offset << 3;
d75c135e 9581 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9582 }
9583 break;
9584 case I64_DADDIU5:
9585 check_mips_64(ctx);
9586 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9587 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9588 break;
9589 case I64_DADDIUPC:
9590 check_mips_64(ctx);
9591 offset = extended ? offset : offset << 2;
9592 gen_addiupc(ctx, ry, offset, 1, extended);
9593 break;
9594 case I64_DADDIUSP:
9595 check_mips_64(ctx);
9596 offset = extended ? offset : offset << 2;
d75c135e 9597 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9598 break;
9599 }
9600}
9601#endif
9602
7db13fae 9603static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9604 int *is_branch)
9605{
895c2d04 9606 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9607 int op, rx, ry, funct, sa;
9608 int16_t imm, offset;
9609
9610 ctx->opcode = (ctx->opcode << 16) | extend;
9611 op = (ctx->opcode >> 11) & 0x1f;
9612 sa = (ctx->opcode >> 22) & 0x1f;
9613 funct = (ctx->opcode >> 8) & 0x7;
9614 rx = xlat((ctx->opcode >> 8) & 0x7);
9615 ry = xlat((ctx->opcode >> 5) & 0x7);
9616 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9617 | ((ctx->opcode >> 21) & 0x3f) << 5
9618 | (ctx->opcode & 0x1f));
9619
9620 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9621 counterparts. */
9622 switch (op) {
9623 case M16_OPC_ADDIUSP:
d75c135e 9624 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9625 break;
9626 case M16_OPC_ADDIUPC:
9627 gen_addiupc(ctx, rx, imm, 0, 1);
9628 break;
9629 case M16_OPC_B:
9630 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9631 /* No delay slot, so just process as a normal instruction */
9632 break;
9633 case M16_OPC_BEQZ:
9634 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9635 /* No delay slot, so just process as a normal instruction */
9636 break;
9637 case M16_OPC_BNEQZ:
9638 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9639 /* No delay slot, so just process as a normal instruction */
9640 break;
9641 case M16_OPC_SHIFT:
9642 switch (ctx->opcode & 0x3) {
9643 case 0x0:
d75c135e 9644 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9645 break;
9646 case 0x1:
9647#if defined(TARGET_MIPS64)
9648 check_mips_64(ctx);
d75c135e 9649 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9650#else
9651 generate_exception(ctx, EXCP_RI);
9652#endif
9653 break;
9654 case 0x2:
d75c135e 9655 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9656 break;
9657 case 0x3:
d75c135e 9658 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9659 break;
9660 }
9661 break;
9662#if defined(TARGET_MIPS64)
9663 case M16_OPC_LD:
9664 check_mips_64(ctx);
d75c135e 9665 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9666 break;
9667#endif
9668 case M16_OPC_RRIA:
9669 imm = ctx->opcode & 0xf;
9670 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9671 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9672 imm = (int16_t) (imm << 1) >> 1;
9673 if ((ctx->opcode >> 4) & 0x1) {
9674#if defined(TARGET_MIPS64)
9675 check_mips_64(ctx);
d75c135e 9676 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9677#else
9678 generate_exception(ctx, EXCP_RI);
9679#endif
9680 } else {
d75c135e 9681 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9682 }
9683 break;
9684 case M16_OPC_ADDIU8:
d75c135e 9685 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9686 break;
9687 case M16_OPC_SLTI:
d75c135e 9688 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9689 break;
9690 case M16_OPC_SLTIU:
d75c135e 9691 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9692 break;
9693 case M16_OPC_I8:
9694 switch (funct) {
9695 case I8_BTEQZ:
9696 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9697 break;
9698 case I8_BTNEZ:
9699 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9700 break;
9701 case I8_SWRASP:
5c13fdfd 9702 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9703 break;
9704 case I8_ADJSP:
d75c135e 9705 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
9706 break;
9707 case I8_SVRS:
9708 {
9709 int xsregs = (ctx->opcode >> 24) & 0x7;
9710 int aregs = (ctx->opcode >> 16) & 0xf;
9711 int do_ra = (ctx->opcode >> 6) & 0x1;
9712 int do_s0 = (ctx->opcode >> 5) & 0x1;
9713 int do_s1 = (ctx->opcode >> 4) & 0x1;
9714 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9715 | (ctx->opcode & 0xf)) << 3;
9716
9717 if (ctx->opcode & (1 << 7)) {
9718 gen_mips16_save(ctx, xsregs, aregs,
9719 do_ra, do_s0, do_s1,
9720 framesize);
9721 } else {
9722 gen_mips16_restore(ctx, xsregs, aregs,
9723 do_ra, do_s0, do_s1,
9724 framesize);
9725 }
9726 }
9727 break;
9728 default:
9729 generate_exception(ctx, EXCP_RI);
9730 break;
9731 }
9732 break;
9733 case M16_OPC_LI:
9734 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9735 break;
9736 case M16_OPC_CMPI:
9737 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9738 break;
9739#if defined(TARGET_MIPS64)
9740 case M16_OPC_SD:
5c13fdfd 9741 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9742 break;
9743#endif
9744 case M16_OPC_LB:
d75c135e 9745 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9746 break;
9747 case M16_OPC_LH:
d75c135e 9748 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9749 break;
9750 case M16_OPC_LWSP:
d75c135e 9751 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9752 break;
9753 case M16_OPC_LW:
d75c135e 9754 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9755 break;
9756 case M16_OPC_LBU:
d75c135e 9757 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9758 break;
9759 case M16_OPC_LHU:
d75c135e 9760 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9761 break;
9762 case M16_OPC_LWPC:
d75c135e 9763 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9764 break;
9765#if defined(TARGET_MIPS64)
9766 case M16_OPC_LWU:
d75c135e 9767 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9768 break;
9769#endif
9770 case M16_OPC_SB:
5c13fdfd 9771 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9772 break;
9773 case M16_OPC_SH:
5c13fdfd 9774 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9775 break;
9776 case M16_OPC_SWSP:
5c13fdfd 9777 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9778 break;
9779 case M16_OPC_SW:
5c13fdfd 9780 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9781 break;
9782#if defined(TARGET_MIPS64)
9783 case M16_OPC_I64:
d75c135e 9784 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
9785 break;
9786#endif
9787 default:
9788 generate_exception(ctx, EXCP_RI);
9789 break;
9790 }
9791
9792 return 4;
9793}
9794
7db13fae 9795static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9796 int *is_branch)
9797{
9798 int rx, ry;
9799 int sa;
9800 int op, cnvt_op, op1, offset;
9801 int funct;
9802 int n_bytes;
9803
9804 op = (ctx->opcode >> 11) & 0x1f;
9805 sa = (ctx->opcode >> 2) & 0x7;
9806 sa = sa == 0 ? 8 : sa;
9807 rx = xlat((ctx->opcode >> 8) & 0x7);
9808 cnvt_op = (ctx->opcode >> 5) & 0x7;
9809 ry = xlat((ctx->opcode >> 5) & 0x7);
9810 op1 = offset = ctx->opcode & 0x1f;
9811
9812 n_bytes = 2;
9813
9814 switch (op) {
9815 case M16_OPC_ADDIUSP:
9816 {
9817 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9818
d75c135e 9819 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9820 }
9821 break;
9822 case M16_OPC_ADDIUPC:
9823 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9824 break;
9825 case M16_OPC_B:
9826 offset = (ctx->opcode & 0x7ff) << 1;
9827 offset = (int16_t)(offset << 4) >> 4;
9828 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9829 /* No delay slot, so just process as a normal instruction */
9830 break;
9831 case M16_OPC_JAL:
895c2d04 9832 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9833 offset = (((ctx->opcode & 0x1f) << 21)
9834 | ((ctx->opcode >> 5) & 0x1f) << 16
9835 | offset) << 2;
620e48f6 9836 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9837 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9838 n_bytes = 4;
9839 *is_branch = 1;
9840 break;
9841 case M16_OPC_BEQZ:
9842 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9843 /* No delay slot, so just process as a normal instruction */
9844 break;
9845 case M16_OPC_BNEQZ:
9846 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9847 /* No delay slot, so just process as a normal instruction */
9848 break;
9849 case M16_OPC_SHIFT:
9850 switch (ctx->opcode & 0x3) {
9851 case 0x0:
d75c135e 9852 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9853 break;
9854 case 0x1:
9855#if defined(TARGET_MIPS64)
9856 check_mips_64(ctx);
d75c135e 9857 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9858#else
9859 generate_exception(ctx, EXCP_RI);
9860#endif
9861 break;
9862 case 0x2:
d75c135e 9863 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9864 break;
9865 case 0x3:
d75c135e 9866 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9867 break;
9868 }
9869 break;
9870#if defined(TARGET_MIPS64)
9871 case M16_OPC_LD:
9872 check_mips_64(ctx);
d75c135e 9873 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9874 break;
9875#endif
9876 case M16_OPC_RRIA:
9877 {
9878 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9879
9880 if ((ctx->opcode >> 4) & 1) {
9881#if defined(TARGET_MIPS64)
9882 check_mips_64(ctx);
d75c135e 9883 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9884#else
9885 generate_exception(ctx, EXCP_RI);
9886#endif
9887 } else {
d75c135e 9888 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9889 }
9890 }
9891 break;
9892 case M16_OPC_ADDIU8:
9893 {
9894 int16_t imm = (int8_t) ctx->opcode;
9895
d75c135e 9896 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9897 }
9898 break;
9899 case M16_OPC_SLTI:
9900 {
9901 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9902 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9903 }
9904 break;
9905 case M16_OPC_SLTIU:
9906 {
9907 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9908 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9909 }
9910 break;
9911 case M16_OPC_I8:
9912 {
9913 int reg32;
9914
9915 funct = (ctx->opcode >> 8) & 0x7;
9916 switch (funct) {
9917 case I8_BTEQZ:
9918 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9919 ((int8_t)ctx->opcode) << 1);
9920 break;
9921 case I8_BTNEZ:
9922 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9923 ((int8_t)ctx->opcode) << 1);
9924 break;
9925 case I8_SWRASP:
5c13fdfd 9926 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9927 break;
9928 case I8_ADJSP:
d75c135e 9929 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
9930 ((int8_t)ctx->opcode) << 3);
9931 break;
9932 case I8_SVRS:
9933 {
9934 int do_ra = ctx->opcode & (1 << 6);
9935 int do_s0 = ctx->opcode & (1 << 5);
9936 int do_s1 = ctx->opcode & (1 << 4);
9937 int framesize = ctx->opcode & 0xf;
9938
9939 if (framesize == 0) {
9940 framesize = 128;
9941 } else {
9942 framesize = framesize << 3;
9943 }
9944
9945 if (ctx->opcode & (1 << 7)) {
9946 gen_mips16_save(ctx, 0, 0,
9947 do_ra, do_s0, do_s1, framesize);
9948 } else {
9949 gen_mips16_restore(ctx, 0, 0,
9950 do_ra, do_s0, do_s1, framesize);
9951 }
9952 }
9953 break;
9954 case I8_MOV32R:
9955 {
9956 int rz = xlat(ctx->opcode & 0x7);
9957
9958 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9959 ((ctx->opcode >> 5) & 0x7);
d75c135e 9960 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
9961 }
9962 break;
9963 case I8_MOVR32:
9964 reg32 = ctx->opcode & 0x1f;
d75c135e 9965 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
9966 break;
9967 default:
9968 generate_exception(ctx, EXCP_RI);
9969 break;
9970 }
9971 }
9972 break;
9973 case M16_OPC_LI:
9974 {
9975 int16_t imm = (uint8_t) ctx->opcode;
9976
d75c135e 9977 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
9978 }
9979 break;
9980 case M16_OPC_CMPI:
9981 {
9982 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9983 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
9984 }
9985 break;
9986#if defined(TARGET_MIPS64)
9987 case M16_OPC_SD:
9988 check_mips_64(ctx);
5c13fdfd 9989 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
9990 break;
9991#endif
9992 case M16_OPC_LB:
d75c135e 9993 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9994 break;
9995 case M16_OPC_LH:
d75c135e 9996 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
9997 break;
9998 case M16_OPC_LWSP:
d75c135e 9999 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10000 break;
10001 case M16_OPC_LW:
d75c135e 10002 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10003 break;
10004 case M16_OPC_LBU:
d75c135e 10005 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10006 break;
10007 case M16_OPC_LHU:
d75c135e 10008 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10009 break;
10010 case M16_OPC_LWPC:
d75c135e 10011 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10012 break;
10013#if defined (TARGET_MIPS64)
10014 case M16_OPC_LWU:
10015 check_mips_64(ctx);
d75c135e 10016 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10017 break;
10018#endif
10019 case M16_OPC_SB:
5c13fdfd 10020 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10021 break;
10022 case M16_OPC_SH:
5c13fdfd 10023 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10024 break;
10025 case M16_OPC_SWSP:
5c13fdfd 10026 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10027 break;
10028 case M16_OPC_SW:
5c13fdfd 10029 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10030 break;
10031 case M16_OPC_RRR:
10032 {
10033 int rz = xlat((ctx->opcode >> 2) & 0x7);
10034 int mips32_op;
10035
10036 switch (ctx->opcode & 0x3) {
10037 case RRR_ADDU:
10038 mips32_op = OPC_ADDU;
10039 break;
10040 case RRR_SUBU:
10041 mips32_op = OPC_SUBU;
10042 break;
10043#if defined(TARGET_MIPS64)
10044 case RRR_DADDU:
10045 mips32_op = OPC_DADDU;
10046 check_mips_64(ctx);
10047 break;
10048 case RRR_DSUBU:
10049 mips32_op = OPC_DSUBU;
10050 check_mips_64(ctx);
10051 break;
10052#endif
10053 default:
10054 generate_exception(ctx, EXCP_RI);
10055 goto done;
10056 }
10057
d75c135e 10058 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10059 done:
10060 ;
10061 }
10062 break;
10063 case M16_OPC_RR:
10064 switch (op1) {
10065 case RR_JR:
10066 {
10067 int nd = (ctx->opcode >> 7) & 0x1;
10068 int link = (ctx->opcode >> 6) & 0x1;
10069 int ra = (ctx->opcode >> 5) & 0x1;
10070
10071 if (link) {
620e48f6 10072 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10073 } else {
10074 op = OPC_JR;
10075 }
10076
10077 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10078 if (!nd) {
10079 *is_branch = 1;
10080 }
10081 }
10082 break;
10083 case RR_SDBBP:
10084 /* XXX: not clear which exception should be raised
10085 * when in debug mode...
10086 */
d75c135e 10087 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10088 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10089 generate_exception(ctx, EXCP_DBp);
10090 } else {
10091 generate_exception(ctx, EXCP_DBp);
10092 }
10093 break;
10094 case RR_SLT:
d75c135e 10095 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10096 break;
10097 case RR_SLTU:
d75c135e 10098 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10099 break;
10100 case RR_BREAK:
10101 generate_exception(ctx, EXCP_BREAK);
10102 break;
10103 case RR_SLLV:
d75c135e 10104 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10105 break;
10106 case RR_SRLV:
d75c135e 10107 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10108 break;
10109 case RR_SRAV:
d75c135e 10110 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10111 break;
10112#if defined (TARGET_MIPS64)
10113 case RR_DSRL:
10114 check_mips_64(ctx);
d75c135e 10115 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10116 break;
10117#endif
10118 case RR_CMP:
d75c135e 10119 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10120 break;
10121 case RR_NEG:
d75c135e 10122 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10123 break;
10124 case RR_AND:
d75c135e 10125 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10126 break;
10127 case RR_OR:
d75c135e 10128 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10129 break;
10130 case RR_XOR:
d75c135e 10131 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10132 break;
10133 case RR_NOT:
d75c135e 10134 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10135 break;
10136 case RR_MFHI:
10137 gen_HILO(ctx, OPC_MFHI, rx);
10138 break;
10139 case RR_CNVT:
10140 switch (cnvt_op) {
10141 case RR_RY_CNVT_ZEB:
10142 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10143 break;
10144 case RR_RY_CNVT_ZEH:
10145 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10146 break;
10147 case RR_RY_CNVT_SEB:
10148 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10149 break;
10150 case RR_RY_CNVT_SEH:
10151 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10152 break;
10153#if defined (TARGET_MIPS64)
10154 case RR_RY_CNVT_ZEW:
10155 check_mips_64(ctx);
10156 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10157 break;
10158 case RR_RY_CNVT_SEW:
10159 check_mips_64(ctx);
10160 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10161 break;
10162#endif
10163 default:
10164 generate_exception(ctx, EXCP_RI);
10165 break;
10166 }
10167 break;
10168 case RR_MFLO:
10169 gen_HILO(ctx, OPC_MFLO, rx);
10170 break;
10171#if defined (TARGET_MIPS64)
10172 case RR_DSRA:
10173 check_mips_64(ctx);
d75c135e 10174 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10175 break;
10176 case RR_DSLLV:
10177 check_mips_64(ctx);
d75c135e 10178 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10179 break;
10180 case RR_DSRLV:
10181 check_mips_64(ctx);
d75c135e 10182 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10183 break;
10184 case RR_DSRAV:
10185 check_mips_64(ctx);
d75c135e 10186 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10187 break;
10188#endif
10189 case RR_MULT:
10190 gen_muldiv(ctx, OPC_MULT, rx, ry);
10191 break;
10192 case RR_MULTU:
10193 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10194 break;
10195 case RR_DIV:
10196 gen_muldiv(ctx, OPC_DIV, rx, ry);
10197 break;
10198 case RR_DIVU:
10199 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10200 break;
10201#if defined (TARGET_MIPS64)
10202 case RR_DMULT:
10203 check_mips_64(ctx);
10204 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10205 break;
10206 case RR_DMULTU:
10207 check_mips_64(ctx);
10208 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10209 break;
10210 case RR_DDIV:
10211 check_mips_64(ctx);
10212 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10213 break;
10214 case RR_DDIVU:
10215 check_mips_64(ctx);
10216 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10217 break;
10218#endif
10219 default:
10220 generate_exception(ctx, EXCP_RI);
10221 break;
10222 }
10223 break;
10224 case M16_OPC_EXTEND:
10225 decode_extended_mips16_opc(env, ctx, is_branch);
10226 n_bytes = 4;
10227 break;
10228#if defined(TARGET_MIPS64)
10229 case M16_OPC_I64:
10230 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10231 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10232 break;
10233#endif
10234 default:
10235 generate_exception(ctx, EXCP_RI);
10236 break;
10237 }
10238
10239 return n_bytes;
10240}
10241
211da992 10242/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10243
211da992
WRC
10244/*
10245 * microMIPS32/microMIPS64 major opcodes
10246 *
10247 * 1. MIPS Architecture for Programmers Volume II-B:
10248 * The microMIPS32 Instruction Set (Revision 3.05)
10249 *
10250 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10251 *
10252 * 2. MIPS Architecture For Programmers Volume II-A:
10253 * The MIPS64 Instruction Set (Revision 3.51)
10254 */
6af0bf9c 10255
3c824109
NF
10256enum {
10257 POOL32A = 0x00,
10258 POOL16A = 0x01,
10259 LBU16 = 0x02,
10260 MOVE16 = 0x03,
10261 ADDI32 = 0x04,
10262 LBU32 = 0x05,
10263 SB32 = 0x06,
10264 LB32 = 0x07,
10265
10266 POOL32B = 0x08,
10267 POOL16B = 0x09,
10268 LHU16 = 0x0a,
10269 ANDI16 = 0x0b,
10270 ADDIU32 = 0x0c,
10271 LHU32 = 0x0d,
10272 SH32 = 0x0e,
10273 LH32 = 0x0f,
10274
10275 POOL32I = 0x10,
10276 POOL16C = 0x11,
10277 LWSP16 = 0x12,
10278 POOL16D = 0x13,
10279 ORI32 = 0x14,
10280 POOL32F = 0x15,
211da992
WRC
10281 POOL32S = 0x16, /* MIPS64 */
10282 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10283
211da992 10284 /* 0x1f is reserved */
3c824109
NF
10285 POOL32C = 0x18,
10286 LWGP16 = 0x19,
10287 LW16 = 0x1a,
10288 POOL16E = 0x1b,
10289 XORI32 = 0x1c,
10290 JALS32 = 0x1d,
10291 ADDIUPC = 0x1e,
3c824109
NF
10292
10293 /* 0x20 is reserved */
10294 RES_20 = 0x20,
10295 POOL16F = 0x21,
10296 SB16 = 0x22,
10297 BEQZ16 = 0x23,
10298 SLTI32 = 0x24,
10299 BEQ32 = 0x25,
10300 SWC132 = 0x26,
10301 LWC132 = 0x27,
10302
10303 /* 0x28 and 0x29 are reserved */
10304 RES_28 = 0x28,
10305 RES_29 = 0x29,
10306 SH16 = 0x2a,
10307 BNEZ16 = 0x2b,
10308 SLTIU32 = 0x2c,
10309 BNE32 = 0x2d,
10310 SDC132 = 0x2e,
10311 LDC132 = 0x2f,
10312
10313 /* 0x30 and 0x31 are reserved */
10314 RES_30 = 0x30,
10315 RES_31 = 0x31,
10316 SWSP16 = 0x32,
10317 B16 = 0x33,
10318 ANDI32 = 0x34,
10319 J32 = 0x35,
211da992
WRC
10320 SD32 = 0x36, /* MIPS64 */
10321 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10322
10323 /* 0x38 and 0x39 are reserved */
10324 RES_38 = 0x38,
10325 RES_39 = 0x39,
10326 SW16 = 0x3a,
10327 LI16 = 0x3b,
10328 JALX32 = 0x3c,
10329 JAL32 = 0x3d,
10330 SW32 = 0x3e,
10331 LW32 = 0x3f
10332};
10333
10334/* POOL32A encoding of minor opcode field */
10335
10336enum {
10337 /* These opcodes are distinguished only by bits 9..6; those bits are
10338 * what are recorded below. */
10339 SLL32 = 0x0,
10340 SRL32 = 0x1,
10341 SRA = 0x2,
10342 ROTR = 0x3,
10343
10344 SLLV = 0x0,
10345 SRLV = 0x1,
10346 SRAV = 0x2,
10347 ROTRV = 0x3,
10348 ADD = 0x4,
10349 ADDU32 = 0x5,
10350 SUB = 0x6,
10351 SUBU32 = 0x7,
10352 MUL = 0x8,
10353 AND = 0x9,
10354 OR32 = 0xa,
10355 NOR = 0xb,
10356 XOR32 = 0xc,
10357 SLT = 0xd,
10358 SLTU = 0xe,
10359
10360 MOVN = 0x0,
10361 MOVZ = 0x1,
10362 LWXS = 0x4,
10363
10364 /* The following can be distinguished by their lower 6 bits. */
10365 INS = 0x0c,
10366 EXT = 0x2c,
10367 POOL32AXF = 0x3c
10368};
10369
10370/* POOL32AXF encoding of minor opcode field extension */
10371
d132c79f
WRC
10372/*
10373 * 1. MIPS Architecture for Programmers Volume II-B:
10374 * The microMIPS32 Instruction Set (Revision 3.05)
10375 *
10376 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10377 *
10378 * 2. MIPS Architecture for Programmers VolumeIV-e:
10379 * The MIPS DSP Application-Specific Extension
10380 * to the microMIPS32 Architecture (Revision 2.34)
10381 *
10382 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10383 */
10384
3c824109
NF
10385enum {
10386 /* bits 11..6 */
10387 TEQ = 0x00,
10388 TGE = 0x08,
10389 TGEU = 0x10,
10390 TLT = 0x20,
10391 TLTU = 0x28,
10392 TNE = 0x30,
10393
10394 MFC0 = 0x03,
10395 MTC0 = 0x0b,
10396
d132c79f
WRC
10397 /* begin of microMIPS32 DSP */
10398
3c824109
NF
10399 /* bits 13..12 for 0x01 */
10400 MFHI_ACC = 0x0,
10401 MFLO_ACC = 0x1,
10402 MTHI_ACC = 0x2,
10403 MTLO_ACC = 0x3,
10404
10405 /* bits 13..12 for 0x2a */
10406 MADD_ACC = 0x0,
10407 MADDU_ACC = 0x1,
10408 MSUB_ACC = 0x2,
10409 MSUBU_ACC = 0x3,
10410
10411 /* bits 13..12 for 0x32 */
10412 MULT_ACC = 0x0,
6801038b 10413 MULTU_ACC = 0x1,
3c824109 10414
d132c79f
WRC
10415 /* end of microMIPS32 DSP */
10416
3c824109
NF
10417 /* bits 15..12 for 0x2c */
10418 SEB = 0x2,
10419 SEH = 0x3,
10420 CLO = 0x4,
10421 CLZ = 0x5,
10422 RDHWR = 0x6,
10423 WSBH = 0x7,
10424 MULT = 0x8,
10425 MULTU = 0x9,
10426 DIV = 0xa,
10427 DIVU = 0xb,
10428 MADD = 0xc,
10429 MADDU = 0xd,
10430 MSUB = 0xe,
10431 MSUBU = 0xf,
10432
10433 /* bits 15..12 for 0x34 */
10434 MFC2 = 0x4,
10435 MTC2 = 0x5,
10436 MFHC2 = 0x8,
10437 MTHC2 = 0x9,
10438 CFC2 = 0xc,
10439 CTC2 = 0xd,
10440
10441 /* bits 15..12 for 0x3c */
10442 JALR = 0x0,
10443 JR = 0x0, /* alias */
10444 JALR_HB = 0x1,
10445 JALRS = 0x4,
10446 JALRS_HB = 0x5,
10447
10448 /* bits 15..12 for 0x05 */
10449 RDPGPR = 0xe,
10450 WRPGPR = 0xf,
10451
10452 /* bits 15..12 for 0x0d */
10453 TLBP = 0x0,
10454 TLBR = 0x1,
10455 TLBWI = 0x2,
10456 TLBWR = 0x3,
10457 WAIT = 0x9,
10458 IRET = 0xd,
10459 DERET = 0xe,
10460 ERET = 0xf,
10461
10462 /* bits 15..12 for 0x15 */
10463 DMT = 0x0,
10464 DVPE = 0x1,
10465 EMT = 0x2,
10466 EVPE = 0x3,
10467
10468 /* bits 15..12 for 0x1d */
10469 DI = 0x4,
10470 EI = 0x5,
10471
10472 /* bits 15..12 for 0x2d */
10473 SYNC = 0x6,
10474 SYSCALL = 0x8,
10475 SDBBP = 0xd,
10476
10477 /* bits 15..12 for 0x35 */
10478 MFHI32 = 0x0,
10479 MFLO32 = 0x1,
10480 MTHI32 = 0x2,
10481 MTLO32 = 0x3,
10482};
10483
10484/* POOL32B encoding of minor opcode field (bits 15..12) */
10485
10486enum {
10487 LWC2 = 0x0,
10488 LWP = 0x1,
10489 LDP = 0x4,
10490 LWM32 = 0x5,
10491 CACHE = 0x6,
10492 LDM = 0x7,
10493 SWC2 = 0x8,
10494 SWP = 0x9,
10495 SDP = 0xc,
10496 SWM32 = 0xd,
10497 SDM = 0xf
10498};
10499
10500/* POOL32C encoding of minor opcode field (bits 15..12) */
10501
10502enum {
10503 LWL = 0x0,
10504 SWL = 0x8,
10505 LWR = 0x1,
10506 SWR = 0x9,
10507 PREF = 0x2,
10508 /* 0xa is reserved */
10509 LL = 0x3,
10510 SC = 0xb,
10511 LDL = 0x4,
10512 SDL = 0xc,
10513 LDR = 0x5,
10514 SDR = 0xd,
10515 /* 0x6 is reserved */
10516 LWU = 0xe,
10517 LLD = 0x7,
10518 SCD = 0xf
10519};
10520
10521/* POOL32F encoding of minor opcode field (bits 5..0) */
10522
10523enum {
10524 /* These are the bit 7..6 values */
10525 ADD_FMT = 0x0,
10526 MOVN_FMT = 0x0,
10527
10528 SUB_FMT = 0x1,
10529 MOVZ_FMT = 0x1,
10530
10531 MUL_FMT = 0x2,
10532
10533 DIV_FMT = 0x3,
10534
10535 /* These are the bit 8..6 values */
10536 RSQRT2_FMT = 0x0,
10537 MOVF_FMT = 0x0,
10538
10539 LWXC1 = 0x1,
10540 MOVT_FMT = 0x1,
10541
10542 PLL_PS = 0x2,
10543 SWXC1 = 0x2,
10544
10545 PLU_PS = 0x3,
10546 LDXC1 = 0x3,
10547
10548 PUL_PS = 0x4,
10549 SDXC1 = 0x4,
10550 RECIP2_FMT = 0x4,
10551
10552 PUU_PS = 0x5,
10553 LUXC1 = 0x5,
10554
10555 CVT_PS_S = 0x6,
10556 SUXC1 = 0x6,
10557 ADDR_PS = 0x6,
10558 PREFX = 0x6,
10559
10560 MULR_PS = 0x7,
10561
10562 MADD_S = 0x01,
10563 MADD_D = 0x09,
10564 MADD_PS = 0x11,
10565 ALNV_PS = 0x19,
10566 MSUB_S = 0x21,
10567 MSUB_D = 0x29,
10568 MSUB_PS = 0x31,
10569
10570 NMADD_S = 0x02,
10571 NMADD_D = 0x0a,
10572 NMADD_PS = 0x12,
10573 NMSUB_S = 0x22,
10574 NMSUB_D = 0x2a,
10575 NMSUB_PS = 0x32,
10576
10577 POOL32FXF = 0x3b,
10578
10579 CABS_COND_FMT = 0x1c, /* MIPS3D */
10580 C_COND_FMT = 0x3c
10581};
10582
10583/* POOL32Fxf encoding of minor opcode extension field */
10584
10585enum {
10586 CVT_L = 0x04,
10587 RSQRT_FMT = 0x08,
10588 FLOOR_L = 0x0c,
10589 CVT_PW_PS = 0x1c,
10590 CVT_W = 0x24,
10591 SQRT_FMT = 0x28,
10592 FLOOR_W = 0x2c,
10593 CVT_PS_PW = 0x3c,
10594 CFC1 = 0x40,
10595 RECIP_FMT = 0x48,
10596 CEIL_L = 0x4c,
10597 CTC1 = 0x60,
10598 CEIL_W = 0x6c,
10599 MFC1 = 0x80,
10600 CVT_S_PL = 0x84,
10601 TRUNC_L = 0x8c,
10602 MTC1 = 0xa0,
10603 CVT_S_PU = 0xa4,
10604 TRUNC_W = 0xac,
10605 MFHC1 = 0xc0,
10606 ROUND_L = 0xcc,
10607 MTHC1 = 0xe0,
10608 ROUND_W = 0xec,
10609
10610 MOV_FMT = 0x01,
10611 MOVF = 0x05,
10612 ABS_FMT = 0x0d,
10613 RSQRT1_FMT = 0x1d,
10614 MOVT = 0x25,
10615 NEG_FMT = 0x2d,
10616 CVT_D = 0x4d,
10617 RECIP1_FMT = 0x5d,
10618 CVT_S = 0x6d
10619};
10620
10621/* POOL32I encoding of minor opcode field (bits 25..21) */
10622
10623enum {
10624 BLTZ = 0x00,
10625 BLTZAL = 0x01,
10626 BGEZ = 0x02,
10627 BGEZAL = 0x03,
10628 BLEZ = 0x04,
10629 BNEZC = 0x05,
10630 BGTZ = 0x06,
10631 BEQZC = 0x07,
10632 TLTI = 0x08,
10633 TGEI = 0x09,
10634 TLTIU = 0x0a,
10635 TGEIU = 0x0b,
10636 TNEI = 0x0c,
10637 LUI = 0x0d,
10638 TEQI = 0x0e,
10639 SYNCI = 0x10,
10640 BLTZALS = 0x11,
10641 BGEZALS = 0x13,
10642 BC2F = 0x14,
10643 BC2T = 0x15,
10644 BPOSGE64 = 0x1a,
10645 BPOSGE32 = 0x1b,
10646 /* These overlap and are distinguished by bit16 of the instruction */
10647 BC1F = 0x1c,
10648 BC1T = 0x1d,
10649 BC1ANY2F = 0x1c,
10650 BC1ANY2T = 0x1d,
10651 BC1ANY4F = 0x1e,
10652 BC1ANY4T = 0x1f
10653};
10654
10655/* POOL16A encoding of minor opcode field */
10656
10657enum {
10658 ADDU16 = 0x0,
10659 SUBU16 = 0x1
10660};
10661
10662/* POOL16B encoding of minor opcode field */
10663
10664enum {
10665 SLL16 = 0x0,
10666 SRL16 = 0x1
10667};
10668
10669/* POOL16C encoding of minor opcode field */
10670
10671enum {
10672 NOT16 = 0x00,
10673 XOR16 = 0x04,
10674 AND16 = 0x08,
10675 OR16 = 0x0c,
10676 LWM16 = 0x10,
10677 SWM16 = 0x14,
10678 JR16 = 0x18,
10679 JRC16 = 0x1a,
10680 JALR16 = 0x1c,
10681 JALR16S = 0x1e,
10682 MFHI16 = 0x20,
10683 MFLO16 = 0x24,
10684 BREAK16 = 0x28,
10685 SDBBP16 = 0x2c,
10686 JRADDIUSP = 0x30
10687};
10688
10689/* POOL16D encoding of minor opcode field */
10690
10691enum {
10692 ADDIUS5 = 0x0,
10693 ADDIUSP = 0x1
10694};
10695
10696/* POOL16E encoding of minor opcode field */
10697
10698enum {
10699 ADDIUR2 = 0x0,
10700 ADDIUR1SP = 0x1
10701};
10702
10703static int mmreg (int r)
10704{
10705 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10706
10707 return map[r];
10708}
10709
10710/* Used for 16-bit store instructions. */
10711static int mmreg2 (int r)
10712{
10713 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10714
10715 return map[r];
10716}
10717
10718#define uMIPS_RD(op) ((op >> 7) & 0x7)
10719#define uMIPS_RS(op) ((op >> 4) & 0x7)
10720#define uMIPS_RS2(op) uMIPS_RS(op)
10721#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10722#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10723#define uMIPS_RS5(op) (op & 0x1f)
10724
10725/* Signed immediate */
10726#define SIMM(op, start, width) \
10727 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10728 << (32-width)) \
10729 >> (32-width))
10730/* Zero-extended immediate */
10731#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10732
d75c135e 10733static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
10734{
10735 int rd = mmreg(uMIPS_RD(ctx->opcode));
10736
d75c135e 10737 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
10738}
10739
d75c135e 10740static void gen_addiur2(DisasContext *ctx)
3c824109
NF
10741{
10742 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10743 int rd = mmreg(uMIPS_RD(ctx->opcode));
10744 int rs = mmreg(uMIPS_RS(ctx->opcode));
10745
d75c135e 10746 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
10747}
10748
d75c135e 10749static void gen_addiusp(DisasContext *ctx)
3c824109
NF
10750{
10751 int encoded = ZIMM(ctx->opcode, 1, 9);
10752 int decoded;
10753
10754 if (encoded <= 1) {
10755 decoded = 256 + encoded;
10756 } else if (encoded <= 255) {
10757 decoded = encoded;
10758 } else if (encoded <= 509) {
10759 decoded = encoded - 512;
10760 } else {
10761 decoded = encoded - 768;
10762 }
10763
d75c135e 10764 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
10765}
10766
d75c135e 10767static void gen_addius5(DisasContext *ctx)
3c824109
NF
10768{
10769 int imm = SIMM(ctx->opcode, 1, 4);
10770 int rd = (ctx->opcode >> 5) & 0x1f;
10771
d75c135e 10772 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
10773}
10774
d75c135e 10775static void gen_andi16(DisasContext *ctx)
3c824109
NF
10776{
10777 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10778 31, 32, 63, 64, 255, 32768, 65535 };
10779 int rd = mmreg(uMIPS_RD(ctx->opcode));
10780 int rs = mmreg(uMIPS_RS(ctx->opcode));
10781 int encoded = ZIMM(ctx->opcode, 0, 4);
10782
d75c135e 10783 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10784}
10785
10786static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10787 int base, int16_t offset)
10788{
e1050a76 10789 const char *opn = "ldst_multiple";
3c824109
NF
10790 TCGv t0, t1;
10791 TCGv_i32 t2;
10792
10793 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10794 generate_exception(ctx, EXCP_RI);
10795 return;
10796 }
10797
10798 t0 = tcg_temp_new();
10799
10800 gen_base_offset_addr(ctx, t0, base, offset);
10801
10802 t1 = tcg_const_tl(reglist);
10803 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10804
3c824109
NF
10805 save_cpu_state(ctx, 1);
10806 switch (opc) {
10807 case LWM32:
895c2d04 10808 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10809 opn = "lwm";
3c824109
NF
10810 break;
10811 case SWM32:
895c2d04 10812 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10813 opn = "swm";
3c824109
NF
10814 break;
10815#ifdef TARGET_MIPS64
10816 case LDM:
895c2d04 10817 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10818 opn = "ldm";
3c824109
NF
10819 break;
10820 case SDM:
895c2d04 10821 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10822 opn = "sdm";
3c824109 10823 break;
6af0bf9c 10824#endif
3c824109 10825 }
e1050a76 10826 (void)opn;
3c824109
NF
10827 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10828 tcg_temp_free(t0);
33087598 10829 tcg_temp_free(t1);
3c824109
NF
10830 tcg_temp_free_i32(t2);
10831}
6af0bf9c 10832
3c824109 10833
d75c135e 10834static void gen_pool16c_insn(DisasContext *ctx, int *is_branch)
6af0bf9c 10835{
3c824109
NF
10836 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10837 int rs = mmreg(ctx->opcode & 0x7);
10838 int opc;
6af0bf9c 10839
3c824109
NF
10840 switch (((ctx->opcode) >> 4) & 0x3f) {
10841 case NOT16 + 0:
10842 case NOT16 + 1:
10843 case NOT16 + 2:
10844 case NOT16 + 3:
d75c135e 10845 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10846 break;
10847 case XOR16 + 0:
10848 case XOR16 + 1:
10849 case XOR16 + 2:
10850 case XOR16 + 3:
d75c135e 10851 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10852 break;
10853 case AND16 + 0:
10854 case AND16 + 1:
10855 case AND16 + 2:
10856 case AND16 + 3:
d75c135e 10857 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10858 break;
10859 case OR16 + 0:
10860 case OR16 + 1:
10861 case OR16 + 2:
10862 case OR16 + 3:
d75c135e 10863 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10864 break;
10865 case LWM16 + 0:
10866 case LWM16 + 1:
10867 case LWM16 + 2:
10868 case LWM16 + 3:
10869 {
10870 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10871 int offset = ZIMM(ctx->opcode, 0, 4);
10872
10873 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10874 29, offset << 2);
10875 }
10876 break;
10877 case SWM16 + 0:
10878 case SWM16 + 1:
10879 case SWM16 + 2:
10880 case SWM16 + 3:
10881 {
10882 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10883 int offset = ZIMM(ctx->opcode, 0, 4);
10884
10885 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10886 29, offset << 2);
10887 }
10888 break;
10889 case JR16 + 0:
10890 case JR16 + 1:
10891 {
10892 int reg = ctx->opcode & 0x1f;
10893
10894 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10895 }
10896 *is_branch = 1;
10897 break;
10898 case JRC16 + 0:
10899 case JRC16 + 1:
10900 {
10901 int reg = ctx->opcode & 0x1f;
10902
10903 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10904 /* Let normal delay slot handling in our caller take us
10905 to the branch target. */
10906 }
10907 break;
10908 case JALR16 + 0:
10909 case JALR16 + 1:
10910 opc = OPC_JALR;
10911 goto do_jalr;
10912 case JALR16S + 0:
10913 case JALR16S + 1:
10914 opc = OPC_JALRS;
10915 do_jalr:
10916 {
10917 int reg = ctx->opcode & 0x1f;
10918
10919 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10920 }
10921 *is_branch = 1;
10922 break;
10923 case MFHI16 + 0:
10924 case MFHI16 + 1:
10925 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10926 break;
10927 case MFLO16 + 0:
10928 case MFLO16 + 1:
10929 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10930 break;
10931 case BREAK16:
10932 generate_exception(ctx, EXCP_BREAK);
10933 break;
10934 case SDBBP16:
10935 /* XXX: not clear which exception should be raised
10936 * when in debug mode...
10937 */
d75c135e 10938 check_insn(ctx, ISA_MIPS32);
3c824109
NF
10939 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10940 generate_exception(ctx, EXCP_DBp);
10941 } else {
10942 generate_exception(ctx, EXCP_DBp);
10943 }
10944 break;
10945 case JRADDIUSP + 0:
10946 case JRADDIUSP + 1:
10947 {
10948 int imm = ZIMM(ctx->opcode, 0, 5);
10949
10950 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 10951 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
10952 /* Let normal delay slot handling in our caller take us
10953 to the branch target. */
10954 }
10955 break;
10956 default:
10957 generate_exception(ctx, EXCP_RI);
10958 break;
10959 }
10960}
10961
10962static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10963{
10964 TCGv t0 = tcg_temp_new();
10965 TCGv t1 = tcg_temp_new();
10966
10967 gen_load_gpr(t0, base);
10968
10969 if (index != 0) {
10970 gen_load_gpr(t1, index);
10971 tcg_gen_shli_tl(t1, t1, 2);
10972 gen_op_addr_add(ctx, t0, t1, t0);
10973 }
10974
2910c6cb 10975 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
10976 gen_store_gpr(t1, rd);
10977
10978 tcg_temp_free(t0);
10979 tcg_temp_free(t1);
10980}
10981
10982static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10983 int base, int16_t offset)
10984{
10985 const char *opn = "ldst_pair";
10986 TCGv t0, t1;
10987
36c6711b 10988 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10989 generate_exception(ctx, EXCP_RI);
d796321b
FB
10990 return;
10991 }
10992
3c824109
NF
10993 t0 = tcg_temp_new();
10994 t1 = tcg_temp_new();
8e9ade68 10995
3c824109
NF
10996 gen_base_offset_addr(ctx, t0, base, offset);
10997
10998 switch (opc) {
10999 case LWP:
36c6711b
EJ
11000 if (rd == base) {
11001 generate_exception(ctx, EXCP_RI);
11002 return;
11003 }
2910c6cb 11004 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11005 gen_store_gpr(t1, rd);
11006 tcg_gen_movi_tl(t1, 4);
11007 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11008 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11009 gen_store_gpr(t1, rd+1);
11010 opn = "lwp";
11011 break;
11012 case SWP:
3c824109 11013 gen_load_gpr(t1, rd);
2910c6cb 11014 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11015 tcg_gen_movi_tl(t1, 4);
11016 gen_op_addr_add(ctx, t0, t0, t1);
11017 gen_load_gpr(t1, rd+1);
2910c6cb 11018 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11019 opn = "swp";
11020 break;
11021#ifdef TARGET_MIPS64
11022 case LDP:
36c6711b
EJ
11023 if (rd == base) {
11024 generate_exception(ctx, EXCP_RI);
11025 return;
11026 }
2910c6cb 11027 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11028 gen_store_gpr(t1, rd);
11029 tcg_gen_movi_tl(t1, 8);
11030 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11031 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11032 gen_store_gpr(t1, rd+1);
11033 opn = "ldp";
11034 break;
11035 case SDP:
3c824109 11036 gen_load_gpr(t1, rd);
2910c6cb 11037 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11038 tcg_gen_movi_tl(t1, 8);
11039 gen_op_addr_add(ctx, t0, t0, t1);
11040 gen_load_gpr(t1, rd+1);
2910c6cb 11041 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11042 opn = "sdp";
11043 break;
11044#endif
6af0bf9c 11045 }
2abf314d 11046 (void)opn; /* avoid a compiler warning */
3c824109
NF
11047 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11048 tcg_temp_free(t0);
11049 tcg_temp_free(t1);
11050}
618b0fe9 11051
7db13fae 11052static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
3c824109
NF
11053 int *is_branch)
11054{
11055 int extension = (ctx->opcode >> 6) & 0x3f;
11056 int minor = (ctx->opcode >> 12) & 0xf;
11057 uint32_t mips32_op;
11058
11059 switch (extension) {
11060 case TEQ:
11061 mips32_op = OPC_TEQ;
11062 goto do_trap;
11063 case TGE:
11064 mips32_op = OPC_TGE;
11065 goto do_trap;
11066 case TGEU:
11067 mips32_op = OPC_TGEU;
11068 goto do_trap;
11069 case TLT:
11070 mips32_op = OPC_TLT;
11071 goto do_trap;
11072 case TLTU:
11073 mips32_op = OPC_TLTU;
11074 goto do_trap;
11075 case TNE:
11076 mips32_op = OPC_TNE;
11077 do_trap:
11078 gen_trap(ctx, mips32_op, rs, rt, -1);
11079 break;
11080#ifndef CONFIG_USER_ONLY
11081 case MFC0:
11082 case MFC0 + 32:
2e15497c 11083 check_cp0_enabled(ctx);
3c824109
NF
11084 if (rt == 0) {
11085 /* Treat as NOP. */
11086 break;
11087 }
d75c135e 11088 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11089 break;
11090 case MTC0:
11091 case MTC0 + 32:
2e15497c 11092 check_cp0_enabled(ctx);
3c824109
NF
11093 {
11094 TCGv t0 = tcg_temp_new();
618b0fe9 11095
3c824109 11096 gen_load_gpr(t0, rt);
d75c135e 11097 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11098 tcg_temp_free(t0);
11099 }
11100 break;
11101#endif
11102 case 0x2c:
11103 switch (minor) {
11104 case SEB:
11105 gen_bshfl(ctx, OPC_SEB, rs, rt);
11106 break;
11107 case SEH:
11108 gen_bshfl(ctx, OPC_SEH, rs, rt);
11109 break;
11110 case CLO:
11111 mips32_op = OPC_CLO;
11112 goto do_cl;
11113 case CLZ:
11114 mips32_op = OPC_CLZ;
11115 do_cl:
d75c135e 11116 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11117 gen_cl(ctx, mips32_op, rt, rs);
11118 break;
11119 case RDHWR:
d75c135e 11120 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11121 break;
11122 case WSBH:
11123 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11124 break;
11125 case MULT:
11126 mips32_op = OPC_MULT;
11127 goto do_muldiv;
11128 case MULTU:
11129 mips32_op = OPC_MULTU;
11130 goto do_muldiv;
11131 case DIV:
11132 mips32_op = OPC_DIV;
11133 goto do_muldiv;
11134 case DIVU:
11135 mips32_op = OPC_DIVU;
11136 goto do_muldiv;
11137 case MADD:
11138 mips32_op = OPC_MADD;
11139 goto do_muldiv;
11140 case MADDU:
11141 mips32_op = OPC_MADDU;
11142 goto do_muldiv;
11143 case MSUB:
11144 mips32_op = OPC_MSUB;
11145 goto do_muldiv;
11146 case MSUBU:
11147 mips32_op = OPC_MSUBU;
11148 do_muldiv:
d75c135e 11149 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11150 gen_muldiv(ctx, mips32_op, rs, rt);
11151 break;
11152 default:
11153 goto pool32axf_invalid;
11154 }
11155 break;
11156 case 0x34:
11157 switch (minor) {
11158 case MFC2:
11159 case MTC2:
11160 case MFHC2:
11161 case MTHC2:
11162 case CFC2:
11163 case CTC2:
11164 generate_exception_err(ctx, EXCP_CpU, 2);
11165 break;
11166 default:
11167 goto pool32axf_invalid;
11168 }
11169 break;
11170 case 0x3c:
11171 switch (minor) {
11172 case JALR:
11173 case JALR_HB:
11174 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11175 *is_branch = 1;
11176 break;
11177 case JALRS:
11178 case JALRS_HB:
11179 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11180 *is_branch = 1;
11181 break;
11182 default:
11183 goto pool32axf_invalid;
11184 }
11185 break;
11186 case 0x05:
11187 switch (minor) {
11188 case RDPGPR:
2e15497c 11189 check_cp0_enabled(ctx);
d75c135e 11190 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11191 gen_load_srsgpr(rt, rs);
11192 break;
11193 case WRPGPR:
2e15497c 11194 check_cp0_enabled(ctx);
d75c135e 11195 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11196 gen_store_srsgpr(rt, rs);
11197 break;
11198 default:
11199 goto pool32axf_invalid;
11200 }
11201 break;
11202#ifndef CONFIG_USER_ONLY
11203 case 0x0d:
11204 switch (minor) {
11205 case TLBP:
11206 mips32_op = OPC_TLBP;
11207 goto do_cp0;
11208 case TLBR:
11209 mips32_op = OPC_TLBR;
11210 goto do_cp0;
11211 case TLBWI:
11212 mips32_op = OPC_TLBWI;
11213 goto do_cp0;
11214 case TLBWR:
11215 mips32_op = OPC_TLBWR;
11216 goto do_cp0;
11217 case WAIT:
11218 mips32_op = OPC_WAIT;
11219 goto do_cp0;
11220 case DERET:
11221 mips32_op = OPC_DERET;
11222 goto do_cp0;
11223 case ERET:
11224 mips32_op = OPC_ERET;
11225 do_cp0:
11226 gen_cp0(env, ctx, mips32_op, rt, rs);
11227 break;
11228 default:
11229 goto pool32axf_invalid;
11230 }
11231 break;
11232 case 0x1d:
11233 switch (minor) {
11234 case DI:
2e15497c 11235 check_cp0_enabled(ctx);
3c824109
NF
11236 {
11237 TCGv t0 = tcg_temp_new();
11238
11239 save_cpu_state(ctx, 1);
895c2d04 11240 gen_helper_di(t0, cpu_env);
3c824109
NF
11241 gen_store_gpr(t0, rs);
11242 /* Stop translation as we may have switched the execution mode */
11243 ctx->bstate = BS_STOP;
11244 tcg_temp_free(t0);
11245 }
11246 break;
11247 case EI:
2e15497c 11248 check_cp0_enabled(ctx);
3c824109
NF
11249 {
11250 TCGv t0 = tcg_temp_new();
11251
11252 save_cpu_state(ctx, 1);
895c2d04 11253 gen_helper_ei(t0, cpu_env);
3c824109
NF
11254 gen_store_gpr(t0, rs);
11255 /* Stop translation as we may have switched the execution mode */
11256 ctx->bstate = BS_STOP;
11257 tcg_temp_free(t0);
11258 }
11259 break;
11260 default:
11261 goto pool32axf_invalid;
11262 }
11263 break;
11264#endif
11265 case 0x2d:
11266 switch (minor) {
11267 case SYNC:
11268 /* NOP */
11269 break;
11270 case SYSCALL:
11271 generate_exception(ctx, EXCP_SYSCALL);
11272 ctx->bstate = BS_STOP;
11273 break;
11274 case SDBBP:
d75c135e 11275 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11276 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11277 generate_exception(ctx, EXCP_DBp);
11278 } else {
11279 generate_exception(ctx, EXCP_DBp);
11280 }
11281 break;
11282 default:
11283 goto pool32axf_invalid;
11284 }
11285 break;
11286 case 0x35:
11287 switch (minor) {
11288 case MFHI32:
11289 gen_HILO(ctx, OPC_MFHI, rs);
11290 break;
11291 case MFLO32:
11292 gen_HILO(ctx, OPC_MFLO, rs);
11293 break;
11294 case MTHI32:
11295 gen_HILO(ctx, OPC_MTHI, rs);
11296 break;
11297 case MTLO32:
11298 gen_HILO(ctx, OPC_MTLO, rs);
11299 break;
11300 default:
11301 goto pool32axf_invalid;
11302 }
11303 break;
11304 default:
11305 pool32axf_invalid:
11306 MIPS_INVAL("pool32axf");
11307 generate_exception(ctx, EXCP_RI);
11308 break;
11309 }
11310}
11311
11312/* Values for microMIPS fmt field. Variable-width, depending on which
11313 formats the instruction supports. */
11314
11315enum {
11316 FMT_SD_S = 0,
11317 FMT_SD_D = 1,
11318
11319 FMT_SDPS_S = 0,
11320 FMT_SDPS_D = 1,
11321 FMT_SDPS_PS = 2,
11322
11323 FMT_SWL_S = 0,
11324 FMT_SWL_W = 1,
11325 FMT_SWL_L = 2,
11326
11327 FMT_DWL_D = 0,
11328 FMT_DWL_W = 1,
11329 FMT_DWL_L = 2
11330};
11331
d75c135e 11332static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11333{
11334 int extension = (ctx->opcode >> 6) & 0x3ff;
11335 uint32_t mips32_op;
11336
11337#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11338#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11339#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11340
11341 switch (extension) {
11342 case FLOAT_1BIT_FMT(CFC1, 0):
11343 mips32_op = OPC_CFC1;
11344 goto do_cp1;
11345 case FLOAT_1BIT_FMT(CTC1, 0):
11346 mips32_op = OPC_CTC1;
11347 goto do_cp1;
11348 case FLOAT_1BIT_FMT(MFC1, 0):
11349 mips32_op = OPC_MFC1;
11350 goto do_cp1;
11351 case FLOAT_1BIT_FMT(MTC1, 0):
11352 mips32_op = OPC_MTC1;
11353 goto do_cp1;
11354 case FLOAT_1BIT_FMT(MFHC1, 0):
11355 mips32_op = OPC_MFHC1;
11356 goto do_cp1;
11357 case FLOAT_1BIT_FMT(MTHC1, 0):
11358 mips32_op = OPC_MTHC1;
11359 do_cp1:
11360 gen_cp1(ctx, mips32_op, rt, rs);
11361 break;
11362
11363 /* Reciprocal square root */
11364 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11365 mips32_op = OPC_RSQRT_S;
11366 goto do_unaryfp;
11367 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11368 mips32_op = OPC_RSQRT_D;
11369 goto do_unaryfp;
11370
11371 /* Square root */
11372 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11373 mips32_op = OPC_SQRT_S;
11374 goto do_unaryfp;
11375 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11376 mips32_op = OPC_SQRT_D;
11377 goto do_unaryfp;
11378
11379 /* Reciprocal */
11380 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11381 mips32_op = OPC_RECIP_S;
11382 goto do_unaryfp;
11383 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11384 mips32_op = OPC_RECIP_D;
11385 goto do_unaryfp;
11386
11387 /* Floor */
11388 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11389 mips32_op = OPC_FLOOR_L_S;
11390 goto do_unaryfp;
11391 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11392 mips32_op = OPC_FLOOR_L_D;
11393 goto do_unaryfp;
11394 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11395 mips32_op = OPC_FLOOR_W_S;
11396 goto do_unaryfp;
11397 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11398 mips32_op = OPC_FLOOR_W_D;
11399 goto do_unaryfp;
11400
11401 /* Ceiling */
11402 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11403 mips32_op = OPC_CEIL_L_S;
11404 goto do_unaryfp;
11405 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11406 mips32_op = OPC_CEIL_L_D;
11407 goto do_unaryfp;
11408 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11409 mips32_op = OPC_CEIL_W_S;
11410 goto do_unaryfp;
11411 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11412 mips32_op = OPC_CEIL_W_D;
11413 goto do_unaryfp;
11414
11415 /* Truncation */
11416 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11417 mips32_op = OPC_TRUNC_L_S;
11418 goto do_unaryfp;
11419 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11420 mips32_op = OPC_TRUNC_L_D;
11421 goto do_unaryfp;
11422 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11423 mips32_op = OPC_TRUNC_W_S;
11424 goto do_unaryfp;
11425 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11426 mips32_op = OPC_TRUNC_W_D;
11427 goto do_unaryfp;
11428
11429 /* Round */
11430 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11431 mips32_op = OPC_ROUND_L_S;
11432 goto do_unaryfp;
11433 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11434 mips32_op = OPC_ROUND_L_D;
11435 goto do_unaryfp;
11436 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11437 mips32_op = OPC_ROUND_W_S;
11438 goto do_unaryfp;
11439 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11440 mips32_op = OPC_ROUND_W_D;
11441 goto do_unaryfp;
11442
11443 /* Integer to floating-point conversion */
11444 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11445 mips32_op = OPC_CVT_L_S;
11446 goto do_unaryfp;
11447 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11448 mips32_op = OPC_CVT_L_D;
11449 goto do_unaryfp;
11450 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11451 mips32_op = OPC_CVT_W_S;
11452 goto do_unaryfp;
11453 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11454 mips32_op = OPC_CVT_W_D;
11455 goto do_unaryfp;
11456
11457 /* Paired-foo conversions */
11458 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11459 mips32_op = OPC_CVT_S_PL;
11460 goto do_unaryfp;
11461 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11462 mips32_op = OPC_CVT_S_PU;
11463 goto do_unaryfp;
11464 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11465 mips32_op = OPC_CVT_PW_PS;
11466 goto do_unaryfp;
11467 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11468 mips32_op = OPC_CVT_PS_PW;
11469 goto do_unaryfp;
11470
11471 /* Floating-point moves */
11472 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11473 mips32_op = OPC_MOV_S;
11474 goto do_unaryfp;
11475 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11476 mips32_op = OPC_MOV_D;
11477 goto do_unaryfp;
11478 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11479 mips32_op = OPC_MOV_PS;
11480 goto do_unaryfp;
11481
11482 /* Absolute value */
11483 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11484 mips32_op = OPC_ABS_S;
11485 goto do_unaryfp;
11486 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11487 mips32_op = OPC_ABS_D;
11488 goto do_unaryfp;
11489 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11490 mips32_op = OPC_ABS_PS;
11491 goto do_unaryfp;
11492
11493 /* Negation */
11494 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11495 mips32_op = OPC_NEG_S;
11496 goto do_unaryfp;
11497 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11498 mips32_op = OPC_NEG_D;
11499 goto do_unaryfp;
11500 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11501 mips32_op = OPC_NEG_PS;
11502 goto do_unaryfp;
11503
11504 /* Reciprocal square root step */
11505 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11506 mips32_op = OPC_RSQRT1_S;
11507 goto do_unaryfp;
11508 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11509 mips32_op = OPC_RSQRT1_D;
11510 goto do_unaryfp;
11511 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11512 mips32_op = OPC_RSQRT1_PS;
11513 goto do_unaryfp;
11514
11515 /* Reciprocal step */
11516 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11517 mips32_op = OPC_RECIP1_S;
11518 goto do_unaryfp;
11519 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11520 mips32_op = OPC_RECIP1_S;
11521 goto do_unaryfp;
11522 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11523 mips32_op = OPC_RECIP1_PS;
11524 goto do_unaryfp;
11525
11526 /* Conversions from double */
11527 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11528 mips32_op = OPC_CVT_D_S;
11529 goto do_unaryfp;
11530 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11531 mips32_op = OPC_CVT_D_W;
11532 goto do_unaryfp;
11533 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11534 mips32_op = OPC_CVT_D_L;
11535 goto do_unaryfp;
11536
11537 /* Conversions from single */
11538 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11539 mips32_op = OPC_CVT_S_D;
11540 goto do_unaryfp;
11541 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11542 mips32_op = OPC_CVT_S_W;
11543 goto do_unaryfp;
11544 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11545 mips32_op = OPC_CVT_S_L;
11546 do_unaryfp:
11547 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11548 break;
11549
11550 /* Conditional moves on floating-point codes */
11551 case COND_FLOAT_MOV(MOVT, 0):
11552 case COND_FLOAT_MOV(MOVT, 1):
11553 case COND_FLOAT_MOV(MOVT, 2):
11554 case COND_FLOAT_MOV(MOVT, 3):
11555 case COND_FLOAT_MOV(MOVT, 4):
11556 case COND_FLOAT_MOV(MOVT, 5):
11557 case COND_FLOAT_MOV(MOVT, 6):
11558 case COND_FLOAT_MOV(MOVT, 7):
11559 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11560 break;
11561 case COND_FLOAT_MOV(MOVF, 0):
11562 case COND_FLOAT_MOV(MOVF, 1):
11563 case COND_FLOAT_MOV(MOVF, 2):
11564 case COND_FLOAT_MOV(MOVF, 3):
11565 case COND_FLOAT_MOV(MOVF, 4):
11566 case COND_FLOAT_MOV(MOVF, 5):
11567 case COND_FLOAT_MOV(MOVF, 6):
11568 case COND_FLOAT_MOV(MOVF, 7):
11569 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11570 break;
11571 default:
11572 MIPS_INVAL("pool32fxf");
11573 generate_exception(ctx, EXCP_RI);
11574 break;
11575 }
11576}
11577
7db13fae 11578static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
3c824109
NF
11579 uint16_t insn_hw1, int *is_branch)
11580{
11581 int32_t offset;
11582 uint16_t insn;
11583 int rt, rs, rd, rr;
11584 int16_t imm;
11585 uint32_t op, minor, mips32_op;
11586 uint32_t cond, fmt, cc;
11587
895c2d04 11588 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11589 ctx->opcode = (ctx->opcode << 16) | insn;
11590
11591 rt = (ctx->opcode >> 21) & 0x1f;
11592 rs = (ctx->opcode >> 16) & 0x1f;
11593 rd = (ctx->opcode >> 11) & 0x1f;
11594 rr = (ctx->opcode >> 6) & 0x1f;
11595 imm = (int16_t) ctx->opcode;
11596
11597 op = (ctx->opcode >> 26) & 0x3f;
11598 switch (op) {
11599 case POOL32A:
11600 minor = ctx->opcode & 0x3f;
11601 switch (minor) {
11602 case 0x00:
11603 minor = (ctx->opcode >> 6) & 0xf;
11604 switch (minor) {
11605 case SLL32:
11606 mips32_op = OPC_SLL;
11607 goto do_shifti;
11608 case SRA:
11609 mips32_op = OPC_SRA;
11610 goto do_shifti;
11611 case SRL32:
11612 mips32_op = OPC_SRL;
11613 goto do_shifti;
11614 case ROTR:
11615 mips32_op = OPC_ROTR;
11616 do_shifti:
d75c135e 11617 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
11618 break;
11619 default:
11620 goto pool32a_invalid;
11621 }
11622 break;
11623 case 0x10:
11624 minor = (ctx->opcode >> 6) & 0xf;
11625 switch (minor) {
11626 /* Arithmetic */
11627 case ADD:
11628 mips32_op = OPC_ADD;
11629 goto do_arith;
11630 case ADDU32:
11631 mips32_op = OPC_ADDU;
11632 goto do_arith;
11633 case SUB:
11634 mips32_op = OPC_SUB;
11635 goto do_arith;
11636 case SUBU32:
11637 mips32_op = OPC_SUBU;
11638 goto do_arith;
11639 case MUL:
11640 mips32_op = OPC_MUL;
11641 do_arith:
d75c135e 11642 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11643 break;
11644 /* Shifts */
11645 case SLLV:
11646 mips32_op = OPC_SLLV;
11647 goto do_shift;
11648 case SRLV:
11649 mips32_op = OPC_SRLV;
11650 goto do_shift;
11651 case SRAV:
11652 mips32_op = OPC_SRAV;
11653 goto do_shift;
11654 case ROTRV:
11655 mips32_op = OPC_ROTRV;
11656 do_shift:
d75c135e 11657 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11658 break;
11659 /* Logical operations */
11660 case AND:
11661 mips32_op = OPC_AND;
11662 goto do_logic;
11663 case OR32:
11664 mips32_op = OPC_OR;
11665 goto do_logic;
11666 case NOR:
11667 mips32_op = OPC_NOR;
11668 goto do_logic;
11669 case XOR32:
11670 mips32_op = OPC_XOR;
11671 do_logic:
d75c135e 11672 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11673 break;
11674 /* Set less than */
11675 case SLT:
11676 mips32_op = OPC_SLT;
11677 goto do_slt;
11678 case SLTU:
11679 mips32_op = OPC_SLTU;
11680 do_slt:
d75c135e 11681 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11682 break;
11683 default:
11684 goto pool32a_invalid;
11685 }
11686 break;
11687 case 0x18:
11688 minor = (ctx->opcode >> 6) & 0xf;
11689 switch (minor) {
11690 /* Conditional moves */
11691 case MOVN:
11692 mips32_op = OPC_MOVN;
11693 goto do_cmov;
11694 case MOVZ:
11695 mips32_op = OPC_MOVZ;
11696 do_cmov:
d75c135e 11697 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11698 break;
11699 case LWXS:
11700 gen_ldxs(ctx, rs, rt, rd);
11701 break;
11702 default:
11703 goto pool32a_invalid;
11704 }
11705 break;
11706 case INS:
11707 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11708 return;
11709 case EXT:
11710 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11711 return;
11712 case POOL32AXF:
11713 gen_pool32axf(env, ctx, rt, rs, is_branch);
11714 break;
11715 case 0x07:
11716 generate_exception(ctx, EXCP_BREAK);
11717 break;
11718 default:
11719 pool32a_invalid:
11720 MIPS_INVAL("pool32a");
11721 generate_exception(ctx, EXCP_RI);
11722 break;
11723 }
11724 break;
11725 case POOL32B:
11726 minor = (ctx->opcode >> 12) & 0xf;
11727 switch (minor) {
11728 case CACHE:
2e15497c 11729 check_cp0_enabled(ctx);
3c824109
NF
11730 /* Treat as no-op. */
11731 break;
11732 case LWC2:
11733 case SWC2:
11734 /* COP2: Not implemented. */
11735 generate_exception_err(ctx, EXCP_CpU, 2);
11736 break;
11737 case LWP:
11738 case SWP:
11739#ifdef TARGET_MIPS64
11740 case LDP:
11741 case SDP:
11742#endif
11743 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11744 break;
11745 case LWM32:
11746 case SWM32:
11747#ifdef TARGET_MIPS64
11748 case LDM:
11749 case SDM:
11750#endif
11751 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11752 break;
11753 default:
11754 MIPS_INVAL("pool32b");
11755 generate_exception(ctx, EXCP_RI);
11756 break;
11757 }
11758 break;
11759 case POOL32F:
11760 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11761 minor = ctx->opcode & 0x3f;
11762 check_cp1_enabled(ctx);
11763 switch (minor) {
11764 case ALNV_PS:
11765 mips32_op = OPC_ALNV_PS;
11766 goto do_madd;
11767 case MADD_S:
11768 mips32_op = OPC_MADD_S;
11769 goto do_madd;
11770 case MADD_D:
11771 mips32_op = OPC_MADD_D;
11772 goto do_madd;
11773 case MADD_PS:
11774 mips32_op = OPC_MADD_PS;
11775 goto do_madd;
11776 case MSUB_S:
11777 mips32_op = OPC_MSUB_S;
11778 goto do_madd;
11779 case MSUB_D:
11780 mips32_op = OPC_MSUB_D;
11781 goto do_madd;
11782 case MSUB_PS:
11783 mips32_op = OPC_MSUB_PS;
11784 goto do_madd;
11785 case NMADD_S:
11786 mips32_op = OPC_NMADD_S;
11787 goto do_madd;
11788 case NMADD_D:
11789 mips32_op = OPC_NMADD_D;
11790 goto do_madd;
11791 case NMADD_PS:
11792 mips32_op = OPC_NMADD_PS;
11793 goto do_madd;
11794 case NMSUB_S:
11795 mips32_op = OPC_NMSUB_S;
11796 goto do_madd;
11797 case NMSUB_D:
11798 mips32_op = OPC_NMSUB_D;
11799 goto do_madd;
11800 case NMSUB_PS:
11801 mips32_op = OPC_NMSUB_PS;
11802 do_madd:
11803 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11804 break;
11805 case CABS_COND_FMT:
11806 cond = (ctx->opcode >> 6) & 0xf;
11807 cc = (ctx->opcode >> 13) & 0x7;
11808 fmt = (ctx->opcode >> 10) & 0x3;
11809 switch (fmt) {
11810 case 0x0:
11811 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11812 break;
11813 case 0x1:
11814 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11815 break;
11816 case 0x2:
11817 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11818 break;
11819 default:
11820 goto pool32f_invalid;
11821 }
11822 break;
11823 case C_COND_FMT:
11824 cond = (ctx->opcode >> 6) & 0xf;
11825 cc = (ctx->opcode >> 13) & 0x7;
11826 fmt = (ctx->opcode >> 10) & 0x3;
11827 switch (fmt) {
11828 case 0x0:
11829 gen_cmp_s(ctx, cond, rt, rs, cc);
11830 break;
11831 case 0x1:
11832 gen_cmp_d(ctx, cond, rt, rs, cc);
11833 break;
11834 case 0x2:
11835 gen_cmp_ps(ctx, cond, rt, rs, cc);
11836 break;
11837 default:
11838 goto pool32f_invalid;
11839 }
11840 break;
11841 case POOL32FXF:
d75c135e 11842 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
11843 break;
11844 case 0x00:
11845 /* PLL foo */
11846 switch ((ctx->opcode >> 6) & 0x7) {
11847 case PLL_PS:
11848 mips32_op = OPC_PLL_PS;
11849 goto do_ps;
11850 case PLU_PS:
11851 mips32_op = OPC_PLU_PS;
11852 goto do_ps;
11853 case PUL_PS:
11854 mips32_op = OPC_PUL_PS;
11855 goto do_ps;
11856 case PUU_PS:
11857 mips32_op = OPC_PUU_PS;
11858 goto do_ps;
11859 case CVT_PS_S:
11860 mips32_op = OPC_CVT_PS_S;
11861 do_ps:
11862 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11863 break;
11864 default:
11865 goto pool32f_invalid;
11866 }
11867 break;
11868 case 0x08:
11869 /* [LS][WDU]XC1 */
11870 switch ((ctx->opcode >> 6) & 0x7) {
11871 case LWXC1:
11872 mips32_op = OPC_LWXC1;
11873 goto do_ldst_cp1;
11874 case SWXC1:
11875 mips32_op = OPC_SWXC1;
11876 goto do_ldst_cp1;
11877 case LDXC1:
11878 mips32_op = OPC_LDXC1;
11879 goto do_ldst_cp1;
11880 case SDXC1:
11881 mips32_op = OPC_SDXC1;
11882 goto do_ldst_cp1;
11883 case LUXC1:
11884 mips32_op = OPC_LUXC1;
11885 goto do_ldst_cp1;
11886 case SUXC1:
11887 mips32_op = OPC_SUXC1;
11888 do_ldst_cp1:
11889 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11890 break;
11891 default:
11892 goto pool32f_invalid;
11893 }
11894 break;
11895 case 0x18:
11896 /* 3D insns */
11897 fmt = (ctx->opcode >> 9) & 0x3;
11898 switch ((ctx->opcode >> 6) & 0x7) {
11899 case RSQRT2_FMT:
11900 switch (fmt) {
11901 case FMT_SDPS_S:
11902 mips32_op = OPC_RSQRT2_S;
11903 goto do_3d;
11904 case FMT_SDPS_D:
11905 mips32_op = OPC_RSQRT2_D;
11906 goto do_3d;
11907 case FMT_SDPS_PS:
11908 mips32_op = OPC_RSQRT2_PS;
11909 goto do_3d;
11910 default:
11911 goto pool32f_invalid;
11912 }
11913 break;
11914 case RECIP2_FMT:
11915 switch (fmt) {
11916 case FMT_SDPS_S:
11917 mips32_op = OPC_RECIP2_S;
11918 goto do_3d;
11919 case FMT_SDPS_D:
11920 mips32_op = OPC_RECIP2_D;
11921 goto do_3d;
11922 case FMT_SDPS_PS:
11923 mips32_op = OPC_RECIP2_PS;
11924 goto do_3d;
11925 default:
11926 goto pool32f_invalid;
11927 }
11928 break;
11929 case ADDR_PS:
11930 mips32_op = OPC_ADDR_PS;
11931 goto do_3d;
11932 case MULR_PS:
11933 mips32_op = OPC_MULR_PS;
11934 do_3d:
11935 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11936 break;
11937 default:
11938 goto pool32f_invalid;
11939 }
11940 break;
11941 case 0x20:
11942 /* MOV[FT].fmt and PREFX */
11943 cc = (ctx->opcode >> 13) & 0x7;
11944 fmt = (ctx->opcode >> 9) & 0x3;
11945 switch ((ctx->opcode >> 6) & 0x7) {
11946 case MOVF_FMT:
11947 switch (fmt) {
11948 case FMT_SDPS_S:
11949 gen_movcf_s(rs, rt, cc, 0);
11950 break;
11951 case FMT_SDPS_D:
11952 gen_movcf_d(ctx, rs, rt, cc, 0);
11953 break;
11954 case FMT_SDPS_PS:
11955 gen_movcf_ps(rs, rt, cc, 0);
11956 break;
11957 default:
11958 goto pool32f_invalid;
11959 }
11960 break;
11961 case MOVT_FMT:
11962 switch (fmt) {
11963 case FMT_SDPS_S:
11964 gen_movcf_s(rs, rt, cc, 1);
11965 break;
11966 case FMT_SDPS_D:
11967 gen_movcf_d(ctx, rs, rt, cc, 1);
11968 break;
11969 case FMT_SDPS_PS:
11970 gen_movcf_ps(rs, rt, cc, 1);
11971 break;
11972 default:
11973 goto pool32f_invalid;
11974 }
11975 break;
11976 case PREFX:
11977 break;
11978 default:
11979 goto pool32f_invalid;
11980 }
11981 break;
11982#define FINSN_3ARG_SDPS(prfx) \
11983 switch ((ctx->opcode >> 8) & 0x3) { \
11984 case FMT_SDPS_S: \
11985 mips32_op = OPC_##prfx##_S; \
11986 goto do_fpop; \
11987 case FMT_SDPS_D: \
11988 mips32_op = OPC_##prfx##_D; \
11989 goto do_fpop; \
11990 case FMT_SDPS_PS: \
11991 mips32_op = OPC_##prfx##_PS; \
11992 goto do_fpop; \
11993 default: \
11994 goto pool32f_invalid; \
11995 }
11996 case 0x30:
11997 /* regular FP ops */
11998 switch ((ctx->opcode >> 6) & 0x3) {
11999 case ADD_FMT:
12000 FINSN_3ARG_SDPS(ADD);
12001 break;
12002 case SUB_FMT:
12003 FINSN_3ARG_SDPS(SUB);
12004 break;
12005 case MUL_FMT:
12006 FINSN_3ARG_SDPS(MUL);
12007 break;
12008 case DIV_FMT:
12009 fmt = (ctx->opcode >> 8) & 0x3;
12010 if (fmt == 1) {
12011 mips32_op = OPC_DIV_D;
12012 } else if (fmt == 0) {
12013 mips32_op = OPC_DIV_S;
12014 } else {
12015 goto pool32f_invalid;
12016 }
12017 goto do_fpop;
12018 default:
12019 goto pool32f_invalid;
12020 }
12021 break;
12022 case 0x38:
12023 /* cmovs */
12024 switch ((ctx->opcode >> 6) & 0x3) {
12025 case MOVN_FMT:
12026 FINSN_3ARG_SDPS(MOVN);
12027 break;
12028 case MOVZ_FMT:
12029 FINSN_3ARG_SDPS(MOVZ);
12030 break;
12031 default:
12032 goto pool32f_invalid;
12033 }
12034 break;
12035 do_fpop:
12036 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12037 break;
12038 default:
12039 pool32f_invalid:
12040 MIPS_INVAL("pool32f");
12041 generate_exception(ctx, EXCP_RI);
12042 break;
12043 }
12044 } else {
12045 generate_exception_err(ctx, EXCP_CpU, 1);
12046 }
12047 break;
12048 case POOL32I:
12049 minor = (ctx->opcode >> 21) & 0x1f;
12050 switch (minor) {
12051 case BLTZ:
12052 mips32_op = OPC_BLTZ;
12053 goto do_branch;
12054 case BLTZAL:
12055 mips32_op = OPC_BLTZAL;
12056 goto do_branch;
12057 case BLTZALS:
12058 mips32_op = OPC_BLTZALS;
12059 goto do_branch;
12060 case BGEZ:
12061 mips32_op = OPC_BGEZ;
12062 goto do_branch;
12063 case BGEZAL:
12064 mips32_op = OPC_BGEZAL;
12065 goto do_branch;
12066 case BGEZALS:
12067 mips32_op = OPC_BGEZALS;
12068 goto do_branch;
12069 case BLEZ:
12070 mips32_op = OPC_BLEZ;
12071 goto do_branch;
12072 case BGTZ:
12073 mips32_op = OPC_BGTZ;
12074 do_branch:
12075 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12076 *is_branch = 1;
12077 break;
12078
12079 /* Traps */
12080 case TLTI:
12081 mips32_op = OPC_TLTI;
12082 goto do_trapi;
12083 case TGEI:
12084 mips32_op = OPC_TGEI;
12085 goto do_trapi;
12086 case TLTIU:
12087 mips32_op = OPC_TLTIU;
12088 goto do_trapi;
12089 case TGEIU:
12090 mips32_op = OPC_TGEIU;
12091 goto do_trapi;
12092 case TNEI:
12093 mips32_op = OPC_TNEI;
12094 goto do_trapi;
12095 case TEQI:
12096 mips32_op = OPC_TEQI;
12097 do_trapi:
12098 gen_trap(ctx, mips32_op, rs, -1, imm);
12099 break;
12100
12101 case BNEZC:
12102 case BEQZC:
12103 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12104 4, rs, 0, imm << 1);
12105 /* Compact branches don't have a delay slot, so just let
12106 the normal delay slot handling take us to the branch
12107 target. */
12108 break;
12109 case LUI:
d75c135e 12110 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12111 break;
12112 case SYNCI:
12113 break;
12114 case BC2F:
12115 case BC2T:
12116 /* COP2: Not implemented. */
12117 generate_exception_err(ctx, EXCP_CpU, 2);
12118 break;
12119 case BC1F:
12120 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12121 goto do_cp1branch;
12122 case BC1T:
12123 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12124 goto do_cp1branch;
12125 case BC1ANY4F:
12126 mips32_op = OPC_BC1FANY4;
12127 goto do_cp1mips3d;
12128 case BC1ANY4T:
12129 mips32_op = OPC_BC1TANY4;
12130 do_cp1mips3d:
12131 check_cop1x(ctx);
d75c135e 12132 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12133 /* Fall through */
12134 do_cp1branch:
d75c135e 12135 gen_compute_branch1(ctx, mips32_op,
3c824109
NF
12136 (ctx->opcode >> 18) & 0x7, imm << 1);
12137 *is_branch = 1;
12138 break;
12139 case BPOSGE64:
12140 case BPOSGE32:
12141 /* MIPS DSP: not implemented */
12142 /* Fall through */
12143 default:
12144 MIPS_INVAL("pool32i");
12145 generate_exception(ctx, EXCP_RI);
12146 break;
12147 }
12148 break;
12149 case POOL32C:
12150 minor = (ctx->opcode >> 12) & 0xf;
12151 switch (minor) {
12152 case LWL:
12153 mips32_op = OPC_LWL;
5c13fdfd 12154 goto do_ld_lr;
3c824109
NF
12155 case SWL:
12156 mips32_op = OPC_SWL;
5c13fdfd 12157 goto do_st_lr;
3c824109
NF
12158 case LWR:
12159 mips32_op = OPC_LWR;
5c13fdfd 12160 goto do_ld_lr;
3c824109
NF
12161 case SWR:
12162 mips32_op = OPC_SWR;
5c13fdfd 12163 goto do_st_lr;
3c824109
NF
12164#if defined(TARGET_MIPS64)
12165 case LDL:
12166 mips32_op = OPC_LDL;
5c13fdfd 12167 goto do_ld_lr;
3c824109
NF
12168 case SDL:
12169 mips32_op = OPC_SDL;
5c13fdfd 12170 goto do_st_lr;
3c824109
NF
12171 case LDR:
12172 mips32_op = OPC_LDR;
5c13fdfd 12173 goto do_ld_lr;
3c824109
NF
12174 case SDR:
12175 mips32_op = OPC_SDR;
5c13fdfd 12176 goto do_st_lr;
3c824109
NF
12177 case LWU:
12178 mips32_op = OPC_LWU;
5c13fdfd 12179 goto do_ld_lr;
3c824109
NF
12180 case LLD:
12181 mips32_op = OPC_LLD;
5c13fdfd 12182 goto do_ld_lr;
3c824109
NF
12183#endif
12184 case LL:
12185 mips32_op = OPC_LL;
5c13fdfd
AJ
12186 goto do_ld_lr;
12187 do_ld_lr:
d75c135e 12188 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12189 break;
12190 do_st_lr:
12191 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12192 break;
12193 case SC:
12194 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12195 break;
12196#if defined(TARGET_MIPS64)
12197 case SCD:
12198 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12199 break;
12200#endif
12201 case PREF:
12202 /* Treat as no-op */
12203 break;
12204 default:
12205 MIPS_INVAL("pool32c");
12206 generate_exception(ctx, EXCP_RI);
12207 break;
12208 }
12209 break;
12210 case ADDI32:
12211 mips32_op = OPC_ADDI;
12212 goto do_addi;
12213 case ADDIU32:
12214 mips32_op = OPC_ADDIU;
12215 do_addi:
d75c135e 12216 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12217 break;
12218
12219 /* Logical operations */
12220 case ORI32:
12221 mips32_op = OPC_ORI;
12222 goto do_logici;
12223 case XORI32:
12224 mips32_op = OPC_XORI;
12225 goto do_logici;
12226 case ANDI32:
12227 mips32_op = OPC_ANDI;
12228 do_logici:
d75c135e 12229 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12230 break;
12231
12232 /* Set less than immediate */
12233 case SLTI32:
12234 mips32_op = OPC_SLTI;
12235 goto do_slti;
12236 case SLTIU32:
12237 mips32_op = OPC_SLTIU;
12238 do_slti:
d75c135e 12239 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12240 break;
12241 case JALX32:
12242 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12243 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12244 *is_branch = 1;
12245 break;
12246 case JALS32:
12247 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12248 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12249 *is_branch = 1;
12250 break;
12251 case BEQ32:
12252 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12253 *is_branch = 1;
12254 break;
12255 case BNE32:
12256 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12257 *is_branch = 1;
12258 break;
12259 case J32:
12260 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12261 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12262 *is_branch = 1;
12263 break;
12264 case JAL32:
12265 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12266 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12267 *is_branch = 1;
12268 break;
12269 /* Floating point (COP1) */
12270 case LWC132:
12271 mips32_op = OPC_LWC1;
12272 goto do_cop1;
12273 case LDC132:
12274 mips32_op = OPC_LDC1;
12275 goto do_cop1;
12276 case SWC132:
12277 mips32_op = OPC_SWC1;
12278 goto do_cop1;
12279 case SDC132:
12280 mips32_op = OPC_SDC1;
12281 do_cop1:
12282 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12283 break;
12284 case ADDIUPC:
12285 {
12286 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12287 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12288
12289 gen_addiupc(ctx, reg, offset, 0, 0);
12290 }
12291 break;
12292 /* Loads and stores */
12293 case LB32:
12294 mips32_op = OPC_LB;
5c13fdfd 12295 goto do_ld;
3c824109
NF
12296 case LBU32:
12297 mips32_op = OPC_LBU;
5c13fdfd 12298 goto do_ld;
3c824109
NF
12299 case LH32:
12300 mips32_op = OPC_LH;
5c13fdfd 12301 goto do_ld;
3c824109
NF
12302 case LHU32:
12303 mips32_op = OPC_LHU;
5c13fdfd 12304 goto do_ld;
3c824109
NF
12305 case LW32:
12306 mips32_op = OPC_LW;
5c13fdfd 12307 goto do_ld;
3c824109
NF
12308#ifdef TARGET_MIPS64
12309 case LD32:
12310 mips32_op = OPC_LD;
5c13fdfd 12311 goto do_ld;
3c824109
NF
12312 case SD32:
12313 mips32_op = OPC_SD;
5c13fdfd 12314 goto do_st;
3c824109
NF
12315#endif
12316 case SB32:
12317 mips32_op = OPC_SB;
5c13fdfd 12318 goto do_st;
3c824109
NF
12319 case SH32:
12320 mips32_op = OPC_SH;
5c13fdfd 12321 goto do_st;
3c824109
NF
12322 case SW32:
12323 mips32_op = OPC_SW;
5c13fdfd
AJ
12324 goto do_st;
12325 do_ld:
d75c135e 12326 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12327 break;
12328 do_st:
12329 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12330 break;
12331 default:
12332 generate_exception(ctx, EXCP_RI);
12333 break;
12334 }
12335}
12336
7db13fae 12337static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
12338{
12339 uint32_t op;
12340
12341 /* make sure instructions are on a halfword boundary */
12342 if (ctx->pc & 0x1) {
12343 env->CP0_BadVAddr = ctx->pc;
12344 generate_exception(ctx, EXCP_AdEL);
12345 ctx->bstate = BS_STOP;
12346 return 2;
12347 }
12348
12349 op = (ctx->opcode >> 10) & 0x3f;
12350 /* Enforce properly-sized instructions in a delay slot */
12351 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12352 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12353
12354 switch (op) {
12355 case POOL32A:
12356 case POOL32B:
12357 case POOL32I:
12358 case POOL32C:
12359 case ADDI32:
12360 case ADDIU32:
12361 case ORI32:
12362 case XORI32:
12363 case SLTI32:
12364 case SLTIU32:
12365 case ANDI32:
12366 case JALX32:
12367 case LBU32:
12368 case LHU32:
12369 case POOL32F:
12370 case JALS32:
12371 case BEQ32:
12372 case BNE32:
12373 case J32:
12374 case JAL32:
12375 case SB32:
12376 case SH32:
12377 case POOL32S:
12378 case ADDIUPC:
12379 case SWC132:
12380 case SDC132:
12381 case SD32:
12382 case SW32:
12383 case LB32:
12384 case LH32:
12385 case DADDIU32:
3c824109
NF
12386 case LWC132:
12387 case LDC132:
12388 case LD32:
12389 case LW32:
12390 if (bits & MIPS_HFLAG_BDS16) {
12391 generate_exception(ctx, EXCP_RI);
12392 /* Just stop translation; the user is confused. */
12393 ctx->bstate = BS_STOP;
12394 return 2;
12395 }
12396 break;
12397 case POOL16A:
12398 case POOL16B:
12399 case POOL16C:
12400 case LWGP16:
12401 case POOL16F:
12402 case LBU16:
12403 case LHU16:
12404 case LWSP16:
12405 case LW16:
12406 case SB16:
12407 case SH16:
12408 case SWSP16:
12409 case SW16:
12410 case MOVE16:
12411 case ANDI16:
12412 case POOL16D:
12413 case POOL16E:
12414 case BEQZ16:
12415 case BNEZ16:
12416 case B16:
12417 case LI16:
12418 if (bits & MIPS_HFLAG_BDS32) {
12419 generate_exception(ctx, EXCP_RI);
12420 /* Just stop translation; the user is confused. */
12421 ctx->bstate = BS_STOP;
12422 return 2;
12423 }
12424 break;
12425 default:
12426 break;
12427 }
12428 }
12429 switch (op) {
12430 case POOL16A:
12431 {
12432 int rd = mmreg(uMIPS_RD(ctx->opcode));
12433 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12434 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12435 uint32_t opc = 0;
12436
12437 switch (ctx->opcode & 0x1) {
12438 case ADDU16:
12439 opc = OPC_ADDU;
12440 break;
12441 case SUBU16:
12442 opc = OPC_SUBU;
12443 break;
12444 }
12445
d75c135e 12446 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12447 }
12448 break;
12449 case POOL16B:
12450 {
12451 int rd = mmreg(uMIPS_RD(ctx->opcode));
12452 int rs = mmreg(uMIPS_RS(ctx->opcode));
12453 int amount = (ctx->opcode >> 1) & 0x7;
12454 uint32_t opc = 0;
12455 amount = amount == 0 ? 8 : amount;
12456
12457 switch (ctx->opcode & 0x1) {
12458 case SLL16:
12459 opc = OPC_SLL;
12460 break;
12461 case SRL16:
12462 opc = OPC_SRL;
12463 break;
12464 }
12465
d75c135e 12466 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12467 }
12468 break;
12469 case POOL16C:
d75c135e 12470 gen_pool16c_insn(ctx, is_branch);
3c824109
NF
12471 break;
12472 case LWGP16:
12473 {
12474 int rd = mmreg(uMIPS_RD(ctx->opcode));
12475 int rb = 28; /* GP */
12476 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12477
d75c135e 12478 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12479 }
12480 break;
12481 case POOL16F:
12482 if (ctx->opcode & 1) {
12483 generate_exception(ctx, EXCP_RI);
12484 } else {
12485 /* MOVEP */
12486 int enc_dest = uMIPS_RD(ctx->opcode);
12487 int enc_rt = uMIPS_RS2(ctx->opcode);
12488 int enc_rs = uMIPS_RS1(ctx->opcode);
12489 int rd, rs, re, rt;
12490 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12491 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12492 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12493
12494 rd = rd_enc[enc_dest];
12495 re = re_enc[enc_dest];
12496 rs = rs_rt_enc[enc_rs];
12497 rt = rs_rt_enc[enc_rt];
12498
d75c135e
AJ
12499 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12500 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12501 }
12502 break;
12503 case LBU16:
12504 {
12505 int rd = mmreg(uMIPS_RD(ctx->opcode));
12506 int rb = mmreg(uMIPS_RS(ctx->opcode));
12507 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12508 offset = (offset == 0xf ? -1 : offset);
12509
d75c135e 12510 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12511 }
12512 break;
12513 case LHU16:
12514 {
12515 int rd = mmreg(uMIPS_RD(ctx->opcode));
12516 int rb = mmreg(uMIPS_RS(ctx->opcode));
12517 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12518
d75c135e 12519 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12520 }
12521 break;
12522 case LWSP16:
12523 {
12524 int rd = (ctx->opcode >> 5) & 0x1f;
12525 int rb = 29; /* SP */
12526 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12527
d75c135e 12528 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12529 }
12530 break;
12531 case LW16:
12532 {
12533 int rd = mmreg(uMIPS_RD(ctx->opcode));
12534 int rb = mmreg(uMIPS_RS(ctx->opcode));
12535 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12536
d75c135e 12537 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12538 }
12539 break;
12540 case SB16:
12541 {
12542 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12543 int rb = mmreg(uMIPS_RS(ctx->opcode));
12544 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12545
5c13fdfd 12546 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12547 }
12548 break;
12549 case SH16:
12550 {
12551 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12552 int rb = mmreg(uMIPS_RS(ctx->opcode));
12553 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12554
5c13fdfd 12555 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12556 }
12557 break;
12558 case SWSP16:
12559 {
12560 int rd = (ctx->opcode >> 5) & 0x1f;
12561 int rb = 29; /* SP */
12562 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12563
5c13fdfd 12564 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12565 }
12566 break;
12567 case SW16:
12568 {
12569 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12570 int rb = mmreg(uMIPS_RS(ctx->opcode));
12571 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12572
5c13fdfd 12573 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12574 }
12575 break;
12576 case MOVE16:
12577 {
12578 int rd = uMIPS_RD5(ctx->opcode);
12579 int rs = uMIPS_RS5(ctx->opcode);
12580
d75c135e 12581 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12582 }
12583 break;
12584 case ANDI16:
d75c135e 12585 gen_andi16(ctx);
3c824109
NF
12586 break;
12587 case POOL16D:
12588 switch (ctx->opcode & 0x1) {
12589 case ADDIUS5:
d75c135e 12590 gen_addius5(ctx);
3c824109
NF
12591 break;
12592 case ADDIUSP:
d75c135e 12593 gen_addiusp(ctx);
3c824109
NF
12594 break;
12595 }
12596 break;
12597 case POOL16E:
12598 switch (ctx->opcode & 0x1) {
12599 case ADDIUR2:
d75c135e 12600 gen_addiur2(ctx);
3c824109
NF
12601 break;
12602 case ADDIUR1SP:
d75c135e 12603 gen_addiur1sp(ctx);
3c824109
NF
12604 break;
12605 }
12606 break;
12607 case B16:
12608 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12609 SIMM(ctx->opcode, 0, 10) << 1);
12610 *is_branch = 1;
12611 break;
12612 case BNEZ16:
12613 case BEQZ16:
12614 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12615 mmreg(uMIPS_RD(ctx->opcode)),
12616 0, SIMM(ctx->opcode, 0, 7) << 1);
12617 *is_branch = 1;
12618 break;
12619 case LI16:
12620 {
12621 int reg = mmreg(uMIPS_RD(ctx->opcode));
12622 int imm = ZIMM(ctx->opcode, 0, 7);
12623
12624 imm = (imm == 0x7f ? -1 : imm);
12625 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12626 }
12627 break;
12628 case RES_20:
12629 case RES_28:
12630 case RES_29:
12631 case RES_30:
12632 case RES_31:
12633 case RES_38:
12634 case RES_39:
12635 generate_exception(ctx, EXCP_RI);
12636 break;
12637 default:
12638 decode_micromips32_opc (env, ctx, op, is_branch);
12639 return 4;
12640 }
12641
12642 return 2;
12643}
12644
12645/* SmartMIPS extension to MIPS32 */
12646
12647#if defined(TARGET_MIPS64)
12648
12649/* MDMX extension to MIPS64 */
12650
12651#endif
12652
9b1a1d68 12653/* MIPSDSP functions. */
d75c135e 12654static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12655 int rd, int base, int offset)
12656{
12657 const char *opn = "ldx";
12658 TCGv t0;
12659
9b1a1d68
JL
12660 check_dsp(ctx);
12661 t0 = tcg_temp_new();
12662
12663 if (base == 0) {
12664 gen_load_gpr(t0, offset);
12665 } else if (offset == 0) {
12666 gen_load_gpr(t0, base);
12667 } else {
12668 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12669 }
12670
9b1a1d68
JL
12671 switch (opc) {
12672 case OPC_LBUX:
2910c6cb 12673 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12674 gen_store_gpr(t0, rd);
12675 opn = "lbux";
12676 break;
12677 case OPC_LHX:
2910c6cb 12678 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12679 gen_store_gpr(t0, rd);
12680 opn = "lhx";
12681 break;
12682 case OPC_LWX:
2910c6cb 12683 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12684 gen_store_gpr(t0, rd);
12685 opn = "lwx";
12686 break;
12687#if defined(TARGET_MIPS64)
12688 case OPC_LDX:
2910c6cb 12689 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12690 gen_store_gpr(t0, rd);
12691 opn = "ldx";
12692 break;
12693#endif
12694 }
12695 (void)opn; /* avoid a compiler warning */
12696 MIPS_DEBUG("%s %s, %s(%s)", opn,
12697 regnames[rd], regnames[offset], regnames[base]);
12698 tcg_temp_free(t0);
12699}
12700
461c08df
JL
12701static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12702 int ret, int v1, int v2)
12703{
12704 const char *opn = "mipsdsp arith";
12705 TCGv v1_t;
12706 TCGv v2_t;
12707
12708 if (ret == 0) {
12709 /* Treat as NOP. */
12710 MIPS_DEBUG("NOP");
12711 return;
12712 }
12713
12714 v1_t = tcg_temp_new();
12715 v2_t = tcg_temp_new();
12716
12717 gen_load_gpr(v1_t, v1);
12718 gen_load_gpr(v2_t, v2);
12719
12720 switch (op1) {
12721 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12722 case OPC_MULT_G_2E:
12723 check_dspr2(ctx);
12724 switch (op2) {
12725 case OPC_ADDUH_QB:
12726 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12727 break;
12728 case OPC_ADDUH_R_QB:
12729 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12730 break;
12731 case OPC_ADDQH_PH:
12732 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12733 break;
12734 case OPC_ADDQH_R_PH:
12735 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12736 break;
12737 case OPC_ADDQH_W:
12738 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12739 break;
12740 case OPC_ADDQH_R_W:
12741 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12742 break;
12743 case OPC_SUBUH_QB:
12744 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12745 break;
12746 case OPC_SUBUH_R_QB:
12747 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12748 break;
12749 case OPC_SUBQH_PH:
12750 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12751 break;
12752 case OPC_SUBQH_R_PH:
12753 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12754 break;
12755 case OPC_SUBQH_W:
12756 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12757 break;
12758 case OPC_SUBQH_R_W:
12759 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12760 break;
12761 }
12762 break;
12763 case OPC_ABSQ_S_PH_DSP:
12764 switch (op2) {
12765 case OPC_ABSQ_S_QB:
12766 check_dspr2(ctx);
12767 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12768 break;
12769 case OPC_ABSQ_S_PH:
12770 check_dsp(ctx);
12771 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12772 break;
12773 case OPC_ABSQ_S_W:
12774 check_dsp(ctx);
12775 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12776 break;
12777 case OPC_PRECEQ_W_PHL:
12778 check_dsp(ctx);
12779 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12780 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12781 break;
12782 case OPC_PRECEQ_W_PHR:
12783 check_dsp(ctx);
12784 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12785 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12786 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12787 break;
12788 case OPC_PRECEQU_PH_QBL:
12789 check_dsp(ctx);
12790 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12791 break;
12792 case OPC_PRECEQU_PH_QBR:
12793 check_dsp(ctx);
12794 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12795 break;
12796 case OPC_PRECEQU_PH_QBLA:
12797 check_dsp(ctx);
12798 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12799 break;
12800 case OPC_PRECEQU_PH_QBRA:
12801 check_dsp(ctx);
12802 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12803 break;
12804 case OPC_PRECEU_PH_QBL:
12805 check_dsp(ctx);
12806 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12807 break;
12808 case OPC_PRECEU_PH_QBR:
12809 check_dsp(ctx);
12810 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12811 break;
12812 case OPC_PRECEU_PH_QBLA:
12813 check_dsp(ctx);
12814 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12815 break;
12816 case OPC_PRECEU_PH_QBRA:
12817 check_dsp(ctx);
12818 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12819 break;
12820 }
12821 break;
12822 case OPC_ADDU_QB_DSP:
12823 switch (op2) {
12824 case OPC_ADDQ_PH:
12825 check_dsp(ctx);
12826 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12827 break;
12828 case OPC_ADDQ_S_PH:
12829 check_dsp(ctx);
12830 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12831 break;
12832 case OPC_ADDQ_S_W:
12833 check_dsp(ctx);
12834 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12835 break;
12836 case OPC_ADDU_QB:
12837 check_dsp(ctx);
12838 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12839 break;
12840 case OPC_ADDU_S_QB:
12841 check_dsp(ctx);
12842 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12843 break;
12844 case OPC_ADDU_PH:
12845 check_dspr2(ctx);
12846 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12847 break;
12848 case OPC_ADDU_S_PH:
12849 check_dspr2(ctx);
12850 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12851 break;
12852 case OPC_SUBQ_PH:
12853 check_dsp(ctx);
12854 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12855 break;
12856 case OPC_SUBQ_S_PH:
12857 check_dsp(ctx);
12858 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12859 break;
12860 case OPC_SUBQ_S_W:
12861 check_dsp(ctx);
12862 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12863 break;
12864 case OPC_SUBU_QB:
12865 check_dsp(ctx);
12866 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12867 break;
12868 case OPC_SUBU_S_QB:
12869 check_dsp(ctx);
12870 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12871 break;
12872 case OPC_SUBU_PH:
12873 check_dspr2(ctx);
12874 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12875 break;
12876 case OPC_SUBU_S_PH:
12877 check_dspr2(ctx);
12878 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12879 break;
12880 case OPC_ADDSC:
12881 check_dsp(ctx);
12882 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12883 break;
12884 case OPC_ADDWC:
12885 check_dsp(ctx);
12886 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12887 break;
12888 case OPC_MODSUB:
12889 check_dsp(ctx);
12890 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12891 break;
12892 case OPC_RADDU_W_QB:
12893 check_dsp(ctx);
12894 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12895 break;
12896 }
12897 break;
12898 case OPC_CMPU_EQ_QB_DSP:
12899 switch (op2) {
12900 case OPC_PRECR_QB_PH:
12901 check_dspr2(ctx);
12902 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12903 break;
12904 case OPC_PRECRQ_QB_PH:
12905 check_dsp(ctx);
12906 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12907 break;
12908 case OPC_PRECR_SRA_PH_W:
12909 check_dspr2(ctx);
12910 {
12911 TCGv_i32 sa_t = tcg_const_i32(v2);
12912 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12913 cpu_gpr[ret]);
12914 tcg_temp_free_i32(sa_t);
12915 break;
12916 }
12917 case OPC_PRECR_SRA_R_PH_W:
12918 check_dspr2(ctx);
12919 {
12920 TCGv_i32 sa_t = tcg_const_i32(v2);
12921 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12922 cpu_gpr[ret]);
12923 tcg_temp_free_i32(sa_t);
12924 break;
12925 }
12926 case OPC_PRECRQ_PH_W:
12927 check_dsp(ctx);
12928 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12929 break;
12930 case OPC_PRECRQ_RS_PH_W:
12931 check_dsp(ctx);
12932 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12933 break;
12934 case OPC_PRECRQU_S_QB_PH:
12935 check_dsp(ctx);
12936 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12937 break;
12938 }
12939 break;
12940#ifdef TARGET_MIPS64
12941 case OPC_ABSQ_S_QH_DSP:
12942 switch (op2) {
12943 case OPC_PRECEQ_L_PWL:
12944 check_dsp(ctx);
12945 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12946 break;
12947 case OPC_PRECEQ_L_PWR:
12948 check_dsp(ctx);
12949 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12950 break;
12951 case OPC_PRECEQ_PW_QHL:
12952 check_dsp(ctx);
12953 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12954 break;
12955 case OPC_PRECEQ_PW_QHR:
12956 check_dsp(ctx);
12957 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12958 break;
12959 case OPC_PRECEQ_PW_QHLA:
12960 check_dsp(ctx);
12961 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12962 break;
12963 case OPC_PRECEQ_PW_QHRA:
12964 check_dsp(ctx);
12965 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12966 break;
12967 case OPC_PRECEQU_QH_OBL:
12968 check_dsp(ctx);
12969 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12970 break;
12971 case OPC_PRECEQU_QH_OBR:
12972 check_dsp(ctx);
12973 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12974 break;
12975 case OPC_PRECEQU_QH_OBLA:
12976 check_dsp(ctx);
12977 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12978 break;
12979 case OPC_PRECEQU_QH_OBRA:
12980 check_dsp(ctx);
12981 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12982 break;
12983 case OPC_PRECEU_QH_OBL:
12984 check_dsp(ctx);
12985 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12986 break;
12987 case OPC_PRECEU_QH_OBR:
12988 check_dsp(ctx);
12989 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12990 break;
12991 case OPC_PRECEU_QH_OBLA:
12992 check_dsp(ctx);
12993 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12994 break;
12995 case OPC_PRECEU_QH_OBRA:
12996 check_dsp(ctx);
12997 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12998 break;
12999 case OPC_ABSQ_S_OB:
13000 check_dspr2(ctx);
13001 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13002 break;
13003 case OPC_ABSQ_S_PW:
13004 check_dsp(ctx);
13005 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13006 break;
13007 case OPC_ABSQ_S_QH:
13008 check_dsp(ctx);
13009 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13010 break;
13011 }
13012 break;
13013 case OPC_ADDU_OB_DSP:
13014 switch (op2) {
13015 case OPC_RADDU_L_OB:
13016 check_dsp(ctx);
13017 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13018 break;
13019 case OPC_SUBQ_PW:
13020 check_dsp(ctx);
13021 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13022 break;
13023 case OPC_SUBQ_S_PW:
13024 check_dsp(ctx);
13025 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13026 break;
13027 case OPC_SUBQ_QH:
13028 check_dsp(ctx);
13029 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13030 break;
13031 case OPC_SUBQ_S_QH:
13032 check_dsp(ctx);
13033 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13034 break;
13035 case OPC_SUBU_OB:
13036 check_dsp(ctx);
13037 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13038 break;
13039 case OPC_SUBU_S_OB:
13040 check_dsp(ctx);
13041 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13042 break;
13043 case OPC_SUBU_QH:
13044 check_dspr2(ctx);
13045 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13046 break;
13047 case OPC_SUBU_S_QH:
13048 check_dspr2(ctx);
13049 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13050 break;
13051 case OPC_SUBUH_OB:
13052 check_dspr2(ctx);
13053 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13054 break;
13055 case OPC_SUBUH_R_OB:
13056 check_dspr2(ctx);
13057 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13058 break;
13059 case OPC_ADDQ_PW:
13060 check_dsp(ctx);
13061 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13062 break;
13063 case OPC_ADDQ_S_PW:
13064 check_dsp(ctx);
13065 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13066 break;
13067 case OPC_ADDQ_QH:
13068 check_dsp(ctx);
13069 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13070 break;
13071 case OPC_ADDQ_S_QH:
13072 check_dsp(ctx);
13073 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13074 break;
13075 case OPC_ADDU_OB:
13076 check_dsp(ctx);
13077 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13078 break;
13079 case OPC_ADDU_S_OB:
13080 check_dsp(ctx);
13081 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13082 break;
13083 case OPC_ADDU_QH:
13084 check_dspr2(ctx);
13085 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13086 break;
13087 case OPC_ADDU_S_QH:
13088 check_dspr2(ctx);
13089 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13090 break;
13091 case OPC_ADDUH_OB:
13092 check_dspr2(ctx);
13093 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13094 break;
13095 case OPC_ADDUH_R_OB:
13096 check_dspr2(ctx);
13097 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13098 break;
13099 }
13100 break;
13101 case OPC_CMPU_EQ_OB_DSP:
13102 switch (op2) {
13103 case OPC_PRECR_OB_QH:
13104 check_dspr2(ctx);
13105 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13106 break;
13107 case OPC_PRECR_SRA_QH_PW:
13108 check_dspr2(ctx);
13109 {
13110 TCGv_i32 ret_t = tcg_const_i32(ret);
13111 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13112 tcg_temp_free_i32(ret_t);
13113 break;
13114 }
13115 case OPC_PRECR_SRA_R_QH_PW:
13116 check_dspr2(ctx);
13117 {
13118 TCGv_i32 sa_v = tcg_const_i32(ret);
13119 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13120 tcg_temp_free_i32(sa_v);
13121 break;
13122 }
13123 case OPC_PRECRQ_OB_QH:
13124 check_dsp(ctx);
13125 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13126 break;
13127 case OPC_PRECRQ_PW_L:
13128 check_dsp(ctx);
13129 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13130 break;
13131 case OPC_PRECRQ_QH_PW:
13132 check_dsp(ctx);
13133 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13134 break;
13135 case OPC_PRECRQ_RS_QH_PW:
13136 check_dsp(ctx);
13137 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13138 break;
13139 case OPC_PRECRQU_S_OB_QH:
13140 check_dsp(ctx);
13141 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13142 break;
13143 }
13144 break;
13145#endif
13146 }
13147
13148 tcg_temp_free(v1_t);
13149 tcg_temp_free(v2_t);
13150
13151 (void)opn; /* avoid a compiler warning */
13152 MIPS_DEBUG("%s", opn);
13153}
9b1a1d68 13154
77c5fa8b
JL
13155static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13156 int ret, int v1, int v2)
13157{
13158 uint32_t op2;
13159 const char *opn = "mipsdsp shift";
13160 TCGv t0;
13161 TCGv v1_t;
13162 TCGv v2_t;
13163
13164 if (ret == 0) {
13165 /* Treat as NOP. */
13166 MIPS_DEBUG("NOP");
13167 return;
13168 }
13169
13170 t0 = tcg_temp_new();
13171 v1_t = tcg_temp_new();
13172 v2_t = tcg_temp_new();
13173
13174 tcg_gen_movi_tl(t0, v1);
13175 gen_load_gpr(v1_t, v1);
13176 gen_load_gpr(v2_t, v2);
13177
13178 switch (opc) {
13179 case OPC_SHLL_QB_DSP:
13180 {
13181 op2 = MASK_SHLL_QB(ctx->opcode);
13182 switch (op2) {
13183 case OPC_SHLL_QB:
13184 check_dsp(ctx);
13185 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13186 break;
13187 case OPC_SHLLV_QB:
13188 check_dsp(ctx);
13189 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13190 break;
13191 case OPC_SHLL_PH:
13192 check_dsp(ctx);
13193 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13194 break;
13195 case OPC_SHLLV_PH:
13196 check_dsp(ctx);
13197 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13198 break;
13199 case OPC_SHLL_S_PH:
13200 check_dsp(ctx);
13201 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13202 break;
13203 case OPC_SHLLV_S_PH:
13204 check_dsp(ctx);
13205 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13206 break;
13207 case OPC_SHLL_S_W:
13208 check_dsp(ctx);
13209 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13210 break;
13211 case OPC_SHLLV_S_W:
13212 check_dsp(ctx);
13213 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13214 break;
13215 case OPC_SHRL_QB:
13216 check_dsp(ctx);
13217 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13218 break;
13219 case OPC_SHRLV_QB:
13220 check_dsp(ctx);
13221 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13222 break;
13223 case OPC_SHRL_PH:
13224 check_dspr2(ctx);
13225 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13226 break;
13227 case OPC_SHRLV_PH:
13228 check_dspr2(ctx);
13229 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13230 break;
13231 case OPC_SHRA_QB:
13232 check_dspr2(ctx);
13233 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13234 break;
13235 case OPC_SHRA_R_QB:
13236 check_dspr2(ctx);
13237 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13238 break;
13239 case OPC_SHRAV_QB:
13240 check_dspr2(ctx);
13241 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13242 break;
13243 case OPC_SHRAV_R_QB:
13244 check_dspr2(ctx);
13245 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13246 break;
13247 case OPC_SHRA_PH:
13248 check_dsp(ctx);
13249 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13250 break;
13251 case OPC_SHRA_R_PH:
13252 check_dsp(ctx);
13253 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13254 break;
13255 case OPC_SHRAV_PH:
13256 check_dsp(ctx);
13257 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13258 break;
13259 case OPC_SHRAV_R_PH:
13260 check_dsp(ctx);
13261 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13262 break;
13263 case OPC_SHRA_R_W:
13264 check_dsp(ctx);
13265 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13266 break;
13267 case OPC_SHRAV_R_W:
13268 check_dsp(ctx);
13269 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13270 break;
13271 default: /* Invalid */
13272 MIPS_INVAL("MASK SHLL.QB");
13273 generate_exception(ctx, EXCP_RI);
13274 break;
13275 }
13276 break;
13277 }
13278#ifdef TARGET_MIPS64
13279 case OPC_SHLL_OB_DSP:
13280 op2 = MASK_SHLL_OB(ctx->opcode);
13281 switch (op2) {
13282 case OPC_SHLL_PW:
13283 check_dsp(ctx);
13284 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13285 break;
13286 case OPC_SHLLV_PW:
13287 check_dsp(ctx);
13288 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13289 break;
13290 case OPC_SHLL_S_PW:
13291 check_dsp(ctx);
13292 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13293 break;
13294 case OPC_SHLLV_S_PW:
13295 check_dsp(ctx);
13296 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13297 break;
13298 case OPC_SHLL_OB:
13299 check_dsp(ctx);
13300 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13301 break;
13302 case OPC_SHLLV_OB:
13303 check_dsp(ctx);
13304 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13305 break;
13306 case OPC_SHLL_QH:
13307 check_dsp(ctx);
13308 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13309 break;
13310 case OPC_SHLLV_QH:
13311 check_dsp(ctx);
13312 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13313 break;
13314 case OPC_SHLL_S_QH:
13315 check_dsp(ctx);
13316 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13317 break;
13318 case OPC_SHLLV_S_QH:
13319 check_dsp(ctx);
13320 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13321 break;
13322 case OPC_SHRA_OB:
13323 check_dspr2(ctx);
13324 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13325 break;
13326 case OPC_SHRAV_OB:
13327 check_dspr2(ctx);
13328 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13329 break;
13330 case OPC_SHRA_R_OB:
13331 check_dspr2(ctx);
13332 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13333 break;
13334 case OPC_SHRAV_R_OB:
13335 check_dspr2(ctx);
13336 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13337 break;
13338 case OPC_SHRA_PW:
13339 check_dsp(ctx);
13340 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13341 break;
13342 case OPC_SHRAV_PW:
13343 check_dsp(ctx);
13344 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13345 break;
13346 case OPC_SHRA_R_PW:
13347 check_dsp(ctx);
13348 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13349 break;
13350 case OPC_SHRAV_R_PW:
13351 check_dsp(ctx);
13352 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13353 break;
13354 case OPC_SHRA_QH:
13355 check_dsp(ctx);
13356 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13357 break;
13358 case OPC_SHRAV_QH:
13359 check_dsp(ctx);
13360 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13361 break;
13362 case OPC_SHRA_R_QH:
13363 check_dsp(ctx);
13364 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13365 break;
13366 case OPC_SHRAV_R_QH:
13367 check_dsp(ctx);
13368 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13369 break;
13370 case OPC_SHRL_OB:
13371 check_dsp(ctx);
13372 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13373 break;
13374 case OPC_SHRLV_OB:
13375 check_dsp(ctx);
13376 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13377 break;
13378 case OPC_SHRL_QH:
13379 check_dspr2(ctx);
13380 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13381 break;
13382 case OPC_SHRLV_QH:
13383 check_dspr2(ctx);
13384 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13385 break;
13386 default: /* Invalid */
13387 MIPS_INVAL("MASK SHLL.OB");
13388 generate_exception(ctx, EXCP_RI);
13389 break;
13390 }
13391 break;
13392#endif
13393 }
13394
13395 tcg_temp_free(t0);
13396 tcg_temp_free(v1_t);
13397 tcg_temp_free(v2_t);
13398 (void)opn; /* avoid a compiler warning */
13399 MIPS_DEBUG("%s", opn);
13400}
13401
a22260ae
JL
13402static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13403 int ret, int v1, int v2, int check_ret)
13404{
13405 const char *opn = "mipsdsp multiply";
13406 TCGv_i32 t0;
13407 TCGv v1_t;
13408 TCGv v2_t;
13409
13410 if ((ret == 0) && (check_ret == 1)) {
13411 /* Treat as NOP. */
13412 MIPS_DEBUG("NOP");
13413 return;
13414 }
13415
13416 t0 = tcg_temp_new_i32();
13417 v1_t = tcg_temp_new();
13418 v2_t = tcg_temp_new();
13419
13420 tcg_gen_movi_i32(t0, ret);
13421 gen_load_gpr(v1_t, v1);
13422 gen_load_gpr(v2_t, v2);
13423
13424 switch (op1) {
13425 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13426 * the same mask and op1. */
13427 case OPC_MULT_G_2E:
13428 switch (op2) {
13429 case OPC_MUL_PH:
13430 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13431 break;
13432 case OPC_MUL_S_PH:
13433 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13434 break;
13435 case OPC_MULQ_S_W:
13436 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13437 break;
13438 case OPC_MULQ_RS_W:
13439 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13440 break;
13441 }
13442 break;
13443 case OPC_DPA_W_PH_DSP:
13444 switch (op2) {
13445 case OPC_DPAU_H_QBL:
13446 check_dsp(ctx);
13447 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13448 break;
13449 case OPC_DPAU_H_QBR:
13450 check_dsp(ctx);
13451 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13452 break;
13453 case OPC_DPSU_H_QBL:
13454 check_dsp(ctx);
13455 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13456 break;
13457 case OPC_DPSU_H_QBR:
13458 check_dsp(ctx);
13459 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_DPA_W_PH:
13462 check_dspr2(ctx);
13463 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13464 break;
13465 case OPC_DPAX_W_PH:
13466 check_dspr2(ctx);
13467 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13468 break;
13469 case OPC_DPAQ_S_W_PH:
13470 check_dsp(ctx);
13471 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13472 break;
13473 case OPC_DPAQX_S_W_PH:
13474 check_dspr2(ctx);
13475 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13476 break;
13477 case OPC_DPAQX_SA_W_PH:
13478 check_dspr2(ctx);
13479 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13480 break;
13481 case OPC_DPS_W_PH:
13482 check_dspr2(ctx);
13483 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13484 break;
13485 case OPC_DPSX_W_PH:
13486 check_dspr2(ctx);
13487 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13488 break;
13489 case OPC_DPSQ_S_W_PH:
13490 check_dsp(ctx);
13491 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13492 break;
13493 case OPC_DPSQX_S_W_PH:
13494 check_dspr2(ctx);
13495 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13496 break;
13497 case OPC_DPSQX_SA_W_PH:
13498 check_dspr2(ctx);
13499 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13500 break;
13501 case OPC_MULSAQ_S_W_PH:
13502 check_dsp(ctx);
13503 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13504 break;
13505 case OPC_DPAQ_SA_L_W:
13506 check_dsp(ctx);
13507 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13508 break;
13509 case OPC_DPSQ_SA_L_W:
13510 check_dsp(ctx);
13511 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13512 break;
13513 case OPC_MAQ_S_W_PHL:
13514 check_dsp(ctx);
13515 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13516 break;
13517 case OPC_MAQ_S_W_PHR:
13518 check_dsp(ctx);
13519 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13520 break;
13521 case OPC_MAQ_SA_W_PHL:
13522 check_dsp(ctx);
13523 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13524 break;
13525 case OPC_MAQ_SA_W_PHR:
13526 check_dsp(ctx);
13527 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13528 break;
13529 case OPC_MULSA_W_PH:
13530 check_dspr2(ctx);
13531 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13532 break;
13533 }
13534 break;
13535#ifdef TARGET_MIPS64
13536 case OPC_DPAQ_W_QH_DSP:
13537 {
13538 int ac = ret & 0x03;
13539 tcg_gen_movi_i32(t0, ac);
13540
13541 switch (op2) {
13542 case OPC_DMADD:
13543 check_dsp(ctx);
13544 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13545 break;
13546 case OPC_DMADDU:
13547 check_dsp(ctx);
13548 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13549 break;
13550 case OPC_DMSUB:
13551 check_dsp(ctx);
13552 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13553 break;
13554 case OPC_DMSUBU:
13555 check_dsp(ctx);
13556 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13557 break;
13558 case OPC_DPA_W_QH:
13559 check_dspr2(ctx);
13560 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13561 break;
13562 case OPC_DPAQ_S_W_QH:
13563 check_dsp(ctx);
13564 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13565 break;
13566 case OPC_DPAQ_SA_L_PW:
13567 check_dsp(ctx);
13568 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13569 break;
13570 case OPC_DPAU_H_OBL:
13571 check_dsp(ctx);
13572 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13573 break;
13574 case OPC_DPAU_H_OBR:
13575 check_dsp(ctx);
13576 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13577 break;
13578 case OPC_DPS_W_QH:
13579 check_dspr2(ctx);
13580 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13581 break;
13582 case OPC_DPSQ_S_W_QH:
13583 check_dsp(ctx);
13584 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13585 break;
13586 case OPC_DPSQ_SA_L_PW:
13587 check_dsp(ctx);
13588 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13589 break;
13590 case OPC_DPSU_H_OBL:
13591 check_dsp(ctx);
13592 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13593 break;
13594 case OPC_DPSU_H_OBR:
13595 check_dsp(ctx);
13596 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13597 break;
13598 case OPC_MAQ_S_L_PWL:
13599 check_dsp(ctx);
13600 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13601 break;
13602 case OPC_MAQ_S_L_PWR:
13603 check_dsp(ctx);
13604 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13605 break;
13606 case OPC_MAQ_S_W_QHLL:
13607 check_dsp(ctx);
13608 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13609 break;
13610 case OPC_MAQ_SA_W_QHLL:
13611 check_dsp(ctx);
13612 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13613 break;
13614 case OPC_MAQ_S_W_QHLR:
13615 check_dsp(ctx);
13616 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13617 break;
13618 case OPC_MAQ_SA_W_QHLR:
13619 check_dsp(ctx);
13620 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13621 break;
13622 case OPC_MAQ_S_W_QHRL:
13623 check_dsp(ctx);
13624 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13625 break;
13626 case OPC_MAQ_SA_W_QHRL:
13627 check_dsp(ctx);
13628 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13629 break;
13630 case OPC_MAQ_S_W_QHRR:
13631 check_dsp(ctx);
13632 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13633 break;
13634 case OPC_MAQ_SA_W_QHRR:
13635 check_dsp(ctx);
13636 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13637 break;
13638 case OPC_MULSAQ_S_L_PW:
13639 check_dsp(ctx);
13640 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13641 break;
13642 case OPC_MULSAQ_S_W_QH:
13643 check_dsp(ctx);
13644 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13645 break;
13646 }
13647 }
13648 break;
13649#endif
13650 case OPC_ADDU_QB_DSP:
13651 switch (op2) {
13652 case OPC_MULEU_S_PH_QBL:
13653 check_dsp(ctx);
13654 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13655 break;
13656 case OPC_MULEU_S_PH_QBR:
13657 check_dsp(ctx);
13658 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13659 break;
13660 case OPC_MULQ_RS_PH:
13661 check_dsp(ctx);
13662 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13663 break;
13664 case OPC_MULEQ_S_W_PHL:
13665 check_dsp(ctx);
13666 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13667 break;
13668 case OPC_MULEQ_S_W_PHR:
13669 check_dsp(ctx);
13670 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13671 break;
13672 case OPC_MULQ_S_PH:
13673 check_dspr2(ctx);
13674 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13675 break;
13676 }
13677 break;
13678#ifdef TARGET_MIPS64
13679 case OPC_ADDU_OB_DSP:
13680 switch (op2) {
13681 case OPC_MULEQ_S_PW_QHL:
13682 check_dsp(ctx);
13683 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13684 break;
13685 case OPC_MULEQ_S_PW_QHR:
13686 check_dsp(ctx);
13687 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13688 break;
13689 case OPC_MULEU_S_QH_OBL:
13690 check_dsp(ctx);
13691 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13692 break;
13693 case OPC_MULEU_S_QH_OBR:
13694 check_dsp(ctx);
13695 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13696 break;
13697 case OPC_MULQ_RS_QH:
13698 check_dsp(ctx);
13699 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13700 break;
13701 }
13702 break;
13703#endif
13704 }
13705
13706 tcg_temp_free_i32(t0);
13707 tcg_temp_free(v1_t);
13708 tcg_temp_free(v2_t);
13709
13710 (void)opn; /* avoid a compiler warning */
13711 MIPS_DEBUG("%s", opn);
13712
13713}
13714
d75c135e 13715static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13716 int ret, int val)
13717{
13718 const char *opn = "mipsdsp Bit/ Manipulation";
13719 int16_t imm;
13720 TCGv t0;
13721 TCGv val_t;
13722
13723 if (ret == 0) {
13724 /* Treat as NOP. */
13725 MIPS_DEBUG("NOP");
13726 return;
13727 }
13728
13729 t0 = tcg_temp_new();
13730 val_t = tcg_temp_new();
13731 gen_load_gpr(val_t, val);
13732
13733 switch (op1) {
13734 case OPC_ABSQ_S_PH_DSP:
13735 switch (op2) {
13736 case OPC_BITREV:
13737 check_dsp(ctx);
13738 gen_helper_bitrev(cpu_gpr[ret], val_t);
13739 break;
13740 case OPC_REPL_QB:
13741 check_dsp(ctx);
13742 {
13743 target_long result;
13744 imm = (ctx->opcode >> 16) & 0xFF;
13745 result = (uint32_t)imm << 24 |
13746 (uint32_t)imm << 16 |
13747 (uint32_t)imm << 8 |
13748 (uint32_t)imm;
13749 result = (int32_t)result;
13750 tcg_gen_movi_tl(cpu_gpr[ret], result);
13751 }
13752 break;
13753 case OPC_REPLV_QB:
13754 check_dsp(ctx);
13755 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13756 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13757 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13758 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13759 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13760 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13761 break;
13762 case OPC_REPL_PH:
13763 check_dsp(ctx);
13764 {
13765 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13766 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13767 tcg_gen_movi_tl(cpu_gpr[ret], \
13768 (target_long)((int32_t)imm << 16 | \
c4aaba92 13769 (uint16_t)imm));
1cb6686c
JL
13770 }
13771 break;
13772 case OPC_REPLV_PH:
13773 check_dsp(ctx);
13774 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13775 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13776 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13777 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13778 break;
13779 }
13780 break;
13781#ifdef TARGET_MIPS64
13782 case OPC_ABSQ_S_QH_DSP:
13783 switch (op2) {
13784 case OPC_REPL_OB:
13785 check_dsp(ctx);
13786 {
13787 target_long temp;
13788
13789 imm = (ctx->opcode >> 16) & 0xFF;
13790 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13791 temp = (temp << 16) | temp;
13792 temp = (temp << 32) | temp;
13793 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13794 break;
13795 }
13796 case OPC_REPL_PW:
13797 check_dsp(ctx);
13798 {
13799 target_long temp;
13800
13801 imm = (ctx->opcode >> 16) & 0x03FF;
13802 imm = (int16_t)(imm << 6) >> 6;
13803 temp = ((target_long)imm << 32) \
13804 | ((target_long)imm & 0xFFFFFFFF);
13805 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13806 break;
13807 }
13808 case OPC_REPL_QH:
13809 check_dsp(ctx);
13810 {
13811 target_long temp;
13812
13813 imm = (ctx->opcode >> 16) & 0x03FF;
13814 imm = (int16_t)(imm << 6) >> 6;
13815
13816 temp = ((uint64_t)(uint16_t)imm << 48) |
13817 ((uint64_t)(uint16_t)imm << 32) |
13818 ((uint64_t)(uint16_t)imm << 16) |
13819 (uint64_t)(uint16_t)imm;
13820 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13821 break;
13822 }
13823 case OPC_REPLV_OB:
13824 check_dsp(ctx);
13825 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13826 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13827 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13828 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13829 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13830 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13831 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13832 break;
13833 case OPC_REPLV_PW:
13834 check_dsp(ctx);
13835 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13836 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13837 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13838 break;
13839 case OPC_REPLV_QH:
13840 check_dsp(ctx);
13841 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13842 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13843 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13844 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13845 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13846 break;
13847 }
13848 break;
13849#endif
13850 }
13851 tcg_temp_free(t0);
13852 tcg_temp_free(val_t);
13853
13854 (void)opn; /* avoid a compiler warning */
13855 MIPS_DEBUG("%s", opn);
13856}
13857
26690560
JL
13858static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13859 uint32_t op1, uint32_t op2,
13860 int ret, int v1, int v2, int check_ret)
13861{
13862 const char *opn = "mipsdsp add compare pick";
13863 TCGv_i32 t0;
13864 TCGv t1;
13865 TCGv v1_t;
13866 TCGv v2_t;
13867
13868 if ((ret == 0) && (check_ret == 1)) {
13869 /* Treat as NOP. */
13870 MIPS_DEBUG("NOP");
13871 return;
13872 }
13873
13874 t0 = tcg_temp_new_i32();
13875 t1 = tcg_temp_new();
13876 v1_t = tcg_temp_new();
13877 v2_t = tcg_temp_new();
13878
13879 gen_load_gpr(v1_t, v1);
13880 gen_load_gpr(v2_t, v2);
13881
13882 switch (op1) {
13883 case OPC_APPEND_DSP:
13884 switch (op2) {
13885 case OPC_APPEND:
13886 tcg_gen_movi_i32(t0, v2);
13887 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13888 break;
13889 case OPC_PREPEND:
13890 tcg_gen_movi_i32(t0, v2);
13891 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13892 break;
13893 case OPC_BALIGN:
13894 tcg_gen_movi_i32(t0, v2);
13895 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13896 break;
13897 default: /* Invid */
13898 MIPS_INVAL("MASK APPEND");
13899 generate_exception(ctx, EXCP_RI);
13900 break;
13901 }
13902 break;
13903 case OPC_CMPU_EQ_QB_DSP:
13904 switch (op2) {
13905 case OPC_CMPU_EQ_QB:
13906 check_dsp(ctx);
13907 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13908 break;
13909 case OPC_CMPU_LT_QB:
13910 check_dsp(ctx);
13911 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13912 break;
13913 case OPC_CMPU_LE_QB:
13914 check_dsp(ctx);
13915 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13916 break;
13917 case OPC_CMPGU_EQ_QB:
13918 check_dsp(ctx);
13919 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13920 break;
13921 case OPC_CMPGU_LT_QB:
13922 check_dsp(ctx);
13923 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13924 break;
13925 case OPC_CMPGU_LE_QB:
13926 check_dsp(ctx);
13927 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13928 break;
13929 case OPC_CMPGDU_EQ_QB:
13930 check_dspr2(ctx);
13931 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13932 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13933 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13934 tcg_gen_shli_tl(t1, t1, 24);
13935 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13936 break;
13937 case OPC_CMPGDU_LT_QB:
13938 check_dspr2(ctx);
13939 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13940 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13941 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13942 tcg_gen_shli_tl(t1, t1, 24);
13943 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13944 break;
13945 case OPC_CMPGDU_LE_QB:
13946 check_dspr2(ctx);
13947 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13948 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13949 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13950 tcg_gen_shli_tl(t1, t1, 24);
13951 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13952 break;
13953 case OPC_CMP_EQ_PH:
13954 check_dsp(ctx);
13955 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13956 break;
13957 case OPC_CMP_LT_PH:
13958 check_dsp(ctx);
13959 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13960 break;
13961 case OPC_CMP_LE_PH:
13962 check_dsp(ctx);
13963 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13964 break;
13965 case OPC_PICK_QB:
13966 check_dsp(ctx);
13967 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13968 break;
13969 case OPC_PICK_PH:
13970 check_dsp(ctx);
13971 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13972 break;
13973 case OPC_PACKRL_PH:
13974 check_dsp(ctx);
13975 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13976 break;
13977 }
13978 break;
13979#ifdef TARGET_MIPS64
13980 case OPC_CMPU_EQ_OB_DSP:
13981 switch (op2) {
13982 case OPC_CMP_EQ_PW:
13983 check_dsp(ctx);
13984 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13985 break;
13986 case OPC_CMP_LT_PW:
13987 check_dsp(ctx);
13988 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13989 break;
13990 case OPC_CMP_LE_PW:
13991 check_dsp(ctx);
13992 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13993 break;
13994 case OPC_CMP_EQ_QH:
13995 check_dsp(ctx);
13996 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13997 break;
13998 case OPC_CMP_LT_QH:
13999 check_dsp(ctx);
14000 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14001 break;
14002 case OPC_CMP_LE_QH:
14003 check_dsp(ctx);
14004 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14005 break;
14006 case OPC_CMPGDU_EQ_OB:
14007 check_dspr2(ctx);
14008 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14009 break;
14010 case OPC_CMPGDU_LT_OB:
14011 check_dspr2(ctx);
14012 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14013 break;
14014 case OPC_CMPGDU_LE_OB:
14015 check_dspr2(ctx);
14016 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14017 break;
14018 case OPC_CMPGU_EQ_OB:
14019 check_dsp(ctx);
14020 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14021 break;
14022 case OPC_CMPGU_LT_OB:
14023 check_dsp(ctx);
14024 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14025 break;
14026 case OPC_CMPGU_LE_OB:
14027 check_dsp(ctx);
14028 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14029 break;
14030 case OPC_CMPU_EQ_OB:
14031 check_dsp(ctx);
14032 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14033 break;
14034 case OPC_CMPU_LT_OB:
14035 check_dsp(ctx);
14036 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14037 break;
14038 case OPC_CMPU_LE_OB:
14039 check_dsp(ctx);
14040 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14041 break;
14042 case OPC_PACKRL_PW:
14043 check_dsp(ctx);
14044 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14045 break;
14046 case OPC_PICK_OB:
14047 check_dsp(ctx);
14048 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14049 break;
14050 case OPC_PICK_PW:
14051 check_dsp(ctx);
14052 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14053 break;
14054 case OPC_PICK_QH:
14055 check_dsp(ctx);
14056 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14057 break;
14058 }
14059 break;
14060 case OPC_DAPPEND_DSP:
14061 switch (op2) {
14062 case OPC_DAPPEND:
14063 tcg_gen_movi_i32(t0, v2);
14064 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14065 break;
14066 case OPC_PREPENDD:
14067 tcg_gen_movi_i32(t0, v2);
14068 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14069 break;
14070 case OPC_PREPENDW:
14071 tcg_gen_movi_i32(t0, v2);
14072 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14073 break;
14074 case OPC_DBALIGN:
14075 tcg_gen_movi_i32(t0, v2);
14076 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14077 break;
14078 default: /* Invalid */
14079 MIPS_INVAL("MASK DAPPEND");
14080 generate_exception(ctx, EXCP_RI);
14081 break;
14082 }
14083 break;
14084#endif
14085 }
14086
14087 tcg_temp_free_i32(t0);
14088 tcg_temp_free(t1);
14089 tcg_temp_free(v1_t);
14090 tcg_temp_free(v2_t);
14091
14092 (void)opn; /* avoid a compiler warning */
14093 MIPS_DEBUG("%s", opn);
14094}
14095
b53371ed
JL
14096static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14097 int ret, int v1, int v2, int check_ret)
14098
14099{
14100 const char *opn = "mipsdsp accumulator";
14101 TCGv t0;
14102 TCGv t1;
14103 TCGv v1_t;
14104 TCGv v2_t;
14105 int16_t imm;
14106
14107 if ((ret == 0) && (check_ret == 1)) {
14108 /* Treat as NOP. */
14109 MIPS_DEBUG("NOP");
14110 return;
14111 }
14112
14113 t0 = tcg_temp_new();
14114 t1 = tcg_temp_new();
14115 v1_t = tcg_temp_new();
14116 v2_t = tcg_temp_new();
14117
14118 gen_load_gpr(v1_t, v1);
14119 gen_load_gpr(v2_t, v2);
14120
14121 switch (op1) {
14122 case OPC_EXTR_W_DSP:
14123 check_dsp(ctx);
14124 switch (op2) {
14125 case OPC_EXTR_W:
14126 tcg_gen_movi_tl(t0, v2);
14127 tcg_gen_movi_tl(t1, v1);
14128 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14129 break;
14130 case OPC_EXTR_R_W:
14131 tcg_gen_movi_tl(t0, v2);
14132 tcg_gen_movi_tl(t1, v1);
14133 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14134 break;
14135 case OPC_EXTR_RS_W:
14136 tcg_gen_movi_tl(t0, v2);
14137 tcg_gen_movi_tl(t1, v1);
14138 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14139 break;
14140 case OPC_EXTR_S_H:
14141 tcg_gen_movi_tl(t0, v2);
14142 tcg_gen_movi_tl(t1, v1);
14143 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14144 break;
14145 case OPC_EXTRV_S_H:
14146 tcg_gen_movi_tl(t0, v2);
14147 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14148 break;
14149 case OPC_EXTRV_W:
14150 tcg_gen_movi_tl(t0, v2);
14151 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14152 break;
14153 case OPC_EXTRV_R_W:
14154 tcg_gen_movi_tl(t0, v2);
14155 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14156 break;
14157 case OPC_EXTRV_RS_W:
14158 tcg_gen_movi_tl(t0, v2);
14159 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14160 break;
14161 case OPC_EXTP:
14162 tcg_gen_movi_tl(t0, v2);
14163 tcg_gen_movi_tl(t1, v1);
14164 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14165 break;
14166 case OPC_EXTPV:
14167 tcg_gen_movi_tl(t0, v2);
14168 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14169 break;
14170 case OPC_EXTPDP:
14171 tcg_gen_movi_tl(t0, v2);
14172 tcg_gen_movi_tl(t1, v1);
14173 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14174 break;
14175 case OPC_EXTPDPV:
14176 tcg_gen_movi_tl(t0, v2);
14177 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14178 break;
14179 case OPC_SHILO:
14180 imm = (ctx->opcode >> 20) & 0x3F;
14181 tcg_gen_movi_tl(t0, ret);
14182 tcg_gen_movi_tl(t1, imm);
14183 gen_helper_shilo(t0, t1, cpu_env);
14184 break;
14185 case OPC_SHILOV:
14186 tcg_gen_movi_tl(t0, ret);
14187 gen_helper_shilo(t0, v1_t, cpu_env);
14188 break;
14189 case OPC_MTHLIP:
14190 tcg_gen_movi_tl(t0, ret);
14191 gen_helper_mthlip(t0, v1_t, cpu_env);
14192 break;
14193 case OPC_WRDSP:
14194 imm = (ctx->opcode >> 11) & 0x3FF;
14195 tcg_gen_movi_tl(t0, imm);
14196 gen_helper_wrdsp(v1_t, t0, cpu_env);
14197 break;
14198 case OPC_RDDSP:
14199 imm = (ctx->opcode >> 16) & 0x03FF;
14200 tcg_gen_movi_tl(t0, imm);
14201 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14202 break;
14203 }
14204 break;
14205#ifdef TARGET_MIPS64
14206 case OPC_DEXTR_W_DSP:
14207 check_dsp(ctx);
14208 switch (op2) {
14209 case OPC_DMTHLIP:
14210 tcg_gen_movi_tl(t0, ret);
14211 gen_helper_dmthlip(v1_t, t0, cpu_env);
14212 break;
14213 case OPC_DSHILO:
14214 {
14215 int shift = (ctx->opcode >> 19) & 0x7F;
14216 int ac = (ctx->opcode >> 11) & 0x03;
14217 tcg_gen_movi_tl(t0, shift);
14218 tcg_gen_movi_tl(t1, ac);
14219 gen_helper_dshilo(t0, t1, cpu_env);
14220 break;
14221 }
14222 case OPC_DSHILOV:
14223 {
14224 int ac = (ctx->opcode >> 11) & 0x03;
14225 tcg_gen_movi_tl(t0, ac);
14226 gen_helper_dshilo(v1_t, t0, cpu_env);
14227 break;
14228 }
14229 case OPC_DEXTP:
14230 tcg_gen_movi_tl(t0, v2);
14231 tcg_gen_movi_tl(t1, v1);
14232
14233 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14234 break;
14235 case OPC_DEXTPV:
14236 tcg_gen_movi_tl(t0, v2);
14237 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14238 break;
14239 case OPC_DEXTPDP:
14240 tcg_gen_movi_tl(t0, v2);
14241 tcg_gen_movi_tl(t1, v1);
14242 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14243 break;
14244 case OPC_DEXTPDPV:
14245 tcg_gen_movi_tl(t0, v2);
14246 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14247 break;
14248 case OPC_DEXTR_L:
14249 tcg_gen_movi_tl(t0, v2);
14250 tcg_gen_movi_tl(t1, v1);
14251 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14252 break;
14253 case OPC_DEXTR_R_L:
14254 tcg_gen_movi_tl(t0, v2);
14255 tcg_gen_movi_tl(t1, v1);
14256 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14257 break;
14258 case OPC_DEXTR_RS_L:
14259 tcg_gen_movi_tl(t0, v2);
14260 tcg_gen_movi_tl(t1, v1);
14261 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14262 break;
14263 case OPC_DEXTR_W:
14264 tcg_gen_movi_tl(t0, v2);
14265 tcg_gen_movi_tl(t1, v1);
14266 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14267 break;
14268 case OPC_DEXTR_R_W:
14269 tcg_gen_movi_tl(t0, v2);
14270 tcg_gen_movi_tl(t1, v1);
14271 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14272 break;
14273 case OPC_DEXTR_RS_W:
14274 tcg_gen_movi_tl(t0, v2);
14275 tcg_gen_movi_tl(t1, v1);
14276 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14277 break;
14278 case OPC_DEXTR_S_H:
14279 tcg_gen_movi_tl(t0, v2);
14280 tcg_gen_movi_tl(t1, v1);
14281 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14282 break;
14283 case OPC_DEXTRV_S_H:
14284 tcg_gen_movi_tl(t0, v2);
14285 tcg_gen_movi_tl(t1, v1);
14286 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14287 break;
14288 case OPC_DEXTRV_L:
14289 tcg_gen_movi_tl(t0, v2);
14290 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14291 break;
14292 case OPC_DEXTRV_R_L:
14293 tcg_gen_movi_tl(t0, v2);
14294 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14295 break;
14296 case OPC_DEXTRV_RS_L:
14297 tcg_gen_movi_tl(t0, v2);
14298 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14299 break;
14300 case OPC_DEXTRV_W:
14301 tcg_gen_movi_tl(t0, v2);
14302 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14303 break;
14304 case OPC_DEXTRV_R_W:
14305 tcg_gen_movi_tl(t0, v2);
14306 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14307 break;
14308 case OPC_DEXTRV_RS_W:
14309 tcg_gen_movi_tl(t0, v2);
14310 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14311 break;
14312 }
14313 break;
14314#endif
14315 }
14316
14317 tcg_temp_free(t0);
14318 tcg_temp_free(t1);
14319 tcg_temp_free(v1_t);
14320 tcg_temp_free(v2_t);
14321
14322 (void)opn; /* avoid a compiler warning */
14323 MIPS_DEBUG("%s", opn);
14324}
14325
9b1a1d68
JL
14326/* End MIPSDSP functions. */
14327
7db13fae 14328static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
14329{
14330 int32_t offset;
14331 int rs, rt, rd, sa;
14332 uint32_t op, op1, op2;
14333 int16_t imm;
14334
14335 /* make sure instructions are on a word boundary */
14336 if (ctx->pc & 0x3) {
14337 env->CP0_BadVAddr = ctx->pc;
14338 generate_exception(ctx, EXCP_AdEL);
14339 return;
14340 }
14341
14342 /* Handle blikely not taken case */
14343 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14344 int l1 = gen_new_label();
14345
14346 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14347 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14348 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14349 gen_goto_tb(ctx, 1, ctx->pc + 4);
14350 gen_set_label(l1);
14351 }
14352
fdefe51c 14353 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14354 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14355 }
3c824109
NF
14356
14357 op = MASK_OP_MAJOR(ctx->opcode);
14358 rs = (ctx->opcode >> 21) & 0x1f;
14359 rt = (ctx->opcode >> 16) & 0x1f;
14360 rd = (ctx->opcode >> 11) & 0x1f;
14361 sa = (ctx->opcode >> 6) & 0x1f;
14362 imm = (int16_t)ctx->opcode;
14363 switch (op) {
7a387fff
TS
14364 case OPC_SPECIAL:
14365 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14366 switch (op1) {
324d9e32
AJ
14367 case OPC_SLL: /* Shift with immediate */
14368 case OPC_SRA:
d75c135e 14369 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14370 break;
ea63e2c3
NF
14371 case OPC_SRL:
14372 switch ((ctx->opcode >> 21) & 0x1f) {
14373 case 1:
14374 /* rotr is decoded as srl on non-R2 CPUs */
d75c135e 14375 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14376 op1 = OPC_ROTR;
14377 }
14378 /* Fallthrough */
14379 case 0:
d75c135e 14380 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14381 break;
14382 default:
14383 generate_exception(ctx, EXCP_RI);
14384 break;
14385 }
14386 break;
460f00c4
AJ
14387 case OPC_MOVN: /* Conditional move */
14388 case OPC_MOVZ:
d75c135e 14389 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
aa8f4009 14390 INSN_LOONGSON2E | INSN_LOONGSON2F);
d75c135e 14391 gen_cond_move(ctx, op1, rd, rs, rt);
460f00c4
AJ
14392 break;
14393 case OPC_ADD ... OPC_SUBU:
d75c135e 14394 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14395 break;
460f00c4 14396 case OPC_SLLV: /* Shifts */
460f00c4 14397 case OPC_SRAV:
d75c135e 14398 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14399 break;
ea63e2c3
NF
14400 case OPC_SRLV:
14401 switch ((ctx->opcode >> 6) & 0x1f) {
14402 case 1:
14403 /* rotrv is decoded as srlv on non-R2 CPUs */
d75c135e 14404 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14405 op1 = OPC_ROTRV;
14406 }
14407 /* Fallthrough */
14408 case 0:
d75c135e 14409 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14410 break;
14411 default:
14412 generate_exception(ctx, EXCP_RI);
14413 break;
14414 }
14415 break;
460f00c4
AJ
14416 case OPC_SLT: /* Set on less than */
14417 case OPC_SLTU:
d75c135e 14418 gen_slt(ctx, op1, rd, rs, rt);
460f00c4
AJ
14419 break;
14420 case OPC_AND: /* Logic*/
14421 case OPC_OR:
14422 case OPC_NOR:
14423 case OPC_XOR:
d75c135e 14424 gen_logic(ctx, op1, rd, rs, rt);
460f00c4 14425 break;
7a387fff 14426 case OPC_MULT ... OPC_DIVU:
e9c71dd1 14427 if (sa) {
d75c135e 14428 check_insn(ctx, INSN_VR54XX);
e9c71dd1
TS
14429 op1 = MASK_MUL_VR54XX(ctx->opcode);
14430 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14431 } else
14432 gen_muldiv(ctx, op1, rs, rt);
7a387fff
TS
14433 break;
14434 case OPC_JR ... OPC_JALR:
7dca4ad0 14435 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061
NF
14436 *is_branch = 1;
14437 break;
7a387fff
TS
14438 case OPC_TGE ... OPC_TEQ: /* Traps */
14439 case OPC_TNE:
14440 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14441 break;
7a387fff
TS
14442 case OPC_MFHI: /* Move from HI/LO */
14443 case OPC_MFLO:
14444 gen_HILO(ctx, op1, rd);
6af0bf9c 14445 break;
7a387fff
TS
14446 case OPC_MTHI:
14447 case OPC_MTLO: /* Move to HI/LO */
14448 gen_HILO(ctx, op1, rs);
6af0bf9c 14449 break;
b48cfdff
TS
14450 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14451#ifdef MIPS_STRICT_STANDARD
14452 MIPS_INVAL("PMON / selsl");
14453 generate_exception(ctx, EXCP_RI);
14454#else
895c2d04 14455 gen_helper_0e0i(pmon, sa);
b48cfdff 14456#endif
7a387fff
TS
14457 break;
14458 case OPC_SYSCALL:
6af0bf9c 14459 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14460 ctx->bstate = BS_STOP;
6af0bf9c 14461 break;
7a387fff 14462 case OPC_BREAK:
6af0bf9c
FB
14463 generate_exception(ctx, EXCP_BREAK);
14464 break;
b48cfdff
TS
14465 case OPC_SPIM:
14466#ifdef MIPS_STRICT_STANDARD
14467 MIPS_INVAL("SPIM");
14468 generate_exception(ctx, EXCP_RI);
14469#else
7a387fff
TS
14470 /* Implemented as RI exception for now. */
14471 MIPS_INVAL("spim (unofficial)");
14472 generate_exception(ctx, EXCP_RI);
b48cfdff 14473#endif
6af0bf9c 14474 break;
7a387fff 14475 case OPC_SYNC:
ead9360e 14476 /* Treat as NOP. */
6af0bf9c 14477 break;
4ad40f36 14478
7a387fff 14479 case OPC_MOVCI:
d75c135e 14480 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14481 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14482 check_cp1_enabled(ctx);
36d23958
TS
14483 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14484 (ctx->opcode >> 16) & 1);
14485 } else {
e397ee33 14486 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14487 }
4ad40f36
FB
14488 break;
14489
d26bc211 14490#if defined(TARGET_MIPS64)
7a387fff
TS
14491 /* MIPS64 specific opcodes */
14492 case OPC_DSLL:
324d9e32 14493 case OPC_DSRA:
7a387fff 14494 case OPC_DSLL32:
324d9e32 14495 case OPC_DSRA32:
d75c135e 14496 check_insn(ctx, ISA_MIPS3);
e189e748 14497 check_mips_64(ctx);
d75c135e 14498 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14499 break;
ea63e2c3
NF
14500 case OPC_DSRL:
14501 switch ((ctx->opcode >> 21) & 0x1f) {
14502 case 1:
14503 /* drotr is decoded as dsrl on non-R2 CPUs */
d75c135e 14504 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14505 op1 = OPC_DROTR;
14506 }
14507 /* Fallthrough */
14508 case 0:
d75c135e 14509 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14510 check_mips_64(ctx);
d75c135e 14511 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14512 break;
14513 default:
14514 generate_exception(ctx, EXCP_RI);
14515 break;
14516 }
14517 break;
14518 case OPC_DSRL32:
14519 switch ((ctx->opcode >> 21) & 0x1f) {
14520 case 1:
14521 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
d75c135e 14522 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14523 op1 = OPC_DROTR32;
14524 }
14525 /* Fallthrough */
14526 case 0:
d75c135e 14527 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14528 check_mips_64(ctx);
d75c135e 14529 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14530 break;
14531 default:
14532 generate_exception(ctx, EXCP_RI);
14533 break;
14534 }
14535 break;
7a387fff 14536 case OPC_DADD ... OPC_DSUBU:
d75c135e 14537 check_insn(ctx, ISA_MIPS3);
e189e748 14538 check_mips_64(ctx);
d75c135e 14539 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14540 break;
460f00c4
AJ
14541 case OPC_DSLLV:
14542 case OPC_DSRAV:
d75c135e 14543 check_insn(ctx, ISA_MIPS3);
460f00c4 14544 check_mips_64(ctx);
d75c135e 14545 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14546 break;
ea63e2c3
NF
14547 case OPC_DSRLV:
14548 switch ((ctx->opcode >> 6) & 0x1f) {
14549 case 1:
14550 /* drotrv is decoded as dsrlv on non-R2 CPUs */
d75c135e 14551 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14552 op1 = OPC_DROTRV;
14553 }
14554 /* Fallthrough */
14555 case 0:
d75c135e 14556 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14557 check_mips_64(ctx);
d75c135e 14558 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14559 break;
14560 default:
14561 generate_exception(ctx, EXCP_RI);
14562 break;
14563 }
14564 break;
7a387fff 14565 case OPC_DMULT ... OPC_DDIVU:
d75c135e 14566 check_insn(ctx, ISA_MIPS3);
e189e748 14567 check_mips_64(ctx);
7a387fff
TS
14568 gen_muldiv(ctx, op1, rs, rt);
14569 break;
6af0bf9c
FB
14570#endif
14571 default: /* Invalid */
14572 MIPS_INVAL("special");
14573 generate_exception(ctx, EXCP_RI);
14574 break;
14575 }
14576 break;
7a387fff
TS
14577 case OPC_SPECIAL2:
14578 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14579 switch (op1) {
7a387fff
TS
14580 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14581 case OPC_MSUB ... OPC_MSUBU:
d75c135e 14582 check_insn(ctx, ISA_MIPS32);
7a387fff 14583 gen_muldiv(ctx, op1, rs, rt);
6af0bf9c 14584 break;
7a387fff 14585 case OPC_MUL:
d75c135e 14586 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 14587 break;
20e1fb52
AJ
14588 case OPC_CLO:
14589 case OPC_CLZ:
d75c135e 14590 check_insn(ctx, ISA_MIPS32);
7a387fff 14591 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14592 break;
7a387fff 14593 case OPC_SDBBP:
6af0bf9c
FB
14594 /* XXX: not clear which exception should be raised
14595 * when in debug mode...
14596 */
d75c135e 14597 check_insn(ctx, ISA_MIPS32);
6af0bf9c
FB
14598 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14599 generate_exception(ctx, EXCP_DBp);
14600 } else {
14601 generate_exception(ctx, EXCP_DBp);
14602 }
ead9360e 14603 /* Treat as NOP. */
6af0bf9c 14604 break;
161f85e6
AJ
14605 case OPC_DIV_G_2F:
14606 case OPC_DIVU_G_2F:
14607 case OPC_MULT_G_2F:
14608 case OPC_MULTU_G_2F:
14609 case OPC_MOD_G_2F:
14610 case OPC_MODU_G_2F:
d75c135e 14611 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14612 gen_loongson_integer(ctx, op1, rd, rs, rt);
14613 break;
d26bc211 14614#if defined(TARGET_MIPS64)
20e1fb52
AJ
14615 case OPC_DCLO:
14616 case OPC_DCLZ:
d75c135e 14617 check_insn(ctx, ISA_MIPS64);
e189e748 14618 check_mips_64(ctx);
7a387fff
TS
14619 gen_cl(ctx, op1, rd, rs);
14620 break;
161f85e6
AJ
14621 case OPC_DMULT_G_2F:
14622 case OPC_DMULTU_G_2F:
14623 case OPC_DDIV_G_2F:
14624 case OPC_DDIVU_G_2F:
14625 case OPC_DMOD_G_2F:
14626 case OPC_DMODU_G_2F:
d75c135e 14627 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14628 gen_loongson_integer(ctx, op1, rd, rs, rt);
14629 break;
7a387fff 14630#endif
6af0bf9c
FB
14631 default: /* Invalid */
14632 MIPS_INVAL("special2");
14633 generate_exception(ctx, EXCP_RI);
14634 break;
14635 }
14636 break;
7a387fff 14637 case OPC_SPECIAL3:
2b0233ab
TS
14638 op1 = MASK_SPECIAL3(ctx->opcode);
14639 switch (op1) {
14640 case OPC_EXT:
14641 case OPC_INS:
d75c135e 14642 check_insn(ctx, ISA_MIPS32R2);
2b0233ab
TS
14643 gen_bitops(ctx, op1, rt, rs, sa, rd);
14644 break;
14645 case OPC_BSHFL:
d75c135e 14646 check_insn(ctx, ISA_MIPS32R2);
2b0233ab 14647 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14648 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14649 break;
1579a72e 14650 case OPC_RDHWR:
d75c135e 14651 gen_rdhwr(ctx, rt, rd);
1579a72e 14652 break;
ead9360e 14653 case OPC_FORK:
d75c135e 14654 check_insn(ctx, ASE_MT);
6c5c1e20 14655 {
35fbce2c
AJ
14656 TCGv t0 = tcg_temp_new();
14657 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14658
14659 gen_load_gpr(t0, rt);
14660 gen_load_gpr(t1, rs);
a7812ae4 14661 gen_helper_fork(t0, t1);
6c5c1e20
TS
14662 tcg_temp_free(t0);
14663 tcg_temp_free(t1);
14664 }
ead9360e
TS
14665 break;
14666 case OPC_YIELD:
d75c135e 14667 check_insn(ctx, ASE_MT);
6c5c1e20 14668 {
35fbce2c 14669 TCGv t0 = tcg_temp_new();
6c5c1e20 14670
35fbce2c 14671 save_cpu_state(ctx, 1);
6c5c1e20 14672 gen_load_gpr(t0, rs);
895c2d04 14673 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14674 gen_store_gpr(t0, rd);
14675 tcg_temp_free(t0);
14676 }
ead9360e 14677 break;
161f85e6 14678 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14679 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14680 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14681 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14682 * the same mask and op1. */
d75c135e 14683 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
461c08df
JL
14684 op2 = MASK_ADDUH_QB(ctx->opcode);
14685 switch (op2) {
14686 case OPC_ADDUH_QB:
14687 case OPC_ADDUH_R_QB:
14688 case OPC_ADDQH_PH:
14689 case OPC_ADDQH_R_PH:
14690 case OPC_ADDQH_W:
14691 case OPC_ADDQH_R_W:
14692 case OPC_SUBUH_QB:
14693 case OPC_SUBUH_R_QB:
14694 case OPC_SUBQH_PH:
14695 case OPC_SUBQH_R_PH:
14696 case OPC_SUBQH_W:
14697 case OPC_SUBQH_R_W:
14698 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14699 break;
a22260ae
JL
14700 case OPC_MUL_PH:
14701 case OPC_MUL_S_PH:
14702 case OPC_MULQ_S_W:
14703 case OPC_MULQ_RS_W:
14704 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14705 break;
461c08df
JL
14706 default:
14707 MIPS_INVAL("MASK ADDUH.QB");
14708 generate_exception(ctx, EXCP_RI);
14709 break;
14710 }
d75c135e 14711 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
461c08df
JL
14712 gen_loongson_integer(ctx, op1, rd, rs, rt);
14713 } else {
14714 generate_exception(ctx, EXCP_RI);
14715 }
161f85e6 14716 break;
9b1a1d68
JL
14717 case OPC_LX_DSP:
14718 op2 = MASK_LX(ctx->opcode);
14719 switch (op2) {
14720#if defined(TARGET_MIPS64)
14721 case OPC_LDX:
14722#endif
14723 case OPC_LBUX:
14724 case OPC_LHX:
14725 case OPC_LWX:
d75c135e 14726 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
9b1a1d68
JL
14727 break;
14728 default: /* Invalid */
14729 MIPS_INVAL("MASK LX");
14730 generate_exception(ctx, EXCP_RI);
14731 break;
14732 }
14733 break;
461c08df
JL
14734 case OPC_ABSQ_S_PH_DSP:
14735 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14736 switch (op2) {
14737 case OPC_ABSQ_S_QB:
14738 case OPC_ABSQ_S_PH:
14739 case OPC_ABSQ_S_W:
14740 case OPC_PRECEQ_W_PHL:
14741 case OPC_PRECEQ_W_PHR:
14742 case OPC_PRECEQU_PH_QBL:
14743 case OPC_PRECEQU_PH_QBR:
14744 case OPC_PRECEQU_PH_QBLA:
14745 case OPC_PRECEQU_PH_QBRA:
14746 case OPC_PRECEU_PH_QBL:
14747 case OPC_PRECEU_PH_QBR:
14748 case OPC_PRECEU_PH_QBLA:
14749 case OPC_PRECEU_PH_QBRA:
14750 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14751 break;
1cb6686c
JL
14752 case OPC_BITREV:
14753 case OPC_REPL_QB:
14754 case OPC_REPLV_QB:
14755 case OPC_REPL_PH:
14756 case OPC_REPLV_PH:
d75c135e 14757 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14758 break;
461c08df
JL
14759 default:
14760 MIPS_INVAL("MASK ABSQ_S.PH");
14761 generate_exception(ctx, EXCP_RI);
14762 break;
14763 }
14764 break;
14765 case OPC_ADDU_QB_DSP:
14766 op2 = MASK_ADDU_QB(ctx->opcode);
14767 switch (op2) {
14768 case OPC_ADDQ_PH:
14769 case OPC_ADDQ_S_PH:
14770 case OPC_ADDQ_S_W:
14771 case OPC_ADDU_QB:
14772 case OPC_ADDU_S_QB:
14773 case OPC_ADDU_PH:
14774 case OPC_ADDU_S_PH:
14775 case OPC_SUBQ_PH:
14776 case OPC_SUBQ_S_PH:
14777 case OPC_SUBQ_S_W:
14778 case OPC_SUBU_QB:
14779 case OPC_SUBU_S_QB:
14780 case OPC_SUBU_PH:
14781 case OPC_SUBU_S_PH:
14782 case OPC_ADDSC:
14783 case OPC_ADDWC:
14784 case OPC_MODSUB:
14785 case OPC_RADDU_W_QB:
14786 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14787 break;
a22260ae
JL
14788 case OPC_MULEU_S_PH_QBL:
14789 case OPC_MULEU_S_PH_QBR:
14790 case OPC_MULQ_RS_PH:
14791 case OPC_MULEQ_S_W_PHL:
14792 case OPC_MULEQ_S_W_PHR:
14793 case OPC_MULQ_S_PH:
14794 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14795 break;
461c08df
JL
14796 default: /* Invalid */
14797 MIPS_INVAL("MASK ADDU.QB");
14798 generate_exception(ctx, EXCP_RI);
14799 break;
14800
14801 }
14802 break;
14803 case OPC_CMPU_EQ_QB_DSP:
14804 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14805 switch (op2) {
14806 case OPC_PRECR_SRA_PH_W:
14807 case OPC_PRECR_SRA_R_PH_W:
14808 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14809 break;
14810 case OPC_PRECR_QB_PH:
14811 case OPC_PRECRQ_QB_PH:
14812 case OPC_PRECRQ_PH_W:
14813 case OPC_PRECRQ_RS_PH_W:
14814 case OPC_PRECRQU_S_QB_PH:
14815 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14816 break;
26690560
JL
14817 case OPC_CMPU_EQ_QB:
14818 case OPC_CMPU_LT_QB:
14819 case OPC_CMPU_LE_QB:
14820 case OPC_CMP_EQ_PH:
14821 case OPC_CMP_LT_PH:
14822 case OPC_CMP_LE_PH:
14823 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14824 break;
14825 case OPC_CMPGU_EQ_QB:
14826 case OPC_CMPGU_LT_QB:
14827 case OPC_CMPGU_LE_QB:
14828 case OPC_CMPGDU_EQ_QB:
14829 case OPC_CMPGDU_LT_QB:
14830 case OPC_CMPGDU_LE_QB:
14831 case OPC_PICK_QB:
14832 case OPC_PICK_PH:
14833 case OPC_PACKRL_PH:
14834 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14835 break;
461c08df
JL
14836 default: /* Invalid */
14837 MIPS_INVAL("MASK CMPU.EQ.QB");
14838 generate_exception(ctx, EXCP_RI);
14839 break;
14840 }
14841 break;
77c5fa8b
JL
14842 case OPC_SHLL_QB_DSP:
14843 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14844 break;
a22260ae
JL
14845 case OPC_DPA_W_PH_DSP:
14846 op2 = MASK_DPA_W_PH(ctx->opcode);
14847 switch (op2) {
14848 case OPC_DPAU_H_QBL:
14849 case OPC_DPAU_H_QBR:
14850 case OPC_DPSU_H_QBL:
14851 case OPC_DPSU_H_QBR:
14852 case OPC_DPA_W_PH:
14853 case OPC_DPAX_W_PH:
14854 case OPC_DPAQ_S_W_PH:
14855 case OPC_DPAQX_S_W_PH:
14856 case OPC_DPAQX_SA_W_PH:
14857 case OPC_DPS_W_PH:
14858 case OPC_DPSX_W_PH:
14859 case OPC_DPSQ_S_W_PH:
14860 case OPC_DPSQX_S_W_PH:
14861 case OPC_DPSQX_SA_W_PH:
14862 case OPC_MULSAQ_S_W_PH:
14863 case OPC_DPAQ_SA_L_W:
14864 case OPC_DPSQ_SA_L_W:
14865 case OPC_MAQ_S_W_PHL:
14866 case OPC_MAQ_S_W_PHR:
14867 case OPC_MAQ_SA_W_PHL:
14868 case OPC_MAQ_SA_W_PHR:
14869 case OPC_MULSA_W_PH:
14870 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14871 break;
14872 default: /* Invalid */
14873 MIPS_INVAL("MASK DPAW.PH");
14874 generate_exception(ctx, EXCP_RI);
14875 break;
14876 }
14877 break;
1cb6686c
JL
14878 case OPC_INSV_DSP:
14879 op2 = MASK_INSV(ctx->opcode);
14880 switch (op2) {
14881 case OPC_INSV:
14882 check_dsp(ctx);
14883 {
14884 TCGv t0, t1;
14885
14886 if (rt == 0) {
14887 MIPS_DEBUG("NOP");
14888 break;
14889 }
14890
14891 t0 = tcg_temp_new();
14892 t1 = tcg_temp_new();
14893
14894 gen_load_gpr(t0, rt);
14895 gen_load_gpr(t1, rs);
14896
14897 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14898
14899 tcg_temp_free(t0);
14900 tcg_temp_free(t1);
14901 break;
14902 }
14903 default: /* Invalid */
14904 MIPS_INVAL("MASK INSV");
14905 generate_exception(ctx, EXCP_RI);
14906 break;
14907 }
14908 break;
26690560
JL
14909 case OPC_APPEND_DSP:
14910 check_dspr2(ctx);
14911 op2 = MASK_APPEND(ctx->opcode);
14912 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14913 break;
b53371ed
JL
14914 case OPC_EXTR_W_DSP:
14915 op2 = MASK_EXTR_W(ctx->opcode);
14916 switch (op2) {
14917 case OPC_EXTR_W:
14918 case OPC_EXTR_R_W:
14919 case OPC_EXTR_RS_W:
14920 case OPC_EXTR_S_H:
14921 case OPC_EXTRV_S_H:
14922 case OPC_EXTRV_W:
14923 case OPC_EXTRV_R_W:
14924 case OPC_EXTRV_RS_W:
14925 case OPC_EXTP:
14926 case OPC_EXTPV:
14927 case OPC_EXTPDP:
14928 case OPC_EXTPDPV:
14929 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14930 break;
14931 case OPC_RDDSP:
14932 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14933 break;
14934 case OPC_SHILO:
14935 case OPC_SHILOV:
14936 case OPC_MTHLIP:
14937 case OPC_WRDSP:
14938 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14939 break;
14940 default: /* Invalid */
14941 MIPS_INVAL("MASK EXTR.W");
14942 generate_exception(ctx, EXCP_RI);
14943 break;
14944 }
14945 break;
d26bc211 14946#if defined(TARGET_MIPS64)
1579a72e
TS
14947 case OPC_DEXTM ... OPC_DEXT:
14948 case OPC_DINSM ... OPC_DINS:
d75c135e 14949 check_insn(ctx, ISA_MIPS64R2);
e189e748 14950 check_mips_64(ctx);
1579a72e 14951 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 14952 break;
1579a72e 14953 case OPC_DBSHFL:
d75c135e 14954 check_insn(ctx, ISA_MIPS64R2);
e189e748 14955 check_mips_64(ctx);
1579a72e 14956 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 14957 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 14958 break;
161f85e6
AJ
14959 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14960 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14961 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
d75c135e 14962 check_insn(ctx, INSN_LOONGSON2E);
161f85e6
AJ
14963 gen_loongson_integer(ctx, op1, rd, rs, rt);
14964 break;
461c08df
JL
14965 case OPC_ABSQ_S_QH_DSP:
14966 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14967 switch (op2) {
14968 case OPC_PRECEQ_L_PWL:
14969 case OPC_PRECEQ_L_PWR:
14970 case OPC_PRECEQ_PW_QHL:
14971 case OPC_PRECEQ_PW_QHR:
14972 case OPC_PRECEQ_PW_QHLA:
14973 case OPC_PRECEQ_PW_QHRA:
14974 case OPC_PRECEQU_QH_OBL:
14975 case OPC_PRECEQU_QH_OBR:
14976 case OPC_PRECEQU_QH_OBLA:
14977 case OPC_PRECEQU_QH_OBRA:
14978 case OPC_PRECEU_QH_OBL:
14979 case OPC_PRECEU_QH_OBR:
14980 case OPC_PRECEU_QH_OBLA:
14981 case OPC_PRECEU_QH_OBRA:
14982 case OPC_ABSQ_S_OB:
14983 case OPC_ABSQ_S_PW:
14984 case OPC_ABSQ_S_QH:
14985 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14986 break;
1cb6686c
JL
14987 case OPC_REPL_OB:
14988 case OPC_REPL_PW:
14989 case OPC_REPL_QH:
14990 case OPC_REPLV_OB:
14991 case OPC_REPLV_PW:
14992 case OPC_REPLV_QH:
d75c135e 14993 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14994 break;
461c08df
JL
14995 default: /* Invalid */
14996 MIPS_INVAL("MASK ABSQ_S.QH");
14997 generate_exception(ctx, EXCP_RI);
14998 break;
14999 }
15000 break;
15001 case OPC_ADDU_OB_DSP:
15002 op2 = MASK_ADDU_OB(ctx->opcode);
15003 switch (op2) {
15004 case OPC_RADDU_L_OB:
15005 case OPC_SUBQ_PW:
15006 case OPC_SUBQ_S_PW:
15007 case OPC_SUBQ_QH:
15008 case OPC_SUBQ_S_QH:
15009 case OPC_SUBU_OB:
15010 case OPC_SUBU_S_OB:
15011 case OPC_SUBU_QH:
15012 case OPC_SUBU_S_QH:
15013 case OPC_SUBUH_OB:
15014 case OPC_SUBUH_R_OB:
15015 case OPC_ADDQ_PW:
15016 case OPC_ADDQ_S_PW:
15017 case OPC_ADDQ_QH:
15018 case OPC_ADDQ_S_QH:
15019 case OPC_ADDU_OB:
15020 case OPC_ADDU_S_OB:
15021 case OPC_ADDU_QH:
15022 case OPC_ADDU_S_QH:
15023 case OPC_ADDUH_OB:
15024 case OPC_ADDUH_R_OB:
15025 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15026 break;
a22260ae
JL
15027 case OPC_MULEQ_S_PW_QHL:
15028 case OPC_MULEQ_S_PW_QHR:
15029 case OPC_MULEU_S_QH_OBL:
15030 case OPC_MULEU_S_QH_OBR:
15031 case OPC_MULQ_RS_QH:
15032 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15033 break;
461c08df
JL
15034 default: /* Invalid */
15035 MIPS_INVAL("MASK ADDU.OB");
15036 generate_exception(ctx, EXCP_RI);
15037 break;
15038 }
15039 break;
15040 case OPC_CMPU_EQ_OB_DSP:
15041 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15042 switch (op2) {
15043 case OPC_PRECR_SRA_QH_PW:
15044 case OPC_PRECR_SRA_R_QH_PW:
15045 /* Return value is rt. */
15046 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15047 break;
15048 case OPC_PRECR_OB_QH:
15049 case OPC_PRECRQ_OB_QH:
15050 case OPC_PRECRQ_PW_L:
15051 case OPC_PRECRQ_QH_PW:
15052 case OPC_PRECRQ_RS_QH_PW:
15053 case OPC_PRECRQU_S_OB_QH:
15054 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15055 break;
26690560
JL
15056 case OPC_CMPU_EQ_OB:
15057 case OPC_CMPU_LT_OB:
15058 case OPC_CMPU_LE_OB:
15059 case OPC_CMP_EQ_QH:
15060 case OPC_CMP_LT_QH:
15061 case OPC_CMP_LE_QH:
15062 case OPC_CMP_EQ_PW:
15063 case OPC_CMP_LT_PW:
15064 case OPC_CMP_LE_PW:
15065 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15066 break;
15067 case OPC_CMPGDU_EQ_OB:
15068 case OPC_CMPGDU_LT_OB:
15069 case OPC_CMPGDU_LE_OB:
15070 case OPC_CMPGU_EQ_OB:
15071 case OPC_CMPGU_LT_OB:
15072 case OPC_CMPGU_LE_OB:
15073 case OPC_PACKRL_PW:
15074 case OPC_PICK_OB:
15075 case OPC_PICK_PW:
15076 case OPC_PICK_QH:
15077 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15078 break;
461c08df
JL
15079 default: /* Invalid */
15080 MIPS_INVAL("MASK CMPU_EQ.OB");
15081 generate_exception(ctx, EXCP_RI);
15082 break;
15083 }
15084 break;
26690560
JL
15085 case OPC_DAPPEND_DSP:
15086 check_dspr2(ctx);
15087 op2 = MASK_DAPPEND(ctx->opcode);
15088 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15089 break;
b53371ed
JL
15090 case OPC_DEXTR_W_DSP:
15091 op2 = MASK_DEXTR_W(ctx->opcode);
15092 switch (op2) {
15093 case OPC_DEXTP:
15094 case OPC_DEXTPDP:
15095 case OPC_DEXTPDPV:
15096 case OPC_DEXTPV:
15097 case OPC_DEXTR_L:
15098 case OPC_DEXTR_R_L:
15099 case OPC_DEXTR_RS_L:
15100 case OPC_DEXTR_W:
15101 case OPC_DEXTR_R_W:
15102 case OPC_DEXTR_RS_W:
15103 case OPC_DEXTR_S_H:
15104 case OPC_DEXTRV_L:
15105 case OPC_DEXTRV_R_L:
15106 case OPC_DEXTRV_RS_L:
15107 case OPC_DEXTRV_S_H:
15108 case OPC_DEXTRV_W:
15109 case OPC_DEXTRV_R_W:
15110 case OPC_DEXTRV_RS_W:
15111 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15112 break;
15113 case OPC_DMTHLIP:
15114 case OPC_DSHILO:
15115 case OPC_DSHILOV:
15116 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15117 break;
15118 default: /* Invalid */
15119 MIPS_INVAL("MASK EXTR.W");
15120 generate_exception(ctx, EXCP_RI);
15121 break;
15122 }
15123 break;
a22260ae
JL
15124 case OPC_DPAQ_W_QH_DSP:
15125 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15126 switch (op2) {
15127 case OPC_DPAU_H_OBL:
15128 case OPC_DPAU_H_OBR:
15129 case OPC_DPSU_H_OBL:
15130 case OPC_DPSU_H_OBR:
15131 case OPC_DPA_W_QH:
15132 case OPC_DPAQ_S_W_QH:
15133 case OPC_DPS_W_QH:
15134 case OPC_DPSQ_S_W_QH:
15135 case OPC_MULSAQ_S_W_QH:
15136 case OPC_DPAQ_SA_L_PW:
15137 case OPC_DPSQ_SA_L_PW:
15138 case OPC_MULSAQ_S_L_PW:
15139 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15140 break;
15141 case OPC_MAQ_S_W_QHLL:
15142 case OPC_MAQ_S_W_QHLR:
15143 case OPC_MAQ_S_W_QHRL:
15144 case OPC_MAQ_S_W_QHRR:
15145 case OPC_MAQ_SA_W_QHLL:
15146 case OPC_MAQ_SA_W_QHLR:
15147 case OPC_MAQ_SA_W_QHRL:
15148 case OPC_MAQ_SA_W_QHRR:
15149 case OPC_MAQ_S_L_PWL:
15150 case OPC_MAQ_S_L_PWR:
15151 case OPC_DMADD:
15152 case OPC_DMADDU:
15153 case OPC_DMSUB:
15154 case OPC_DMSUBU:
15155 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15156 break;
15157 default: /* Invalid */
15158 MIPS_INVAL("MASK DPAQ.W.QH");
15159 generate_exception(ctx, EXCP_RI);
15160 break;
15161 }
15162 break;
1cb6686c
JL
15163 case OPC_DINSV_DSP:
15164 op2 = MASK_INSV(ctx->opcode);
15165 switch (op2) {
15166 case OPC_DINSV:
15167 {
15168 TCGv t0, t1;
15169
15170 if (rt == 0) {
15171 MIPS_DEBUG("NOP");
15172 break;
15173 }
15174 check_dsp(ctx);
15175
15176 t0 = tcg_temp_new();
15177 t1 = tcg_temp_new();
15178
15179 gen_load_gpr(t0, rt);
15180 gen_load_gpr(t1, rs);
15181
15182 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15183 break;
15184 }
15185 default: /* Invalid */
15186 MIPS_INVAL("MASK DINSV");
15187 generate_exception(ctx, EXCP_RI);
15188 break;
15189 }
15190 break;
77c5fa8b
JL
15191 case OPC_SHLL_OB_DSP:
15192 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15193 break;
7a387fff
TS
15194#endif
15195 default: /* Invalid */
15196 MIPS_INVAL("special3");
15197 generate_exception(ctx, EXCP_RI);
15198 break;
15199 }
15200 break;
15201 case OPC_REGIMM:
15202 op1 = MASK_REGIMM(ctx->opcode);
15203 switch (op1) {
15204 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15205 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15206 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061
NF
15207 *is_branch = 1;
15208 break;
7a387fff
TS
15209 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15210 case OPC_TNEI:
15211 gen_trap(ctx, op1, rs, -1, imm);
15212 break;
15213 case OPC_SYNCI:
d75c135e 15214 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15215 /* Treat as NOP. */
6af0bf9c 15216 break;
e45a93e2
JL
15217 case OPC_BPOSGE32: /* MIPS DSP branch */
15218#if defined(TARGET_MIPS64)
15219 case OPC_BPOSGE64:
15220#endif
15221 check_dsp(ctx);
15222 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15223 *is_branch = 1;
15224 break;
6af0bf9c 15225 default: /* Invalid */
923617a3 15226 MIPS_INVAL("regimm");
6af0bf9c
FB
15227 generate_exception(ctx, EXCP_RI);
15228 break;
15229 }
15230 break;
7a387fff 15231 case OPC_CP0:
387a8fe5 15232 check_cp0_enabled(ctx);
7a387fff 15233 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15234 switch (op1) {
7a387fff
TS
15235 case OPC_MFC0:
15236 case OPC_MTC0:
ead9360e
TS
15237 case OPC_MFTR:
15238 case OPC_MTTR:
d26bc211 15239#if defined(TARGET_MIPS64)
7a387fff
TS
15240 case OPC_DMFC0:
15241 case OPC_DMTC0:
15242#endif
f1aa6320 15243#ifndef CONFIG_USER_ONLY
932e71cd 15244 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15245#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15246 break;
15247 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15248#ifndef CONFIG_USER_ONLY
932e71cd 15249 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15250#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15251 break;
15252 case OPC_MFMC0:
8706c382 15253#ifndef CONFIG_USER_ONLY
932e71cd 15254 {
35fbce2c 15255 TCGv t0 = tcg_temp_new();
6c5c1e20 15256
0eaef5aa 15257 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15258 switch (op2) {
15259 case OPC_DMT:
d75c135e 15260 check_insn(ctx, ASE_MT);
9ed5726c 15261 gen_helper_dmt(t0);
35fbce2c 15262 gen_store_gpr(t0, rt);
6c5c1e20
TS
15263 break;
15264 case OPC_EMT:
d75c135e 15265 check_insn(ctx, ASE_MT);
9ed5726c 15266 gen_helper_emt(t0);
35fbce2c 15267 gen_store_gpr(t0, rt);
da80682b 15268 break;
6c5c1e20 15269 case OPC_DVPE:
d75c135e 15270 check_insn(ctx, ASE_MT);
895c2d04 15271 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15272 gen_store_gpr(t0, rt);
6c5c1e20
TS
15273 break;
15274 case OPC_EVPE:
d75c135e 15275 check_insn(ctx, ASE_MT);
895c2d04 15276 gen_helper_evpe(t0, cpu_env);
35fbce2c 15277 gen_store_gpr(t0, rt);
6c5c1e20
TS
15278 break;
15279 case OPC_DI:
d75c135e 15280 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15281 save_cpu_state(ctx, 1);
895c2d04 15282 gen_helper_di(t0, cpu_env);
35fbce2c 15283 gen_store_gpr(t0, rt);
6c5c1e20
TS
15284 /* Stop translation as we may have switched the execution mode */
15285 ctx->bstate = BS_STOP;
15286 break;
15287 case OPC_EI:
d75c135e 15288 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15289 save_cpu_state(ctx, 1);
895c2d04 15290 gen_helper_ei(t0, cpu_env);
35fbce2c 15291 gen_store_gpr(t0, rt);
6c5c1e20
TS
15292 /* Stop translation as we may have switched the execution mode */
15293 ctx->bstate = BS_STOP;
15294 break;
15295 default: /* Invalid */
15296 MIPS_INVAL("mfmc0");
15297 generate_exception(ctx, EXCP_RI);
15298 break;
15299 }
6c5c1e20 15300 tcg_temp_free(t0);
7a387fff 15301 }
0eaef5aa 15302#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15303 break;
7a387fff 15304 case OPC_RDPGPR:
d75c135e 15305 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15306 gen_load_srsgpr(rt, rd);
ead9360e 15307 break;
7a387fff 15308 case OPC_WRPGPR:
d75c135e 15309 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15310 gen_store_srsgpr(rt, rd);
38121543 15311 break;
6af0bf9c 15312 default:
923617a3 15313 MIPS_INVAL("cp0");
7a387fff 15314 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15315 break;
15316 }
15317 break;
324d9e32
AJ
15318 case OPC_ADDI: /* Arithmetic with immediate opcode */
15319 case OPC_ADDIU:
d75c135e 15320 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15321 break;
324d9e32
AJ
15322 case OPC_SLTI: /* Set on less than with immediate opcode */
15323 case OPC_SLTIU:
d75c135e 15324 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15325 break;
15326 case OPC_ANDI: /* Arithmetic with immediate opcode */
15327 case OPC_LUI:
15328 case OPC_ORI:
15329 case OPC_XORI:
d75c135e 15330 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15331 break;
7a387fff
TS
15332 case OPC_J ... OPC_JAL: /* Jump */
15333 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15334 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061
NF
15335 *is_branch = 1;
15336 break;
7a387fff
TS
15337 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15338 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15339 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061
NF
15340 *is_branch = 1;
15341 break;
7a387fff 15342 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15343 case OPC_LL:
d75c135e 15344 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15345 break;
7a387fff
TS
15346 case OPC_SB ... OPC_SW:
15347 case OPC_SWR:
5c13fdfd 15348 gen_st(ctx, op, rt, rs, imm);
7a387fff 15349 break;
d66c7132
AJ
15350 case OPC_SC:
15351 gen_st_cond(ctx, op, rt, rs, imm);
15352 break;
7a387fff 15353 case OPC_CACHE:
2e15497c 15354 check_cp0_enabled(ctx);
d75c135e 15355 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15356 /* Treat as NOP. */
34ae7b51 15357 break;
7a387fff 15358 case OPC_PREF:
d75c135e 15359 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15360 /* Treat as NOP. */
6af0bf9c 15361 break;
4ad40f36 15362
923617a3 15363 /* Floating point (COP1). */
7a387fff
TS
15364 case OPC_LWC1:
15365 case OPC_LDC1:
15366 case OPC_SWC1:
15367 case OPC_SDC1:
26ebe468 15368 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15369 break;
15370
7a387fff 15371 case OPC_CP1:
36d23958 15372 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15373 check_cp1_enabled(ctx);
36d23958
TS
15374 op1 = MASK_CP1(ctx->opcode);
15375 switch (op1) {
3a95e3a7
TS
15376 case OPC_MFHC1:
15377 case OPC_MTHC1:
d75c135e 15378 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
15379 case OPC_MFC1:
15380 case OPC_CFC1:
15381 case OPC_MTC1:
15382 case OPC_CTC1:
e189e748
TS
15383 gen_cp1(ctx, op1, rt, rd);
15384 break;
d26bc211 15385#if defined(TARGET_MIPS64)
36d23958
TS
15386 case OPC_DMFC1:
15387 case OPC_DMTC1:
d75c135e 15388 check_insn(ctx, ISA_MIPS3);
36d23958
TS
15389 gen_cp1(ctx, op1, rt, rd);
15390 break;
e189e748 15391#endif
fbcc6828
TS
15392 case OPC_BC1ANY2:
15393 case OPC_BC1ANY4:
b8aa4598 15394 check_cop1x(ctx);
d75c135e 15395 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
15396 /* fall through */
15397 case OPC_BC1:
d75c135e 15398 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15399 (rt >> 2) & 0x7, imm << 2);
c9602061
NF
15400 *is_branch = 1;
15401 break;
36d23958
TS
15402 case OPC_S_FMT:
15403 case OPC_D_FMT:
15404 case OPC_W_FMT:
15405 case OPC_L_FMT:
5a5012ec 15406 case OPC_PS_FMT:
bf4120ad 15407 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15408 (imm >> 8) & 0x7);
36d23958
TS
15409 break;
15410 default:
923617a3 15411 MIPS_INVAL("cp1");
e397ee33 15412 generate_exception (ctx, EXCP_RI);
36d23958
TS
15413 break;
15414 }
15415 } else {
15416 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15417 }
4ad40f36
FB
15418 break;
15419
15420 /* COP2. */
7a387fff
TS
15421 case OPC_LWC2:
15422 case OPC_LDC2:
15423 case OPC_SWC2:
15424 case OPC_SDC2:
7a387fff 15425 /* COP2: Not implemented. */
4ad40f36
FB
15426 generate_exception_err(ctx, EXCP_CpU, 2);
15427 break;
bd277fa1 15428 case OPC_CP2:
d75c135e 15429 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
15430 /* Note that these instructions use different fields. */
15431 gen_loongson_multimedia(ctx, sa, rd, rt);
15432 break;
4ad40f36 15433
7a387fff 15434 case OPC_CP3:
36d23958 15435 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15436 check_cp1_enabled(ctx);
36d23958
TS
15437 op1 = MASK_CP3(ctx->opcode);
15438 switch (op1) {
5a5012ec
TS
15439 case OPC_LWXC1:
15440 case OPC_LDXC1:
15441 case OPC_LUXC1:
15442 case OPC_SWXC1:
15443 case OPC_SDXC1:
15444 case OPC_SUXC1:
93b12ccc 15445 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15446 break;
e0c84da7 15447 case OPC_PREFX:
ead9360e 15448 /* Treat as NOP. */
e0c84da7 15449 break;
5a5012ec
TS
15450 case OPC_ALNV_PS:
15451 case OPC_MADD_S:
15452 case OPC_MADD_D:
15453 case OPC_MADD_PS:
15454 case OPC_MSUB_S:
15455 case OPC_MSUB_D:
15456 case OPC_MSUB_PS:
15457 case OPC_NMADD_S:
15458 case OPC_NMADD_D:
15459 case OPC_NMADD_PS:
15460 case OPC_NMSUB_S:
15461 case OPC_NMSUB_D:
15462 case OPC_NMSUB_PS:
15463 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15464 break;
36d23958 15465 default:
923617a3 15466 MIPS_INVAL("cp3");
e397ee33 15467 generate_exception (ctx, EXCP_RI);
36d23958
TS
15468 break;
15469 }
15470 } else {
e397ee33 15471 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15472 }
4ad40f36
FB
15473 break;
15474
d26bc211 15475#if defined(TARGET_MIPS64)
7a387fff
TS
15476 /* MIPS64 opcodes */
15477 case OPC_LWU:
15478 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15479 case OPC_LLD:
15480 case OPC_LD:
d75c135e 15481 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15482 check_mips_64(ctx);
d75c135e 15483 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
15484 break;
15485 case OPC_SDL ... OPC_SDR:
7a387fff 15486 case OPC_SD:
d75c135e 15487 check_insn(ctx, ISA_MIPS3);
e189e748 15488 check_mips_64(ctx);
5c13fdfd 15489 gen_st(ctx, op, rt, rs, imm);
7a387fff 15490 break;
d66c7132 15491 case OPC_SCD:
d75c135e 15492 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
15493 check_mips_64(ctx);
15494 gen_st_cond(ctx, op, rt, rs, imm);
15495 break;
324d9e32
AJ
15496 case OPC_DADDI:
15497 case OPC_DADDIU:
d75c135e 15498 check_insn(ctx, ISA_MIPS3);
e189e748 15499 check_mips_64(ctx);
d75c135e 15500 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15501 break;
6af0bf9c 15502#endif
7a387fff 15503 case OPC_JALX:
d75c135e 15504 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15505 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15506 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15507 *is_branch = 1;
15508 break;
7a387fff 15509 case OPC_MDMX:
d75c135e 15510 check_insn(ctx, ASE_MDMX);
7a387fff 15511 /* MDMX: Not implemented. */
6af0bf9c 15512 default: /* Invalid */
923617a3 15513 MIPS_INVAL("major opcode");
6af0bf9c
FB
15514 generate_exception(ctx, EXCP_RI);
15515 break;
15516 }
6af0bf9c
FB
15517}
15518
2cfc5f17 15519static inline void
7db13fae 15520gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
820e00f2 15521 int search_pc)
6af0bf9c 15522{
278d0702 15523 DisasContext ctx;
6af0bf9c
FB
15524 target_ulong pc_start;
15525 uint16_t *gen_opc_end;
a1d1bb31 15526 CPUBreakpoint *bp;
6af0bf9c 15527 int j, lj = -1;
2e70f6ef
PB
15528 int num_insns;
15529 int max_insns;
c9602061
NF
15530 int insn_bytes;
15531 int is_branch;
6af0bf9c 15532
93fcfe39
AL
15533 if (search_pc)
15534 qemu_log("search pc %d\n", search_pc);
4ad40f36 15535
6af0bf9c 15536 pc_start = tb->pc;
92414b31 15537 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15538 ctx.pc = pc_start;
4ad40f36 15539 ctx.saved_pc = -1;
7b270ef2 15540 ctx.singlestep_enabled = env->singlestep_enabled;
d75c135e 15541 ctx.insn_flags = env->insn_flags;
6af0bf9c
FB
15542 ctx.tb = tb;
15543 ctx.bstate = BS_NONE;
4ad40f36 15544 /* Restore delay slot state from the tb context. */
c068688b 15545 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15546 restore_cpu_state(env, &ctx);
932e71cd 15547#ifdef CONFIG_USER_ONLY
0eaef5aa 15548 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15549#else
0eaef5aa 15550 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15551#endif
2e70f6ef
PB
15552 num_insns = 0;
15553 max_insns = tb->cflags & CF_COUNT_MASK;
15554 if (max_insns == 0)
15555 max_insns = CF_COUNT_MASK;
d12d51d5 15556 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
2e70f6ef 15557 gen_icount_start();
faf7aaa9 15558 while (ctx.bstate == BS_NONE) {
72cf2d4f
BS
15559 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15560 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 15561 if (bp->pc == ctx.pc) {
278d0702 15562 save_cpu_state(&ctx, 1);
4ad40f36 15563 ctx.bstate = BS_BRANCH;
895c2d04 15564 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15565 /* Include the breakpoint location or the tb won't
15566 * be flushed when it must be. */
15567 ctx.pc += 4;
4ad40f36
FB
15568 goto done_generating;
15569 }
15570 }
15571 }
15572
6af0bf9c 15573 if (search_pc) {
92414b31 15574 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15575 if (lj < j) {
15576 lj++;
15577 while (lj < j)
ab1103de 15578 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15579 }
25983cad 15580 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15581 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15582 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15583 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15584 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15585 }
2e70f6ef
PB
15586 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15587 gen_io_start();
c9602061
NF
15588
15589 is_branch = 0;
364d4831 15590 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15591 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061
NF
15592 insn_bytes = 4;
15593 decode_opc(env, &ctx, &is_branch);
d75c135e 15594 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 15595 ctx.opcode = cpu_lduw_code(env, ctx.pc);
3c824109 15596 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
d75c135e 15597 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 15598 ctx.opcode = cpu_lduw_code(env, ctx.pc);
364d4831 15599 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
c9602061
NF
15600 } else {
15601 generate_exception(&ctx, EXCP_RI);
3c824109 15602 ctx.bstate = BS_STOP;
c9602061
NF
15603 break;
15604 }
15605 if (!is_branch) {
d75c135e 15606 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
15607 }
15608 ctx.pc += insn_bytes;
15609
2e70f6ef 15610 num_insns++;
4ad40f36 15611
7b270ef2
NF
15612 /* Execute a branch and its delay slot as a single instruction.
15613 This is what GDB expects and is consistent with what the
15614 hardware does (e.g. if a delay slot instruction faults, the
15615 reported PC is the PC of the branch). */
15616 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
4ad40f36
FB
15617 break;
15618
6af0bf9c
FB
15619 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15620 break;
4ad40f36 15621
efd7f486 15622 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15623 break;
efd7f486 15624 }
faf7aaa9 15625
2e70f6ef
PB
15626 if (num_insns >= max_insns)
15627 break;
1b530a6d
AJ
15628
15629 if (singlestep)
15630 break;
6af0bf9c 15631 }
2e70f6ef
PB
15632 if (tb->cflags & CF_LAST_IO)
15633 gen_io_end();
7b270ef2 15634 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15635 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15636 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15637 } else {
6958549d 15638 switch (ctx.bstate) {
16c00cb2 15639 case BS_STOP:
df1561e2
TS
15640 gen_goto_tb(&ctx, 0, ctx.pc);
15641 break;
16c00cb2 15642 case BS_NONE:
278d0702 15643 save_cpu_state(&ctx, 0);
16c00cb2
TS
15644 gen_goto_tb(&ctx, 0, ctx.pc);
15645 break;
5a5012ec 15646 case BS_EXCP:
57fec1fe 15647 tcg_gen_exit_tb(0);
16c00cb2 15648 break;
5a5012ec
TS
15649 case BS_BRANCH:
15650 default:
15651 break;
6958549d 15652 }
6af0bf9c 15653 }
4ad40f36 15654done_generating:
2e70f6ef 15655 gen_icount_end(tb, num_insns);
efd7f486 15656 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15657 if (search_pc) {
92414b31 15658 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15659 lj++;
15660 while (lj <= j)
ab1103de 15661 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15662 } else {
15663 tb->size = ctx.pc - pc_start;
2e70f6ef 15664 tb->icount = num_insns;
6af0bf9c
FB
15665 }
15666#ifdef DEBUG_DISAS
d12d51d5 15667 LOG_DISAS("\n");
8fec2b8c 15668 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15669 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15670 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15671 qemu_log("\n");
6af0bf9c
FB
15672 }
15673#endif
6af0bf9c
FB
15674}
15675
7db13fae 15676void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15677{
2cfc5f17 15678 gen_intermediate_code_internal(env, tb, 0);
6af0bf9c
FB
15679}
15680
7db13fae 15681void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15682{
2cfc5f17 15683 gen_intermediate_code_internal(env, tb, 1);
6af0bf9c
FB
15684}
15685
7db13fae 15686static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15687 int flags)
6ea83fed
FB
15688{
15689 int i;
5e755519 15690 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15691
2a5612e6
SW
15692#define printfpr(fp) \
15693 do { \
15694 if (is_fpu64) \
15695 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15696 " fd:%13g fs:%13g psu: %13g\n", \
15697 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15698 (double)(fp)->fd, \
15699 (double)(fp)->fs[FP_ENDIAN_IDX], \
15700 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15701 else { \
15702 fpr_t tmp; \
15703 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15704 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15705 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15706 " fd:%13g fs:%13g psu:%13g\n", \
15707 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15708 (double)tmp.fd, \
15709 (double)tmp.fs[FP_ENDIAN_IDX], \
15710 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15711 } \
6ea83fed
FB
15712 } while(0)
15713
5a5012ec 15714
9a78eead
SW
15715 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15716 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15717 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15718 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15719 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15720 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15721 }
15722
15723#undef printfpr
15724}
15725
d26bc211 15726#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15727/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15728 sign-extended values on 64bit machines. */
c570fd16
TS
15729
15730#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15731
8706c382 15732static void
7db13fae 15733cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15734 fprintf_function cpu_fprintf,
8706c382 15735 int flags)
c570fd16
TS
15736{
15737 int i;
15738
b5dc7732
TS
15739 if (!SIGN_EXT_P(env->active_tc.PC))
15740 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15741 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15742 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15743 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15744 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15745 if (!SIGN_EXT_P(env->btarget))
3594c774 15746 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15747
15748 for (i = 0; i < 32; i++) {
b5dc7732
TS
15749 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15750 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15751 }
15752
15753 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15754 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15755 if (!SIGN_EXT_P(env->lladdr))
15756 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15757}
15758#endif
15759
7db13fae 15760void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
6af0bf9c
FB
15761 int flags)
15762{
15763 int i;
3b46e624 15764
a7200c9f
SW
15765 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15766 " LO=0x" TARGET_FMT_lx " ds %04x "
15767 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15768 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15769 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15770 for (i = 0; i < 32; i++) {
15771 if ((i & 3) == 0)
15772 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15773 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15774 if ((i & 3) == 3)
15775 cpu_fprintf(f, "\n");
15776 }
568b600d 15777
3594c774 15778 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15779 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15780 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15781 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15782 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15783 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15784#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15785 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15786#endif
6af0bf9c
FB
15787}
15788
39454628
TS
15789static void mips_tcg_init(void)
15790{
f01be154 15791 int i;
39454628
TS
15792 static int inited;
15793
15794 /* Initialize various static tables. */
15795 if (inited)
6958549d 15796 return;
39454628 15797
a7812ae4 15798 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15799 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15800 for (i = 1; i < 32; i++)
a7812ae4 15801 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15802 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15803 regnames[i]);
d73ee8a2
RH
15804
15805 for (i = 0; i < 32; i++) {
15806 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15807 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15808 }
15809
a7812ae4 15810 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15811 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15812 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15813 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15814 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15815 regnames_HI[i]);
a7812ae4 15816 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15817 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15818 regnames_LO[i]);
a7812ae4 15819 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15820 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15821 regnames_ACX[i]);
15822 }
a7812ae4 15823 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15824 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15825 "DSPControl");
1ba74fb8 15826 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15827 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15828 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15829 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15830 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15831 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15832
a7812ae4 15833 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15834 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15835 "fcr0");
15836 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15837 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15838 "fcr31");
39454628 15839
7dd9e556 15840 /* register helpers */
a7812ae4 15841#define GEN_HELPER 2
7dd9e556
TS
15842#include "helper.h"
15843
39454628
TS
15844 inited = 1;
15845}
15846
aaed909a
FB
15847#include "translate_init.c"
15848
30bf942d 15849MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15850{
0f71a709 15851 MIPSCPU *cpu;
6af0bf9c 15852 CPUMIPSState *env;
c227f099 15853 const mips_def_t *def;
6af0bf9c 15854
aaed909a
FB
15855 def = cpu_mips_find_by_name(cpu_model);
15856 if (!def)
15857 return NULL;
0f71a709
AF
15858 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15859 env = &cpu->env;
aaed909a 15860 env->cpu_model = def;
51cc2e78 15861 env->cpu_model_str = cpu_model;
aaed909a 15862
51cc2e78
BS
15863#ifndef CONFIG_USER_ONLY
15864 mmu_init(env, def);
15865#endif
15866 fpu_init(env, def);
15867 mvp_init(env, def);
39454628 15868 mips_tcg_init();
3bd4122e 15869 cpu_reset(CPU(cpu));
0bf46a40 15870 qemu_init_vcpu(env);
30bf942d 15871 return cpu;
6ae81775
TS
15872}
15873
1bba0dc9 15874void cpu_state_reset(CPUMIPSState *env)
6ae81775 15875{
55e5c285
AF
15876#ifndef CONFIG_USER_ONLY
15877 MIPSCPU *cpu = mips_env_get_cpu(env);
15878 CPUState *cs = CPU(cpu);
15879#endif
6ae81775 15880
51cc2e78
BS
15881 /* Reset registers to their default values */
15882 env->CP0_PRid = env->cpu_model->CP0_PRid;
15883 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15884#ifdef TARGET_WORDS_BIGENDIAN
15885 env->CP0_Config0 |= (1 << CP0C0_BE);
15886#endif
15887 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15888 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15889 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15890 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15891 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15892 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15893 << env->cpu_model->CP0_LLAddr_shift;
15894 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15895 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15896 env->CCRes = env->cpu_model->CCRes;
15897 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15898 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15899 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15900 env->current_tc = 0;
15901 env->SEGBITS = env->cpu_model->SEGBITS;
15902 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15903#if defined(TARGET_MIPS64)
15904 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15905 env->SEGMask |= 3ULL << 62;
15906 }
15907#endif
15908 env->PABITS = env->cpu_model->PABITS;
15909 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15910 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15911 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15912 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15913 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15914 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15915 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15916 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15917 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15918 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15919 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15920 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15921 env->insn_flags = env->cpu_model->insn_flags;
15922
0eaef5aa 15923#if defined(CONFIG_USER_ONLY)
03e6e501 15924 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
94159135
MI
15925 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15926 hardware registers. */
15927 env->CP0_HWREna |= 0x0000000F;
91a75935 15928 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 15929 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 15930 }
853c3240
JL
15931 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15932 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15933 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15934 env->hflags |= MIPS_HFLAG_DSP;
15935 }
932e71cd
AJ
15936#else
15937 if (env->hflags & MIPS_HFLAG_BMASK) {
15938 /* If the exception was raised from a delay slot,
15939 come back to the jump. */
15940 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 15941 } else {
932e71cd
AJ
15942 env->CP0_ErrorEPC = env->active_tc.PC;
15943 }
15944 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
15945 env->CP0_Random = env->tlb->nb_tlb - 1;
15946 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 15947 env->CP0_Wired = 0;
55e5c285 15948 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
932e71cd
AJ
15949 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15950 /* vectored interrupts not implemented, timer on int 7,
15951 no performance counters. */
15952 env->CP0_IntCtl = 0xe0000000;
15953 {
15954 int i;
15955
15956 for (i = 0; i < 7; i++) {
15957 env->CP0_WatchLo[i] = 0;
15958 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 15959 }
932e71cd
AJ
15960 env->CP0_WatchLo[7] = 0;
15961 env->CP0_WatchHi[7] = 0;
fd88b6ab 15962 }
932e71cd
AJ
15963 /* Count register increments in debug mode, EJTAG version 1 */
15964 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
15965
15966 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15967 int i;
15968
15969 /* Only TC0 on VPE 0 starts as active. */
15970 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 15971 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
15972 env->tcs[i].CP0_TCHalt = 1;
15973 }
15974 env->active_tc.CP0_TCHalt = 1;
15975 env->halted = 1;
15976
55e5c285 15977 if (cs->cpu_index == 0) {
9e56e756
EI
15978 /* VPE0 starts up enabled. */
15979 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15980 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15981
15982 /* TC0 starts up unhalted. */
15983 env->halted = 0;
15984 env->active_tc.CP0_TCHalt = 0;
15985 env->tcs[0].CP0_TCHalt = 0;
15986 /* With thread 0 active. */
15987 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15988 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15989 }
15990 }
51cc2e78 15991#endif
03e6e501 15992 compute_hflags(env);
6af0bf9c 15993 env->exception_index = EXCP_NONE;
6af0bf9c 15994}
d2856f1a 15995
7db13fae 15996void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 15997{
25983cad 15998 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
15999 env->hflags &= ~MIPS_HFLAG_BMASK;
16000 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16001 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16002 case MIPS_HFLAG_BR:
16003 break;
16004 case MIPS_HFLAG_BC:
16005 case MIPS_HFLAG_BL:
16006 case MIPS_HFLAG_B:
16007 env->btarget = gen_opc_btarget[pc_pos];
16008 break;
16009 }
d2856f1a 16010}