]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
Merge remote-tracking branch 'remotes/kvm/uq/master' into staging
[mirror_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"
f08b6170 27#include "exec/cpu_ldst.h"
6af0bf9c 28
2ef6175a
RH
29#include "exec/helper-proto.h"
30#include "exec/helper-gen.h"
a7812ae4 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,
df6126a7 339 /* MIPS DSP Append Sub-class */
26690560 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 {
df6126a7 546 /* MIPS DSP Append Sub-class */
26690560
JL
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 {
df6126a7 670 /* DSP Append Sub-class */
26690560
JL
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;
d279279e 1075 bool ulri;
8e9ade68
TS
1076} DisasContext;
1077
1078enum {
1079 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1080 * exception condition */
8e9ade68
TS
1081 BS_STOP = 1, /* We want to stop translation for any reason */
1082 BS_BRANCH = 2, /* We reached a branch condition */
1083 BS_EXCP = 3, /* We reached an exception condition */
1084};
1085
d73ee8a2
RH
1086static const char * const regnames[] = {
1087 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1088 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1089 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1090 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1091};
6af0bf9c 1092
d73ee8a2
RH
1093static const char * const regnames_HI[] = {
1094 "HI0", "HI1", "HI2", "HI3",
1095};
4b2eb8d2 1096
d73ee8a2
RH
1097static const char * const regnames_LO[] = {
1098 "LO0", "LO1", "LO2", "LO3",
1099};
4b2eb8d2 1100
d73ee8a2
RH
1101static const char * const regnames_ACX[] = {
1102 "ACX0", "ACX1", "ACX2", "ACX3",
1103};
4b2eb8d2 1104
d73ee8a2
RH
1105static const char * const fregnames[] = {
1106 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1107 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1108 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1109 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1110};
958fb4a9 1111
fb7729e2
RH
1112#define MIPS_DEBUG(fmt, ...) \
1113 do { \
1114 if (MIPS_DEBUG_DISAS) { \
1115 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1116 TARGET_FMT_lx ": %08x " fmt "\n", \
1117 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1118 } \
1119 } while (0)
1120
1121#define LOG_DISAS(...) \
1122 do { \
1123 if (MIPS_DEBUG_DISAS) { \
1124 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1125 } \
1126 } while (0)
958fb4a9 1127
8e9ade68 1128#define MIPS_INVAL(op) \
8e9ade68 1129 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1130 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1131
8e9ade68
TS
1132/* General purpose registers moves. */
1133static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1134{
8e9ade68
TS
1135 if (reg == 0)
1136 tcg_gen_movi_tl(t, 0);
1137 else
4b2eb8d2 1138 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1139}
1140
8e9ade68 1141static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1142{
8e9ade68 1143 if (reg != 0)
4b2eb8d2 1144 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1145}
1146
b10fa3c9 1147/* Moves to/from ACX register. */
4b2eb8d2 1148static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1149{
4b2eb8d2 1150 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1151}
1152
4b2eb8d2 1153static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1154{
4b2eb8d2 1155 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1156}
1157
8e9ade68 1158/* Moves to/from shadow registers. */
be24bb4f 1159static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1160{
d9bea114 1161 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1162
1163 if (from == 0)
d9bea114 1164 tcg_gen_movi_tl(t0, 0);
8e9ade68 1165 else {
d9bea114 1166 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1167 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1168
7db13fae 1169 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1170 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1171 tcg_gen_andi_i32(t2, t2, 0xf);
1172 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1173 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1174 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1175
d9bea114 1176 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1177 tcg_temp_free_ptr(addr);
d9bea114 1178 tcg_temp_free_i32(t2);
8e9ade68 1179 }
d9bea114
AJ
1180 gen_store_gpr(t0, to);
1181 tcg_temp_free(t0);
aaa9128a
TS
1182}
1183
be24bb4f 1184static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1185{
be24bb4f 1186 if (to != 0) {
d9bea114
AJ
1187 TCGv t0 = tcg_temp_new();
1188 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1189 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1190
d9bea114 1191 gen_load_gpr(t0, from);
7db13fae 1192 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1193 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1194 tcg_gen_andi_i32(t2, t2, 0xf);
1195 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1196 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1197 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1198
d9bea114 1199 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1200 tcg_temp_free_ptr(addr);
d9bea114
AJ
1201 tcg_temp_free_i32(t2);
1202 tcg_temp_free(t0);
8e9ade68 1203 }
aaa9128a
TS
1204}
1205
aaa9128a 1206/* Floating point register moves. */
d73ee8a2 1207static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1208{
d73ee8a2 1209 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1210}
1211
d73ee8a2 1212static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1213{
d73ee8a2
RH
1214 TCGv_i64 t64 = tcg_temp_new_i64();
1215 tcg_gen_extu_i32_i64(t64, t);
1216 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1217 tcg_temp_free_i64(t64);
6d066274
AJ
1218}
1219
7f6613ce 1220static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1221{
7f6613ce
PJ
1222 if (ctx->hflags & MIPS_HFLAG_F64) {
1223 TCGv_i64 t64 = tcg_temp_new_i64();
1224 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1225 tcg_gen_trunc_i64_i32(t, t64);
1226 tcg_temp_free_i64(t64);
1227 } else {
1228 gen_load_fpr32(t, reg | 1);
1229 }
6d066274
AJ
1230}
1231
7f6613ce 1232static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1233{
7f6613ce
PJ
1234 if (ctx->hflags & MIPS_HFLAG_F64) {
1235 TCGv_i64 t64 = tcg_temp_new_i64();
1236 tcg_gen_extu_i32_i64(t64, t);
1237 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1238 tcg_temp_free_i64(t64);
1239 } else {
1240 gen_store_fpr32(t, reg | 1);
1241 }
aa0bf00b 1242}
6ea83fed 1243
d73ee8a2 1244static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1245{
f364515c 1246 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1247 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1248 } else {
d73ee8a2 1249 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1250 }
1251}
6ea83fed 1252
d73ee8a2 1253static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1254{
f364515c 1255 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1256 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1257 } else {
d73ee8a2
RH
1258 TCGv_i64 t0;
1259 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1260 t0 = tcg_temp_new_i64();
6d066274 1261 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1262 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1263 tcg_temp_free_i64(t0);
aa0bf00b
TS
1264 }
1265}
6ea83fed 1266
d94536f4 1267static inline int get_fp_bit (int cc)
a16336e4 1268{
d94536f4
AJ
1269 if (cc)
1270 return 24 + cc;
1271 else
1272 return 23;
a16336e4
TS
1273}
1274
30898801 1275/* Tests */
8e9ade68
TS
1276static inline void gen_save_pc(target_ulong pc)
1277{
1eb75d4a 1278 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1279}
30898801 1280
356265ae 1281static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1282{
d12d51d5 1283 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1284 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1285 gen_save_pc(ctx->pc);
6af0bf9c
FB
1286 ctx->saved_pc = ctx->pc;
1287 }
1288 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1289 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1290 ctx->saved_hflags = ctx->hflags;
364d4831 1291 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1292 case MIPS_HFLAG_BR:
5a5012ec
TS
1293 break;
1294 case MIPS_HFLAG_BC:
5a5012ec 1295 case MIPS_HFLAG_BL:
5a5012ec 1296 case MIPS_HFLAG_B:
d077b6f7 1297 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1298 break;
6af0bf9c
FB
1299 }
1300 }
1301}
1302
7db13fae 1303static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1304{
fd4a04eb 1305 ctx->saved_hflags = ctx->hflags;
364d4831 1306 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1307 case MIPS_HFLAG_BR:
fd4a04eb
TS
1308 break;
1309 case MIPS_HFLAG_BC:
1310 case MIPS_HFLAG_BL:
39454628 1311 case MIPS_HFLAG_B:
fd4a04eb 1312 ctx->btarget = env->btarget;
fd4a04eb 1313 break;
5a5012ec
TS
1314 }
1315}
1316
356265ae 1317static inline void
48d38ca5 1318generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1319{
a7812ae4
PB
1320 TCGv_i32 texcp = tcg_const_i32(excp);
1321 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1322 save_cpu_state(ctx, 1);
895c2d04 1323 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1324 tcg_temp_free_i32(terr);
1325 tcg_temp_free_i32(texcp);
aaa9128a
TS
1326}
1327
356265ae 1328static inline void
48d38ca5 1329generate_exception (DisasContext *ctx, int excp)
aaa9128a 1330{
6af0bf9c 1331 save_cpu_state(ctx, 1);
895c2d04 1332 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1333}
1334
48d38ca5 1335/* Addresses computation */
941694d0 1336static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1337{
941694d0 1338 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1339
1340#if defined(TARGET_MIPS64)
1341 /* For compatibility with 32-bit code, data reference in user mode
1342 with Status_UX = 0 should be casted to 32-bit and sign extended.
1343 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1344 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1345 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1346 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1347 }
1348#endif
4ad40f36
FB
1349}
1350
356265ae 1351static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1352{
fe253235 1353 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1354 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1355}
1356
356265ae 1357static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1358{
fe253235 1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1360 generate_exception_err(ctx, EXCP_CpU, 1);
1361}
1362
b8aa4598
TS
1363/* Verify that the processor is running with COP1X instructions enabled.
1364 This is associated with the nabla symbol in the MIPS32 and MIPS64
1365 opcode tables. */
1366
356265ae 1367static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1368{
1369 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1370 generate_exception(ctx, EXCP_RI);
1371}
1372
1373/* Verify that the processor is running with 64-bit floating-point
1374 operations enabled. */
1375
356265ae 1376static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1377{
b8aa4598 1378 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1379 generate_exception(ctx, EXCP_RI);
1380}
1381
1382/*
1383 * Verify if floating point register is valid; an operation is not defined
1384 * if bit 0 of any register specification is set and the FR bit in the
1385 * Status register equals zero, since the register numbers specify an
1386 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1387 * in the Status register equals one, both even and odd register numbers
1388 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1389 *
1390 * Multiple 64 bit wide registers can be checked by calling
1391 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1392 */
356265ae 1393static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1394{
fe253235 1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1396 generate_exception(ctx, EXCP_RI);
1397}
1398
853c3240
JL
1399/* Verify that the processor is running with DSP instructions enabled.
1400 This is enabled by CP0 Status register MX(24) bit.
1401 */
1402
1403static inline void check_dsp(DisasContext *ctx)
1404{
1405 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1406 if (ctx->insn_flags & ASE_DSP) {
1407 generate_exception(ctx, EXCP_DSPDIS);
1408 } else {
1409 generate_exception(ctx, EXCP_RI);
1410 }
853c3240
JL
1411 }
1412}
1413
1414static inline void check_dspr2(DisasContext *ctx)
1415{
1416 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1417 if (ctx->insn_flags & ASE_DSP) {
1418 generate_exception(ctx, EXCP_DSPDIS);
1419 } else {
1420 generate_exception(ctx, EXCP_RI);
1421 }
853c3240
JL
1422 }
1423}
1424
3a95e3a7 1425/* This code generates a "reserved instruction" exception if the
e189e748 1426 CPU does not support the instruction set corresponding to flags. */
d75c135e 1427static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1428{
d75c135e 1429 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1430 generate_exception(ctx, EXCP_RI);
d75c135e 1431 }
3a95e3a7
TS
1432}
1433
e189e748
TS
1434/* This code generates a "reserved instruction" exception if 64-bit
1435 instructions are not enabled. */
356265ae 1436static inline void check_mips_64(DisasContext *ctx)
e189e748 1437{
fe253235 1438 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1439 generate_exception(ctx, EXCP_RI);
1440}
1441
8153667c
NF
1442/* Define small wrappers for gen_load_fpr* so that we have a uniform
1443 calling interface for 32 and 64-bit FPRs. No sense in changing
1444 all callers for gen_load_fpr32 when we need the CTX parameter for
1445 this one use. */
1446#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1447#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1448#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1449static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1450 int ft, int fs, int cc) \
1451{ \
1452 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1453 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1454 switch (ifmt) { \
1455 case FMT_PS: \
1456 check_cp1_64bitmode(ctx); \
1457 break; \
1458 case FMT_D: \
1459 if (abs) { \
1460 check_cop1x(ctx); \
1461 } \
1462 check_cp1_registers(ctx, fs | ft); \
1463 break; \
1464 case FMT_S: \
1465 if (abs) { \
1466 check_cop1x(ctx); \
1467 } \
1468 break; \
1469 } \
1470 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1471 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1472 switch (n) { \
895c2d04
BS
1473 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1474 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1475 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1476 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1477 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1478 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1479 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1480 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1481 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1482 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1483 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1484 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1485 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1486 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1487 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1488 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1489 default: abort(); \
1490 } \
1491 tcg_temp_free_i##bits (fp0); \
1492 tcg_temp_free_i##bits (fp1); \
1493}
1494
1495FOP_CONDS(, 0, d, FMT_D, 64)
1496FOP_CONDS(abs, 1, d, FMT_D, 64)
1497FOP_CONDS(, 0, s, FMT_S, 32)
1498FOP_CONDS(abs, 1, s, FMT_S, 32)
1499FOP_CONDS(, 0, ps, FMT_PS, 64)
1500FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1501#undef FOP_CONDS
1502#undef gen_ldcmp_fpr32
1503#undef gen_ldcmp_fpr64
1504
958fb4a9 1505/* load/store instructions. */
e7139c44 1506#ifdef CONFIG_USER_ONLY
d9bea114 1507#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1508static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1509{ \
1510 TCGv t0 = tcg_temp_new(); \
1511 tcg_gen_mov_tl(t0, arg1); \
1512 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1513 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1514 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1515 tcg_temp_free(t0); \
aaa9128a 1516}
e7139c44
AJ
1517#else
1518#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1519static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1520{ \
895c2d04 1521 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1522}
1523#endif
aaa9128a
TS
1524OP_LD_ATOMIC(ll,ld32s);
1525#if defined(TARGET_MIPS64)
1526OP_LD_ATOMIC(lld,ld64);
1527#endif
1528#undef OP_LD_ATOMIC
1529
590bc601
PB
1530#ifdef CONFIG_USER_ONLY
1531#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1532static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1533{ \
1534 TCGv t0 = tcg_temp_new(); \
1535 int l1 = gen_new_label(); \
1536 int l2 = gen_new_label(); \
1537 \
1538 tcg_gen_andi_tl(t0, arg2, almask); \
1539 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1540 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1541 generate_exception(ctx, EXCP_AdES); \
1542 gen_set_label(l1); \
7db13fae 1543 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1544 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1545 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1546 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1547 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1548 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1549 gen_set_label(l2); \
1550 tcg_gen_movi_tl(t0, 0); \
1551 gen_store_gpr(t0, rt); \
1552 tcg_temp_free(t0); \
1553}
1554#else
1555#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1556static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1557{ \
1558 TCGv t0 = tcg_temp_new(); \
895c2d04 1559 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1560 gen_store_gpr(t0, rt); \
590bc601
PB
1561 tcg_temp_free(t0); \
1562}
1563#endif
590bc601 1564OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1565#if defined(TARGET_MIPS64)
590bc601 1566OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1567#endif
1568#undef OP_ST_ATOMIC
1569
662d7485
NF
1570static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1571 int base, int16_t offset)
1572{
1573 if (base == 0) {
1574 tcg_gen_movi_tl(addr, offset);
1575 } else if (offset == 0) {
1576 gen_load_gpr(addr, base);
1577 } else {
1578 tcg_gen_movi_tl(addr, offset);
1579 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1580 }
1581}
1582
364d4831
NF
1583static target_ulong pc_relative_pc (DisasContext *ctx)
1584{
1585 target_ulong pc = ctx->pc;
1586
1587 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1588 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1589
1590 pc -= branch_bytes;
1591 }
1592
1593 pc &= ~(target_ulong)3;
1594 return pc;
1595}
1596
5c13fdfd 1597/* Load */
d75c135e
AJ
1598static void gen_ld(DisasContext *ctx, uint32_t opc,
1599 int rt, int base, int16_t offset)
6af0bf9c 1600{
5c13fdfd 1601 const char *opn = "ld";
fc40787a 1602 TCGv t0, t1, t2;
afa88c3a 1603
d75c135e 1604 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1605 /* Loongson CPU uses a load to zero register for prefetch.
1606 We emulate it as a NOP. On other CPU we must perform the
1607 actual memory access. */
1608 MIPS_DEBUG("NOP");
1609 return;
1610 }
6af0bf9c 1611
afa88c3a 1612 t0 = tcg_temp_new();
662d7485 1613 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1614
6af0bf9c 1615 switch (opc) {
d26bc211 1616#if defined(TARGET_MIPS64)
6e473128 1617 case OPC_LWU:
5f68f5ae 1618 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 1619 gen_store_gpr(t0, rt);
6e473128
TS
1620 opn = "lwu";
1621 break;
6af0bf9c 1622 case OPC_LD:
5f68f5ae 1623 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 1624 gen_store_gpr(t0, rt);
6af0bf9c
FB
1625 opn = "ld";
1626 break;
7a387fff 1627 case OPC_LLD:
b835e919 1628 save_cpu_state(ctx, 1);
5c13fdfd 1629 op_ld_lld(t0, t0, ctx);
78723684 1630 gen_store_gpr(t0, rt);
7a387fff
TS
1631 opn = "lld";
1632 break;
6af0bf9c 1633 case OPC_LDL:
3cee3050 1634 t1 = tcg_temp_new();
fc40787a
AJ
1635 tcg_gen_andi_tl(t1, t0, 7);
1636#ifndef TARGET_WORDS_BIGENDIAN
1637 tcg_gen_xori_tl(t1, t1, 7);
1638#endif
1639 tcg_gen_shli_tl(t1, t1, 3);
1640 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1641 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1642 tcg_gen_shl_tl(t0, t0, t1);
1643 tcg_gen_xori_tl(t1, t1, 63);
1644 t2 = tcg_const_tl(0x7fffffffffffffffull);
1645 tcg_gen_shr_tl(t2, t2, t1);
78723684 1646 gen_load_gpr(t1, rt);
fc40787a
AJ
1647 tcg_gen_and_tl(t1, t1, t2);
1648 tcg_temp_free(t2);
1649 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1650 tcg_temp_free(t1);
fc40787a 1651 gen_store_gpr(t0, rt);
6af0bf9c
FB
1652 opn = "ldl";
1653 break;
6af0bf9c 1654 case OPC_LDR:
3cee3050 1655 t1 = tcg_temp_new();
fc40787a
AJ
1656 tcg_gen_andi_tl(t1, t0, 7);
1657#ifdef TARGET_WORDS_BIGENDIAN
1658 tcg_gen_xori_tl(t1, t1, 7);
1659#endif
1660 tcg_gen_shli_tl(t1, t1, 3);
1661 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1662 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1663 tcg_gen_shr_tl(t0, t0, t1);
1664 tcg_gen_xori_tl(t1, t1, 63);
1665 t2 = tcg_const_tl(0xfffffffffffffffeull);
1666 tcg_gen_shl_tl(t2, t2, t1);
78723684 1667 gen_load_gpr(t1, rt);
fc40787a
AJ
1668 tcg_gen_and_tl(t1, t1, t2);
1669 tcg_temp_free(t2);
1670 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1671 tcg_temp_free(t1);
fc40787a 1672 gen_store_gpr(t0, rt);
6af0bf9c
FB
1673 opn = "ldr";
1674 break;
364d4831 1675 case OPC_LDPC:
3cee3050 1676 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1677 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1678 tcg_temp_free(t1);
5f68f5ae 1679 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 1680 gen_store_gpr(t0, rt);
5c13fdfd 1681 opn = "ldpc";
364d4831 1682 break;
6af0bf9c 1683#endif
364d4831 1684 case OPC_LWPC:
3cee3050 1685 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1686 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1687 tcg_temp_free(t1);
5f68f5ae 1688 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 1689 gen_store_gpr(t0, rt);
5c13fdfd 1690 opn = "lwpc";
364d4831 1691 break;
6af0bf9c 1692 case OPC_LW:
5f68f5ae 1693 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 1694 gen_store_gpr(t0, rt);
6af0bf9c
FB
1695 opn = "lw";
1696 break;
6af0bf9c 1697 case OPC_LH:
5f68f5ae 1698 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 1699 gen_store_gpr(t0, rt);
6af0bf9c
FB
1700 opn = "lh";
1701 break;
6af0bf9c 1702 case OPC_LHU:
5f68f5ae 1703 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 1704 gen_store_gpr(t0, rt);
6af0bf9c
FB
1705 opn = "lhu";
1706 break;
1707 case OPC_LB:
5f68f5ae 1708 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 1709 gen_store_gpr(t0, rt);
6af0bf9c
FB
1710 opn = "lb";
1711 break;
6af0bf9c 1712 case OPC_LBU:
5f68f5ae 1713 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 1714 gen_store_gpr(t0, rt);
6af0bf9c
FB
1715 opn = "lbu";
1716 break;
1717 case OPC_LWL:
3cee3050 1718 t1 = tcg_temp_new();
fc40787a
AJ
1719 tcg_gen_andi_tl(t1, t0, 3);
1720#ifndef TARGET_WORDS_BIGENDIAN
1721 tcg_gen_xori_tl(t1, t1, 3);
1722#endif
1723 tcg_gen_shli_tl(t1, t1, 3);
1724 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1725 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1726 tcg_gen_shl_tl(t0, t0, t1);
1727 tcg_gen_xori_tl(t1, t1, 31);
1728 t2 = tcg_const_tl(0x7fffffffull);
1729 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1730 gen_load_gpr(t1, rt);
fc40787a
AJ
1731 tcg_gen_and_tl(t1, t1, t2);
1732 tcg_temp_free(t2);
1733 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1734 tcg_temp_free(t1);
fc40787a
AJ
1735 tcg_gen_ext32s_tl(t0, t0);
1736 gen_store_gpr(t0, rt);
6af0bf9c
FB
1737 opn = "lwl";
1738 break;
6af0bf9c 1739 case OPC_LWR:
3cee3050 1740 t1 = tcg_temp_new();
fc40787a
AJ
1741 tcg_gen_andi_tl(t1, t0, 3);
1742#ifdef TARGET_WORDS_BIGENDIAN
1743 tcg_gen_xori_tl(t1, t1, 3);
1744#endif
1745 tcg_gen_shli_tl(t1, t1, 3);
1746 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1747 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1748 tcg_gen_shr_tl(t0, t0, t1);
1749 tcg_gen_xori_tl(t1, t1, 31);
1750 t2 = tcg_const_tl(0xfffffffeull);
1751 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1752 gen_load_gpr(t1, rt);
fc40787a
AJ
1753 tcg_gen_and_tl(t1, t1, t2);
1754 tcg_temp_free(t2);
1755 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1756 tcg_temp_free(t1);
c728154b 1757 tcg_gen_ext32s_tl(t0, t0);
fc40787a 1758 gen_store_gpr(t0, rt);
6af0bf9c
FB
1759 opn = "lwr";
1760 break;
6af0bf9c 1761 case OPC_LL:
e7139c44 1762 save_cpu_state(ctx, 1);
5c13fdfd 1763 op_ld_ll(t0, t0, ctx);
78723684 1764 gen_store_gpr(t0, rt);
6af0bf9c
FB
1765 opn = "ll";
1766 break;
d66c7132 1767 }
2abf314d 1768 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1769 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1770 tcg_temp_free(t0);
d66c7132
AJ
1771}
1772
5c13fdfd
AJ
1773/* Store */
1774static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1775 int base, int16_t offset)
1776{
1777 const char *opn = "st";
1778 TCGv t0 = tcg_temp_new();
1779 TCGv t1 = tcg_temp_new();
1780
1781 gen_base_offset_addr(ctx, t0, base, offset);
1782 gen_load_gpr(t1, rt);
1783 switch (opc) {
1784#if defined(TARGET_MIPS64)
1785 case OPC_SD:
5f68f5ae 1786 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
1787 opn = "sd";
1788 break;
1789 case OPC_SDL:
1790 save_cpu_state(ctx, 1);
895c2d04 1791 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1792 opn = "sdl";
1793 break;
1794 case OPC_SDR:
1795 save_cpu_state(ctx, 1);
895c2d04 1796 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1797 opn = "sdr";
1798 break;
1799#endif
1800 case OPC_SW:
5f68f5ae 1801 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
1802 opn = "sw";
1803 break;
1804 case OPC_SH:
5f68f5ae 1805 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
1806 opn = "sh";
1807 break;
1808 case OPC_SB:
5f68f5ae 1809 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
1810 opn = "sb";
1811 break;
1812 case OPC_SWL:
1813 save_cpu_state(ctx, 1);
895c2d04 1814 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1815 opn = "swl";
1816 break;
1817 case OPC_SWR:
1818 save_cpu_state(ctx, 1);
895c2d04 1819 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1820 opn = "swr";
1821 break;
1822 }
2abf314d 1823 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1824 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1825 tcg_temp_free(t0);
1826 tcg_temp_free(t1);
1827}
1828
1829
d66c7132
AJ
1830/* Store conditional */
1831static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1832 int base, int16_t offset)
1833{
1834 const char *opn = "st_cond";
1835 TCGv t0, t1;
1836
2d2826b9 1837#ifdef CONFIG_USER_ONLY
d66c7132 1838 t0 = tcg_temp_local_new();
d66c7132 1839 t1 = tcg_temp_local_new();
2d2826b9
AJ
1840#else
1841 t0 = tcg_temp_new();
1842 t1 = tcg_temp_new();
1843#endif
1844 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1845 gen_load_gpr(t1, rt);
1846 switch (opc) {
1847#if defined(TARGET_MIPS64)
1848 case OPC_SCD:
b835e919 1849 save_cpu_state(ctx, 1);
5c13fdfd 1850 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1851 opn = "scd";
1852 break;
1853#endif
6af0bf9c 1854 case OPC_SC:
e7139c44 1855 save_cpu_state(ctx, 1);
5c13fdfd 1856 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1857 opn = "sc";
1858 break;
6af0bf9c 1859 }
2abf314d 1860 (void)opn; /* avoid a compiler warning */
6af0bf9c 1861 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1862 tcg_temp_free(t1);
d66c7132 1863 tcg_temp_free(t0);
6af0bf9c
FB
1864}
1865
6ea83fed 1866/* Load and store */
7a387fff 1867static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1868 int base, int16_t offset)
6ea83fed 1869{
923617a3 1870 const char *opn = "flt_ldst";
4e2474d6 1871 TCGv t0 = tcg_temp_new();
6ea83fed 1872
662d7485 1873 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1874 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1875 memory access. */
6ea83fed
FB
1876 switch (opc) {
1877 case OPC_LWC1:
b6d96bed 1878 {
a7812ae4 1879 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 1880 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 1881 gen_store_fpr32(fp0, ft);
a7812ae4 1882 tcg_temp_free_i32(fp0);
b6d96bed 1883 }
6ea83fed
FB
1884 opn = "lwc1";
1885 break;
1886 case OPC_SWC1:
b6d96bed 1887 {
a7812ae4 1888 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1889 gen_load_fpr32(fp0, ft);
5f68f5ae 1890 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 1891 tcg_temp_free_i32(fp0);
b6d96bed 1892 }
6ea83fed
FB
1893 opn = "swc1";
1894 break;
1895 case OPC_LDC1:
b6d96bed 1896 {
a7812ae4 1897 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 1898 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 1899 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1900 tcg_temp_free_i64(fp0);
b6d96bed 1901 }
6ea83fed
FB
1902 opn = "ldc1";
1903 break;
1904 case OPC_SDC1:
b6d96bed 1905 {
a7812ae4 1906 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 1907 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 1908 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 1909 tcg_temp_free_i64(fp0);
b6d96bed 1910 }
6ea83fed
FB
1911 opn = "sdc1";
1912 break;
1913 default:
923617a3 1914 MIPS_INVAL(opn);
e397ee33 1915 generate_exception(ctx, EXCP_RI);
78723684 1916 goto out;
6ea83fed 1917 }
2abf314d 1918 (void)opn; /* avoid a compiler warning */
6ea83fed 1919 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1920 out:
1921 tcg_temp_free(t0);
6ea83fed 1922}
6ea83fed 1923
7db13fae 1924static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1925 uint32_t op, int rt, int rs, int16_t imm)
1926{
1927 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1928 check_cp1_enabled(ctx);
1929 gen_flt_ldst(ctx, op, rt, rs, imm);
1930 } else {
1931 generate_exception_err(ctx, EXCP_CpU, 1);
1932 }
1933}
1934
6af0bf9c 1935/* Arithmetic with immediate operand */
d75c135e
AJ
1936static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1937 int rt, int rs, int16_t imm)
6af0bf9c 1938{
324d9e32 1939 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1940 const char *opn = "imm arith";
6af0bf9c 1941
7a387fff 1942 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1943 /* If no destination, treat it as a NOP.
1944 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1945 MIPS_DEBUG("NOP");
324d9e32 1946 return;
6af0bf9c
FB
1947 }
1948 switch (opc) {
1949 case OPC_ADDI:
48d38ca5 1950 {
324d9e32
AJ
1951 TCGv t0 = tcg_temp_local_new();
1952 TCGv t1 = tcg_temp_new();
1953 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1954 int l1 = gen_new_label();
1955
324d9e32
AJ
1956 gen_load_gpr(t1, rs);
1957 tcg_gen_addi_tl(t0, t1, uimm);
1958 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1959
324d9e32
AJ
1960 tcg_gen_xori_tl(t1, t1, ~uimm);
1961 tcg_gen_xori_tl(t2, t0, uimm);
1962 tcg_gen_and_tl(t1, t1, t2);
1963 tcg_temp_free(t2);
1964 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1965 tcg_temp_free(t1);
48d38ca5
TS
1966 /* operands of same sign, result different sign */
1967 generate_exception(ctx, EXCP_OVERFLOW);
1968 gen_set_label(l1);
78723684 1969 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1970 gen_store_gpr(t0, rt);
1971 tcg_temp_free(t0);
48d38ca5 1972 }
6af0bf9c
FB
1973 opn = "addi";
1974 break;
1975 case OPC_ADDIU:
324d9e32
AJ
1976 if (rs != 0) {
1977 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1978 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1979 } else {
1980 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1981 }
6af0bf9c
FB
1982 opn = "addiu";
1983 break;
d26bc211 1984#if defined(TARGET_MIPS64)
7a387fff 1985 case OPC_DADDI:
48d38ca5 1986 {
324d9e32
AJ
1987 TCGv t0 = tcg_temp_local_new();
1988 TCGv t1 = tcg_temp_new();
1989 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1990 int l1 = gen_new_label();
1991
324d9e32
AJ
1992 gen_load_gpr(t1, rs);
1993 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1994
324d9e32
AJ
1995 tcg_gen_xori_tl(t1, t1, ~uimm);
1996 tcg_gen_xori_tl(t2, t0, uimm);
1997 tcg_gen_and_tl(t1, t1, t2);
1998 tcg_temp_free(t2);
1999 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2000 tcg_temp_free(t1);
48d38ca5
TS
2001 /* operands of same sign, result different sign */
2002 generate_exception(ctx, EXCP_OVERFLOW);
2003 gen_set_label(l1);
324d9e32
AJ
2004 gen_store_gpr(t0, rt);
2005 tcg_temp_free(t0);
48d38ca5 2006 }
7a387fff
TS
2007 opn = "daddi";
2008 break;
2009 case OPC_DADDIU:
324d9e32
AJ
2010 if (rs != 0) {
2011 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2012 } else {
2013 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2014 }
7a387fff
TS
2015 opn = "daddiu";
2016 break;
2017#endif
324d9e32 2018 }
2abf314d 2019 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2020 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2021}
2022
2023/* Logic with immediate operand */
d75c135e 2024static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2025 int rt, int rs, int16_t imm)
324d9e32
AJ
2026{
2027 target_ulong uimm;
324d9e32
AJ
2028
2029 if (rt == 0) {
2030 /* If no destination, treat it as a NOP. */
2031 MIPS_DEBUG("NOP");
2032 return;
2033 }
2034 uimm = (uint16_t)imm;
2035 switch (opc) {
6af0bf9c 2036 case OPC_ANDI:
324d9e32
AJ
2037 if (likely(rs != 0))
2038 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2039 else
2040 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2041 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2042 regnames[rs], uimm);
6af0bf9c
FB
2043 break;
2044 case OPC_ORI:
324d9e32
AJ
2045 if (rs != 0)
2046 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2047 else
2048 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2049 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2050 regnames[rs], uimm);
6af0bf9c
FB
2051 break;
2052 case OPC_XORI:
324d9e32
AJ
2053 if (likely(rs != 0))
2054 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2055 else
2056 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2057 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2058 regnames[rs], uimm);
6af0bf9c
FB
2059 break;
2060 case OPC_LUI:
324d9e32 2061 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2062 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2063 break;
2064
2065 default:
2066 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2067 break;
324d9e32 2068 }
324d9e32
AJ
2069}
2070
2071/* Set on less than with immediate operand */
d75c135e 2072static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2073 int rt, int rs, int16_t imm)
324d9e32
AJ
2074{
2075 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2076 const char *opn = "imm arith";
2077 TCGv t0;
2078
2079 if (rt == 0) {
2080 /* If no destination, treat it as a NOP. */
2081 MIPS_DEBUG("NOP");
2082 return;
2083 }
2084 t0 = tcg_temp_new();
2085 gen_load_gpr(t0, rs);
2086 switch (opc) {
2087 case OPC_SLTI:
e68dd28f 2088 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2089 opn = "slti";
2090 break;
2091 case OPC_SLTIU:
e68dd28f 2092 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2093 opn = "sltiu";
2094 break;
2095 }
2abf314d 2096 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2097 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2098 tcg_temp_free(t0);
2099}
2100
2101/* Shifts with immediate operand */
d75c135e 2102static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2103 int rt, int rs, int16_t imm)
2104{
2105 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2106 const char *opn = "imm shift";
2107 TCGv t0;
2108
2109 if (rt == 0) {
2110 /* If no destination, treat it as a NOP. */
2111 MIPS_DEBUG("NOP");
2112 return;
2113 }
2114
2115 t0 = tcg_temp_new();
2116 gen_load_gpr(t0, rs);
2117 switch (opc) {
6af0bf9c 2118 case OPC_SLL:
78723684 2119 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2120 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2121 opn = "sll";
2122 break;
2123 case OPC_SRA:
324d9e32 2124 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2125 opn = "sra";
2126 break;
2127 case OPC_SRL:
ea63e2c3
NF
2128 if (uimm != 0) {
2129 tcg_gen_ext32u_tl(t0, t0);
2130 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2131 } else {
2132 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2133 }
ea63e2c3
NF
2134 opn = "srl";
2135 break;
2136 case OPC_ROTR:
2137 if (uimm != 0) {
2138 TCGv_i32 t1 = tcg_temp_new_i32();
2139
2140 tcg_gen_trunc_tl_i32(t1, t0);
2141 tcg_gen_rotri_i32(t1, t1, uimm);
2142 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2143 tcg_temp_free_i32(t1);
3399e30f
NF
2144 } else {
2145 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2146 }
2147 opn = "rotr";
7a387fff 2148 break;
d26bc211 2149#if defined(TARGET_MIPS64)
7a387fff 2150 case OPC_DSLL:
324d9e32 2151 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2152 opn = "dsll";
2153 break;
2154 case OPC_DSRA:
324d9e32 2155 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2156 opn = "dsra";
2157 break;
2158 case OPC_DSRL:
ea63e2c3
NF
2159 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2160 opn = "dsrl";
2161 break;
2162 case OPC_DROTR:
2163 if (uimm != 0) {
2164 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2165 } else {
2166 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2167 }
ea63e2c3 2168 opn = "drotr";
7a387fff
TS
2169 break;
2170 case OPC_DSLL32:
324d9e32 2171 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2172 opn = "dsll32";
2173 break;
2174 case OPC_DSRA32:
324d9e32 2175 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2176 opn = "dsra32";
2177 break;
2178 case OPC_DSRL32:
ea63e2c3
NF
2179 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2180 opn = "dsrl32";
2181 break;
2182 case OPC_DROTR32:
2183 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2184 opn = "drotr32";
6af0bf9c 2185 break;
7a387fff 2186#endif
6af0bf9c 2187 }
2abf314d 2188 (void)opn; /* avoid a compiler warning */
93b12ccc 2189 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2190 tcg_temp_free(t0);
6af0bf9c
FB
2191}
2192
2193/* Arithmetic */
d75c135e
AJ
2194static void gen_arith(DisasContext *ctx, uint32_t opc,
2195 int rd, int rs, int rt)
6af0bf9c 2196{
923617a3 2197 const char *opn = "arith";
6af0bf9c 2198
7a387fff
TS
2199 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2200 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2201 /* If no destination, treat it as a NOP.
2202 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2203 MIPS_DEBUG("NOP");
460f00c4 2204 return;
185f0762 2205 }
460f00c4 2206
6af0bf9c
FB
2207 switch (opc) {
2208 case OPC_ADD:
48d38ca5 2209 {
460f00c4
AJ
2210 TCGv t0 = tcg_temp_local_new();
2211 TCGv t1 = tcg_temp_new();
2212 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2213 int l1 = gen_new_label();
2214
460f00c4
AJ
2215 gen_load_gpr(t1, rs);
2216 gen_load_gpr(t2, rt);
2217 tcg_gen_add_tl(t0, t1, t2);
2218 tcg_gen_ext32s_tl(t0, t0);
2219 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2220 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2221 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2222 tcg_temp_free(t2);
2223 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2224 tcg_temp_free(t1);
48d38ca5
TS
2225 /* operands of same sign, result different sign */
2226 generate_exception(ctx, EXCP_OVERFLOW);
2227 gen_set_label(l1);
460f00c4
AJ
2228 gen_store_gpr(t0, rd);
2229 tcg_temp_free(t0);
48d38ca5 2230 }
6af0bf9c
FB
2231 opn = "add";
2232 break;
2233 case OPC_ADDU:
460f00c4
AJ
2234 if (rs != 0 && rt != 0) {
2235 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2236 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2237 } else if (rs == 0 && rt != 0) {
2238 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2239 } else if (rs != 0 && rt == 0) {
2240 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2241 } else {
2242 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2243 }
6af0bf9c
FB
2244 opn = "addu";
2245 break;
2246 case OPC_SUB:
48d38ca5 2247 {
460f00c4
AJ
2248 TCGv t0 = tcg_temp_local_new();
2249 TCGv t1 = tcg_temp_new();
2250 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2251 int l1 = gen_new_label();
2252
460f00c4
AJ
2253 gen_load_gpr(t1, rs);
2254 gen_load_gpr(t2, rt);
2255 tcg_gen_sub_tl(t0, t1, t2);
2256 tcg_gen_ext32s_tl(t0, t0);
2257 tcg_gen_xor_tl(t2, t1, t2);
2258 tcg_gen_xor_tl(t1, t0, t1);
2259 tcg_gen_and_tl(t1, t1, t2);
2260 tcg_temp_free(t2);
2261 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2262 tcg_temp_free(t1);
31e3104f 2263 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2264 generate_exception(ctx, EXCP_OVERFLOW);
2265 gen_set_label(l1);
460f00c4
AJ
2266 gen_store_gpr(t0, rd);
2267 tcg_temp_free(t0);
48d38ca5 2268 }
6af0bf9c
FB
2269 opn = "sub";
2270 break;
2271 case OPC_SUBU:
460f00c4
AJ
2272 if (rs != 0 && rt != 0) {
2273 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2274 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2275 } else if (rs == 0 && rt != 0) {
2276 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2277 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2278 } else if (rs != 0 && rt == 0) {
2279 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2280 } else {
2281 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2282 }
6af0bf9c
FB
2283 opn = "subu";
2284 break;
d26bc211 2285#if defined(TARGET_MIPS64)
7a387fff 2286 case OPC_DADD:
48d38ca5 2287 {
460f00c4
AJ
2288 TCGv t0 = tcg_temp_local_new();
2289 TCGv t1 = tcg_temp_new();
2290 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2291 int l1 = gen_new_label();
2292
460f00c4
AJ
2293 gen_load_gpr(t1, rs);
2294 gen_load_gpr(t2, rt);
2295 tcg_gen_add_tl(t0, t1, t2);
2296 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2297 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2298 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2299 tcg_temp_free(t2);
2300 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2301 tcg_temp_free(t1);
48d38ca5
TS
2302 /* operands of same sign, result different sign */
2303 generate_exception(ctx, EXCP_OVERFLOW);
2304 gen_set_label(l1);
460f00c4
AJ
2305 gen_store_gpr(t0, rd);
2306 tcg_temp_free(t0);
48d38ca5 2307 }
7a387fff
TS
2308 opn = "dadd";
2309 break;
2310 case OPC_DADDU:
460f00c4
AJ
2311 if (rs != 0 && rt != 0) {
2312 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2313 } else if (rs == 0 && rt != 0) {
2314 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2315 } else if (rs != 0 && rt == 0) {
2316 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2317 } else {
2318 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2319 }
7a387fff
TS
2320 opn = "daddu";
2321 break;
2322 case OPC_DSUB:
48d38ca5 2323 {
460f00c4
AJ
2324 TCGv t0 = tcg_temp_local_new();
2325 TCGv t1 = tcg_temp_new();
2326 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2327 int l1 = gen_new_label();
2328
460f00c4
AJ
2329 gen_load_gpr(t1, rs);
2330 gen_load_gpr(t2, rt);
2331 tcg_gen_sub_tl(t0, t1, t2);
2332 tcg_gen_xor_tl(t2, t1, t2);
2333 tcg_gen_xor_tl(t1, t0, t1);
2334 tcg_gen_and_tl(t1, t1, t2);
2335 tcg_temp_free(t2);
2336 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2337 tcg_temp_free(t1);
31e3104f 2338 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2339 generate_exception(ctx, EXCP_OVERFLOW);
2340 gen_set_label(l1);
460f00c4
AJ
2341 gen_store_gpr(t0, rd);
2342 tcg_temp_free(t0);
48d38ca5 2343 }
7a387fff
TS
2344 opn = "dsub";
2345 break;
2346 case OPC_DSUBU:
460f00c4
AJ
2347 if (rs != 0 && rt != 0) {
2348 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2349 } else if (rs == 0 && rt != 0) {
2350 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2351 } else if (rs != 0 && rt == 0) {
2352 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2353 } else {
2354 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2355 }
7a387fff
TS
2356 opn = "dsubu";
2357 break;
2358#endif
460f00c4
AJ
2359 case OPC_MUL:
2360 if (likely(rs != 0 && rt != 0)) {
2361 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2362 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2363 } else {
2364 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2365 }
2366 opn = "mul";
6af0bf9c 2367 break;
460f00c4 2368 }
2abf314d 2369 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2370 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2371}
2372
2373/* Conditional move */
d75c135e 2374static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2375 int rd, int rs, int rt)
460f00c4
AJ
2376{
2377 const char *opn = "cond move";
acf12465 2378 TCGv t0, t1, t2;
460f00c4
AJ
2379
2380 if (rd == 0) {
acf12465 2381 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2382 MIPS_DEBUG("NOP");
2383 return;
2384 }
2385
acf12465
AJ
2386 t0 = tcg_temp_new();
2387 gen_load_gpr(t0, rt);
2388 t1 = tcg_const_tl(0);
2389 t2 = tcg_temp_new();
2390 gen_load_gpr(t2, rs);
460f00c4
AJ
2391 switch (opc) {
2392 case OPC_MOVN:
acf12465 2393 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2394 opn = "movn";
6af0bf9c 2395 break;
460f00c4 2396 case OPC_MOVZ:
acf12465 2397 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2398 opn = "movz";
2399 break;
2400 }
acf12465
AJ
2401 tcg_temp_free(t2);
2402 tcg_temp_free(t1);
2403 tcg_temp_free(t0);
460f00c4 2404
2abf314d 2405 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2406 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2407}
2408
2409/* Logic */
d75c135e 2410static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2411 int rd, int rs, int rt)
460f00c4
AJ
2412{
2413 const char *opn = "logic";
2414
2415 if (rd == 0) {
2416 /* If no destination, treat it as a NOP. */
2417 MIPS_DEBUG("NOP");
2418 return;
2419 }
2420
2421 switch (opc) {
6af0bf9c 2422 case OPC_AND:
460f00c4
AJ
2423 if (likely(rs != 0 && rt != 0)) {
2424 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2425 } else {
2426 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2427 }
6af0bf9c
FB
2428 opn = "and";
2429 break;
2430 case OPC_NOR:
460f00c4
AJ
2431 if (rs != 0 && rt != 0) {
2432 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2433 } else if (rs == 0 && rt != 0) {
2434 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2435 } else if (rs != 0 && rt == 0) {
2436 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2437 } else {
2438 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2439 }
6af0bf9c
FB
2440 opn = "nor";
2441 break;
2442 case OPC_OR:
460f00c4
AJ
2443 if (likely(rs != 0 && rt != 0)) {
2444 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2445 } else if (rs == 0 && rt != 0) {
2446 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2447 } else if (rs != 0 && rt == 0) {
2448 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2449 } else {
2450 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2451 }
6af0bf9c
FB
2452 opn = "or";
2453 break;
2454 case OPC_XOR:
460f00c4
AJ
2455 if (likely(rs != 0 && rt != 0)) {
2456 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2457 } else if (rs == 0 && rt != 0) {
2458 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2459 } else if (rs != 0 && rt == 0) {
2460 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2461 } else {
2462 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2463 }
6af0bf9c
FB
2464 opn = "xor";
2465 break;
460f00c4 2466 }
2abf314d 2467 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2468 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2469}
2470
2471/* Set on lower than */
d75c135e 2472static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2473 int rd, int rs, int rt)
460f00c4
AJ
2474{
2475 const char *opn = "slt";
2476 TCGv t0, t1;
2477
2478 if (rd == 0) {
2479 /* If no destination, treat it as a NOP. */
2480 MIPS_DEBUG("NOP");
2481 return;
2482 }
2483
2484 t0 = tcg_temp_new();
2485 t1 = tcg_temp_new();
2486 gen_load_gpr(t0, rs);
2487 gen_load_gpr(t1, rt);
2488 switch (opc) {
2489 case OPC_SLT:
e68dd28f 2490 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2491 opn = "slt";
6af0bf9c 2492 break;
460f00c4 2493 case OPC_SLTU:
e68dd28f 2494 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2495 opn = "sltu";
2496 break;
2497 }
2abf314d 2498 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2499 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2500 tcg_temp_free(t0);
2501 tcg_temp_free(t1);
2502}
20c4c97c 2503
460f00c4 2504/* Shifts */
d75c135e
AJ
2505static void gen_shift(DisasContext *ctx, uint32_t opc,
2506 int rd, int rs, int rt)
460f00c4
AJ
2507{
2508 const char *opn = "shifts";
2509 TCGv t0, t1;
20c4c97c 2510
460f00c4
AJ
2511 if (rd == 0) {
2512 /* If no destination, treat it as a NOP.
2513 For add & sub, we must generate the overflow exception when needed. */
2514 MIPS_DEBUG("NOP");
2515 return;
2516 }
2517
2518 t0 = tcg_temp_new();
2519 t1 = tcg_temp_new();
2520 gen_load_gpr(t0, rs);
2521 gen_load_gpr(t1, rt);
2522 switch (opc) {
6af0bf9c 2523 case OPC_SLLV:
78723684
TS
2524 tcg_gen_andi_tl(t0, t0, 0x1f);
2525 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2526 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2527 opn = "sllv";
2528 break;
2529 case OPC_SRAV:
78723684 2530 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2531 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2532 opn = "srav";
2533 break;
2534 case OPC_SRLV:
ea63e2c3
NF
2535 tcg_gen_ext32u_tl(t1, t1);
2536 tcg_gen_andi_tl(t0, t0, 0x1f);
2537 tcg_gen_shr_tl(t0, t1, t0);
2538 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2539 opn = "srlv";
2540 break;
2541 case OPC_ROTRV:
2542 {
2543 TCGv_i32 t2 = tcg_temp_new_i32();
2544 TCGv_i32 t3 = tcg_temp_new_i32();
2545
2546 tcg_gen_trunc_tl_i32(t2, t0);
2547 tcg_gen_trunc_tl_i32(t3, t1);
2548 tcg_gen_andi_i32(t2, t2, 0x1f);
2549 tcg_gen_rotr_i32(t2, t3, t2);
2550 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2551 tcg_temp_free_i32(t2);
2552 tcg_temp_free_i32(t3);
2553 opn = "rotrv";
5a63bcb2 2554 }
7a387fff 2555 break;
d26bc211 2556#if defined(TARGET_MIPS64)
7a387fff 2557 case OPC_DSLLV:
78723684 2558 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2559 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2560 opn = "dsllv";
2561 break;
2562 case OPC_DSRAV:
78723684 2563 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2564 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2565 opn = "dsrav";
2566 break;
2567 case OPC_DSRLV:
ea63e2c3
NF
2568 tcg_gen_andi_tl(t0, t0, 0x3f);
2569 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2570 opn = "dsrlv";
2571 break;
2572 case OPC_DROTRV:
2573 tcg_gen_andi_tl(t0, t0, 0x3f);
2574 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2575 opn = "drotrv";
6af0bf9c 2576 break;
7a387fff 2577#endif
6af0bf9c 2578 }
2abf314d 2579 (void)opn; /* avoid a compiler warning */
6af0bf9c 2580 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2581 tcg_temp_free(t0);
2582 tcg_temp_free(t1);
6af0bf9c
FB
2583}
2584
2585/* Arithmetic on HI/LO registers */
26135ead 2586static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2587{
923617a3 2588 const char *opn = "hilo";
6af0bf9c
FB
2589
2590 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2591 /* Treat as NOP. */
6af0bf9c 2592 MIPS_DEBUG("NOP");
a1f6684d 2593 return;
6af0bf9c 2594 }
4133498f 2595
4133498f
JL
2596 if (acc != 0) {
2597 check_dsp(ctx);
2598 }
2599
6af0bf9c
FB
2600 switch (opc) {
2601 case OPC_MFHI:
4133498f
JL
2602#if defined(TARGET_MIPS64)
2603 if (acc != 0) {
2604 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2605 } else
2606#endif
2607 {
2608 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2609 }
6af0bf9c
FB
2610 opn = "mfhi";
2611 break;
2612 case OPC_MFLO:
4133498f
JL
2613#if defined(TARGET_MIPS64)
2614 if (acc != 0) {
2615 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2616 } else
2617#endif
2618 {
2619 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2620 }
6af0bf9c
FB
2621 opn = "mflo";
2622 break;
2623 case OPC_MTHI:
4133498f
JL
2624 if (reg != 0) {
2625#if defined(TARGET_MIPS64)
2626 if (acc != 0) {
2627 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2628 } else
2629#endif
2630 {
2631 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2632 }
2633 } else {
2634 tcg_gen_movi_tl(cpu_HI[acc], 0);
2635 }
6af0bf9c
FB
2636 opn = "mthi";
2637 break;
2638 case OPC_MTLO:
4133498f
JL
2639 if (reg != 0) {
2640#if defined(TARGET_MIPS64)
2641 if (acc != 0) {
2642 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2643 } else
2644#endif
2645 {
2646 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2647 }
2648 } else {
2649 tcg_gen_movi_tl(cpu_LO[acc], 0);
2650 }
6af0bf9c
FB
2651 opn = "mtlo";
2652 break;
6af0bf9c 2653 }
2abf314d 2654 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2655 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2656}
2657
26135ead
RS
2658static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2659 int acc, int rs, int rt)
6af0bf9c 2660{
923617a3 2661 const char *opn = "mul/div";
d45f89f4
AJ
2662 TCGv t0, t1;
2663
51127181
AJ
2664 t0 = tcg_temp_new();
2665 t1 = tcg_temp_new();
6af0bf9c 2666
78723684
TS
2667 gen_load_gpr(t0, rs);
2668 gen_load_gpr(t1, rt);
51127181 2669
26135ead
RS
2670 if (acc != 0) {
2671 check_dsp(ctx);
2672 }
2673
6af0bf9c
FB
2674 switch (opc) {
2675 case OPC_DIV:
48d38ca5 2676 {
51127181
AJ
2677 TCGv t2 = tcg_temp_new();
2678 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2679 tcg_gen_ext32s_tl(t0, t0);
2680 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2681 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2682 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2683 tcg_gen_and_tl(t2, t2, t3);
2684 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2685 tcg_gen_or_tl(t2, t2, t3);
2686 tcg_gen_movi_tl(t3, 0);
2687 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2688 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2689 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2690 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2691 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2692 tcg_temp_free(t3);
2693 tcg_temp_free(t2);
48d38ca5 2694 }
6af0bf9c
FB
2695 opn = "div";
2696 break;
2697 case OPC_DIVU:
48d38ca5 2698 {
51127181
AJ
2699 TCGv t2 = tcg_const_tl(0);
2700 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2701 tcg_gen_ext32u_tl(t0, t0);
2702 tcg_gen_ext32u_tl(t1, t1);
51127181 2703 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2704 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2705 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2706 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2707 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2708 tcg_temp_free(t3);
2709 tcg_temp_free(t2);
48d38ca5 2710 }
6af0bf9c
FB
2711 opn = "divu";
2712 break;
2713 case OPC_MULT:
214c465f 2714 {
ce1dd5d1
RH
2715 TCGv_i32 t2 = tcg_temp_new_i32();
2716 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2717 tcg_gen_trunc_tl_i32(t2, t0);
2718 tcg_gen_trunc_tl_i32(t3, t1);
2719 tcg_gen_muls2_i32(t2, t3, t2, t3);
2720 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2721 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2722 tcg_temp_free_i32(t2);
2723 tcg_temp_free_i32(t3);
214c465f 2724 }
6af0bf9c
FB
2725 opn = "mult";
2726 break;
2727 case OPC_MULTU:
214c465f 2728 {
ce1dd5d1
RH
2729 TCGv_i32 t2 = tcg_temp_new_i32();
2730 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2731 tcg_gen_trunc_tl_i32(t2, t0);
2732 tcg_gen_trunc_tl_i32(t3, t1);
2733 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2734 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2735 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2736 tcg_temp_free_i32(t2);
2737 tcg_temp_free_i32(t3);
214c465f 2738 }
6af0bf9c
FB
2739 opn = "multu";
2740 break;
d26bc211 2741#if defined(TARGET_MIPS64)
7a387fff 2742 case OPC_DDIV:
48d38ca5 2743 {
51127181
AJ
2744 TCGv t2 = tcg_temp_new();
2745 TCGv t3 = tcg_temp_new();
2746 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2747 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2748 tcg_gen_and_tl(t2, t2, t3);
2749 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2750 tcg_gen_or_tl(t2, t2, t3);
2751 tcg_gen_movi_tl(t3, 0);
2752 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2753 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2754 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
2755 tcg_temp_free(t3);
2756 tcg_temp_free(t2);
48d38ca5 2757 }
7a387fff
TS
2758 opn = "ddiv";
2759 break;
2760 case OPC_DDIVU:
48d38ca5 2761 {
51127181
AJ
2762 TCGv t2 = tcg_const_tl(0);
2763 TCGv t3 = tcg_const_tl(1);
2764 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2765 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2766 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
2767 tcg_temp_free(t3);
2768 tcg_temp_free(t2);
48d38ca5 2769 }
7a387fff
TS
2770 opn = "ddivu";
2771 break;
2772 case OPC_DMULT:
26135ead 2773 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2774 opn = "dmult";
2775 break;
2776 case OPC_DMULTU:
26135ead 2777 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2778 opn = "dmultu";
2779 break;
2780#endif
6af0bf9c 2781 case OPC_MADD:
214c465f 2782 {
d45f89f4
AJ
2783 TCGv_i64 t2 = tcg_temp_new_i64();
2784 TCGv_i64 t3 = tcg_temp_new_i64();
2785
2786 tcg_gen_ext_tl_i64(t2, t0);
2787 tcg_gen_ext_tl_i64(t3, t1);
2788 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2789 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2790 tcg_gen_add_i64(t2, t2, t3);
2791 tcg_temp_free_i64(t3);
2792 tcg_gen_trunc_i64_tl(t0, t2);
2793 tcg_gen_shri_i64(t2, t2, 32);
2794 tcg_gen_trunc_i64_tl(t1, t2);
2795 tcg_temp_free_i64(t2);
4133498f
JL
2796 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2797 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2798 }
6af0bf9c
FB
2799 opn = "madd";
2800 break;
2801 case OPC_MADDU:
4133498f 2802 {
d45f89f4
AJ
2803 TCGv_i64 t2 = tcg_temp_new_i64();
2804 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2805
78723684
TS
2806 tcg_gen_ext32u_tl(t0, t0);
2807 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2808 tcg_gen_extu_tl_i64(t2, t0);
2809 tcg_gen_extu_tl_i64(t3, t1);
2810 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2811 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2812 tcg_gen_add_i64(t2, t2, t3);
2813 tcg_temp_free_i64(t3);
2814 tcg_gen_trunc_i64_tl(t0, t2);
2815 tcg_gen_shri_i64(t2, t2, 32);
2816 tcg_gen_trunc_i64_tl(t1, t2);
2817 tcg_temp_free_i64(t2);
4133498f
JL
2818 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2819 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2820 }
6af0bf9c
FB
2821 opn = "maddu";
2822 break;
2823 case OPC_MSUB:
214c465f 2824 {
d45f89f4
AJ
2825 TCGv_i64 t2 = tcg_temp_new_i64();
2826 TCGv_i64 t3 = tcg_temp_new_i64();
2827
2828 tcg_gen_ext_tl_i64(t2, t0);
2829 tcg_gen_ext_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]);
98070ce0 2832 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
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 = "msub";
2842 break;
2843 case OPC_MSUBU:
214c465f 2844 {
d45f89f4
AJ
2845 TCGv_i64 t2 = tcg_temp_new_i64();
2846 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2847
78723684
TS
2848 tcg_gen_ext32u_tl(t0, t0);
2849 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2850 tcg_gen_extu_tl_i64(t2, t0);
2851 tcg_gen_extu_tl_i64(t3, t1);
2852 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2853 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2854 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2855 tcg_temp_free_i64(t3);
2856 tcg_gen_trunc_i64_tl(t0, t2);
2857 tcg_gen_shri_i64(t2, t2, 32);
2858 tcg_gen_trunc_i64_tl(t1, t2);
2859 tcg_temp_free_i64(t2);
4133498f
JL
2860 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2861 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2862 }
6af0bf9c
FB
2863 opn = "msubu";
2864 break;
2865 default:
923617a3 2866 MIPS_INVAL(opn);
6af0bf9c 2867 generate_exception(ctx, EXCP_RI);
78723684 2868 goto out;
6af0bf9c 2869 }
2abf314d 2870 (void)opn; /* avoid a compiler warning */
6af0bf9c 2871 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2872 out:
2873 tcg_temp_free(t0);
2874 tcg_temp_free(t1);
6af0bf9c
FB
2875}
2876
e9c71dd1
TS
2877static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2878 int rd, int rs, int rt)
2879{
2880 const char *opn = "mul vr54xx";
f157bfe1
AJ
2881 TCGv t0 = tcg_temp_new();
2882 TCGv t1 = tcg_temp_new();
e9c71dd1 2883
6c5c1e20
TS
2884 gen_load_gpr(t0, rs);
2885 gen_load_gpr(t1, rt);
e9c71dd1
TS
2886
2887 switch (opc) {
2888 case OPC_VR54XX_MULS:
895c2d04 2889 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2890 opn = "muls";
6958549d 2891 break;
e9c71dd1 2892 case OPC_VR54XX_MULSU:
895c2d04 2893 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2894 opn = "mulsu";
6958549d 2895 break;
e9c71dd1 2896 case OPC_VR54XX_MACC:
895c2d04 2897 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2898 opn = "macc";
6958549d 2899 break;
e9c71dd1 2900 case OPC_VR54XX_MACCU:
895c2d04 2901 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2902 opn = "maccu";
6958549d 2903 break;
e9c71dd1 2904 case OPC_VR54XX_MSAC:
895c2d04 2905 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2906 opn = "msac";
6958549d 2907 break;
e9c71dd1 2908 case OPC_VR54XX_MSACU:
895c2d04 2909 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2910 opn = "msacu";
6958549d 2911 break;
e9c71dd1 2912 case OPC_VR54XX_MULHI:
895c2d04 2913 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2914 opn = "mulhi";
6958549d 2915 break;
e9c71dd1 2916 case OPC_VR54XX_MULHIU:
895c2d04 2917 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2918 opn = "mulhiu";
6958549d 2919 break;
e9c71dd1 2920 case OPC_VR54XX_MULSHI:
895c2d04 2921 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2922 opn = "mulshi";
6958549d 2923 break;
e9c71dd1 2924 case OPC_VR54XX_MULSHIU:
895c2d04 2925 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2926 opn = "mulshiu";
6958549d 2927 break;
e9c71dd1 2928 case OPC_VR54XX_MACCHI:
895c2d04 2929 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2930 opn = "macchi";
6958549d 2931 break;
e9c71dd1 2932 case OPC_VR54XX_MACCHIU:
895c2d04 2933 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2934 opn = "macchiu";
6958549d 2935 break;
e9c71dd1 2936 case OPC_VR54XX_MSACHI:
895c2d04 2937 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2938 opn = "msachi";
6958549d 2939 break;
e9c71dd1 2940 case OPC_VR54XX_MSACHIU:
895c2d04 2941 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2942 opn = "msachiu";
6958549d 2943 break;
e9c71dd1
TS
2944 default:
2945 MIPS_INVAL("mul vr54xx");
2946 generate_exception(ctx, EXCP_RI);
6c5c1e20 2947 goto out;
e9c71dd1 2948 }
6c5c1e20 2949 gen_store_gpr(t0, rd);
2abf314d 2950 (void)opn; /* avoid a compiler warning */
e9c71dd1 2951 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2952
2953 out:
2954 tcg_temp_free(t0);
2955 tcg_temp_free(t1);
e9c71dd1
TS
2956}
2957
7a387fff 2958static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2959 int rd, int rs)
2960{
923617a3 2961 const char *opn = "CLx";
20e1fb52 2962 TCGv t0;
6c5c1e20 2963
6af0bf9c 2964 if (rd == 0) {
ead9360e 2965 /* Treat as NOP. */
6af0bf9c 2966 MIPS_DEBUG("NOP");
20e1fb52 2967 return;
6af0bf9c 2968 }
20e1fb52 2969 t0 = tcg_temp_new();
6c5c1e20 2970 gen_load_gpr(t0, rs);
6af0bf9c
FB
2971 switch (opc) {
2972 case OPC_CLO:
20e1fb52 2973 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
2974 opn = "clo";
2975 break;
2976 case OPC_CLZ:
20e1fb52 2977 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
2978 opn = "clz";
2979 break;
d26bc211 2980#if defined(TARGET_MIPS64)
7a387fff 2981 case OPC_DCLO:
20e1fb52 2982 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
2983 opn = "dclo";
2984 break;
2985 case OPC_DCLZ:
20e1fb52 2986 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
2987 opn = "dclz";
2988 break;
2989#endif
6af0bf9c 2990 }
2abf314d 2991 (void)opn; /* avoid a compiler warning */
6af0bf9c 2992 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 2993 tcg_temp_free(t0);
6af0bf9c
FB
2994}
2995
161f85e6 2996/* Godson integer instructions */
bd277fa1
RH
2997static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2998 int rd, int rs, int rt)
161f85e6
AJ
2999{
3000 const char *opn = "loongson";
3001 TCGv t0, t1;
3002
3003 if (rd == 0) {
3004 /* Treat as NOP. */
3005 MIPS_DEBUG("NOP");
3006 return;
3007 }
3008
3009 switch (opc) {
3010 case OPC_MULT_G_2E:
3011 case OPC_MULT_G_2F:
3012 case OPC_MULTU_G_2E:
3013 case OPC_MULTU_G_2F:
3014#if defined(TARGET_MIPS64)
3015 case OPC_DMULT_G_2E:
3016 case OPC_DMULT_G_2F:
3017 case OPC_DMULTU_G_2E:
3018 case OPC_DMULTU_G_2F:
3019#endif
3020 t0 = tcg_temp_new();
3021 t1 = tcg_temp_new();
3022 break;
3023 default:
3024 t0 = tcg_temp_local_new();
3025 t1 = tcg_temp_local_new();
3026 break;
3027 }
3028
3029 gen_load_gpr(t0, rs);
3030 gen_load_gpr(t1, rt);
3031
3032 switch (opc) {
3033 case OPC_MULT_G_2E:
3034 case OPC_MULT_G_2F:
3035 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3036 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3037 opn = "mult.g";
3038 break;
3039 case OPC_MULTU_G_2E:
3040 case OPC_MULTU_G_2F:
3041 tcg_gen_ext32u_tl(t0, t0);
3042 tcg_gen_ext32u_tl(t1, t1);
3043 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3044 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3045 opn = "multu.g";
3046 break;
3047 case OPC_DIV_G_2E:
3048 case OPC_DIV_G_2F:
3049 {
3050 int l1 = gen_new_label();
3051 int l2 = gen_new_label();
3052 int l3 = gen_new_label();
3053 tcg_gen_ext32s_tl(t0, t0);
3054 tcg_gen_ext32s_tl(t1, t1);
3055 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3056 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3057 tcg_gen_br(l3);
3058 gen_set_label(l1);
3059 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3060 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3061 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3062 tcg_gen_br(l3);
3063 gen_set_label(l2);
3064 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3065 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3066 gen_set_label(l3);
3067 }
3068 opn = "div.g";
3069 break;
3070 case OPC_DIVU_G_2E:
3071 case OPC_DIVU_G_2F:
3072 {
3073 int l1 = gen_new_label();
3074 int l2 = gen_new_label();
3075 tcg_gen_ext32u_tl(t0, t0);
3076 tcg_gen_ext32u_tl(t1, t1);
3077 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3078 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3079 tcg_gen_br(l2);
3080 gen_set_label(l1);
3081 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3082 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3083 gen_set_label(l2);
3084 }
3085 opn = "divu.g";
3086 break;
3087 case OPC_MOD_G_2E:
3088 case OPC_MOD_G_2F:
3089 {
3090 int l1 = gen_new_label();
3091 int l2 = gen_new_label();
3092 int l3 = gen_new_label();
3093 tcg_gen_ext32u_tl(t0, t0);
3094 tcg_gen_ext32u_tl(t1, t1);
3095 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3097 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3098 gen_set_label(l1);
3099 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3100 tcg_gen_br(l3);
3101 gen_set_label(l2);
3102 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3103 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3104 gen_set_label(l3);
3105 }
3106 opn = "mod.g";
3107 break;
3108 case OPC_MODU_G_2E:
3109 case OPC_MODU_G_2F:
3110 {
3111 int l1 = gen_new_label();
3112 int l2 = gen_new_label();
3113 tcg_gen_ext32u_tl(t0, t0);
3114 tcg_gen_ext32u_tl(t1, t1);
3115 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3116 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3117 tcg_gen_br(l2);
3118 gen_set_label(l1);
3119 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3120 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3121 gen_set_label(l2);
3122 }
3123 opn = "modu.g";
3124 break;
3125#if defined(TARGET_MIPS64)
3126 case OPC_DMULT_G_2E:
3127 case OPC_DMULT_G_2F:
3128 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3129 opn = "dmult.g";
3130 break;
3131 case OPC_DMULTU_G_2E:
3132 case OPC_DMULTU_G_2F:
3133 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3134 opn = "dmultu.g";
3135 break;
3136 case OPC_DDIV_G_2E:
3137 case OPC_DDIV_G_2F:
3138 {
3139 int l1 = gen_new_label();
3140 int l2 = gen_new_label();
3141 int l3 = gen_new_label();
3142 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3143 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3144 tcg_gen_br(l3);
3145 gen_set_label(l1);
3146 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3147 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3148 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3149 tcg_gen_br(l3);
3150 gen_set_label(l2);
3151 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3152 gen_set_label(l3);
3153 }
3154 opn = "ddiv.g";
3155 break;
3156 case OPC_DDIVU_G_2E:
3157 case OPC_DDIVU_G_2F:
3158 {
3159 int l1 = gen_new_label();
3160 int l2 = gen_new_label();
3161 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3162 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3163 tcg_gen_br(l2);
3164 gen_set_label(l1);
3165 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3166 gen_set_label(l2);
3167 }
3168 opn = "ddivu.g";
3169 break;
3170 case OPC_DMOD_G_2E:
3171 case OPC_DMOD_G_2F:
3172 {
3173 int l1 = gen_new_label();
3174 int l2 = gen_new_label();
3175 int l3 = gen_new_label();
3176 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3177 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3178 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3179 gen_set_label(l1);
3180 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3181 tcg_gen_br(l3);
3182 gen_set_label(l2);
3183 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3184 gen_set_label(l3);
3185 }
3186 opn = "dmod.g";
3187 break;
3188 case OPC_DMODU_G_2E:
3189 case OPC_DMODU_G_2F:
3190 {
3191 int l1 = gen_new_label();
3192 int l2 = gen_new_label();
3193 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3194 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3195 tcg_gen_br(l2);
3196 gen_set_label(l1);
3197 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3198 gen_set_label(l2);
3199 }
3200 opn = "dmodu.g";
3201 break;
3202#endif
3203 }
3204
2abf314d 3205 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3206 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3207 tcg_temp_free(t0);
3208 tcg_temp_free(t1);
3209}
3210
bd277fa1
RH
3211/* Loongson multimedia instructions */
3212static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3213{
3214 const char *opn = "loongson_cp2";
3215 uint32_t opc, shift_max;
3216 TCGv_i64 t0, t1;
3217
3218 opc = MASK_LMI(ctx->opcode);
3219 switch (opc) {
3220 case OPC_ADD_CP2:
3221 case OPC_SUB_CP2:
3222 case OPC_DADD_CP2:
3223 case OPC_DSUB_CP2:
3224 t0 = tcg_temp_local_new_i64();
3225 t1 = tcg_temp_local_new_i64();
3226 break;
3227 default:
3228 t0 = tcg_temp_new_i64();
3229 t1 = tcg_temp_new_i64();
3230 break;
3231 }
3232
3233 gen_load_fpr64(ctx, t0, rs);
3234 gen_load_fpr64(ctx, t1, rt);
3235
3236#define LMI_HELPER(UP, LO) \
3237 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3238#define LMI_HELPER_1(UP, LO) \
3239 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3240#define LMI_DIRECT(UP, LO, OP) \
3241 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3242
3243 switch (opc) {
3244 LMI_HELPER(PADDSH, paddsh);
3245 LMI_HELPER(PADDUSH, paddush);
3246 LMI_HELPER(PADDH, paddh);
3247 LMI_HELPER(PADDW, paddw);
3248 LMI_HELPER(PADDSB, paddsb);
3249 LMI_HELPER(PADDUSB, paddusb);
3250 LMI_HELPER(PADDB, paddb);
3251
3252 LMI_HELPER(PSUBSH, psubsh);
3253 LMI_HELPER(PSUBUSH, psubush);
3254 LMI_HELPER(PSUBH, psubh);
3255 LMI_HELPER(PSUBW, psubw);
3256 LMI_HELPER(PSUBSB, psubsb);
3257 LMI_HELPER(PSUBUSB, psubusb);
3258 LMI_HELPER(PSUBB, psubb);
3259
3260 LMI_HELPER(PSHUFH, pshufh);
3261 LMI_HELPER(PACKSSWH, packsswh);
3262 LMI_HELPER(PACKSSHB, packsshb);
3263 LMI_HELPER(PACKUSHB, packushb);
3264
3265 LMI_HELPER(PUNPCKLHW, punpcklhw);
3266 LMI_HELPER(PUNPCKHHW, punpckhhw);
3267 LMI_HELPER(PUNPCKLBH, punpcklbh);
3268 LMI_HELPER(PUNPCKHBH, punpckhbh);
3269 LMI_HELPER(PUNPCKLWD, punpcklwd);
3270 LMI_HELPER(PUNPCKHWD, punpckhwd);
3271
3272 LMI_HELPER(PAVGH, pavgh);
3273 LMI_HELPER(PAVGB, pavgb);
3274 LMI_HELPER(PMAXSH, pmaxsh);
3275 LMI_HELPER(PMINSH, pminsh);
3276 LMI_HELPER(PMAXUB, pmaxub);
3277 LMI_HELPER(PMINUB, pminub);
3278
3279 LMI_HELPER(PCMPEQW, pcmpeqw);
3280 LMI_HELPER(PCMPGTW, pcmpgtw);
3281 LMI_HELPER(PCMPEQH, pcmpeqh);
3282 LMI_HELPER(PCMPGTH, pcmpgth);
3283 LMI_HELPER(PCMPEQB, pcmpeqb);
3284 LMI_HELPER(PCMPGTB, pcmpgtb);
3285
3286 LMI_HELPER(PSLLW, psllw);
3287 LMI_HELPER(PSLLH, psllh);
3288 LMI_HELPER(PSRLW, psrlw);
3289 LMI_HELPER(PSRLH, psrlh);
3290 LMI_HELPER(PSRAW, psraw);
3291 LMI_HELPER(PSRAH, psrah);
3292
3293 LMI_HELPER(PMULLH, pmullh);
3294 LMI_HELPER(PMULHH, pmulhh);
3295 LMI_HELPER(PMULHUH, pmulhuh);
3296 LMI_HELPER(PMADDHW, pmaddhw);
3297
3298 LMI_HELPER(PASUBUB, pasubub);
3299 LMI_HELPER_1(BIADD, biadd);
3300 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3301
3302 LMI_DIRECT(PADDD, paddd, add);
3303 LMI_DIRECT(PSUBD, psubd, sub);
3304 LMI_DIRECT(XOR_CP2, xor, xor);
3305 LMI_DIRECT(NOR_CP2, nor, nor);
3306 LMI_DIRECT(AND_CP2, and, and);
3307 LMI_DIRECT(PANDN, pandn, andc);
3308 LMI_DIRECT(OR, or, or);
3309
3310 case OPC_PINSRH_0:
3311 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3312 opn = "pinsrh_0";
3313 break;
3314 case OPC_PINSRH_1:
3315 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3316 opn = "pinsrh_1";
3317 break;
3318 case OPC_PINSRH_2:
3319 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3320 opn = "pinsrh_2";
3321 break;
3322 case OPC_PINSRH_3:
3323 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3324 opn = "pinsrh_3";
3325 break;
3326
3327 case OPC_PEXTRH:
3328 tcg_gen_andi_i64(t1, t1, 3);
3329 tcg_gen_shli_i64(t1, t1, 4);
3330 tcg_gen_shr_i64(t0, t0, t1);
3331 tcg_gen_ext16u_i64(t0, t0);
3332 opn = "pextrh";
3333 break;
3334
3335 case OPC_ADDU_CP2:
3336 tcg_gen_add_i64(t0, t0, t1);
3337 tcg_gen_ext32s_i64(t0, t0);
3338 opn = "addu";
3339 break;
3340 case OPC_SUBU_CP2:
3341 tcg_gen_sub_i64(t0, t0, t1);
3342 tcg_gen_ext32s_i64(t0, t0);
3343 opn = "addu";
3344 break;
3345
3346 case OPC_SLL_CP2:
3347 opn = "sll";
3348 shift_max = 32;
3349 goto do_shift;
3350 case OPC_SRL_CP2:
3351 opn = "srl";
3352 shift_max = 32;
3353 goto do_shift;
3354 case OPC_SRA_CP2:
3355 opn = "sra";
3356 shift_max = 32;
3357 goto do_shift;
3358 case OPC_DSLL_CP2:
3359 opn = "dsll";
3360 shift_max = 64;
3361 goto do_shift;
3362 case OPC_DSRL_CP2:
3363 opn = "dsrl";
3364 shift_max = 64;
3365 goto do_shift;
3366 case OPC_DSRA_CP2:
3367 opn = "dsra";
3368 shift_max = 64;
3369 goto do_shift;
3370 do_shift:
3371 /* Make sure shift count isn't TCG undefined behaviour. */
3372 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3373
3374 switch (opc) {
3375 case OPC_SLL_CP2:
3376 case OPC_DSLL_CP2:
3377 tcg_gen_shl_i64(t0, t0, t1);
3378 break;
3379 case OPC_SRA_CP2:
3380 case OPC_DSRA_CP2:
3381 /* Since SRA is UndefinedResult without sign-extended inputs,
3382 we can treat SRA and DSRA the same. */
3383 tcg_gen_sar_i64(t0, t0, t1);
3384 break;
3385 case OPC_SRL_CP2:
3386 /* We want to shift in zeros for SRL; zero-extend first. */
3387 tcg_gen_ext32u_i64(t0, t0);
3388 /* FALLTHRU */
3389 case OPC_DSRL_CP2:
3390 tcg_gen_shr_i64(t0, t0, t1);
3391 break;
3392 }
3393
3394 if (shift_max == 32) {
3395 tcg_gen_ext32s_i64(t0, t0);
3396 }
3397
3398 /* Shifts larger than MAX produce zero. */
3399 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3400 tcg_gen_neg_i64(t1, t1);
3401 tcg_gen_and_i64(t0, t0, t1);
3402 break;
3403
3404 case OPC_ADD_CP2:
3405 case OPC_DADD_CP2:
3406 {
3407 TCGv_i64 t2 = tcg_temp_new_i64();
3408 int lab = gen_new_label();
3409
3410 tcg_gen_mov_i64(t2, t0);
3411 tcg_gen_add_i64(t0, t1, t2);
3412 if (opc == OPC_ADD_CP2) {
3413 tcg_gen_ext32s_i64(t0, t0);
3414 }
3415 tcg_gen_xor_i64(t1, t1, t2);
3416 tcg_gen_xor_i64(t2, t2, t0);
3417 tcg_gen_andc_i64(t1, t2, t1);
3418 tcg_temp_free_i64(t2);
3419 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3420 generate_exception(ctx, EXCP_OVERFLOW);
3421 gen_set_label(lab);
3422
3423 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3424 break;
3425 }
3426
3427 case OPC_SUB_CP2:
3428 case OPC_DSUB_CP2:
3429 {
3430 TCGv_i64 t2 = tcg_temp_new_i64();
3431 int lab = gen_new_label();
3432
3433 tcg_gen_mov_i64(t2, t0);
3434 tcg_gen_sub_i64(t0, t1, t2);
3435 if (opc == OPC_SUB_CP2) {
3436 tcg_gen_ext32s_i64(t0, t0);
3437 }
3438 tcg_gen_xor_i64(t1, t1, t2);
3439 tcg_gen_xor_i64(t2, t2, t0);
3440 tcg_gen_and_i64(t1, t1, t2);
3441 tcg_temp_free_i64(t2);
3442 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3443 generate_exception(ctx, EXCP_OVERFLOW);
3444 gen_set_label(lab);
3445
3446 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3447 break;
3448 }
3449
3450 case OPC_PMULUW:
3451 tcg_gen_ext32u_i64(t0, t0);
3452 tcg_gen_ext32u_i64(t1, t1);
3453 tcg_gen_mul_i64(t0, t0, t1);
3454 opn = "pmuluw";
3455 break;
3456
3457 case OPC_SEQU_CP2:
3458 case OPC_SEQ_CP2:
3459 case OPC_SLTU_CP2:
3460 case OPC_SLT_CP2:
3461 case OPC_SLEU_CP2:
3462 case OPC_SLE_CP2:
3463 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3464 FD field is the CC field? */
3465 default:
3466 MIPS_INVAL(opn);
3467 generate_exception(ctx, EXCP_RI);
3468 return;
3469 }
3470
3471#undef LMI_HELPER
3472#undef LMI_DIRECT
3473
3474 gen_store_fpr64(ctx, t0, rd);
3475
3476 (void)opn; /* avoid a compiler warning */
3477 MIPS_DEBUG("%s %s, %s, %s", opn,
3478 fregnames[rd], fregnames[rs], fregnames[rt]);
3479 tcg_temp_free_i64(t0);
3480 tcg_temp_free_i64(t1);
3481}
3482
6af0bf9c 3483/* Traps */
7a387fff 3484static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3485 int rs, int rt, int16_t imm)
3486{
3487 int cond;
cdc0faa6 3488 TCGv t0 = tcg_temp_new();
1ba74fb8 3489 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3490
3491 cond = 0;
3492 /* Load needed operands */
3493 switch (opc) {
3494 case OPC_TEQ:
3495 case OPC_TGE:
3496 case OPC_TGEU:
3497 case OPC_TLT:
3498 case OPC_TLTU:
3499 case OPC_TNE:
3500 /* Compare two registers */
3501 if (rs != rt) {
be24bb4f
TS
3502 gen_load_gpr(t0, rs);
3503 gen_load_gpr(t1, rt);
6af0bf9c
FB
3504 cond = 1;
3505 }
179e32bb 3506 break;
6af0bf9c
FB
3507 case OPC_TEQI:
3508 case OPC_TGEI:
3509 case OPC_TGEIU:
3510 case OPC_TLTI:
3511 case OPC_TLTIU:
3512 case OPC_TNEI:
3513 /* Compare register to immediate */
3514 if (rs != 0 || imm != 0) {
be24bb4f
TS
3515 gen_load_gpr(t0, rs);
3516 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3517 cond = 1;
3518 }
3519 break;
3520 }
3521 if (cond == 0) {
3522 switch (opc) {
3523 case OPC_TEQ: /* rs == rs */
3524 case OPC_TEQI: /* r0 == 0 */
3525 case OPC_TGE: /* rs >= rs */
3526 case OPC_TGEI: /* r0 >= 0 */
3527 case OPC_TGEU: /* rs >= rs unsigned */
3528 case OPC_TGEIU: /* r0 >= 0 unsigned */
3529 /* Always trap */
cdc0faa6 3530 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3531 break;
3532 case OPC_TLT: /* rs < rs */
3533 case OPC_TLTI: /* r0 < 0 */
3534 case OPC_TLTU: /* rs < rs unsigned */
3535 case OPC_TLTIU: /* r0 < 0 unsigned */
3536 case OPC_TNE: /* rs != rs */
3537 case OPC_TNEI: /* r0 != 0 */
ead9360e 3538 /* Never trap: treat as NOP. */
cdc0faa6 3539 break;
6af0bf9c
FB
3540 }
3541 } else {
cdc0faa6
AJ
3542 int l1 = gen_new_label();
3543
6af0bf9c
FB
3544 switch (opc) {
3545 case OPC_TEQ:
3546 case OPC_TEQI:
cdc0faa6 3547 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3548 break;
3549 case OPC_TGE:
3550 case OPC_TGEI:
cdc0faa6 3551 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3552 break;
3553 case OPC_TGEU:
3554 case OPC_TGEIU:
cdc0faa6 3555 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3556 break;
3557 case OPC_TLT:
3558 case OPC_TLTI:
cdc0faa6 3559 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3560 break;
3561 case OPC_TLTU:
3562 case OPC_TLTIU:
cdc0faa6 3563 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3564 break;
3565 case OPC_TNE:
3566 case OPC_TNEI:
cdc0faa6 3567 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3568 break;
6af0bf9c 3569 }
cdc0faa6 3570 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3571 gen_set_label(l1);
3572 }
be24bb4f
TS
3573 tcg_temp_free(t0);
3574 tcg_temp_free(t1);
6af0bf9c
FB
3575}
3576
356265ae 3577static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3578{
6e256c93
FB
3579 TranslationBlock *tb;
3580 tb = ctx->tb;
7b270ef2
NF
3581 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3582 likely(!ctx->singlestep_enabled)) {
57fec1fe 3583 tcg_gen_goto_tb(n);
9b9e4393 3584 gen_save_pc(dest);
8cfd0495 3585 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 3586 } else {
9b9e4393 3587 gen_save_pc(dest);
7b270ef2
NF
3588 if (ctx->singlestep_enabled) {
3589 save_cpu_state(ctx, 0);
895c2d04 3590 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3591 }
57fec1fe 3592 tcg_gen_exit_tb(0);
6e256c93 3593 }
c53be334
FB
3594}
3595
6af0bf9c 3596/* Branches (before delay slot) */
7a387fff 3597static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3598 int insn_bytes,
6af0bf9c
FB
3599 int rs, int rt, int32_t offset)
3600{
d077b6f7 3601 target_ulong btgt = -1;
3ad4bb2d 3602 int blink = 0;
2fdbad25 3603 int bcond_compute = 0;
1ba74fb8
AJ
3604 TCGv t0 = tcg_temp_new();
3605 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3606
3607 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3608#ifdef MIPS_DEBUG_DISAS
d12d51d5 3609 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3610#endif
3ad4bb2d 3611 generate_exception(ctx, EXCP_RI);
6c5c1e20 3612 goto out;
3ad4bb2d 3613 }
6af0bf9c 3614
6af0bf9c
FB
3615 /* Load needed operands */
3616 switch (opc) {
3617 case OPC_BEQ:
3618 case OPC_BEQL:
3619 case OPC_BNE:
3620 case OPC_BNEL:
3621 /* Compare two registers */
3622 if (rs != rt) {
6c5c1e20
TS
3623 gen_load_gpr(t0, rs);
3624 gen_load_gpr(t1, rt);
2fdbad25 3625 bcond_compute = 1;
6af0bf9c 3626 }
7dca4ad0 3627 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3628 break;
3629 case OPC_BGEZ:
3630 case OPC_BGEZAL:
3c824109 3631 case OPC_BGEZALS:
6af0bf9c
FB
3632 case OPC_BGEZALL:
3633 case OPC_BGEZL:
3634 case OPC_BGTZ:
3635 case OPC_BGTZL:
3636 case OPC_BLEZ:
3637 case OPC_BLEZL:
3638 case OPC_BLTZ:
3639 case OPC_BLTZAL:
3c824109 3640 case OPC_BLTZALS:
6af0bf9c
FB
3641 case OPC_BLTZALL:
3642 case OPC_BLTZL:
3643 /* Compare to zero */
3644 if (rs != 0) {
6c5c1e20 3645 gen_load_gpr(t0, rs);
2fdbad25 3646 bcond_compute = 1;
6af0bf9c 3647 }
7dca4ad0 3648 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3649 break;
e45a93e2
JL
3650 case OPC_BPOSGE32:
3651#if defined(TARGET_MIPS64)
3652 case OPC_BPOSGE64:
3653 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3654#else
3655 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3656#endif
3657 bcond_compute = 1;
3658 btgt = ctx->pc + insn_bytes + offset;
3659 break;
6af0bf9c
FB
3660 case OPC_J:
3661 case OPC_JAL:
364d4831 3662 case OPC_JALX:
620e48f6
NF
3663 case OPC_JALS:
3664 case OPC_JALXS:
6af0bf9c 3665 /* Jump to immediate */
7dca4ad0 3666 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3667 break;
3668 case OPC_JR:
3669 case OPC_JALR:
364d4831 3670 case OPC_JALRC:
620e48f6 3671 case OPC_JALRS:
6af0bf9c 3672 /* Jump to register */
7a387fff
TS
3673 if (offset != 0 && offset != 16) {
3674 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3675 others are reserved. */
923617a3 3676 MIPS_INVAL("jump hint");
6af0bf9c 3677 generate_exception(ctx, EXCP_RI);
6c5c1e20 3678 goto out;
6af0bf9c 3679 }
d077b6f7 3680 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3681 break;
3682 default:
3683 MIPS_INVAL("branch/jump");
3684 generate_exception(ctx, EXCP_RI);
6c5c1e20 3685 goto out;
6af0bf9c 3686 }
2fdbad25 3687 if (bcond_compute == 0) {
6af0bf9c
FB
3688 /* No condition to be computed */
3689 switch (opc) {
3690 case OPC_BEQ: /* rx == rx */
3691 case OPC_BEQL: /* rx == rx likely */
3692 case OPC_BGEZ: /* 0 >= 0 */
3693 case OPC_BGEZL: /* 0 >= 0 likely */
3694 case OPC_BLEZ: /* 0 <= 0 */
3695 case OPC_BLEZL: /* 0 <= 0 likely */
3696 /* Always take */
4ad40f36 3697 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3698 MIPS_DEBUG("balways");
3699 break;
3c824109 3700 case OPC_BGEZALS:
6af0bf9c
FB
3701 case OPC_BGEZAL: /* 0 >= 0 */
3702 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3703 ctx->hflags |= (opc == OPC_BGEZALS
3704 ? MIPS_HFLAG_BDS16
3705 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3706 /* Always take and link */
3707 blink = 31;
4ad40f36 3708 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3709 MIPS_DEBUG("balways and link");
3710 break;
3711 case OPC_BNE: /* rx != rx */
3712 case OPC_BGTZ: /* 0 > 0 */
3713 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3714 /* Treat as NOP. */
6af0bf9c 3715 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3716 goto out;
3c824109 3717 case OPC_BLTZALS:
eeef26cd 3718 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3719 ctx->hflags |= (opc == OPC_BLTZALS
3720 ? MIPS_HFLAG_BDS16
3721 : MIPS_HFLAG_BDS32);
3722 /* Handle as an unconditional branch to get correct delay
3723 slot checking. */
3724 blink = 31;
3725 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3726 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3727 MIPS_DEBUG("bnever and link");
3c824109 3728 break;
eeef26cd 3729 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3730 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3731 /* Skip the instruction in the delay slot */
3732 MIPS_DEBUG("bnever, link and skip");
3733 ctx->pc += 4;
6c5c1e20 3734 goto out;
6af0bf9c
FB
3735 case OPC_BNEL: /* rx != rx likely */
3736 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3737 case OPC_BLTZL: /* 0 < 0 likely */
3738 /* Skip the instruction in the delay slot */
3739 MIPS_DEBUG("bnever and skip");
9898128f 3740 ctx->pc += 4;
6c5c1e20 3741 goto out;
6af0bf9c 3742 case OPC_J:
4ad40f36 3743 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3744 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3745 break;
620e48f6 3746 case OPC_JALXS:
364d4831
NF
3747 case OPC_JALX:
3748 ctx->hflags |= MIPS_HFLAG_BX;
3749 /* Fallthrough */
620e48f6 3750 case OPC_JALS:
6af0bf9c
FB
3751 case OPC_JAL:
3752 blink = 31;
4ad40f36 3753 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3754 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3755 ? MIPS_HFLAG_BDS16
3756 : MIPS_HFLAG_BDS32);
d077b6f7 3757 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3758 break;
3759 case OPC_JR:
4ad40f36 3760 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3761 if (insn_bytes == 4)
3762 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3763 MIPS_DEBUG("jr %s", regnames[rs]);
3764 break;
620e48f6 3765 case OPC_JALRS:
6af0bf9c 3766 case OPC_JALR:
364d4831 3767 case OPC_JALRC:
6af0bf9c 3768 blink = rt;
4ad40f36 3769 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3770 ctx->hflags |= (opc == OPC_JALRS
3771 ? MIPS_HFLAG_BDS16
3772 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3773 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3774 break;
3775 default:
3776 MIPS_INVAL("branch/jump");
3777 generate_exception(ctx, EXCP_RI);
6c5c1e20 3778 goto out;
6af0bf9c
FB
3779 }
3780 } else {
3781 switch (opc) {
3782 case OPC_BEQ:
e68dd28f 3783 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3784 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3785 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3786 goto not_likely;
3787 case OPC_BEQL:
e68dd28f 3788 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3789 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3790 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3791 goto likely;
3792 case OPC_BNE:
e68dd28f 3793 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3794 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3795 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3796 goto not_likely;
3797 case OPC_BNEL:
e68dd28f 3798 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3799 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3800 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3801 goto likely;
3802 case OPC_BGEZ:
e68dd28f 3803 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3804 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3805 goto not_likely;
3806 case OPC_BGEZL:
e68dd28f 3807 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3808 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3809 goto likely;
3c824109 3810 case OPC_BGEZALS:
6af0bf9c 3811 case OPC_BGEZAL:
3c824109
NF
3812 ctx->hflags |= (opc == OPC_BGEZALS
3813 ? MIPS_HFLAG_BDS16
3814 : MIPS_HFLAG_BDS32);
e68dd28f 3815 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3816 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3817 blink = 31;
3818 goto not_likely;
3819 case OPC_BGEZALL:
e68dd28f 3820 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3821 blink = 31;
d077b6f7 3822 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3823 goto likely;
3824 case OPC_BGTZ:
e68dd28f 3825 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3826 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3827 goto not_likely;
3828 case OPC_BGTZL:
e68dd28f 3829 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3830 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3831 goto likely;
3832 case OPC_BLEZ:
e68dd28f 3833 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3834 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3835 goto not_likely;
3836 case OPC_BLEZL:
e68dd28f 3837 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3838 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3839 goto likely;
3840 case OPC_BLTZ:
e68dd28f 3841 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3842 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3843 goto not_likely;
3844 case OPC_BLTZL:
e68dd28f 3845 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3846 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3847 goto likely;
e45a93e2
JL
3848 case OPC_BPOSGE32:
3849 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3850 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3851 goto not_likely;
3852#if defined(TARGET_MIPS64)
3853 case OPC_BPOSGE64:
3854 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3855 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3856 goto not_likely;
3857#endif
3c824109 3858 case OPC_BLTZALS:
6af0bf9c 3859 case OPC_BLTZAL:
3c824109
NF
3860 ctx->hflags |= (opc == OPC_BLTZALS
3861 ? MIPS_HFLAG_BDS16
3862 : MIPS_HFLAG_BDS32);
e68dd28f 3863 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3864 blink = 31;
d077b6f7 3865 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3866 not_likely:
4ad40f36 3867 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3868 break;
3869 case OPC_BLTZALL:
e68dd28f 3870 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3871 blink = 31;
d077b6f7 3872 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3873 likely:
4ad40f36 3874 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3875 break;
c53f4a62
TS
3876 default:
3877 MIPS_INVAL("conditional branch/jump");
3878 generate_exception(ctx, EXCP_RI);
6c5c1e20 3879 goto out;
6af0bf9c 3880 }
6af0bf9c 3881 }
923617a3 3882 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3883 blink, ctx->hflags, btgt);
9b9e4393 3884
d077b6f7 3885 ctx->btarget = btgt;
6af0bf9c 3886 if (blink > 0) {
364d4831
NF
3887 int post_delay = insn_bytes;
3888 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3889
3890 if (opc != OPC_JALRC)
3891 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3892
3893 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3894 }
6c5c1e20
TS
3895
3896 out:
364d4831
NF
3897 if (insn_bytes == 2)
3898 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3899 tcg_temp_free(t0);
3900 tcg_temp_free(t1);
6af0bf9c
FB
3901}
3902
7a387fff
TS
3903/* special3 bitfield operations */
3904static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3905 int rs, int lsb, int msb)
7a387fff 3906{
a7812ae4
PB
3907 TCGv t0 = tcg_temp_new();
3908 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3909
3910 gen_load_gpr(t1, rs);
7a387fff
TS
3911 switch (opc) {
3912 case OPC_EXT:
3913 if (lsb + msb > 31)
3914 goto fail;
505ad7c2
AJ
3915 tcg_gen_shri_tl(t0, t1, lsb);
3916 if (msb != 31) {
3917 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3918 } else {
3919 tcg_gen_ext32s_tl(t0, t0);
3920 }
7a387fff 3921 break;
c6d6dd7c 3922#if defined(TARGET_MIPS64)
7a387fff 3923 case OPC_DEXTM:
505ad7c2
AJ
3924 tcg_gen_shri_tl(t0, t1, lsb);
3925 if (msb != 31) {
3926 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3927 }
7a387fff
TS
3928 break;
3929 case OPC_DEXTU:
505ad7c2
AJ
3930 tcg_gen_shri_tl(t0, t1, lsb + 32);
3931 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3932 break;
3933 case OPC_DEXT:
505ad7c2
AJ
3934 tcg_gen_shri_tl(t0, t1, lsb);
3935 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3936 break;
c6d6dd7c 3937#endif
7a387fff
TS
3938 case OPC_INS:
3939 if (lsb > msb)
3940 goto fail;
6c5c1e20 3941 gen_load_gpr(t0, rt);
e0d002f1 3942 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3943 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3944 break;
c6d6dd7c 3945#if defined(TARGET_MIPS64)
7a387fff 3946 case OPC_DINSM:
6c5c1e20 3947 gen_load_gpr(t0, rt);
e0d002f1 3948 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3949 break;
3950 case OPC_DINSU:
6c5c1e20 3951 gen_load_gpr(t0, rt);
e0d002f1 3952 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3953 break;
3954 case OPC_DINS:
6c5c1e20 3955 gen_load_gpr(t0, rt);
e0d002f1 3956 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3957 break;
c6d6dd7c 3958#endif
7a387fff
TS
3959 default:
3960fail:
3961 MIPS_INVAL("bitops");
3962 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3963 tcg_temp_free(t0);
3964 tcg_temp_free(t1);
7a387fff
TS
3965 return;
3966 }
6c5c1e20
TS
3967 gen_store_gpr(t0, rt);
3968 tcg_temp_free(t0);
3969 tcg_temp_free(t1);
7a387fff
TS
3970}
3971
49bcf33c
AJ
3972static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3973{
3a55fa47 3974 TCGv t0;
49bcf33c 3975
3a55fa47
AJ
3976 if (rd == 0) {
3977 /* If no destination, treat it as a NOP. */
3978 MIPS_DEBUG("NOP");
3979 return;
3980 }
3981
3982 t0 = tcg_temp_new();
3983 gen_load_gpr(t0, rt);
49bcf33c
AJ
3984 switch (op2) {
3985 case OPC_WSBH:
3a55fa47
AJ
3986 {
3987 TCGv t1 = tcg_temp_new();
3988
3989 tcg_gen_shri_tl(t1, t0, 8);
3990 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3991 tcg_gen_shli_tl(t0, t0, 8);
3992 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3993 tcg_gen_or_tl(t0, t0, t1);
3994 tcg_temp_free(t1);
3995 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3996 }
49bcf33c
AJ
3997 break;
3998 case OPC_SEB:
3a55fa47 3999 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4000 break;
4001 case OPC_SEH:
3a55fa47 4002 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4003 break;
4004#if defined(TARGET_MIPS64)
4005 case OPC_DSBH:
3a55fa47
AJ
4006 {
4007 TCGv t1 = tcg_temp_new();
4008
4009 tcg_gen_shri_tl(t1, t0, 8);
4010 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4011 tcg_gen_shli_tl(t0, t0, 8);
4012 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4013 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4014 tcg_temp_free(t1);
4015 }
49bcf33c
AJ
4016 break;
4017 case OPC_DSHD:
3a55fa47
AJ
4018 {
4019 TCGv t1 = tcg_temp_new();
4020
4021 tcg_gen_shri_tl(t1, t0, 16);
4022 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4023 tcg_gen_shli_tl(t0, t0, 16);
4024 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4025 tcg_gen_or_tl(t0, t0, t1);
4026 tcg_gen_shri_tl(t1, t0, 32);
4027 tcg_gen_shli_tl(t0, t0, 32);
4028 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4029 tcg_temp_free(t1);
4030 }
49bcf33c
AJ
4031 break;
4032#endif
4033 default:
4034 MIPS_INVAL("bsfhl");
4035 generate_exception(ctx, EXCP_RI);
4036 tcg_temp_free(t0);
49bcf33c
AJ
4037 return;
4038 }
49bcf33c 4039 tcg_temp_free(t0);
49bcf33c
AJ
4040}
4041
f1aa6320 4042#ifndef CONFIG_USER_ONLY
0eaef5aa 4043/* CP0 (MMU and control) */
d9bea114 4044static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4045{
d9bea114 4046 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4047
d9bea114
AJ
4048 tcg_gen_ld_i32(t0, cpu_env, off);
4049 tcg_gen_ext_i32_tl(arg, t0);
4050 tcg_temp_free_i32(t0);
4f57689a
TS
4051}
4052
d9bea114 4053static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4054{
d9bea114
AJ
4055 tcg_gen_ld_tl(arg, cpu_env, off);
4056 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4057}
4058
d9bea114 4059static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4060{
d9bea114 4061 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4062
d9bea114
AJ
4063 tcg_gen_trunc_tl_i32(t0, arg);
4064 tcg_gen_st_i32(t0, cpu_env, off);
4065 tcg_temp_free_i32(t0);
f1aa6320
TS
4066}
4067
d9bea114 4068static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4069{
d9bea114
AJ
4070 tcg_gen_ext32s_tl(arg, arg);
4071 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4072}
4073
d75c135e 4074static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4075{
7a387fff 4076 const char *rn = "invalid";
873eb012 4077
e189e748 4078 if (sel != 0)
d75c135e 4079 check_insn(ctx, ISA_MIPS32);
e189e748 4080
873eb012
TS
4081 switch (reg) {
4082 case 0:
7a387fff
TS
4083 switch (sel) {
4084 case 0:
7db13fae 4085 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4086 rn = "Index";
4087 break;
4088 case 1:
d75c135e 4089 check_insn(ctx, ASE_MT);
895c2d04 4090 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4091 rn = "MVPControl";
ead9360e 4092 break;
7a387fff 4093 case 2:
d75c135e 4094 check_insn(ctx, ASE_MT);
895c2d04 4095 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4096 rn = "MVPConf0";
ead9360e 4097 break;
7a387fff 4098 case 3:
d75c135e 4099 check_insn(ctx, ASE_MT);
895c2d04 4100 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4101 rn = "MVPConf1";
ead9360e 4102 break;
7a387fff
TS
4103 default:
4104 goto die;
4105 }
873eb012
TS
4106 break;
4107 case 1:
7a387fff
TS
4108 switch (sel) {
4109 case 0:
895c2d04 4110 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4111 rn = "Random";
2423f660 4112 break;
7a387fff 4113 case 1:
d75c135e 4114 check_insn(ctx, ASE_MT);
7db13fae 4115 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4116 rn = "VPEControl";
ead9360e 4117 break;
7a387fff 4118 case 2:
d75c135e 4119 check_insn(ctx, ASE_MT);
7db13fae 4120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4121 rn = "VPEConf0";
ead9360e 4122 break;
7a387fff 4123 case 3:
d75c135e 4124 check_insn(ctx, ASE_MT);
7db13fae 4125 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4126 rn = "VPEConf1";
ead9360e 4127 break;
7a387fff 4128 case 4:
d75c135e 4129 check_insn(ctx, ASE_MT);
7db13fae 4130 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4131 rn = "YQMask";
ead9360e 4132 break;
7a387fff 4133 case 5:
d75c135e 4134 check_insn(ctx, ASE_MT);
7db13fae 4135 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4136 rn = "VPESchedule";
ead9360e 4137 break;
7a387fff 4138 case 6:
d75c135e 4139 check_insn(ctx, ASE_MT);
7db13fae 4140 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4141 rn = "VPEScheFBack";
ead9360e 4142 break;
7a387fff 4143 case 7:
d75c135e 4144 check_insn(ctx, ASE_MT);
7db13fae 4145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4146 rn = "VPEOpt";
ead9360e 4147 break;
7a387fff
TS
4148 default:
4149 goto die;
4150 }
873eb012
TS
4151 break;
4152 case 2:
7a387fff
TS
4153 switch (sel) {
4154 case 0:
7db13fae 4155 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4156 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4157 rn = "EntryLo0";
4158 break;
7a387fff 4159 case 1:
d75c135e 4160 check_insn(ctx, ASE_MT);
895c2d04 4161 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4162 rn = "TCStatus";
ead9360e 4163 break;
7a387fff 4164 case 2:
d75c135e 4165 check_insn(ctx, ASE_MT);
895c2d04 4166 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4167 rn = "TCBind";
ead9360e 4168 break;
7a387fff 4169 case 3:
d75c135e 4170 check_insn(ctx, ASE_MT);
895c2d04 4171 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4172 rn = "TCRestart";
ead9360e 4173 break;
7a387fff 4174 case 4:
d75c135e 4175 check_insn(ctx, ASE_MT);
895c2d04 4176 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4177 rn = "TCHalt";
ead9360e 4178 break;
7a387fff 4179 case 5:
d75c135e 4180 check_insn(ctx, ASE_MT);
895c2d04 4181 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4182 rn = "TCContext";
ead9360e 4183 break;
7a387fff 4184 case 6:
d75c135e 4185 check_insn(ctx, ASE_MT);
895c2d04 4186 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4187 rn = "TCSchedule";
ead9360e 4188 break;
7a387fff 4189 case 7:
d75c135e 4190 check_insn(ctx, ASE_MT);
895c2d04 4191 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4192 rn = "TCScheFBack";
ead9360e 4193 break;
7a387fff
TS
4194 default:
4195 goto die;
4196 }
873eb012
TS
4197 break;
4198 case 3:
7a387fff
TS
4199 switch (sel) {
4200 case 0:
7db13fae 4201 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4202 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4203 rn = "EntryLo1";
4204 break;
7a387fff
TS
4205 default:
4206 goto die;
1579a72e 4207 }
873eb012
TS
4208 break;
4209 case 4:
7a387fff
TS
4210 switch (sel) {
4211 case 0:
7db13fae 4212 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4213 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4214 rn = "Context";
4215 break;
7a387fff 4216 case 1:
d9bea114 4217// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 4218 rn = "ContextConfig";
d279279e 4219 goto die;
2423f660 4220// break;
d279279e
PJ
4221 case 2:
4222 if (ctx->ulri) {
4223 tcg_gen_ld32s_tl(arg, cpu_env,
4224 offsetof(CPUMIPSState,
4225 active_tc.CP0_UserLocal));
4226 rn = "UserLocal";
4227 } else {
4228 tcg_gen_movi_tl(arg, 0);
4229 }
4230 break;
7a387fff
TS
4231 default:
4232 goto die;
1579a72e 4233 }
873eb012
TS
4234 break;
4235 case 5:
7a387fff
TS
4236 switch (sel) {
4237 case 0:
7db13fae 4238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4239 rn = "PageMask";
4240 break;
7a387fff 4241 case 1:
d75c135e 4242 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4244 rn = "PageGrain";
4245 break;
7a387fff
TS
4246 default:
4247 goto die;
1579a72e 4248 }
873eb012
TS
4249 break;
4250 case 6:
7a387fff
TS
4251 switch (sel) {
4252 case 0:
7db13fae 4253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4254 rn = "Wired";
4255 break;
7a387fff 4256 case 1:
d75c135e 4257 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4259 rn = "SRSConf0";
ead9360e 4260 break;
7a387fff 4261 case 2:
d75c135e 4262 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4264 rn = "SRSConf1";
ead9360e 4265 break;
7a387fff 4266 case 3:
d75c135e 4267 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4269 rn = "SRSConf2";
ead9360e 4270 break;
7a387fff 4271 case 4:
d75c135e 4272 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4274 rn = "SRSConf3";
ead9360e 4275 break;
7a387fff 4276 case 5:
d75c135e 4277 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4279 rn = "SRSConf4";
ead9360e 4280 break;
7a387fff
TS
4281 default:
4282 goto die;
1579a72e 4283 }
873eb012 4284 break;
8c0fdd85 4285 case 7:
7a387fff
TS
4286 switch (sel) {
4287 case 0:
d75c135e 4288 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4289 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4290 rn = "HWREna";
4291 break;
7a387fff
TS
4292 default:
4293 goto die;
1579a72e 4294 }
8c0fdd85 4295 break;
873eb012 4296 case 8:
7a387fff
TS
4297 switch (sel) {
4298 case 0:
7db13fae 4299 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4300 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4301 rn = "BadVAddr";
2423f660 4302 break;
7a387fff
TS
4303 default:
4304 goto die;
4305 }
873eb012
TS
4306 break;
4307 case 9:
7a387fff
TS
4308 switch (sel) {
4309 case 0:
2e70f6ef
PB
4310 /* Mark as an IO operation because we read the time. */
4311 if (use_icount)
4312 gen_io_start();
895c2d04 4313 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4314 if (use_icount) {
4315 gen_io_end();
2e70f6ef 4316 }
55807224
EI
4317 /* Break the TB to be able to take timer interrupts immediately
4318 after reading count. */
4319 ctx->bstate = BS_STOP;
2423f660
TS
4320 rn = "Count";
4321 break;
4322 /* 6,7 are implementation dependent */
7a387fff
TS
4323 default:
4324 goto die;
2423f660 4325 }
873eb012
TS
4326 break;
4327 case 10:
7a387fff
TS
4328 switch (sel) {
4329 case 0:
7db13fae 4330 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4331 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4332 rn = "EntryHi";
4333 break;
7a387fff
TS
4334 default:
4335 goto die;
1579a72e 4336 }
873eb012
TS
4337 break;
4338 case 11:
7a387fff
TS
4339 switch (sel) {
4340 case 0:
7db13fae 4341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4342 rn = "Compare";
4343 break;
4344 /* 6,7 are implementation dependent */
7a387fff
TS
4345 default:
4346 goto die;
2423f660 4347 }
873eb012
TS
4348 break;
4349 case 12:
7a387fff
TS
4350 switch (sel) {
4351 case 0:
7db13fae 4352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4353 rn = "Status";
4354 break;
7a387fff 4355 case 1:
d75c135e 4356 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4358 rn = "IntCtl";
4359 break;
7a387fff 4360 case 2:
d75c135e 4361 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4363 rn = "SRSCtl";
4364 break;
7a387fff 4365 case 3:
d75c135e 4366 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4368 rn = "SRSMap";
fd88b6ab 4369 break;
7a387fff
TS
4370 default:
4371 goto die;
4372 }
873eb012
TS
4373 break;
4374 case 13:
7a387fff
TS
4375 switch (sel) {
4376 case 0:
7db13fae 4377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4378 rn = "Cause";
4379 break;
7a387fff
TS
4380 default:
4381 goto die;
4382 }
873eb012
TS
4383 break;
4384 case 14:
7a387fff
TS
4385 switch (sel) {
4386 case 0:
7db13fae 4387 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4388 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4389 rn = "EPC";
4390 break;
7a387fff
TS
4391 default:
4392 goto die;
1579a72e 4393 }
873eb012
TS
4394 break;
4395 case 15:
7a387fff
TS
4396 switch (sel) {
4397 case 0:
7db13fae 4398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4399 rn = "PRid";
4400 break;
7a387fff 4401 case 1:
d75c135e 4402 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4404 rn = "EBase";
4405 break;
7a387fff
TS
4406 default:
4407 goto die;
4408 }
873eb012
TS
4409 break;
4410 case 16:
4411 switch (sel) {
4412 case 0:
7db13fae 4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4414 rn = "Config";
4415 break;
4416 case 1:
7db13fae 4417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4418 rn = "Config1";
4419 break;
7a387fff 4420 case 2:
7db13fae 4421 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4422 rn = "Config2";
4423 break;
4424 case 3:
7db13fae 4425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4426 rn = "Config3";
4427 break;
b4160af1
PJ
4428 case 4:
4429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4430 rn = "Config4";
4431 break;
b4dd99a3
PJ
4432 case 5:
4433 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4434 rn = "Config5";
4435 break;
e397ee33
TS
4436 /* 6,7 are implementation dependent */
4437 case 6:
7db13fae 4438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4439 rn = "Config6";
4440 break;
4441 case 7:
7db13fae 4442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4443 rn = "Config7";
4444 break;
873eb012 4445 default:
873eb012
TS
4446 goto die;
4447 }
4448 break;
4449 case 17:
7a387fff
TS
4450 switch (sel) {
4451 case 0:
895c2d04 4452 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4453 rn = "LLAddr";
4454 break;
7a387fff
TS
4455 default:
4456 goto die;
4457 }
873eb012
TS
4458 break;
4459 case 18:
7a387fff 4460 switch (sel) {
fd88b6ab 4461 case 0 ... 7:
895c2d04 4462 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4463 rn = "WatchLo";
4464 break;
7a387fff
TS
4465 default:
4466 goto die;
4467 }
873eb012
TS
4468 break;
4469 case 19:
7a387fff 4470 switch (sel) {
fd88b6ab 4471 case 0 ...7:
895c2d04 4472 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4473 rn = "WatchHi";
4474 break;
7a387fff
TS
4475 default:
4476 goto die;
4477 }
873eb012 4478 break;
8c0fdd85 4479 case 20:
7a387fff
TS
4480 switch (sel) {
4481 case 0:
d26bc211 4482#if defined(TARGET_MIPS64)
d75c135e 4483 check_insn(ctx, ISA_MIPS3);
7db13fae 4484 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4485 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4486 rn = "XContext";
4487 break;
703eaf37 4488#endif
7a387fff
TS
4489 default:
4490 goto die;
4491 }
8c0fdd85
TS
4492 break;
4493 case 21:
7a387fff
TS
4494 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4495 switch (sel) {
4496 case 0:
7db13fae 4497 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4498 rn = "Framemask";
4499 break;
7a387fff
TS
4500 default:
4501 goto die;
4502 }
8c0fdd85
TS
4503 break;
4504 case 22:
d9bea114 4505 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4506 rn = "'Diagnostic"; /* implementation dependent */
4507 break;
873eb012 4508 case 23:
7a387fff
TS
4509 switch (sel) {
4510 case 0:
895c2d04 4511 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4512 rn = "Debug";
4513 break;
7a387fff 4514 case 1:
d9bea114 4515// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4516 rn = "TraceControl";
4517// break;
7a387fff 4518 case 2:
d9bea114 4519// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4520 rn = "TraceControl2";
4521// break;
7a387fff 4522 case 3:
d9bea114 4523// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4524 rn = "UserTraceData";
4525// break;
7a387fff 4526 case 4:
d9bea114 4527// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4528 rn = "TraceBPC";
4529// break;
7a387fff
TS
4530 default:
4531 goto die;
4532 }
873eb012
TS
4533 break;
4534 case 24:
7a387fff
TS
4535 switch (sel) {
4536 case 0:
f0b3f3ae 4537 /* EJTAG support */
7db13fae 4538 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4539 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4540 rn = "DEPC";
4541 break;
7a387fff
TS
4542 default:
4543 goto die;
4544 }
873eb012 4545 break;
8c0fdd85 4546 case 25:
7a387fff
TS
4547 switch (sel) {
4548 case 0:
7db13fae 4549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4550 rn = "Performance0";
7a387fff
TS
4551 break;
4552 case 1:
d9bea114 4553// gen_helper_mfc0_performance1(arg);
2423f660
TS
4554 rn = "Performance1";
4555// break;
7a387fff 4556 case 2:
d9bea114 4557// gen_helper_mfc0_performance2(arg);
2423f660
TS
4558 rn = "Performance2";
4559// break;
7a387fff 4560 case 3:
d9bea114 4561// gen_helper_mfc0_performance3(arg);
2423f660
TS
4562 rn = "Performance3";
4563// break;
7a387fff 4564 case 4:
d9bea114 4565// gen_helper_mfc0_performance4(arg);
2423f660
TS
4566 rn = "Performance4";
4567// break;
7a387fff 4568 case 5:
d9bea114 4569// gen_helper_mfc0_performance5(arg);
2423f660
TS
4570 rn = "Performance5";
4571// break;
7a387fff 4572 case 6:
d9bea114 4573// gen_helper_mfc0_performance6(arg);
2423f660
TS
4574 rn = "Performance6";
4575// break;
7a387fff 4576 case 7:
d9bea114 4577// gen_helper_mfc0_performance7(arg);
2423f660
TS
4578 rn = "Performance7";
4579// break;
7a387fff
TS
4580 default:
4581 goto die;
4582 }
8c0fdd85
TS
4583 break;
4584 case 26:
d9bea114 4585 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4586 rn = "ECC";
4587 break;
8c0fdd85 4588 case 27:
7a387fff 4589 switch (sel) {
7a387fff 4590 case 0 ... 3:
d9bea114 4591 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4592 rn = "CacheErr";
4593 break;
7a387fff
TS
4594 default:
4595 goto die;
4596 }
8c0fdd85 4597 break;
873eb012
TS
4598 case 28:
4599 switch (sel) {
4600 case 0:
7a387fff
TS
4601 case 2:
4602 case 4:
4603 case 6:
7db13fae 4604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4605 rn = "TagLo";
4606 break;
4607 case 1:
7a387fff
TS
4608 case 3:
4609 case 5:
4610 case 7:
7db13fae 4611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4612 rn = "DataLo";
4613 break;
4614 default:
873eb012
TS
4615 goto die;
4616 }
4617 break;
8c0fdd85 4618 case 29:
7a387fff
TS
4619 switch (sel) {
4620 case 0:
4621 case 2:
4622 case 4:
4623 case 6:
7db13fae 4624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4625 rn = "TagHi";
4626 break;
4627 case 1:
4628 case 3:
4629 case 5:
4630 case 7:
7db13fae 4631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4632 rn = "DataHi";
4633 break;
4634 default:
4635 goto die;
4636 }
8c0fdd85 4637 break;
873eb012 4638 case 30:
7a387fff
TS
4639 switch (sel) {
4640 case 0:
7db13fae 4641 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4642 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4643 rn = "ErrorEPC";
4644 break;
7a387fff
TS
4645 default:
4646 goto die;
4647 }
873eb012
TS
4648 break;
4649 case 31:
7a387fff
TS
4650 switch (sel) {
4651 case 0:
f0b3f3ae 4652 /* EJTAG support */
7db13fae 4653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4654 rn = "DESAVE";
4655 break;
7a387fff
TS
4656 default:
4657 goto die;
4658 }
873eb012
TS
4659 break;
4660 default:
873eb012
TS
4661 goto die;
4662 }
2abf314d 4663 (void)rn; /* avoid a compiler warning */
d12d51d5 4664 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4665 return;
4666
4667die:
d12d51d5 4668 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4669 generate_exception(ctx, EXCP_RI);
4670}
4671
d75c135e 4672static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4673{
7a387fff
TS
4674 const char *rn = "invalid";
4675
e189e748 4676 if (sel != 0)
d75c135e 4677 check_insn(ctx, ISA_MIPS32);
e189e748 4678
2e70f6ef
PB
4679 if (use_icount)
4680 gen_io_start();
4681
8c0fdd85
TS
4682 switch (reg) {
4683 case 0:
7a387fff
TS
4684 switch (sel) {
4685 case 0:
895c2d04 4686 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4687 rn = "Index";
4688 break;
4689 case 1:
d75c135e 4690 check_insn(ctx, ASE_MT);
895c2d04 4691 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4692 rn = "MVPControl";
ead9360e 4693 break;
7a387fff 4694 case 2:
d75c135e 4695 check_insn(ctx, ASE_MT);
ead9360e 4696 /* ignored */
7a387fff 4697 rn = "MVPConf0";
ead9360e 4698 break;
7a387fff 4699 case 3:
d75c135e 4700 check_insn(ctx, ASE_MT);
ead9360e 4701 /* ignored */
7a387fff 4702 rn = "MVPConf1";
ead9360e 4703 break;
7a387fff
TS
4704 default:
4705 goto die;
4706 }
8c0fdd85
TS
4707 break;
4708 case 1:
7a387fff
TS
4709 switch (sel) {
4710 case 0:
2423f660 4711 /* ignored */
7a387fff 4712 rn = "Random";
2423f660 4713 break;
7a387fff 4714 case 1:
d75c135e 4715 check_insn(ctx, ASE_MT);
895c2d04 4716 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4717 rn = "VPEControl";
ead9360e 4718 break;
7a387fff 4719 case 2:
d75c135e 4720 check_insn(ctx, ASE_MT);
895c2d04 4721 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4722 rn = "VPEConf0";
ead9360e 4723 break;
7a387fff 4724 case 3:
d75c135e 4725 check_insn(ctx, ASE_MT);
895c2d04 4726 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4727 rn = "VPEConf1";
ead9360e 4728 break;
7a387fff 4729 case 4:
d75c135e 4730 check_insn(ctx, ASE_MT);
895c2d04 4731 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4732 rn = "YQMask";
ead9360e 4733 break;
7a387fff 4734 case 5:
d75c135e 4735 check_insn(ctx, ASE_MT);
7db13fae 4736 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4737 rn = "VPESchedule";
ead9360e 4738 break;
7a387fff 4739 case 6:
d75c135e 4740 check_insn(ctx, ASE_MT);
7db13fae 4741 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4742 rn = "VPEScheFBack";
ead9360e 4743 break;
7a387fff 4744 case 7:
d75c135e 4745 check_insn(ctx, ASE_MT);
895c2d04 4746 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4747 rn = "VPEOpt";
ead9360e 4748 break;
7a387fff
TS
4749 default:
4750 goto die;
4751 }
8c0fdd85
TS
4752 break;
4753 case 2:
7a387fff
TS
4754 switch (sel) {
4755 case 0:
895c2d04 4756 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4757 rn = "EntryLo0";
4758 break;
7a387fff 4759 case 1:
d75c135e 4760 check_insn(ctx, ASE_MT);
895c2d04 4761 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4762 rn = "TCStatus";
ead9360e 4763 break;
7a387fff 4764 case 2:
d75c135e 4765 check_insn(ctx, ASE_MT);
895c2d04 4766 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4767 rn = "TCBind";
ead9360e 4768 break;
7a387fff 4769 case 3:
d75c135e 4770 check_insn(ctx, ASE_MT);
895c2d04 4771 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4772 rn = "TCRestart";
ead9360e 4773 break;
7a387fff 4774 case 4:
d75c135e 4775 check_insn(ctx, ASE_MT);
895c2d04 4776 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4777 rn = "TCHalt";
ead9360e 4778 break;
7a387fff 4779 case 5:
d75c135e 4780 check_insn(ctx, ASE_MT);
895c2d04 4781 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4782 rn = "TCContext";
ead9360e 4783 break;
7a387fff 4784 case 6:
d75c135e 4785 check_insn(ctx, ASE_MT);
895c2d04 4786 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4787 rn = "TCSchedule";
ead9360e 4788 break;
7a387fff 4789 case 7:
d75c135e 4790 check_insn(ctx, ASE_MT);
895c2d04 4791 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4792 rn = "TCScheFBack";
ead9360e 4793 break;
7a387fff
TS
4794 default:
4795 goto die;
4796 }
8c0fdd85
TS
4797 break;
4798 case 3:
7a387fff
TS
4799 switch (sel) {
4800 case 0:
895c2d04 4801 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4802 rn = "EntryLo1";
4803 break;
7a387fff
TS
4804 default:
4805 goto die;
876d4b07 4806 }
8c0fdd85
TS
4807 break;
4808 case 4:
7a387fff
TS
4809 switch (sel) {
4810 case 0:
895c2d04 4811 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4812 rn = "Context";
4813 break;
7a387fff 4814 case 1:
895c2d04 4815// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 4816 rn = "ContextConfig";
d279279e 4817 goto die;
2423f660 4818// break;
d279279e
PJ
4819 case 2:
4820 if (ctx->ulri) {
4821 tcg_gen_st_tl(arg, cpu_env,
4822 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
4823 rn = "UserLocal";
4824 }
4825 break;
7a387fff
TS
4826 default:
4827 goto die;
876d4b07 4828 }
8c0fdd85
TS
4829 break;
4830 case 5:
7a387fff
TS
4831 switch (sel) {
4832 case 0:
895c2d04 4833 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4834 rn = "PageMask";
4835 break;
7a387fff 4836 case 1:
d75c135e 4837 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4838 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4839 rn = "PageGrain";
4840 break;
7a387fff
TS
4841 default:
4842 goto die;
876d4b07 4843 }
8c0fdd85
TS
4844 break;
4845 case 6:
7a387fff
TS
4846 switch (sel) {
4847 case 0:
895c2d04 4848 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4849 rn = "Wired";
4850 break;
7a387fff 4851 case 1:
d75c135e 4852 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4853 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4854 rn = "SRSConf0";
ead9360e 4855 break;
7a387fff 4856 case 2:
d75c135e 4857 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4858 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4859 rn = "SRSConf1";
ead9360e 4860 break;
7a387fff 4861 case 3:
d75c135e 4862 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4863 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4864 rn = "SRSConf2";
ead9360e 4865 break;
7a387fff 4866 case 4:
d75c135e 4867 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4868 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4869 rn = "SRSConf3";
ead9360e 4870 break;
7a387fff 4871 case 5:
d75c135e 4872 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4873 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4874 rn = "SRSConf4";
ead9360e 4875 break;
7a387fff
TS
4876 default:
4877 goto die;
876d4b07 4878 }
8c0fdd85
TS
4879 break;
4880 case 7:
7a387fff
TS
4881 switch (sel) {
4882 case 0:
d75c135e 4883 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4884 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 4885 ctx->bstate = BS_STOP;
2423f660
TS
4886 rn = "HWREna";
4887 break;
7a387fff
TS
4888 default:
4889 goto die;
876d4b07 4890 }
8c0fdd85
TS
4891 break;
4892 case 8:
7a387fff 4893 /* ignored */
f0b3f3ae 4894 rn = "BadVAddr";
8c0fdd85
TS
4895 break;
4896 case 9:
7a387fff
TS
4897 switch (sel) {
4898 case 0:
895c2d04 4899 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4900 rn = "Count";
4901 break;
876d4b07 4902 /* 6,7 are implementation dependent */
7a387fff
TS
4903 default:
4904 goto die;
876d4b07 4905 }
8c0fdd85
TS
4906 break;
4907 case 10:
7a387fff
TS
4908 switch (sel) {
4909 case 0:
895c2d04 4910 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4911 rn = "EntryHi";
4912 break;
7a387fff
TS
4913 default:
4914 goto die;
876d4b07 4915 }
8c0fdd85
TS
4916 break;
4917 case 11:
7a387fff
TS
4918 switch (sel) {
4919 case 0:
895c2d04 4920 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4921 rn = "Compare";
4922 break;
4923 /* 6,7 are implementation dependent */
7a387fff
TS
4924 default:
4925 goto die;
876d4b07 4926 }
8c0fdd85
TS
4927 break;
4928 case 12:
7a387fff
TS
4929 switch (sel) {
4930 case 0:
867abc7e 4931 save_cpu_state(ctx, 1);
895c2d04 4932 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4933 /* BS_STOP isn't good enough here, hflags may have changed. */
4934 gen_save_pc(ctx->pc + 4);
4935 ctx->bstate = BS_EXCP;
2423f660
TS
4936 rn = "Status";
4937 break;
7a387fff 4938 case 1:
d75c135e 4939 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4940 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4941 /* Stop translation as we may have switched the execution mode */
4942 ctx->bstate = BS_STOP;
2423f660
TS
4943 rn = "IntCtl";
4944 break;
7a387fff 4945 case 2:
d75c135e 4946 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4947 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4948 /* Stop translation as we may have switched the execution mode */
4949 ctx->bstate = BS_STOP;
2423f660
TS
4950 rn = "SRSCtl";
4951 break;
7a387fff 4952 case 3:
d75c135e 4953 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4954 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4955 /* Stop translation as we may have switched the execution mode */
4956 ctx->bstate = BS_STOP;
2423f660 4957 rn = "SRSMap";
fd88b6ab 4958 break;
7a387fff
TS
4959 default:
4960 goto die;
876d4b07 4961 }
8c0fdd85
TS
4962 break;
4963 case 13:
7a387fff
TS
4964 switch (sel) {
4965 case 0:
867abc7e 4966 save_cpu_state(ctx, 1);
895c2d04 4967 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4968 rn = "Cause";
4969 break;
7a387fff
TS
4970 default:
4971 goto die;
876d4b07 4972 }
8c0fdd85
TS
4973 break;
4974 case 14:
7a387fff
TS
4975 switch (sel) {
4976 case 0:
7db13fae 4977 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4978 rn = "EPC";
4979 break;
7a387fff
TS
4980 default:
4981 goto die;
876d4b07 4982 }
8c0fdd85
TS
4983 break;
4984 case 15:
7a387fff
TS
4985 switch (sel) {
4986 case 0:
2423f660
TS
4987 /* ignored */
4988 rn = "PRid";
4989 break;
7a387fff 4990 case 1:
d75c135e 4991 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4992 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
4993 rn = "EBase";
4994 break;
7a387fff
TS
4995 default:
4996 goto die;
1579a72e 4997 }
8c0fdd85
TS
4998 break;
4999 case 16:
5000 switch (sel) {
5001 case 0:
895c2d04 5002 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5003 rn = "Config";
2423f660
TS
5004 /* Stop translation as we may have switched the execution mode */
5005 ctx->bstate = BS_STOP;
7a387fff
TS
5006 break;
5007 case 1:
e397ee33 5008 /* ignored, read only */
7a387fff
TS
5009 rn = "Config1";
5010 break;
5011 case 2:
895c2d04 5012 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5013 rn = "Config2";
2423f660
TS
5014 /* Stop translation as we may have switched the execution mode */
5015 ctx->bstate = BS_STOP;
8c0fdd85 5016 break;
7a387fff 5017 case 3:
e397ee33 5018 /* ignored, read only */
7a387fff
TS
5019 rn = "Config3";
5020 break;
b4160af1
PJ
5021 case 4:
5022 gen_helper_mtc0_config4(cpu_env, arg);
5023 rn = "Config4";
5024 ctx->bstate = BS_STOP;
5025 break;
b4dd99a3
PJ
5026 case 5:
5027 gen_helper_mtc0_config5(cpu_env, arg);
5028 rn = "Config5";
5029 /* Stop translation as we may have switched the execution mode */
5030 ctx->bstate = BS_STOP;
5031 break;
e397ee33
TS
5032 /* 6,7 are implementation dependent */
5033 case 6:
5034 /* ignored */
5035 rn = "Config6";
5036 break;
5037 case 7:
5038 /* ignored */
5039 rn = "Config7";
5040 break;
8c0fdd85
TS
5041 default:
5042 rn = "Invalid config selector";
5043 goto die;
5044 }
5045 break;
5046 case 17:
7a387fff
TS
5047 switch (sel) {
5048 case 0:
895c2d04 5049 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5050 rn = "LLAddr";
5051 break;
7a387fff
TS
5052 default:
5053 goto die;
5054 }
8c0fdd85
TS
5055 break;
5056 case 18:
7a387fff 5057 switch (sel) {
fd88b6ab 5058 case 0 ... 7:
895c2d04 5059 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5060 rn = "WatchLo";
5061 break;
7a387fff
TS
5062 default:
5063 goto die;
5064 }
8c0fdd85
TS
5065 break;
5066 case 19:
7a387fff 5067 switch (sel) {
fd88b6ab 5068 case 0 ... 7:
895c2d04 5069 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5070 rn = "WatchHi";
5071 break;
7a387fff
TS
5072 default:
5073 goto die;
5074 }
8c0fdd85
TS
5075 break;
5076 case 20:
7a387fff
TS
5077 switch (sel) {
5078 case 0:
d26bc211 5079#if defined(TARGET_MIPS64)
d75c135e 5080 check_insn(ctx, ISA_MIPS3);
895c2d04 5081 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5082 rn = "XContext";
5083 break;
703eaf37 5084#endif
7a387fff
TS
5085 default:
5086 goto die;
5087 }
8c0fdd85
TS
5088 break;
5089 case 21:
7a387fff
TS
5090 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5091 switch (sel) {
5092 case 0:
895c2d04 5093 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5094 rn = "Framemask";
5095 break;
7a387fff
TS
5096 default:
5097 goto die;
5098 }
5099 break;
8c0fdd85 5100 case 22:
7a387fff
TS
5101 /* ignored */
5102 rn = "Diagnostic"; /* implementation dependent */
2423f660 5103 break;
8c0fdd85 5104 case 23:
7a387fff
TS
5105 switch (sel) {
5106 case 0:
895c2d04 5107 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5108 /* BS_STOP isn't good enough here, hflags may have changed. */
5109 gen_save_pc(ctx->pc + 4);
5110 ctx->bstate = BS_EXCP;
2423f660
TS
5111 rn = "Debug";
5112 break;
7a387fff 5113 case 1:
895c2d04 5114// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5115 rn = "TraceControl";
8487327a
TS
5116 /* Stop translation as we may have switched the execution mode */
5117 ctx->bstate = BS_STOP;
2423f660 5118// break;
7a387fff 5119 case 2:
895c2d04 5120// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5121 rn = "TraceControl2";
8487327a
TS
5122 /* Stop translation as we may have switched the execution mode */
5123 ctx->bstate = BS_STOP;
2423f660 5124// break;
7a387fff 5125 case 3:
8487327a
TS
5126 /* Stop translation as we may have switched the execution mode */
5127 ctx->bstate = BS_STOP;
895c2d04 5128// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5129 rn = "UserTraceData";
8487327a
TS
5130 /* Stop translation as we may have switched the execution mode */
5131 ctx->bstate = BS_STOP;
2423f660 5132// break;
7a387fff 5133 case 4:
895c2d04 5134// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5135 /* Stop translation as we may have switched the execution mode */
5136 ctx->bstate = BS_STOP;
2423f660
TS
5137 rn = "TraceBPC";
5138// break;
7a387fff
TS
5139 default:
5140 goto die;
5141 }
8c0fdd85
TS
5142 break;
5143 case 24:
7a387fff
TS
5144 switch (sel) {
5145 case 0:
f1aa6320 5146 /* EJTAG support */
7db13fae 5147 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5148 rn = "DEPC";
5149 break;
7a387fff
TS
5150 default:
5151 goto die;
5152 }
8c0fdd85
TS
5153 break;
5154 case 25:
7a387fff
TS
5155 switch (sel) {
5156 case 0:
895c2d04 5157 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5158 rn = "Performance0";
5159 break;
7a387fff 5160 case 1:
d9bea114 5161// gen_helper_mtc0_performance1(arg);
2423f660
TS
5162 rn = "Performance1";
5163// break;
7a387fff 5164 case 2:
d9bea114 5165// gen_helper_mtc0_performance2(arg);
2423f660
TS
5166 rn = "Performance2";
5167// break;
7a387fff 5168 case 3:
d9bea114 5169// gen_helper_mtc0_performance3(arg);
2423f660
TS
5170 rn = "Performance3";
5171// break;
7a387fff 5172 case 4:
d9bea114 5173// gen_helper_mtc0_performance4(arg);
2423f660
TS
5174 rn = "Performance4";
5175// break;
7a387fff 5176 case 5:
d9bea114 5177// gen_helper_mtc0_performance5(arg);
2423f660
TS
5178 rn = "Performance5";
5179// break;
7a387fff 5180 case 6:
d9bea114 5181// gen_helper_mtc0_performance6(arg);
2423f660
TS
5182 rn = "Performance6";
5183// break;
7a387fff 5184 case 7:
d9bea114 5185// gen_helper_mtc0_performance7(arg);
2423f660
TS
5186 rn = "Performance7";
5187// break;
7a387fff
TS
5188 default:
5189 goto die;
5190 }
8c0fdd85
TS
5191 break;
5192 case 26:
2423f660 5193 /* ignored */
8c0fdd85 5194 rn = "ECC";
2423f660 5195 break;
8c0fdd85 5196 case 27:
7a387fff
TS
5197 switch (sel) {
5198 case 0 ... 3:
2423f660
TS
5199 /* ignored */
5200 rn = "CacheErr";
5201 break;
7a387fff
TS
5202 default:
5203 goto die;
5204 }
8c0fdd85
TS
5205 break;
5206 case 28:
5207 switch (sel) {
5208 case 0:
7a387fff
TS
5209 case 2:
5210 case 4:
5211 case 6:
895c2d04 5212 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5213 rn = "TagLo";
5214 break;
7a387fff
TS
5215 case 1:
5216 case 3:
5217 case 5:
5218 case 7:
895c2d04 5219 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5220 rn = "DataLo";
5221 break;
8c0fdd85 5222 default:
8c0fdd85
TS
5223 goto die;
5224 }
5225 break;
5226 case 29:
7a387fff
TS
5227 switch (sel) {
5228 case 0:
5229 case 2:
5230 case 4:
5231 case 6:
895c2d04 5232 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5233 rn = "TagHi";
5234 break;
5235 case 1:
5236 case 3:
5237 case 5:
5238 case 7:
895c2d04 5239 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5240 rn = "DataHi";
5241 break;
5242 default:
5243 rn = "invalid sel";
5244 goto die;
5245 }
8c0fdd85
TS
5246 break;
5247 case 30:
7a387fff
TS
5248 switch (sel) {
5249 case 0:
7db13fae 5250 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5251 rn = "ErrorEPC";
5252 break;
7a387fff
TS
5253 default:
5254 goto die;
5255 }
8c0fdd85
TS
5256 break;
5257 case 31:
7a387fff
TS
5258 switch (sel) {
5259 case 0:
f1aa6320 5260 /* EJTAG support */
7db13fae 5261 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5262 rn = "DESAVE";
5263 break;
7a387fff
TS
5264 default:
5265 goto die;
5266 }
2423f660
TS
5267 /* Stop translation as we may have switched the execution mode */
5268 ctx->bstate = BS_STOP;
8c0fdd85
TS
5269 break;
5270 default:
8c0fdd85
TS
5271 goto die;
5272 }
2abf314d 5273 (void)rn; /* avoid a compiler warning */
d12d51d5 5274 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5275 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5276 if (use_icount) {
5277 gen_io_end();
5278 ctx->bstate = BS_STOP;
5279 }
8c0fdd85
TS
5280 return;
5281
5282die:
d12d51d5 5283 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5284 generate_exception(ctx, EXCP_RI);
5285}
5286
d26bc211 5287#if defined(TARGET_MIPS64)
d75c135e 5288static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5289{
5290 const char *rn = "invalid";
5291
e189e748 5292 if (sel != 0)
d75c135e 5293 check_insn(ctx, ISA_MIPS64);
e189e748 5294
9c2149c8
TS
5295 switch (reg) {
5296 case 0:
5297 switch (sel) {
5298 case 0:
7db13fae 5299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5300 rn = "Index";
5301 break;
5302 case 1:
d75c135e 5303 check_insn(ctx, ASE_MT);
895c2d04 5304 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5305 rn = "MVPControl";
ead9360e 5306 break;
9c2149c8 5307 case 2:
d75c135e 5308 check_insn(ctx, ASE_MT);
895c2d04 5309 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5310 rn = "MVPConf0";
ead9360e 5311 break;
9c2149c8 5312 case 3:
d75c135e 5313 check_insn(ctx, ASE_MT);
895c2d04 5314 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5315 rn = "MVPConf1";
ead9360e 5316 break;
9c2149c8
TS
5317 default:
5318 goto die;
5319 }
5320 break;
5321 case 1:
5322 switch (sel) {
5323 case 0:
895c2d04 5324 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5325 rn = "Random";
2423f660 5326 break;
9c2149c8 5327 case 1:
d75c135e 5328 check_insn(ctx, ASE_MT);
7db13fae 5329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5330 rn = "VPEControl";
ead9360e 5331 break;
9c2149c8 5332 case 2:
d75c135e 5333 check_insn(ctx, ASE_MT);
7db13fae 5334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5335 rn = "VPEConf0";
ead9360e 5336 break;
9c2149c8 5337 case 3:
d75c135e 5338 check_insn(ctx, ASE_MT);
7db13fae 5339 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5340 rn = "VPEConf1";
ead9360e 5341 break;
9c2149c8 5342 case 4:
d75c135e 5343 check_insn(ctx, ASE_MT);
7db13fae 5344 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5345 rn = "YQMask";
ead9360e 5346 break;
9c2149c8 5347 case 5:
d75c135e 5348 check_insn(ctx, ASE_MT);
7db13fae 5349 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5350 rn = "VPESchedule";
ead9360e 5351 break;
9c2149c8 5352 case 6:
d75c135e 5353 check_insn(ctx, ASE_MT);
7db13fae 5354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5355 rn = "VPEScheFBack";
ead9360e 5356 break;
9c2149c8 5357 case 7:
d75c135e 5358 check_insn(ctx, ASE_MT);
7db13fae 5359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5360 rn = "VPEOpt";
ead9360e 5361 break;
9c2149c8
TS
5362 default:
5363 goto die;
5364 }
5365 break;
5366 case 2:
5367 switch (sel) {
5368 case 0:
7db13fae 5369 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5370 rn = "EntryLo0";
5371 break;
9c2149c8 5372 case 1:
d75c135e 5373 check_insn(ctx, ASE_MT);
895c2d04 5374 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5375 rn = "TCStatus";
ead9360e 5376 break;
9c2149c8 5377 case 2:
d75c135e 5378 check_insn(ctx, ASE_MT);
895c2d04 5379 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5380 rn = "TCBind";
ead9360e 5381 break;
9c2149c8 5382 case 3:
d75c135e 5383 check_insn(ctx, ASE_MT);
895c2d04 5384 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5385 rn = "TCRestart";
ead9360e 5386 break;
9c2149c8 5387 case 4:
d75c135e 5388 check_insn(ctx, ASE_MT);
895c2d04 5389 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5390 rn = "TCHalt";
ead9360e 5391 break;
9c2149c8 5392 case 5:
d75c135e 5393 check_insn(ctx, ASE_MT);
895c2d04 5394 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5395 rn = "TCContext";
ead9360e 5396 break;
9c2149c8 5397 case 6:
d75c135e 5398 check_insn(ctx, ASE_MT);
895c2d04 5399 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5400 rn = "TCSchedule";
ead9360e 5401 break;
9c2149c8 5402 case 7:
d75c135e 5403 check_insn(ctx, ASE_MT);
895c2d04 5404 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5405 rn = "TCScheFBack";
ead9360e 5406 break;
9c2149c8
TS
5407 default:
5408 goto die;
5409 }
5410 break;
5411 case 3:
5412 switch (sel) {
5413 case 0:
7db13fae 5414 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5415 rn = "EntryLo1";
5416 break;
9c2149c8
TS
5417 default:
5418 goto die;
1579a72e 5419 }
9c2149c8
TS
5420 break;
5421 case 4:
5422 switch (sel) {
5423 case 0:
7db13fae 5424 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5425 rn = "Context";
5426 break;
9c2149c8 5427 case 1:
d9bea114 5428// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5429 rn = "ContextConfig";
d279279e 5430 goto die;
2423f660 5431// break;
d279279e
PJ
5432 case 2:
5433 if (ctx->ulri) {
5434 tcg_gen_ld_tl(arg, cpu_env,
5435 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5436 rn = "UserLocal";
5437 } else {
5438 tcg_gen_movi_tl(arg, 0);
5439 }
5440 break;
9c2149c8
TS
5441 default:
5442 goto die;
876d4b07 5443 }
9c2149c8
TS
5444 break;
5445 case 5:
5446 switch (sel) {
5447 case 0:
7db13fae 5448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5449 rn = "PageMask";
5450 break;
9c2149c8 5451 case 1:
d75c135e 5452 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5454 rn = "PageGrain";
5455 break;
9c2149c8
TS
5456 default:
5457 goto die;
876d4b07 5458 }
9c2149c8
TS
5459 break;
5460 case 6:
5461 switch (sel) {
5462 case 0:
7db13fae 5463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5464 rn = "Wired";
5465 break;
9c2149c8 5466 case 1:
d75c135e 5467 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5469 rn = "SRSConf0";
ead9360e 5470 break;
9c2149c8 5471 case 2:
d75c135e 5472 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5474 rn = "SRSConf1";
ead9360e 5475 break;
9c2149c8 5476 case 3:
d75c135e 5477 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5479 rn = "SRSConf2";
ead9360e 5480 break;
9c2149c8 5481 case 4:
d75c135e 5482 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5484 rn = "SRSConf3";
ead9360e 5485 break;
9c2149c8 5486 case 5:
d75c135e 5487 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5489 rn = "SRSConf4";
ead9360e 5490 break;
9c2149c8
TS
5491 default:
5492 goto die;
876d4b07 5493 }
9c2149c8
TS
5494 break;
5495 case 7:
5496 switch (sel) {
5497 case 0:
d75c135e 5498 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5499 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5500 rn = "HWREna";
5501 break;
9c2149c8
TS
5502 default:
5503 goto die;
876d4b07 5504 }
9c2149c8
TS
5505 break;
5506 case 8:
5507 switch (sel) {
5508 case 0:
7db13fae 5509 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5510 rn = "BadVAddr";
2423f660 5511 break;
9c2149c8
TS
5512 default:
5513 goto die;
876d4b07 5514 }
9c2149c8
TS
5515 break;
5516 case 9:
5517 switch (sel) {
5518 case 0:
2e70f6ef
PB
5519 /* Mark as an IO operation because we read the time. */
5520 if (use_icount)
5521 gen_io_start();
895c2d04 5522 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5523 if (use_icount) {
5524 gen_io_end();
2e70f6ef 5525 }
55807224
EI
5526 /* Break the TB to be able to take timer interrupts immediately
5527 after reading count. */
5528 ctx->bstate = BS_STOP;
2423f660
TS
5529 rn = "Count";
5530 break;
5531 /* 6,7 are implementation dependent */
9c2149c8
TS
5532 default:
5533 goto die;
876d4b07 5534 }
9c2149c8
TS
5535 break;
5536 case 10:
5537 switch (sel) {
5538 case 0:
7db13fae 5539 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5540 rn = "EntryHi";
5541 break;
9c2149c8
TS
5542 default:
5543 goto die;
876d4b07 5544 }
9c2149c8
TS
5545 break;
5546 case 11:
5547 switch (sel) {
5548 case 0:
7db13fae 5549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5550 rn = "Compare";
5551 break;
876d4b07 5552 /* 6,7 are implementation dependent */
9c2149c8
TS
5553 default:
5554 goto die;
876d4b07 5555 }
9c2149c8
TS
5556 break;
5557 case 12:
5558 switch (sel) {
5559 case 0:
7db13fae 5560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5561 rn = "Status";
5562 break;
9c2149c8 5563 case 1:
d75c135e 5564 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5566 rn = "IntCtl";
5567 break;
9c2149c8 5568 case 2:
d75c135e 5569 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5571 rn = "SRSCtl";
5572 break;
9c2149c8 5573 case 3:
d75c135e 5574 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5576 rn = "SRSMap";
5577 break;
9c2149c8
TS
5578 default:
5579 goto die;
876d4b07 5580 }
9c2149c8
TS
5581 break;
5582 case 13:
5583 switch (sel) {
5584 case 0:
7db13fae 5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5586 rn = "Cause";
5587 break;
9c2149c8
TS
5588 default:
5589 goto die;
876d4b07 5590 }
9c2149c8
TS
5591 break;
5592 case 14:
5593 switch (sel) {
5594 case 0:
7db13fae 5595 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5596 rn = "EPC";
5597 break;
9c2149c8
TS
5598 default:
5599 goto die;
876d4b07 5600 }
9c2149c8
TS
5601 break;
5602 case 15:
5603 switch (sel) {
5604 case 0:
7db13fae 5605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5606 rn = "PRid";
5607 break;
9c2149c8 5608 case 1:
d75c135e 5609 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5611 rn = "EBase";
5612 break;
9c2149c8
TS
5613 default:
5614 goto die;
876d4b07 5615 }
9c2149c8
TS
5616 break;
5617 case 16:
5618 switch (sel) {
5619 case 0:
7db13fae 5620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5621 rn = "Config";
5622 break;
5623 case 1:
7db13fae 5624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5625 rn = "Config1";
5626 break;
5627 case 2:
7db13fae 5628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5629 rn = "Config2";
5630 break;
5631 case 3:
7db13fae 5632 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5633 rn = "Config3";
5634 break;
5635 /* 6,7 are implementation dependent */
f0b3f3ae 5636 case 6:
7db13fae 5637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5638 rn = "Config6";
5639 break;
5640 case 7:
7db13fae 5641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5642 rn = "Config7";
5643 break;
9c2149c8
TS
5644 default:
5645 goto die;
5646 }
5647 break;
5648 case 17:
5649 switch (sel) {
5650 case 0:
895c2d04 5651 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5652 rn = "LLAddr";
5653 break;
9c2149c8
TS
5654 default:
5655 goto die;
5656 }
5657 break;
5658 case 18:
5659 switch (sel) {
fd88b6ab 5660 case 0 ... 7:
895c2d04 5661 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5662 rn = "WatchLo";
5663 break;
9c2149c8
TS
5664 default:
5665 goto die;
5666 }
5667 break;
5668 case 19:
5669 switch (sel) {
fd88b6ab 5670 case 0 ... 7:
895c2d04 5671 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5672 rn = "WatchHi";
5673 break;
9c2149c8
TS
5674 default:
5675 goto die;
5676 }
5677 break;
5678 case 20:
5679 switch (sel) {
5680 case 0:
d75c135e 5681 check_insn(ctx, ISA_MIPS3);
7db13fae 5682 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5683 rn = "XContext";
5684 break;
9c2149c8
TS
5685 default:
5686 goto die;
5687 }
5688 break;
5689 case 21:
5690 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5691 switch (sel) {
5692 case 0:
7db13fae 5693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5694 rn = "Framemask";
5695 break;
9c2149c8
TS
5696 default:
5697 goto die;
5698 }
5699 break;
5700 case 22:
d9bea114 5701 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5702 rn = "'Diagnostic"; /* implementation dependent */
5703 break;
9c2149c8
TS
5704 case 23:
5705 switch (sel) {
5706 case 0:
895c2d04 5707 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5708 rn = "Debug";
5709 break;
9c2149c8 5710 case 1:
895c2d04 5711// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5712 rn = "TraceControl";
5713// break;
9c2149c8 5714 case 2:
895c2d04 5715// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5716 rn = "TraceControl2";
5717// break;
9c2149c8 5718 case 3:
895c2d04 5719// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5720 rn = "UserTraceData";
5721// break;
9c2149c8 5722 case 4:
895c2d04 5723// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5724 rn = "TraceBPC";
5725// break;
9c2149c8
TS
5726 default:
5727 goto die;
5728 }
5729 break;
5730 case 24:
5731 switch (sel) {
5732 case 0:
f0b3f3ae 5733 /* EJTAG support */
7db13fae 5734 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5735 rn = "DEPC";
5736 break;
9c2149c8
TS
5737 default:
5738 goto die;
5739 }
5740 break;
5741 case 25:
5742 switch (sel) {
5743 case 0:
7db13fae 5744 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5745 rn = "Performance0";
9c2149c8
TS
5746 break;
5747 case 1:
d9bea114 5748// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5749 rn = "Performance1";
5750// break;
9c2149c8 5751 case 2:
d9bea114 5752// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5753 rn = "Performance2";
5754// break;
9c2149c8 5755 case 3:
d9bea114 5756// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5757 rn = "Performance3";
5758// break;
9c2149c8 5759 case 4:
d9bea114 5760// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5761 rn = "Performance4";
5762// break;
9c2149c8 5763 case 5:
d9bea114 5764// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5765 rn = "Performance5";
5766// break;
9c2149c8 5767 case 6:
d9bea114 5768// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5769 rn = "Performance6";
5770// break;
9c2149c8 5771 case 7:
d9bea114 5772// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5773 rn = "Performance7";
5774// break;
9c2149c8
TS
5775 default:
5776 goto die;
5777 }
5778 break;
5779 case 26:
d9bea114 5780 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5781 rn = "ECC";
5782 break;
9c2149c8
TS
5783 case 27:
5784 switch (sel) {
5785 /* ignored */
5786 case 0 ... 3:
d9bea114 5787 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5788 rn = "CacheErr";
5789 break;
9c2149c8
TS
5790 default:
5791 goto die;
5792 }
5793 break;
5794 case 28:
5795 switch (sel) {
5796 case 0:
5797 case 2:
5798 case 4:
5799 case 6:
7db13fae 5800 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5801 rn = "TagLo";
5802 break;
5803 case 1:
5804 case 3:
5805 case 5:
5806 case 7:
7db13fae 5807 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5808 rn = "DataLo";
5809 break;
5810 default:
5811 goto die;
5812 }
5813 break;
5814 case 29:
5815 switch (sel) {
5816 case 0:
5817 case 2:
5818 case 4:
5819 case 6:
7db13fae 5820 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5821 rn = "TagHi";
5822 break;
5823 case 1:
5824 case 3:
5825 case 5:
5826 case 7:
7db13fae 5827 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5828 rn = "DataHi";
5829 break;
5830 default:
5831 goto die;
5832 }
5833 break;
5834 case 30:
5835 switch (sel) {
5836 case 0:
7db13fae 5837 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5838 rn = "ErrorEPC";
5839 break;
9c2149c8
TS
5840 default:
5841 goto die;
5842 }
5843 break;
5844 case 31:
5845 switch (sel) {
5846 case 0:
f0b3f3ae 5847 /* EJTAG support */
7db13fae 5848 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5849 rn = "DESAVE";
5850 break;
9c2149c8
TS
5851 default:
5852 goto die;
5853 }
5854 break;
5855 default:
876d4b07 5856 goto die;
9c2149c8 5857 }
2abf314d 5858 (void)rn; /* avoid a compiler warning */
d12d51d5 5859 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5860 return;
5861
5862die:
d12d51d5 5863 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5864 generate_exception(ctx, EXCP_RI);
5865}
5866
d75c135e 5867static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5868{
5869 const char *rn = "invalid";
5870
e189e748 5871 if (sel != 0)
d75c135e 5872 check_insn(ctx, ISA_MIPS64);
e189e748 5873
2e70f6ef
PB
5874 if (use_icount)
5875 gen_io_start();
5876
9c2149c8
TS
5877 switch (reg) {
5878 case 0:
5879 switch (sel) {
5880 case 0:
895c2d04 5881 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5882 rn = "Index";
5883 break;
5884 case 1:
d75c135e 5885 check_insn(ctx, ASE_MT);
895c2d04 5886 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5887 rn = "MVPControl";
ead9360e 5888 break;
9c2149c8 5889 case 2:
d75c135e 5890 check_insn(ctx, ASE_MT);
ead9360e 5891 /* ignored */
9c2149c8 5892 rn = "MVPConf0";
ead9360e 5893 break;
9c2149c8 5894 case 3:
d75c135e 5895 check_insn(ctx, ASE_MT);
ead9360e 5896 /* ignored */
9c2149c8 5897 rn = "MVPConf1";
ead9360e 5898 break;
9c2149c8
TS
5899 default:
5900 goto die;
5901 }
5902 break;
5903 case 1:
5904 switch (sel) {
5905 case 0:
2423f660 5906 /* ignored */
9c2149c8 5907 rn = "Random";
2423f660 5908 break;
9c2149c8 5909 case 1:
d75c135e 5910 check_insn(ctx, ASE_MT);
895c2d04 5911 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5912 rn = "VPEControl";
ead9360e 5913 break;
9c2149c8 5914 case 2:
d75c135e 5915 check_insn(ctx, ASE_MT);
895c2d04 5916 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5917 rn = "VPEConf0";
ead9360e 5918 break;
9c2149c8 5919 case 3:
d75c135e 5920 check_insn(ctx, ASE_MT);
895c2d04 5921 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5922 rn = "VPEConf1";
ead9360e 5923 break;
9c2149c8 5924 case 4:
d75c135e 5925 check_insn(ctx, ASE_MT);
895c2d04 5926 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5927 rn = "YQMask";
ead9360e 5928 break;
9c2149c8 5929 case 5:
d75c135e 5930 check_insn(ctx, ASE_MT);
7db13fae 5931 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5932 rn = "VPESchedule";
ead9360e 5933 break;
9c2149c8 5934 case 6:
d75c135e 5935 check_insn(ctx, ASE_MT);
7db13fae 5936 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5937 rn = "VPEScheFBack";
ead9360e 5938 break;
9c2149c8 5939 case 7:
d75c135e 5940 check_insn(ctx, ASE_MT);
895c2d04 5941 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5942 rn = "VPEOpt";
ead9360e 5943 break;
9c2149c8
TS
5944 default:
5945 goto die;
5946 }
5947 break;
5948 case 2:
5949 switch (sel) {
5950 case 0:
895c2d04 5951 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5952 rn = "EntryLo0";
5953 break;
9c2149c8 5954 case 1:
d75c135e 5955 check_insn(ctx, ASE_MT);
895c2d04 5956 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5957 rn = "TCStatus";
ead9360e 5958 break;
9c2149c8 5959 case 2:
d75c135e 5960 check_insn(ctx, ASE_MT);
895c2d04 5961 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5962 rn = "TCBind";
ead9360e 5963 break;
9c2149c8 5964 case 3:
d75c135e 5965 check_insn(ctx, ASE_MT);
895c2d04 5966 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5967 rn = "TCRestart";
ead9360e 5968 break;
9c2149c8 5969 case 4:
d75c135e 5970 check_insn(ctx, ASE_MT);
895c2d04 5971 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5972 rn = "TCHalt";
ead9360e 5973 break;
9c2149c8 5974 case 5:
d75c135e 5975 check_insn(ctx, ASE_MT);
895c2d04 5976 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5977 rn = "TCContext";
ead9360e 5978 break;
9c2149c8 5979 case 6:
d75c135e 5980 check_insn(ctx, ASE_MT);
895c2d04 5981 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5982 rn = "TCSchedule";
ead9360e 5983 break;
9c2149c8 5984 case 7:
d75c135e 5985 check_insn(ctx, ASE_MT);
895c2d04 5986 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5987 rn = "TCScheFBack";
ead9360e 5988 break;
9c2149c8
TS
5989 default:
5990 goto die;
5991 }
5992 break;
5993 case 3:
5994 switch (sel) {
5995 case 0:
895c2d04 5996 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5997 rn = "EntryLo1";
5998 break;
9c2149c8
TS
5999 default:
6000 goto die;
876d4b07 6001 }
9c2149c8
TS
6002 break;
6003 case 4:
6004 switch (sel) {
6005 case 0:
895c2d04 6006 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6007 rn = "Context";
6008 break;
9c2149c8 6009 case 1:
895c2d04 6010// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6011 rn = "ContextConfig";
d279279e 6012 goto die;
2423f660 6013// break;
d279279e
PJ
6014 case 2:
6015 if (ctx->ulri) {
6016 tcg_gen_st_tl(arg, cpu_env,
6017 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6018 rn = "UserLocal";
6019 }
6020 break;
9c2149c8
TS
6021 default:
6022 goto die;
876d4b07 6023 }
9c2149c8
TS
6024 break;
6025 case 5:
6026 switch (sel) {
6027 case 0:
895c2d04 6028 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6029 rn = "PageMask";
6030 break;
9c2149c8 6031 case 1:
d75c135e 6032 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6033 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6034 rn = "PageGrain";
6035 break;
9c2149c8
TS
6036 default:
6037 goto die;
876d4b07 6038 }
9c2149c8
TS
6039 break;
6040 case 6:
6041 switch (sel) {
6042 case 0:
895c2d04 6043 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6044 rn = "Wired";
6045 break;
9c2149c8 6046 case 1:
d75c135e 6047 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6048 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6049 rn = "SRSConf0";
ead9360e 6050 break;
9c2149c8 6051 case 2:
d75c135e 6052 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6053 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6054 rn = "SRSConf1";
ead9360e 6055 break;
9c2149c8 6056 case 3:
d75c135e 6057 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6058 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6059 rn = "SRSConf2";
ead9360e 6060 break;
9c2149c8 6061 case 4:
d75c135e 6062 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6063 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6064 rn = "SRSConf3";
ead9360e 6065 break;
9c2149c8 6066 case 5:
d75c135e 6067 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6068 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6069 rn = "SRSConf4";
ead9360e 6070 break;
9c2149c8
TS
6071 default:
6072 goto die;
876d4b07 6073 }
9c2149c8
TS
6074 break;
6075 case 7:
6076 switch (sel) {
6077 case 0:
d75c135e 6078 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6079 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6080 ctx->bstate = BS_STOP;
2423f660
TS
6081 rn = "HWREna";
6082 break;
9c2149c8
TS
6083 default:
6084 goto die;
876d4b07 6085 }
9c2149c8
TS
6086 break;
6087 case 8:
6088 /* ignored */
f0b3f3ae 6089 rn = "BadVAddr";
9c2149c8
TS
6090 break;
6091 case 9:
6092 switch (sel) {
6093 case 0:
895c2d04 6094 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6095 rn = "Count";
6096 break;
876d4b07 6097 /* 6,7 are implementation dependent */
9c2149c8
TS
6098 default:
6099 goto die;
876d4b07
TS
6100 }
6101 /* Stop translation as we may have switched the execution mode */
6102 ctx->bstate = BS_STOP;
9c2149c8
TS
6103 break;
6104 case 10:
6105 switch (sel) {
6106 case 0:
895c2d04 6107 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6108 rn = "EntryHi";
6109 break;
9c2149c8
TS
6110 default:
6111 goto die;
876d4b07 6112 }
9c2149c8
TS
6113 break;
6114 case 11:
6115 switch (sel) {
6116 case 0:
895c2d04 6117 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6118 rn = "Compare";
6119 break;
876d4b07 6120 /* 6,7 are implementation dependent */
9c2149c8
TS
6121 default:
6122 goto die;
876d4b07 6123 }
de9a95f0
AJ
6124 /* Stop translation as we may have switched the execution mode */
6125 ctx->bstate = BS_STOP;
9c2149c8
TS
6126 break;
6127 case 12:
6128 switch (sel) {
6129 case 0:
867abc7e 6130 save_cpu_state(ctx, 1);
895c2d04 6131 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6132 /* BS_STOP isn't good enough here, hflags may have changed. */
6133 gen_save_pc(ctx->pc + 4);
6134 ctx->bstate = BS_EXCP;
2423f660
TS
6135 rn = "Status";
6136 break;
9c2149c8 6137 case 1:
d75c135e 6138 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6139 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6140 /* Stop translation as we may have switched the execution mode */
6141 ctx->bstate = BS_STOP;
2423f660
TS
6142 rn = "IntCtl";
6143 break;
9c2149c8 6144 case 2:
d75c135e 6145 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6146 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6147 /* Stop translation as we may have switched the execution mode */
6148 ctx->bstate = BS_STOP;
2423f660
TS
6149 rn = "SRSCtl";
6150 break;
9c2149c8 6151 case 3:
d75c135e 6152 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6153 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6154 /* Stop translation as we may have switched the execution mode */
6155 ctx->bstate = BS_STOP;
2423f660
TS
6156 rn = "SRSMap";
6157 break;
6158 default:
9c2149c8 6159 goto die;
876d4b07 6160 }
9c2149c8
TS
6161 break;
6162 case 13:
6163 switch (sel) {
6164 case 0:
867abc7e 6165 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6166 /* Mark as an IO operation because we may trigger a software
6167 interrupt. */
6168 if (use_icount) {
6169 gen_io_start();
6170 }
895c2d04 6171 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6172 if (use_icount) {
6173 gen_io_end();
6174 }
6175 /* Stop translation as we may have triggered an intetrupt */
6176 ctx->bstate = BS_STOP;
2423f660
TS
6177 rn = "Cause";
6178 break;
9c2149c8
TS
6179 default:
6180 goto die;
876d4b07 6181 }
9c2149c8
TS
6182 break;
6183 case 14:
6184 switch (sel) {
6185 case 0:
7db13fae 6186 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6187 rn = "EPC";
6188 break;
9c2149c8
TS
6189 default:
6190 goto die;
876d4b07 6191 }
9c2149c8
TS
6192 break;
6193 case 15:
6194 switch (sel) {
6195 case 0:
2423f660
TS
6196 /* ignored */
6197 rn = "PRid";
6198 break;
9c2149c8 6199 case 1:
d75c135e 6200 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6201 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6202 rn = "EBase";
6203 break;
9c2149c8
TS
6204 default:
6205 goto die;
876d4b07 6206 }
9c2149c8
TS
6207 break;
6208 case 16:
6209 switch (sel) {
6210 case 0:
895c2d04 6211 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6212 rn = "Config";
2423f660
TS
6213 /* Stop translation as we may have switched the execution mode */
6214 ctx->bstate = BS_STOP;
9c2149c8
TS
6215 break;
6216 case 1:
1fc7bf6e 6217 /* ignored, read only */
9c2149c8
TS
6218 rn = "Config1";
6219 break;
6220 case 2:
895c2d04 6221 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6222 rn = "Config2";
2423f660
TS
6223 /* Stop translation as we may have switched the execution mode */
6224 ctx->bstate = BS_STOP;
9c2149c8
TS
6225 break;
6226 case 3:
2423f660 6227 /* ignored */
9c2149c8
TS
6228 rn = "Config3";
6229 break;
6230 /* 6,7 are implementation dependent */
6231 default:
6232 rn = "Invalid config selector";
6233 goto die;
6234 }
9c2149c8
TS
6235 break;
6236 case 17:
6237 switch (sel) {
6238 case 0:
895c2d04 6239 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6240 rn = "LLAddr";
6241 break;
9c2149c8
TS
6242 default:
6243 goto die;
6244 }
6245 break;
6246 case 18:
6247 switch (sel) {
fd88b6ab 6248 case 0 ... 7:
895c2d04 6249 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6250 rn = "WatchLo";
6251 break;
9c2149c8
TS
6252 default:
6253 goto die;
6254 }
6255 break;
6256 case 19:
6257 switch (sel) {
fd88b6ab 6258 case 0 ... 7:
895c2d04 6259 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6260 rn = "WatchHi";
6261 break;
9c2149c8
TS
6262 default:
6263 goto die;
6264 }
6265 break;
6266 case 20:
6267 switch (sel) {
6268 case 0:
d75c135e 6269 check_insn(ctx, ISA_MIPS3);
895c2d04 6270 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6271 rn = "XContext";
6272 break;
9c2149c8
TS
6273 default:
6274 goto die;
6275 }
6276 break;
6277 case 21:
6278 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6279 switch (sel) {
6280 case 0:
895c2d04 6281 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6282 rn = "Framemask";
6283 break;
9c2149c8
TS
6284 default:
6285 goto die;
6286 }
6287 break;
6288 case 22:
6289 /* ignored */
6290 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6291 break;
9c2149c8
TS
6292 case 23:
6293 switch (sel) {
6294 case 0:
895c2d04 6295 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6296 /* BS_STOP isn't good enough here, hflags may have changed. */
6297 gen_save_pc(ctx->pc + 4);
6298 ctx->bstate = BS_EXCP;
2423f660
TS
6299 rn = "Debug";
6300 break;
9c2149c8 6301 case 1:
895c2d04 6302// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6303 /* Stop translation as we may have switched the execution mode */
6304 ctx->bstate = BS_STOP;
2423f660
TS
6305 rn = "TraceControl";
6306// break;
9c2149c8 6307 case 2:
895c2d04 6308// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6309 /* Stop translation as we may have switched the execution mode */
6310 ctx->bstate = BS_STOP;
2423f660
TS
6311 rn = "TraceControl2";
6312// break;
9c2149c8 6313 case 3:
895c2d04 6314// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6315 /* Stop translation as we may have switched the execution mode */
6316 ctx->bstate = BS_STOP;
2423f660
TS
6317 rn = "UserTraceData";
6318// break;
9c2149c8 6319 case 4:
895c2d04 6320// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6321 /* Stop translation as we may have switched the execution mode */
6322 ctx->bstate = BS_STOP;
2423f660
TS
6323 rn = "TraceBPC";
6324// break;
9c2149c8
TS
6325 default:
6326 goto die;
6327 }
9c2149c8
TS
6328 break;
6329 case 24:
6330 switch (sel) {
6331 case 0:
f1aa6320 6332 /* EJTAG support */
7db13fae 6333 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6334 rn = "DEPC";
6335 break;
9c2149c8
TS
6336 default:
6337 goto die;
6338 }
6339 break;
6340 case 25:
6341 switch (sel) {
6342 case 0:
895c2d04 6343 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6344 rn = "Performance0";
6345 break;
9c2149c8 6346 case 1:
895c2d04 6347// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6348 rn = "Performance1";
6349// break;
9c2149c8 6350 case 2:
895c2d04 6351// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6352 rn = "Performance2";
6353// break;
9c2149c8 6354 case 3:
895c2d04 6355// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6356 rn = "Performance3";
6357// break;
9c2149c8 6358 case 4:
895c2d04 6359// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6360 rn = "Performance4";
6361// break;
9c2149c8 6362 case 5:
895c2d04 6363// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6364 rn = "Performance5";
6365// break;
9c2149c8 6366 case 6:
895c2d04 6367// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6368 rn = "Performance6";
6369// break;
9c2149c8 6370 case 7:
895c2d04 6371// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6372 rn = "Performance7";
6373// break;
9c2149c8
TS
6374 default:
6375 goto die;
6376 }
876d4b07 6377 break;
9c2149c8 6378 case 26:
876d4b07 6379 /* ignored */
9c2149c8 6380 rn = "ECC";
876d4b07 6381 break;
9c2149c8
TS
6382 case 27:
6383 switch (sel) {
6384 case 0 ... 3:
2423f660
TS
6385 /* ignored */
6386 rn = "CacheErr";
6387 break;
9c2149c8
TS
6388 default:
6389 goto die;
6390 }
876d4b07 6391 break;
9c2149c8
TS
6392 case 28:
6393 switch (sel) {
6394 case 0:
6395 case 2:
6396 case 4:
6397 case 6:
895c2d04 6398 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6399 rn = "TagLo";
6400 break;
6401 case 1:
6402 case 3:
6403 case 5:
6404 case 7:
895c2d04 6405 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6406 rn = "DataLo";
6407 break;
6408 default:
6409 goto die;
6410 }
6411 break;
6412 case 29:
6413 switch (sel) {
6414 case 0:
6415 case 2:
6416 case 4:
6417 case 6:
895c2d04 6418 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6419 rn = "TagHi";
6420 break;
6421 case 1:
6422 case 3:
6423 case 5:
6424 case 7:
895c2d04 6425 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6426 rn = "DataHi";
6427 break;
6428 default:
6429 rn = "invalid sel";
6430 goto die;
6431 }
876d4b07 6432 break;
9c2149c8
TS
6433 case 30:
6434 switch (sel) {
6435 case 0:
7db13fae 6436 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6437 rn = "ErrorEPC";
6438 break;
9c2149c8
TS
6439 default:
6440 goto die;
6441 }
6442 break;
6443 case 31:
6444 switch (sel) {
6445 case 0:
f1aa6320 6446 /* EJTAG support */
7db13fae 6447 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6448 rn = "DESAVE";
6449 break;
9c2149c8
TS
6450 default:
6451 goto die;
6452 }
876d4b07
TS
6453 /* Stop translation as we may have switched the execution mode */
6454 ctx->bstate = BS_STOP;
9c2149c8
TS
6455 break;
6456 default:
876d4b07 6457 goto die;
9c2149c8 6458 }
2abf314d 6459 (void)rn; /* avoid a compiler warning */
d12d51d5 6460 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6461 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6462 if (use_icount) {
6463 gen_io_end();
6464 ctx->bstate = BS_STOP;
6465 }
9c2149c8
TS
6466 return;
6467
6468die:
d12d51d5 6469 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6470 generate_exception(ctx, EXCP_RI);
6471}
d26bc211 6472#endif /* TARGET_MIPS64 */
9c2149c8 6473
7db13fae 6474static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6475 int u, int sel, int h)
6476{
6477 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6478 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6479
6480 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6481 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6482 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6483 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6484 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6485 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6486 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6487 else if (u == 0) {
6488 switch (rt) {
5a25ce94
EI
6489 case 1:
6490 switch (sel) {
6491 case 1:
895c2d04 6492 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6493 break;
6494 case 2:
895c2d04 6495 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6496 break;
6497 default:
6498 goto die;
6499 break;
6500 }
6501 break;
ead9360e
TS
6502 case 2:
6503 switch (sel) {
6504 case 1:
895c2d04 6505 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6506 break;
6507 case 2:
895c2d04 6508 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6509 break;
6510 case 3:
895c2d04 6511 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6512 break;
6513 case 4:
895c2d04 6514 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6515 break;
6516 case 5:
895c2d04 6517 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6518 break;
6519 case 6:
895c2d04 6520 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6521 break;
6522 case 7:
895c2d04 6523 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6524 break;
6525 default:
d75c135e 6526 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6527 break;
6528 }
6529 break;
6530 case 10:
6531 switch (sel) {
6532 case 0:
895c2d04 6533 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6534 break;
6535 default:
d75c135e 6536 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6537 break;
6538 }
6539 case 12:
6540 switch (sel) {
6541 case 0:
895c2d04 6542 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6543 break;
6544 default:
d75c135e 6545 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6546 break;
6547 }
5a25ce94
EI
6548 case 13:
6549 switch (sel) {
6550 case 0:
895c2d04 6551 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6552 break;
6553 default:
6554 goto die;
6555 break;
6556 }
6557 break;
6558 case 14:
6559 switch (sel) {
6560 case 0:
895c2d04 6561 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6562 break;
6563 default:
6564 goto die;
6565 break;
6566 }
6567 break;
6568 case 15:
6569 switch (sel) {
6570 case 1:
895c2d04 6571 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6572 break;
6573 default:
6574 goto die;
6575 break;
6576 }
6577 break;
6578 case 16:
6579 switch (sel) {
6580 case 0 ... 7:
895c2d04 6581 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6582 break;
6583 default:
6584 goto die;
6585 break;
6586 }
6587 break;
ead9360e
TS
6588 case 23:
6589 switch (sel) {
6590 case 0:
895c2d04 6591 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6592 break;
6593 default:
d75c135e 6594 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6595 break;
6596 }
6597 break;
6598 default:
d75c135e 6599 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6600 }
6601 } else switch (sel) {
6602 /* GPR registers. */
6603 case 0:
895c2d04 6604 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6605 break;
6606 /* Auxiliary CPU registers */
6607 case 1:
6608 switch (rt) {
6609 case 0:
895c2d04 6610 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6611 break;
6612 case 1:
895c2d04 6613 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6614 break;
6615 case 2:
895c2d04 6616 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6617 break;
6618 case 4:
895c2d04 6619 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6620 break;
6621 case 5:
895c2d04 6622 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6623 break;
6624 case 6:
895c2d04 6625 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6626 break;
6627 case 8:
895c2d04 6628 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6629 break;
6630 case 9:
895c2d04 6631 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6632 break;
6633 case 10:
895c2d04 6634 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6635 break;
6636 case 12:
895c2d04 6637 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6638 break;
6639 case 13:
895c2d04 6640 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6641 break;
6642 case 14:
895c2d04 6643 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6644 break;
6645 case 16:
895c2d04 6646 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6647 break;
6648 default:
6649 goto die;
6650 }
6651 break;
6652 /* Floating point (COP1). */
6653 case 2:
6654 /* XXX: For now we support only a single FPU context. */
6655 if (h == 0) {
a7812ae4 6656 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6657
6658 gen_load_fpr32(fp0, rt);
6659 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6660 tcg_temp_free_i32(fp0);
ead9360e 6661 } else {
a7812ae4 6662 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 6663
7f6613ce 6664 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 6665 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6666 tcg_temp_free_i32(fp0);
ead9360e
TS
6667 }
6668 break;
6669 case 3:
6670 /* XXX: For now we support only a single FPU context. */
895c2d04 6671 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6672 break;
6673 /* COP2: Not implemented. */
6674 case 4:
6675 case 5:
6676 /* fall through */
6677 default:
6678 goto die;
6679 }
d12d51d5 6680 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6681 gen_store_gpr(t0, rd);
6682 tcg_temp_free(t0);
ead9360e
TS
6683 return;
6684
6685die:
1a3fd9c3 6686 tcg_temp_free(t0);
d12d51d5 6687 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6688 generate_exception(ctx, EXCP_RI);
6689}
6690
7db13fae 6691static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6692 int u, int sel, int h)
6693{
6694 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6695 TCGv t0 = tcg_temp_local_new();
ead9360e 6696
1a3fd9c3 6697 gen_load_gpr(t0, rt);
ead9360e 6698 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6699 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6700 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6701 /* NOP */ ;
6702 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6703 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6704 /* NOP */ ;
6705 else if (u == 0) {
6706 switch (rd) {
5a25ce94
EI
6707 case 1:
6708 switch (sel) {
6709 case 1:
895c2d04 6710 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6711 break;
6712 case 2:
895c2d04 6713 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6714 break;
6715 default:
6716 goto die;
6717 break;
6718 }
6719 break;
ead9360e
TS
6720 case 2:
6721 switch (sel) {
6722 case 1:
895c2d04 6723 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6724 break;
6725 case 2:
895c2d04 6726 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6727 break;
6728 case 3:
895c2d04 6729 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6730 break;
6731 case 4:
895c2d04 6732 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6733 break;
6734 case 5:
895c2d04 6735 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6736 break;
6737 case 6:
895c2d04 6738 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6739 break;
6740 case 7:
895c2d04 6741 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6742 break;
6743 default:
d75c135e 6744 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6745 break;
6746 }
6747 break;
6748 case 10:
6749 switch (sel) {
6750 case 0:
895c2d04 6751 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6752 break;
6753 default:
d75c135e 6754 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6755 break;
6756 }
6757 case 12:
6758 switch (sel) {
6759 case 0:
895c2d04 6760 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6761 break;
6762 default:
d75c135e 6763 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6764 break;
6765 }
5a25ce94
EI
6766 case 13:
6767 switch (sel) {
6768 case 0:
895c2d04 6769 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6770 break;
6771 default:
6772 goto die;
6773 break;
6774 }
6775 break;
6776 case 15:
6777 switch (sel) {
6778 case 1:
895c2d04 6779 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6780 break;
6781 default:
6782 goto die;
6783 break;
6784 }
6785 break;
ead9360e
TS
6786 case 23:
6787 switch (sel) {
6788 case 0:
895c2d04 6789 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6790 break;
6791 default:
d75c135e 6792 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6793 break;
6794 }
6795 break;
6796 default:
d75c135e 6797 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6798 }
6799 } else switch (sel) {
6800 /* GPR registers. */
6801 case 0:
895c2d04 6802 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6803 break;
6804 /* Auxiliary CPU registers */
6805 case 1:
6806 switch (rd) {
6807 case 0:
895c2d04 6808 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6809 break;
6810 case 1:
895c2d04 6811 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6812 break;
6813 case 2:
895c2d04 6814 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6815 break;
6816 case 4:
895c2d04 6817 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6818 break;
6819 case 5:
895c2d04 6820 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6821 break;
6822 case 6:
895c2d04 6823 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6824 break;
6825 case 8:
895c2d04 6826 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6827 break;
6828 case 9:
895c2d04 6829 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6830 break;
6831 case 10:
895c2d04 6832 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6833 break;
6834 case 12:
895c2d04 6835 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6836 break;
6837 case 13:
895c2d04 6838 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6839 break;
6840 case 14:
895c2d04 6841 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6842 break;
6843 case 16:
895c2d04 6844 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6845 break;
6846 default:
6847 goto die;
6848 }
6849 break;
6850 /* Floating point (COP1). */
6851 case 2:
6852 /* XXX: For now we support only a single FPU context. */
6853 if (h == 0) {
a7812ae4 6854 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6855
6856 tcg_gen_trunc_tl_i32(fp0, t0);
6857 gen_store_fpr32(fp0, rd);
a7812ae4 6858 tcg_temp_free_i32(fp0);
ead9360e 6859 } else {
a7812ae4 6860 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6861
6862 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 6863 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 6864 tcg_temp_free_i32(fp0);
ead9360e
TS
6865 }
6866 break;
6867 case 3:
6868 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
6869 {
6870 TCGv_i32 fs_tmp = tcg_const_i32(rd);
6871
6872 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
6873 tcg_temp_free_i32(fs_tmp);
6874 }
ead9360e
TS
6875 break;
6876 /* COP2: Not implemented. */
6877 case 4:
6878 case 5:
6879 /* fall through */
6880 default:
6881 goto die;
6882 }
d12d51d5 6883 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6884 tcg_temp_free(t0);
ead9360e
TS
6885 return;
6886
6887die:
1a3fd9c3 6888 tcg_temp_free(t0);
d12d51d5 6889 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6890 generate_exception(ctx, EXCP_RI);
6891}
6892
7db13fae 6893static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6894{
287c4b84 6895 const char *opn = "ldst";
6af0bf9c 6896
2e15497c 6897 check_cp0_enabled(ctx);
6af0bf9c
FB
6898 switch (opc) {
6899 case OPC_MFC0:
6900 if (rt == 0) {
ead9360e 6901 /* Treat as NOP. */
6af0bf9c
FB
6902 return;
6903 }
d75c135e 6904 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6905 opn = "mfc0";
6906 break;
6907 case OPC_MTC0:
1a3fd9c3 6908 {
1fc7bf6e 6909 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6910
6911 gen_load_gpr(t0, rt);
d75c135e 6912 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6913 tcg_temp_free(t0);
6914 }
6af0bf9c
FB
6915 opn = "mtc0";
6916 break;
d26bc211 6917#if defined(TARGET_MIPS64)
9c2149c8 6918 case OPC_DMFC0:
d75c135e 6919 check_insn(ctx, ISA_MIPS3);
9c2149c8 6920 if (rt == 0) {
ead9360e 6921 /* Treat as NOP. */
9c2149c8
TS
6922 return;
6923 }
d75c135e 6924 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6925 opn = "dmfc0";
6926 break;
6927 case OPC_DMTC0:
d75c135e 6928 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 6929 {
1fc7bf6e 6930 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6931
6932 gen_load_gpr(t0, rt);
d75c135e 6933 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6934 tcg_temp_free(t0);
6935 }
9c2149c8
TS
6936 opn = "dmtc0";
6937 break;
534ce69f 6938#endif
ead9360e 6939 case OPC_MFTR:
d75c135e 6940 check_insn(ctx, ASE_MT);
ead9360e
TS
6941 if (rd == 0) {
6942 /* Treat as NOP. */
6943 return;
6944 }
6c5c1e20 6945 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6946 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6947 opn = "mftr";
6948 break;
6949 case OPC_MTTR:
d75c135e 6950 check_insn(ctx, ASE_MT);
6c5c1e20 6951 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6952 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6953 opn = "mttr";
6954 break;
6af0bf9c 6955 case OPC_TLBWI:
6af0bf9c 6956 opn = "tlbwi";
c01fccd2 6957 if (!env->tlb->helper_tlbwi)
29929e34 6958 goto die;
895c2d04 6959 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6960 break;
6961 case OPC_TLBWR:
6af0bf9c 6962 opn = "tlbwr";
c01fccd2 6963 if (!env->tlb->helper_tlbwr)
29929e34 6964 goto die;
895c2d04 6965 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6966 break;
6967 case OPC_TLBP:
6af0bf9c 6968 opn = "tlbp";
c01fccd2 6969 if (!env->tlb->helper_tlbp)
29929e34 6970 goto die;
895c2d04 6971 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6972 break;
6973 case OPC_TLBR:
6af0bf9c 6974 opn = "tlbr";
c01fccd2 6975 if (!env->tlb->helper_tlbr)
29929e34 6976 goto die;
895c2d04 6977 gen_helper_tlbr(cpu_env);
6af0bf9c 6978 break;
6af0bf9c
FB
6979 case OPC_ERET:
6980 opn = "eret";
d75c135e 6981 check_insn(ctx, ISA_MIPS2);
895c2d04 6982 gen_helper_eret(cpu_env);
6af0bf9c
FB
6983 ctx->bstate = BS_EXCP;
6984 break;
6985 case OPC_DERET:
6986 opn = "deret";
d75c135e 6987 check_insn(ctx, ISA_MIPS32);
6af0bf9c 6988 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6989 MIPS_INVAL(opn);
6af0bf9c
FB
6990 generate_exception(ctx, EXCP_RI);
6991 } else {
895c2d04 6992 gen_helper_deret(cpu_env);
6af0bf9c
FB
6993 ctx->bstate = BS_EXCP;
6994 }
6995 break;
4ad40f36
FB
6996 case OPC_WAIT:
6997 opn = "wait";
d75c135e 6998 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6999 /* If we get an exception, we want to restart at next instruction */
7000 ctx->pc += 4;
7001 save_cpu_state(ctx, 1);
7002 ctx->pc -= 4;
895c2d04 7003 gen_helper_wait(cpu_env);
4ad40f36
FB
7004 ctx->bstate = BS_EXCP;
7005 break;
6af0bf9c 7006 default:
29929e34 7007 die:
923617a3 7008 MIPS_INVAL(opn);
6af0bf9c
FB
7009 generate_exception(ctx, EXCP_RI);
7010 return;
7011 }
2abf314d 7012 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7013 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7014}
f1aa6320 7015#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7016
6ea83fed 7017/* CP1 Branches (before delay slot) */
d75c135e
AJ
7018static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7019 int32_t cc, int32_t offset)
6ea83fed
FB
7020{
7021 target_ulong btarget;
923617a3 7022 const char *opn = "cp1 cond branch";
a7812ae4 7023 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7024
e189e748 7025 if (cc != 0)
d75c135e 7026 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7027
6ea83fed
FB
7028 btarget = ctx->pc + 4 + offset;
7029
7a387fff
TS
7030 switch (op) {
7031 case OPC_BC1F:
d94536f4
AJ
7032 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7033 tcg_gen_not_i32(t0, t0);
7034 tcg_gen_andi_i32(t0, t0, 1);
7035 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7036 opn = "bc1f";
6ea83fed 7037 goto not_likely;
7a387fff 7038 case OPC_BC1FL:
d94536f4
AJ
7039 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7040 tcg_gen_not_i32(t0, t0);
7041 tcg_gen_andi_i32(t0, t0, 1);
7042 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7043 opn = "bc1fl";
6ea83fed 7044 goto likely;
7a387fff 7045 case OPC_BC1T:
d94536f4
AJ
7046 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7047 tcg_gen_andi_i32(t0, t0, 1);
7048 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7049 opn = "bc1t";
5a5012ec 7050 goto not_likely;
7a387fff 7051 case OPC_BC1TL:
d94536f4
AJ
7052 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7053 tcg_gen_andi_i32(t0, t0, 1);
7054 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7055 opn = "bc1tl";
6ea83fed
FB
7056 likely:
7057 ctx->hflags |= MIPS_HFLAG_BL;
7058 break;
5a5012ec 7059 case OPC_BC1FANY2:
a16336e4 7060 {
d94536f4
AJ
7061 TCGv_i32 t1 = tcg_temp_new_i32();
7062 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7063 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7064 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7065 tcg_temp_free_i32(t1);
d94536f4
AJ
7066 tcg_gen_andi_i32(t0, t0, 1);
7067 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7068 }
fd4a04eb 7069 opn = "bc1any2f";
5a5012ec
TS
7070 goto not_likely;
7071 case OPC_BC1TANY2:
a16336e4 7072 {
d94536f4
AJ
7073 TCGv_i32 t1 = tcg_temp_new_i32();
7074 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7075 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7076 tcg_gen_or_i32(t0, t0, t1);
7077 tcg_temp_free_i32(t1);
7078 tcg_gen_andi_i32(t0, t0, 1);
7079 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7080 }
fd4a04eb 7081 opn = "bc1any2t";
5a5012ec
TS
7082 goto not_likely;
7083 case OPC_BC1FANY4:
a16336e4 7084 {
d94536f4
AJ
7085 TCGv_i32 t1 = tcg_temp_new_i32();
7086 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7087 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7088 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7089 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7090 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7091 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7092 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7093 tcg_temp_free_i32(t1);
d94536f4
AJ
7094 tcg_gen_andi_i32(t0, t0, 1);
7095 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7096 }
fd4a04eb 7097 opn = "bc1any4f";
5a5012ec
TS
7098 goto not_likely;
7099 case OPC_BC1TANY4:
a16336e4 7100 {
d94536f4
AJ
7101 TCGv_i32 t1 = tcg_temp_new_i32();
7102 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7103 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7104 tcg_gen_or_i32(t0, t0, t1);
7105 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7106 tcg_gen_or_i32(t0, t0, t1);
7107 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7108 tcg_gen_or_i32(t0, t0, t1);
7109 tcg_temp_free_i32(t1);
7110 tcg_gen_andi_i32(t0, t0, 1);
7111 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7112 }
fd4a04eb 7113 opn = "bc1any4t";
5a5012ec
TS
7114 not_likely:
7115 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7116 break;
7117 default:
923617a3 7118 MIPS_INVAL(opn);
e397ee33 7119 generate_exception (ctx, EXCP_RI);
6c5c1e20 7120 goto out;
6ea83fed 7121 }
2abf314d 7122 (void)opn; /* avoid a compiler warning */
923617a3 7123 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7124 ctx->hflags, btarget);
7125 ctx->btarget = btarget;
6c5c1e20
TS
7126
7127 out:
a7812ae4 7128 tcg_temp_free_i32(t0);
6ea83fed
FB
7129}
7130
6af0bf9c 7131/* Coprocessor 1 (FPU) */
5a5012ec 7132
5a5012ec
TS
7133#define FOP(func, fmt) (((fmt) << 21) | (func))
7134
bf4120ad
NF
7135enum fopcode {
7136 OPC_ADD_S = FOP(0, FMT_S),
7137 OPC_SUB_S = FOP(1, FMT_S),
7138 OPC_MUL_S = FOP(2, FMT_S),
7139 OPC_DIV_S = FOP(3, FMT_S),
7140 OPC_SQRT_S = FOP(4, FMT_S),
7141 OPC_ABS_S = FOP(5, FMT_S),
7142 OPC_MOV_S = FOP(6, FMT_S),
7143 OPC_NEG_S = FOP(7, FMT_S),
7144 OPC_ROUND_L_S = FOP(8, FMT_S),
7145 OPC_TRUNC_L_S = FOP(9, FMT_S),
7146 OPC_CEIL_L_S = FOP(10, FMT_S),
7147 OPC_FLOOR_L_S = FOP(11, FMT_S),
7148 OPC_ROUND_W_S = FOP(12, FMT_S),
7149 OPC_TRUNC_W_S = FOP(13, FMT_S),
7150 OPC_CEIL_W_S = FOP(14, FMT_S),
7151 OPC_FLOOR_W_S = FOP(15, FMT_S),
7152 OPC_MOVCF_S = FOP(17, FMT_S),
7153 OPC_MOVZ_S = FOP(18, FMT_S),
7154 OPC_MOVN_S = FOP(19, FMT_S),
7155 OPC_RECIP_S = FOP(21, FMT_S),
7156 OPC_RSQRT_S = FOP(22, FMT_S),
7157 OPC_RECIP2_S = FOP(28, FMT_S),
7158 OPC_RECIP1_S = FOP(29, FMT_S),
7159 OPC_RSQRT1_S = FOP(30, FMT_S),
7160 OPC_RSQRT2_S = FOP(31, FMT_S),
7161 OPC_CVT_D_S = FOP(33, FMT_S),
7162 OPC_CVT_W_S = FOP(36, FMT_S),
7163 OPC_CVT_L_S = FOP(37, FMT_S),
7164 OPC_CVT_PS_S = FOP(38, FMT_S),
7165 OPC_CMP_F_S = FOP (48, FMT_S),
7166 OPC_CMP_UN_S = FOP (49, FMT_S),
7167 OPC_CMP_EQ_S = FOP (50, FMT_S),
7168 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7169 OPC_CMP_OLT_S = FOP (52, FMT_S),
7170 OPC_CMP_ULT_S = FOP (53, FMT_S),
7171 OPC_CMP_OLE_S = FOP (54, FMT_S),
7172 OPC_CMP_ULE_S = FOP (55, FMT_S),
7173 OPC_CMP_SF_S = FOP (56, FMT_S),
7174 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7175 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7176 OPC_CMP_NGL_S = FOP (59, FMT_S),
7177 OPC_CMP_LT_S = FOP (60, FMT_S),
7178 OPC_CMP_NGE_S = FOP (61, FMT_S),
7179 OPC_CMP_LE_S = FOP (62, FMT_S),
7180 OPC_CMP_NGT_S = FOP (63, FMT_S),
7181
7182 OPC_ADD_D = FOP(0, FMT_D),
7183 OPC_SUB_D = FOP(1, FMT_D),
7184 OPC_MUL_D = FOP(2, FMT_D),
7185 OPC_DIV_D = FOP(3, FMT_D),
7186 OPC_SQRT_D = FOP(4, FMT_D),
7187 OPC_ABS_D = FOP(5, FMT_D),
7188 OPC_MOV_D = FOP(6, FMT_D),
7189 OPC_NEG_D = FOP(7, FMT_D),
7190 OPC_ROUND_L_D = FOP(8, FMT_D),
7191 OPC_TRUNC_L_D = FOP(9, FMT_D),
7192 OPC_CEIL_L_D = FOP(10, FMT_D),
7193 OPC_FLOOR_L_D = FOP(11, FMT_D),
7194 OPC_ROUND_W_D = FOP(12, FMT_D),
7195 OPC_TRUNC_W_D = FOP(13, FMT_D),
7196 OPC_CEIL_W_D = FOP(14, FMT_D),
7197 OPC_FLOOR_W_D = FOP(15, FMT_D),
7198 OPC_MOVCF_D = FOP(17, FMT_D),
7199 OPC_MOVZ_D = FOP(18, FMT_D),
7200 OPC_MOVN_D = FOP(19, FMT_D),
7201 OPC_RECIP_D = FOP(21, FMT_D),
7202 OPC_RSQRT_D = FOP(22, FMT_D),
7203 OPC_RECIP2_D = FOP(28, FMT_D),
7204 OPC_RECIP1_D = FOP(29, FMT_D),
7205 OPC_RSQRT1_D = FOP(30, FMT_D),
7206 OPC_RSQRT2_D = FOP(31, FMT_D),
7207 OPC_CVT_S_D = FOP(32, FMT_D),
7208 OPC_CVT_W_D = FOP(36, FMT_D),
7209 OPC_CVT_L_D = FOP(37, FMT_D),
7210 OPC_CMP_F_D = FOP (48, FMT_D),
7211 OPC_CMP_UN_D = FOP (49, FMT_D),
7212 OPC_CMP_EQ_D = FOP (50, FMT_D),
7213 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7214 OPC_CMP_OLT_D = FOP (52, FMT_D),
7215 OPC_CMP_ULT_D = FOP (53, FMT_D),
7216 OPC_CMP_OLE_D = FOP (54, FMT_D),
7217 OPC_CMP_ULE_D = FOP (55, FMT_D),
7218 OPC_CMP_SF_D = FOP (56, FMT_D),
7219 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7220 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7221 OPC_CMP_NGL_D = FOP (59, FMT_D),
7222 OPC_CMP_LT_D = FOP (60, FMT_D),
7223 OPC_CMP_NGE_D = FOP (61, FMT_D),
7224 OPC_CMP_LE_D = FOP (62, FMT_D),
7225 OPC_CMP_NGT_D = FOP (63, FMT_D),
7226
7227 OPC_CVT_S_W = FOP(32, FMT_W),
7228 OPC_CVT_D_W = FOP(33, FMT_W),
7229 OPC_CVT_S_L = FOP(32, FMT_L),
7230 OPC_CVT_D_L = FOP(33, FMT_L),
7231 OPC_CVT_PS_PW = FOP(38, FMT_W),
7232
7233 OPC_ADD_PS = FOP(0, FMT_PS),
7234 OPC_SUB_PS = FOP(1, FMT_PS),
7235 OPC_MUL_PS = FOP(2, FMT_PS),
7236 OPC_DIV_PS = FOP(3, FMT_PS),
7237 OPC_ABS_PS = FOP(5, FMT_PS),
7238 OPC_MOV_PS = FOP(6, FMT_PS),
7239 OPC_NEG_PS = FOP(7, FMT_PS),
7240 OPC_MOVCF_PS = FOP(17, FMT_PS),
7241 OPC_MOVZ_PS = FOP(18, FMT_PS),
7242 OPC_MOVN_PS = FOP(19, FMT_PS),
7243 OPC_ADDR_PS = FOP(24, FMT_PS),
7244 OPC_MULR_PS = FOP(26, FMT_PS),
7245 OPC_RECIP2_PS = FOP(28, FMT_PS),
7246 OPC_RECIP1_PS = FOP(29, FMT_PS),
7247 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7248 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7249
7250 OPC_CVT_S_PU = FOP(32, FMT_PS),
7251 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7252 OPC_CVT_S_PL = FOP(40, FMT_PS),
7253 OPC_PLL_PS = FOP(44, FMT_PS),
7254 OPC_PLU_PS = FOP(45, FMT_PS),
7255 OPC_PUL_PS = FOP(46, FMT_PS),
7256 OPC_PUU_PS = FOP(47, FMT_PS),
7257 OPC_CMP_F_PS = FOP (48, FMT_PS),
7258 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7259 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7260 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7261 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7262 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7263 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7264 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7265 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7266 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7267 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7268 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7269 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7270 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7271 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7272 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7273};
7274
7a387fff 7275static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7276{
923617a3 7277 const char *opn = "cp1 move";
72c3a3ee 7278 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7279
7280 switch (opc) {
7281 case OPC_MFC1:
b6d96bed 7282 {
a7812ae4 7283 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7284
7285 gen_load_fpr32(fp0, fs);
7286 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7287 tcg_temp_free_i32(fp0);
6958549d 7288 }
6c5c1e20 7289 gen_store_gpr(t0, rt);
6ea83fed
FB
7290 opn = "mfc1";
7291 break;
7292 case OPC_MTC1:
6c5c1e20 7293 gen_load_gpr(t0, rt);
b6d96bed 7294 {
a7812ae4 7295 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7296
7297 tcg_gen_trunc_tl_i32(fp0, t0);
7298 gen_store_fpr32(fp0, fs);
a7812ae4 7299 tcg_temp_free_i32(fp0);
6958549d 7300 }
6ea83fed
FB
7301 opn = "mtc1";
7302 break;
7303 case OPC_CFC1:
895c2d04 7304 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7305 gen_store_gpr(t0, rt);
6ea83fed
FB
7306 opn = "cfc1";
7307 break;
7308 case OPC_CTC1:
6c5c1e20 7309 gen_load_gpr(t0, rt);
736d120a
PJ
7310 {
7311 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7312
7313 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7314 tcg_temp_free_i32(fs_tmp);
7315 }
6ea83fed
FB
7316 opn = "ctc1";
7317 break;
72c3a3ee 7318#if defined(TARGET_MIPS64)
9c2149c8 7319 case OPC_DMFC1:
72c3a3ee 7320 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7321 gen_store_gpr(t0, rt);
5a5012ec
TS
7322 opn = "dmfc1";
7323 break;
9c2149c8 7324 case OPC_DMTC1:
6c5c1e20 7325 gen_load_gpr(t0, rt);
72c3a3ee 7326 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7327 opn = "dmtc1";
7328 break;
72c3a3ee 7329#endif
5a5012ec 7330 case OPC_MFHC1:
b6d96bed 7331 {
a7812ae4 7332 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7333
7f6613ce 7334 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 7335 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7336 tcg_temp_free_i32(fp0);
6958549d 7337 }
6c5c1e20 7338 gen_store_gpr(t0, rt);
5a5012ec
TS
7339 opn = "mfhc1";
7340 break;
7341 case OPC_MTHC1:
6c5c1e20 7342 gen_load_gpr(t0, rt);
b6d96bed 7343 {
a7812ae4 7344 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7345
7346 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7347 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 7348 tcg_temp_free_i32(fp0);
6958549d 7349 }
5a5012ec
TS
7350 opn = "mthc1";
7351 break;
6ea83fed 7352 default:
923617a3 7353 MIPS_INVAL(opn);
e397ee33 7354 generate_exception (ctx, EXCP_RI);
6c5c1e20 7355 goto out;
6ea83fed 7356 }
2abf314d 7357 (void)opn; /* avoid a compiler warning */
6ea83fed 7358 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7359
7360 out:
7361 tcg_temp_free(t0);
6ea83fed
FB
7362}
7363
5a5012ec
TS
7364static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7365{
af58f9ca 7366 int l1;
e214b9bb 7367 TCGCond cond;
af58f9ca
AJ
7368 TCGv_i32 t0;
7369
7370 if (rd == 0) {
7371 /* Treat as NOP. */
7372 return;
7373 }
6ea83fed 7374
e214b9bb 7375 if (tf)
e214b9bb 7376 cond = TCG_COND_EQ;
27848470
TS
7377 else
7378 cond = TCG_COND_NE;
7379
af58f9ca
AJ
7380 l1 = gen_new_label();
7381 t0 = tcg_temp_new_i32();
fa31af0e 7382 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7383 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7384 tcg_temp_free_i32(t0);
af58f9ca
AJ
7385 if (rs == 0) {
7386 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7387 } else {
7388 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7389 }
e214b9bb 7390 gen_set_label(l1);
5a5012ec
TS
7391}
7392
b6d96bed 7393static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7394{
a16336e4 7395 int cond;
cbc37b28 7396 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7397 int l1 = gen_new_label();
7398
a16336e4
TS
7399 if (tf)
7400 cond = TCG_COND_EQ;
7401 else
7402 cond = TCG_COND_NE;
7403
fa31af0e 7404 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7405 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7406 gen_load_fpr32(t0, fs);
7407 gen_store_fpr32(t0, fd);
a16336e4 7408 gen_set_label(l1);
cbc37b28 7409 tcg_temp_free_i32(t0);
5a5012ec 7410}
a16336e4 7411
b6d96bed 7412static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7413{
a16336e4 7414 int cond;
cbc37b28
AJ
7415 TCGv_i32 t0 = tcg_temp_new_i32();
7416 TCGv_i64 fp0;
a16336e4
TS
7417 int l1 = gen_new_label();
7418
a16336e4
TS
7419 if (tf)
7420 cond = TCG_COND_EQ;
7421 else
7422 cond = TCG_COND_NE;
7423
fa31af0e 7424 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7425 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7426 tcg_temp_free_i32(t0);
11f94258 7427 fp0 = tcg_temp_new_i64();
9bf3eb2c 7428 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7429 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7430 tcg_temp_free_i64(fp0);
cbc37b28 7431 gen_set_label(l1);
a16336e4
TS
7432}
7433
7f6613ce
PJ
7434static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
7435 int cc, int tf)
a16336e4
TS
7436{
7437 int cond;
cbc37b28 7438 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7439 int l1 = gen_new_label();
7440 int l2 = gen_new_label();
7441
7442 if (tf)
7443 cond = TCG_COND_EQ;
7444 else
7445 cond = TCG_COND_NE;
7446
fa31af0e 7447 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7448 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7449 gen_load_fpr32(t0, fs);
7450 gen_store_fpr32(t0, fd);
a16336e4 7451 gen_set_label(l1);
9bf3eb2c 7452
fa31af0e 7453 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 7454 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
7455 gen_load_fpr32h(ctx, t0, fs);
7456 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 7457 tcg_temp_free_i32(t0);
a16336e4 7458 gen_set_label(l2);
a16336e4
TS
7459}
7460
6ea83fed 7461
bf4120ad 7462static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7463 int ft, int fs, int fd, int cc)
6ea83fed 7464{
923617a3 7465 const char *opn = "farith";
6ea83fed
FB
7466 const char *condnames[] = {
7467 "c.f",
7468 "c.un",
7469 "c.eq",
7470 "c.ueq",
7471 "c.olt",
7472 "c.ult",
7473 "c.ole",
7474 "c.ule",
7475 "c.sf",
7476 "c.ngle",
7477 "c.seq",
7478 "c.ngl",
7479 "c.lt",
7480 "c.nge",
7481 "c.le",
7482 "c.ngt",
7483 };
5a1e8ffb
TS
7484 const char *condnames_abs[] = {
7485 "cabs.f",
7486 "cabs.un",
7487 "cabs.eq",
7488 "cabs.ueq",
7489 "cabs.olt",
7490 "cabs.ult",
7491 "cabs.ole",
7492 "cabs.ule",
7493 "cabs.sf",
7494 "cabs.ngle",
7495 "cabs.seq",
7496 "cabs.ngl",
7497 "cabs.lt",
7498 "cabs.nge",
7499 "cabs.le",
7500 "cabs.ngt",
7501 };
7502 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7503 uint32_t func = ctx->opcode & 0x3f;
7504
bf4120ad
NF
7505 switch (op1) {
7506 case OPC_ADD_S:
b6d96bed 7507 {
a7812ae4
PB
7508 TCGv_i32 fp0 = tcg_temp_new_i32();
7509 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7510
7511 gen_load_fpr32(fp0, fs);
7512 gen_load_fpr32(fp1, ft);
895c2d04 7513 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7514 tcg_temp_free_i32(fp1);
b6d96bed 7515 gen_store_fpr32(fp0, fd);
a7812ae4 7516 tcg_temp_free_i32(fp0);
b6d96bed 7517 }
5a5012ec 7518 opn = "add.s";
5a1e8ffb 7519 optype = BINOP;
5a5012ec 7520 break;
bf4120ad 7521 case OPC_SUB_S:
b6d96bed 7522 {
a7812ae4
PB
7523 TCGv_i32 fp0 = tcg_temp_new_i32();
7524 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7525
7526 gen_load_fpr32(fp0, fs);
7527 gen_load_fpr32(fp1, ft);
895c2d04 7528 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7529 tcg_temp_free_i32(fp1);
b6d96bed 7530 gen_store_fpr32(fp0, fd);
a7812ae4 7531 tcg_temp_free_i32(fp0);
b6d96bed 7532 }
5a5012ec 7533 opn = "sub.s";
5a1e8ffb 7534 optype = BINOP;
5a5012ec 7535 break;
bf4120ad 7536 case OPC_MUL_S:
b6d96bed 7537 {
a7812ae4
PB
7538 TCGv_i32 fp0 = tcg_temp_new_i32();
7539 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7540
7541 gen_load_fpr32(fp0, fs);
7542 gen_load_fpr32(fp1, ft);
895c2d04 7543 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7544 tcg_temp_free_i32(fp1);
b6d96bed 7545 gen_store_fpr32(fp0, fd);
a7812ae4 7546 tcg_temp_free_i32(fp0);
b6d96bed 7547 }
5a5012ec 7548 opn = "mul.s";
5a1e8ffb 7549 optype = BINOP;
5a5012ec 7550 break;
bf4120ad 7551 case OPC_DIV_S:
b6d96bed 7552 {
a7812ae4
PB
7553 TCGv_i32 fp0 = tcg_temp_new_i32();
7554 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7555
7556 gen_load_fpr32(fp0, fs);
7557 gen_load_fpr32(fp1, ft);
895c2d04 7558 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7559 tcg_temp_free_i32(fp1);
b6d96bed 7560 gen_store_fpr32(fp0, fd);
a7812ae4 7561 tcg_temp_free_i32(fp0);
b6d96bed 7562 }
5a5012ec 7563 opn = "div.s";
5a1e8ffb 7564 optype = BINOP;
5a5012ec 7565 break;
bf4120ad 7566 case OPC_SQRT_S:
b6d96bed 7567 {
a7812ae4 7568 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7569
7570 gen_load_fpr32(fp0, fs);
895c2d04 7571 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7572 gen_store_fpr32(fp0, fd);
a7812ae4 7573 tcg_temp_free_i32(fp0);
b6d96bed 7574 }
5a5012ec
TS
7575 opn = "sqrt.s";
7576 break;
bf4120ad 7577 case OPC_ABS_S:
b6d96bed 7578 {
a7812ae4 7579 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7580
7581 gen_load_fpr32(fp0, fs);
a7812ae4 7582 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7583 gen_store_fpr32(fp0, fd);
a7812ae4 7584 tcg_temp_free_i32(fp0);
b6d96bed 7585 }
5a5012ec
TS
7586 opn = "abs.s";
7587 break;
bf4120ad 7588 case OPC_MOV_S:
b6d96bed 7589 {
a7812ae4 7590 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7591
7592 gen_load_fpr32(fp0, fs);
7593 gen_store_fpr32(fp0, fd);
a7812ae4 7594 tcg_temp_free_i32(fp0);
b6d96bed 7595 }
5a5012ec
TS
7596 opn = "mov.s";
7597 break;
bf4120ad 7598 case OPC_NEG_S:
b6d96bed 7599 {
a7812ae4 7600 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7601
7602 gen_load_fpr32(fp0, fs);
a7812ae4 7603 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7604 gen_store_fpr32(fp0, fd);
a7812ae4 7605 tcg_temp_free_i32(fp0);
b6d96bed 7606 }
5a5012ec
TS
7607 opn = "neg.s";
7608 break;
bf4120ad 7609 case OPC_ROUND_L_S:
5e755519 7610 check_cp1_64bitmode(ctx);
b6d96bed 7611 {
a7812ae4
PB
7612 TCGv_i32 fp32 = tcg_temp_new_i32();
7613 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7614
7615 gen_load_fpr32(fp32, fs);
895c2d04 7616 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7617 tcg_temp_free_i32(fp32);
b6d96bed 7618 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7619 tcg_temp_free_i64(fp64);
b6d96bed 7620 }
5a5012ec
TS
7621 opn = "round.l.s";
7622 break;
bf4120ad 7623 case OPC_TRUNC_L_S:
5e755519 7624 check_cp1_64bitmode(ctx);
b6d96bed 7625 {
a7812ae4
PB
7626 TCGv_i32 fp32 = tcg_temp_new_i32();
7627 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7628
7629 gen_load_fpr32(fp32, fs);
895c2d04 7630 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7631 tcg_temp_free_i32(fp32);
b6d96bed 7632 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7633 tcg_temp_free_i64(fp64);
b6d96bed 7634 }
5a5012ec
TS
7635 opn = "trunc.l.s";
7636 break;
bf4120ad 7637 case OPC_CEIL_L_S:
5e755519 7638 check_cp1_64bitmode(ctx);
b6d96bed 7639 {
a7812ae4
PB
7640 TCGv_i32 fp32 = tcg_temp_new_i32();
7641 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7642
7643 gen_load_fpr32(fp32, fs);
895c2d04 7644 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7645 tcg_temp_free_i32(fp32);
b6d96bed 7646 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7647 tcg_temp_free_i64(fp64);
b6d96bed 7648 }
5a5012ec
TS
7649 opn = "ceil.l.s";
7650 break;
bf4120ad 7651 case OPC_FLOOR_L_S:
5e755519 7652 check_cp1_64bitmode(ctx);
b6d96bed 7653 {
a7812ae4
PB
7654 TCGv_i32 fp32 = tcg_temp_new_i32();
7655 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7656
7657 gen_load_fpr32(fp32, fs);
895c2d04 7658 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7659 tcg_temp_free_i32(fp32);
b6d96bed 7660 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7661 tcg_temp_free_i64(fp64);
b6d96bed 7662 }
5a5012ec
TS
7663 opn = "floor.l.s";
7664 break;
bf4120ad 7665 case OPC_ROUND_W_S:
b6d96bed 7666 {
a7812ae4 7667 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7668
7669 gen_load_fpr32(fp0, fs);
895c2d04 7670 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7671 gen_store_fpr32(fp0, fd);
a7812ae4 7672 tcg_temp_free_i32(fp0);
b6d96bed 7673 }
5a5012ec
TS
7674 opn = "round.w.s";
7675 break;
bf4120ad 7676 case OPC_TRUNC_W_S:
b6d96bed 7677 {
a7812ae4 7678 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7679
7680 gen_load_fpr32(fp0, fs);
895c2d04 7681 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7682 gen_store_fpr32(fp0, fd);
a7812ae4 7683 tcg_temp_free_i32(fp0);
b6d96bed 7684 }
5a5012ec
TS
7685 opn = "trunc.w.s";
7686 break;
bf4120ad 7687 case OPC_CEIL_W_S:
b6d96bed 7688 {
a7812ae4 7689 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7690
7691 gen_load_fpr32(fp0, fs);
895c2d04 7692 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7693 gen_store_fpr32(fp0, fd);
a7812ae4 7694 tcg_temp_free_i32(fp0);
b6d96bed 7695 }
5a5012ec
TS
7696 opn = "ceil.w.s";
7697 break;
bf4120ad 7698 case OPC_FLOOR_W_S:
b6d96bed 7699 {
a7812ae4 7700 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7701
7702 gen_load_fpr32(fp0, fs);
895c2d04 7703 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7704 gen_store_fpr32(fp0, fd);
a7812ae4 7705 tcg_temp_free_i32(fp0);
b6d96bed 7706 }
5a5012ec
TS
7707 opn = "floor.w.s";
7708 break;
bf4120ad 7709 case OPC_MOVCF_S:
b6d96bed 7710 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7711 opn = "movcf.s";
7712 break;
bf4120ad 7713 case OPC_MOVZ_S:
a16336e4
TS
7714 {
7715 int l1 = gen_new_label();
c9297f4d 7716 TCGv_i32 fp0;
a16336e4 7717
c9297f4d
AJ
7718 if (ft != 0) {
7719 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7720 }
7721 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7722 gen_load_fpr32(fp0, fs);
7723 gen_store_fpr32(fp0, fd);
a7812ae4 7724 tcg_temp_free_i32(fp0);
a16336e4
TS
7725 gen_set_label(l1);
7726 }
5a5012ec
TS
7727 opn = "movz.s";
7728 break;
bf4120ad 7729 case OPC_MOVN_S:
a16336e4
TS
7730 {
7731 int l1 = gen_new_label();
c9297f4d
AJ
7732 TCGv_i32 fp0;
7733
7734 if (ft != 0) {
7735 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7736 fp0 = tcg_temp_new_i32();
7737 gen_load_fpr32(fp0, fs);
7738 gen_store_fpr32(fp0, fd);
7739 tcg_temp_free_i32(fp0);
7740 gen_set_label(l1);
7741 }
a16336e4 7742 }
5a5012ec
TS
7743 opn = "movn.s";
7744 break;
bf4120ad 7745 case OPC_RECIP_S:
b8aa4598 7746 check_cop1x(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_recip_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 = "recip.s";
7756 break;
bf4120ad 7757 case OPC_RSQRT_S:
b8aa4598 7758 check_cop1x(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_rsqrt_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 = "rsqrt.s";
7768 break;
bf4120ad 7769 case OPC_RECIP2_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);
d22d7289 7776 gen_load_fpr32(fp1, ft);
895c2d04 7777 gen_helper_float_recip2_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 = "recip2.s";
7783 break;
bf4120ad 7784 case OPC_RECIP1_S:
5e755519 7785 check_cp1_64bitmode(ctx);
b6d96bed 7786 {
a7812ae4 7787 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7788
7789 gen_load_fpr32(fp0, fs);
895c2d04 7790 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7791 gen_store_fpr32(fp0, fd);
a7812ae4 7792 tcg_temp_free_i32(fp0);
b6d96bed 7793 }
57fa1fb3
TS
7794 opn = "recip1.s";
7795 break;
bf4120ad 7796 case OPC_RSQRT1_S:
5e755519 7797 check_cp1_64bitmode(ctx);
b6d96bed 7798 {
a7812ae4 7799 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7800
7801 gen_load_fpr32(fp0, fs);
895c2d04 7802 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7803 gen_store_fpr32(fp0, fd);
a7812ae4 7804 tcg_temp_free_i32(fp0);
b6d96bed 7805 }
57fa1fb3
TS
7806 opn = "rsqrt1.s";
7807 break;
bf4120ad 7808 case OPC_RSQRT2_S:
5e755519 7809 check_cp1_64bitmode(ctx);
b6d96bed 7810 {
a7812ae4
PB
7811 TCGv_i32 fp0 = tcg_temp_new_i32();
7812 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7813
7814 gen_load_fpr32(fp0, fs);
7815 gen_load_fpr32(fp1, ft);
895c2d04 7816 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7817 tcg_temp_free_i32(fp1);
b6d96bed 7818 gen_store_fpr32(fp0, fd);
a7812ae4 7819 tcg_temp_free_i32(fp0);
b6d96bed 7820 }
57fa1fb3
TS
7821 opn = "rsqrt2.s";
7822 break;
bf4120ad 7823 case OPC_CVT_D_S:
5e755519 7824 check_cp1_registers(ctx, fd);
b6d96bed 7825 {
a7812ae4
PB
7826 TCGv_i32 fp32 = tcg_temp_new_i32();
7827 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7828
7829 gen_load_fpr32(fp32, fs);
895c2d04 7830 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7831 tcg_temp_free_i32(fp32);
b6d96bed 7832 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7833 tcg_temp_free_i64(fp64);
b6d96bed 7834 }
5a5012ec
TS
7835 opn = "cvt.d.s";
7836 break;
bf4120ad 7837 case OPC_CVT_W_S:
b6d96bed 7838 {
a7812ae4 7839 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7840
7841 gen_load_fpr32(fp0, fs);
895c2d04 7842 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7843 gen_store_fpr32(fp0, fd);
a7812ae4 7844 tcg_temp_free_i32(fp0);
b6d96bed 7845 }
5a5012ec
TS
7846 opn = "cvt.w.s";
7847 break;
bf4120ad 7848 case OPC_CVT_L_S:
5e755519 7849 check_cp1_64bitmode(ctx);
b6d96bed 7850 {
a7812ae4
PB
7851 TCGv_i32 fp32 = tcg_temp_new_i32();
7852 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7853
7854 gen_load_fpr32(fp32, fs);
895c2d04 7855 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7856 tcg_temp_free_i32(fp32);
b6d96bed 7857 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7858 tcg_temp_free_i64(fp64);
b6d96bed 7859 }
5a5012ec
TS
7860 opn = "cvt.l.s";
7861 break;
bf4120ad 7862 case OPC_CVT_PS_S:
5e755519 7863 check_cp1_64bitmode(ctx);
b6d96bed 7864 {
a7812ae4
PB
7865 TCGv_i64 fp64 = tcg_temp_new_i64();
7866 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7867 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7868
7869 gen_load_fpr32(fp32_0, fs);
7870 gen_load_fpr32(fp32_1, ft);
13d24f49 7871 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7872 tcg_temp_free_i32(fp32_1);
7873 tcg_temp_free_i32(fp32_0);
36aa55dc 7874 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7875 tcg_temp_free_i64(fp64);
b6d96bed 7876 }
5a5012ec
TS
7877 opn = "cvt.ps.s";
7878 break;
bf4120ad
NF
7879 case OPC_CMP_F_S:
7880 case OPC_CMP_UN_S:
7881 case OPC_CMP_EQ_S:
7882 case OPC_CMP_UEQ_S:
7883 case OPC_CMP_OLT_S:
7884 case OPC_CMP_ULT_S:
7885 case OPC_CMP_OLE_S:
7886 case OPC_CMP_ULE_S:
7887 case OPC_CMP_SF_S:
7888 case OPC_CMP_NGLE_S:
7889 case OPC_CMP_SEQ_S:
7890 case OPC_CMP_NGL_S:
7891 case OPC_CMP_LT_S:
7892 case OPC_CMP_NGE_S:
7893 case OPC_CMP_LE_S:
7894 case OPC_CMP_NGT_S:
8153667c
NF
7895 if (ctx->opcode & (1 << 6)) {
7896 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7897 opn = condnames_abs[func-48];
7898 } else {
7899 gen_cmp_s(ctx, func-48, ft, fs, cc);
7900 opn = condnames[func-48];
5a1e8ffb 7901 }
5a5012ec 7902 break;
bf4120ad 7903 case OPC_ADD_D:
5e755519 7904 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7905 {
a7812ae4
PB
7906 TCGv_i64 fp0 = tcg_temp_new_i64();
7907 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7908
7909 gen_load_fpr64(ctx, fp0, fs);
7910 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7911 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7912 tcg_temp_free_i64(fp1);
b6d96bed 7913 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7914 tcg_temp_free_i64(fp0);
b6d96bed 7915 }
6ea83fed 7916 opn = "add.d";
5a1e8ffb 7917 optype = BINOP;
6ea83fed 7918 break;
bf4120ad 7919 case OPC_SUB_D:
5e755519 7920 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7921 {
a7812ae4
PB
7922 TCGv_i64 fp0 = tcg_temp_new_i64();
7923 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7924
7925 gen_load_fpr64(ctx, fp0, fs);
7926 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7927 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7928 tcg_temp_free_i64(fp1);
b6d96bed 7929 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7930 tcg_temp_free_i64(fp0);
b6d96bed 7931 }
6ea83fed 7932 opn = "sub.d";
5a1e8ffb 7933 optype = BINOP;
6ea83fed 7934 break;
bf4120ad 7935 case OPC_MUL_D:
5e755519 7936 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7937 {
a7812ae4
PB
7938 TCGv_i64 fp0 = tcg_temp_new_i64();
7939 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7940
7941 gen_load_fpr64(ctx, fp0, fs);
7942 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7943 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7944 tcg_temp_free_i64(fp1);
b6d96bed 7945 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7946 tcg_temp_free_i64(fp0);
b6d96bed 7947 }
6ea83fed 7948 opn = "mul.d";
5a1e8ffb 7949 optype = BINOP;
6ea83fed 7950 break;
bf4120ad 7951 case OPC_DIV_D:
5e755519 7952 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7953 {
a7812ae4
PB
7954 TCGv_i64 fp0 = tcg_temp_new_i64();
7955 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7956
7957 gen_load_fpr64(ctx, fp0, fs);
7958 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7959 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7960 tcg_temp_free_i64(fp1);
b6d96bed 7961 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7962 tcg_temp_free_i64(fp0);
b6d96bed 7963 }
6ea83fed 7964 opn = "div.d";
5a1e8ffb 7965 optype = BINOP;
6ea83fed 7966 break;
bf4120ad 7967 case OPC_SQRT_D:
5e755519 7968 check_cp1_registers(ctx, fs | fd);
b6d96bed 7969 {
a7812ae4 7970 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7971
7972 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7973 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7974 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7975 tcg_temp_free_i64(fp0);
b6d96bed 7976 }
6ea83fed
FB
7977 opn = "sqrt.d";
7978 break;
bf4120ad 7979 case OPC_ABS_D:
5e755519 7980 check_cp1_registers(ctx, fs | fd);
b6d96bed 7981 {
a7812ae4 7982 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7983
7984 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7985 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7986 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7987 tcg_temp_free_i64(fp0);
b6d96bed 7988 }
6ea83fed
FB
7989 opn = "abs.d";
7990 break;
bf4120ad 7991 case OPC_MOV_D:
5e755519 7992 check_cp1_registers(ctx, fs | fd);
b6d96bed 7993 {
a7812ae4 7994 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7995
7996 gen_load_fpr64(ctx, fp0, fs);
7997 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7998 tcg_temp_free_i64(fp0);
b6d96bed 7999 }
6ea83fed
FB
8000 opn = "mov.d";
8001 break;
bf4120ad 8002 case OPC_NEG_D:
5e755519 8003 check_cp1_registers(ctx, fs | fd);
b6d96bed 8004 {
a7812ae4 8005 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8006
8007 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8008 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 8009 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8010 tcg_temp_free_i64(fp0);
b6d96bed 8011 }
6ea83fed
FB
8012 opn = "neg.d";
8013 break;
bf4120ad 8014 case OPC_ROUND_L_D:
5e755519 8015 check_cp1_64bitmode(ctx);
b6d96bed 8016 {
a7812ae4 8017 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8018
8019 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8020 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 8021 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8022 tcg_temp_free_i64(fp0);
b6d96bed 8023 }
5a5012ec
TS
8024 opn = "round.l.d";
8025 break;
bf4120ad 8026 case OPC_TRUNC_L_D:
5e755519 8027 check_cp1_64bitmode(ctx);
b6d96bed 8028 {
a7812ae4 8029 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8030
8031 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8032 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 8033 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8034 tcg_temp_free_i64(fp0);
b6d96bed 8035 }
5a5012ec
TS
8036 opn = "trunc.l.d";
8037 break;
bf4120ad 8038 case OPC_CEIL_L_D:
5e755519 8039 check_cp1_64bitmode(ctx);
b6d96bed 8040 {
a7812ae4 8041 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8042
8043 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8044 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8045 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8046 tcg_temp_free_i64(fp0);
b6d96bed 8047 }
5a5012ec
TS
8048 opn = "ceil.l.d";
8049 break;
bf4120ad 8050 case OPC_FLOOR_L_D:
5e755519 8051 check_cp1_64bitmode(ctx);
b6d96bed 8052 {
a7812ae4 8053 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8054
8055 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8056 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8057 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8058 tcg_temp_free_i64(fp0);
b6d96bed 8059 }
5a5012ec
TS
8060 opn = "floor.l.d";
8061 break;
bf4120ad 8062 case OPC_ROUND_W_D:
5e755519 8063 check_cp1_registers(ctx, fs);
b6d96bed 8064 {
a7812ae4
PB
8065 TCGv_i32 fp32 = tcg_temp_new_i32();
8066 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8067
8068 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8069 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8070 tcg_temp_free_i64(fp64);
b6d96bed 8071 gen_store_fpr32(fp32, fd);
a7812ae4 8072 tcg_temp_free_i32(fp32);
b6d96bed 8073 }
6ea83fed
FB
8074 opn = "round.w.d";
8075 break;
bf4120ad 8076 case OPC_TRUNC_W_D:
5e755519 8077 check_cp1_registers(ctx, fs);
b6d96bed 8078 {
a7812ae4
PB
8079 TCGv_i32 fp32 = tcg_temp_new_i32();
8080 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8081
8082 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8083 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8084 tcg_temp_free_i64(fp64);
b6d96bed 8085 gen_store_fpr32(fp32, fd);
a7812ae4 8086 tcg_temp_free_i32(fp32);
b6d96bed 8087 }
6ea83fed
FB
8088 opn = "trunc.w.d";
8089 break;
bf4120ad 8090 case OPC_CEIL_W_D:
5e755519 8091 check_cp1_registers(ctx, fs);
b6d96bed 8092 {
a7812ae4
PB
8093 TCGv_i32 fp32 = tcg_temp_new_i32();
8094 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8095
8096 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8097 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8098 tcg_temp_free_i64(fp64);
b6d96bed 8099 gen_store_fpr32(fp32, fd);
a7812ae4 8100 tcg_temp_free_i32(fp32);
b6d96bed 8101 }
6ea83fed
FB
8102 opn = "ceil.w.d";
8103 break;
bf4120ad 8104 case OPC_FLOOR_W_D:
5e755519 8105 check_cp1_registers(ctx, fs);
b6d96bed 8106 {
a7812ae4
PB
8107 TCGv_i32 fp32 = tcg_temp_new_i32();
8108 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8109
8110 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8111 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8112 tcg_temp_free_i64(fp64);
b6d96bed 8113 gen_store_fpr32(fp32, fd);
a7812ae4 8114 tcg_temp_free_i32(fp32);
b6d96bed 8115 }
7a387fff 8116 opn = "floor.w.d";
6ea83fed 8117 break;
bf4120ad 8118 case OPC_MOVCF_D:
b6d96bed 8119 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8120 opn = "movcf.d";
dd016883 8121 break;
bf4120ad 8122 case OPC_MOVZ_D:
a16336e4
TS
8123 {
8124 int l1 = gen_new_label();
c9297f4d 8125 TCGv_i64 fp0;
a16336e4 8126
c9297f4d
AJ
8127 if (ft != 0) {
8128 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8129 }
8130 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8131 gen_load_fpr64(ctx, fp0, fs);
8132 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8133 tcg_temp_free_i64(fp0);
a16336e4
TS
8134 gen_set_label(l1);
8135 }
5a5012ec
TS
8136 opn = "movz.d";
8137 break;
bf4120ad 8138 case OPC_MOVN_D:
a16336e4
TS
8139 {
8140 int l1 = gen_new_label();
c9297f4d
AJ
8141 TCGv_i64 fp0;
8142
8143 if (ft != 0) {
8144 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8145 fp0 = tcg_temp_new_i64();
8146 gen_load_fpr64(ctx, fp0, fs);
8147 gen_store_fpr64(ctx, fp0, fd);
8148 tcg_temp_free_i64(fp0);
8149 gen_set_label(l1);
8150 }
a16336e4 8151 }
5a5012ec 8152 opn = "movn.d";
6ea83fed 8153 break;
bf4120ad 8154 case OPC_RECIP_D:
b8aa4598 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_recip_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 = "recip.d";
8165 break;
bf4120ad 8166 case OPC_RSQRT_D:
b8aa4598 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_rsqrt_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 = "rsqrt.d";
8177 break;
bf4120ad 8178 case OPC_RECIP2_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_recip2_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 = "recip2.d";
8192 break;
bf4120ad 8193 case OPC_RECIP1_D:
5e755519 8194 check_cp1_64bitmode(ctx);
b6d96bed 8195 {
a7812ae4 8196 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8197
8198 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8199 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8200 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8201 tcg_temp_free_i64(fp0);
b6d96bed 8202 }
57fa1fb3
TS
8203 opn = "recip1.d";
8204 break;
bf4120ad 8205 case OPC_RSQRT1_D:
5e755519 8206 check_cp1_64bitmode(ctx);
b6d96bed 8207 {
a7812ae4 8208 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8209
8210 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8211 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8212 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8213 tcg_temp_free_i64(fp0);
b6d96bed 8214 }
57fa1fb3
TS
8215 opn = "rsqrt1.d";
8216 break;
bf4120ad 8217 case OPC_RSQRT2_D:
5e755519 8218 check_cp1_64bitmode(ctx);
b6d96bed 8219 {
a7812ae4
PB
8220 TCGv_i64 fp0 = tcg_temp_new_i64();
8221 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8222
8223 gen_load_fpr64(ctx, fp0, fs);
8224 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8225 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8226 tcg_temp_free_i64(fp1);
b6d96bed 8227 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8228 tcg_temp_free_i64(fp0);
b6d96bed 8229 }
57fa1fb3
TS
8230 opn = "rsqrt2.d";
8231 break;
bf4120ad
NF
8232 case OPC_CMP_F_D:
8233 case OPC_CMP_UN_D:
8234 case OPC_CMP_EQ_D:
8235 case OPC_CMP_UEQ_D:
8236 case OPC_CMP_OLT_D:
8237 case OPC_CMP_ULT_D:
8238 case OPC_CMP_OLE_D:
8239 case OPC_CMP_ULE_D:
8240 case OPC_CMP_SF_D:
8241 case OPC_CMP_NGLE_D:
8242 case OPC_CMP_SEQ_D:
8243 case OPC_CMP_NGL_D:
8244 case OPC_CMP_LT_D:
8245 case OPC_CMP_NGE_D:
8246 case OPC_CMP_LE_D:
8247 case OPC_CMP_NGT_D:
8153667c
NF
8248 if (ctx->opcode & (1 << 6)) {
8249 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8250 opn = condnames_abs[func-48];
8251 } else {
8252 gen_cmp_d(ctx, func-48, ft, fs, cc);
8253 opn = condnames[func-48];
5a1e8ffb 8254 }
6ea83fed 8255 break;
bf4120ad 8256 case OPC_CVT_S_D:
5e755519 8257 check_cp1_registers(ctx, fs);
b6d96bed 8258 {
a7812ae4
PB
8259 TCGv_i32 fp32 = tcg_temp_new_i32();
8260 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8261
8262 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8263 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8264 tcg_temp_free_i64(fp64);
b6d96bed 8265 gen_store_fpr32(fp32, fd);
a7812ae4 8266 tcg_temp_free_i32(fp32);
b6d96bed 8267 }
5a5012ec
TS
8268 opn = "cvt.s.d";
8269 break;
bf4120ad 8270 case OPC_CVT_W_D:
5e755519 8271 check_cp1_registers(ctx, fs);
b6d96bed 8272 {
a7812ae4
PB
8273 TCGv_i32 fp32 = tcg_temp_new_i32();
8274 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8275
8276 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8277 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8278 tcg_temp_free_i64(fp64);
b6d96bed 8279 gen_store_fpr32(fp32, fd);
a7812ae4 8280 tcg_temp_free_i32(fp32);
b6d96bed 8281 }
5a5012ec
TS
8282 opn = "cvt.w.d";
8283 break;
bf4120ad 8284 case OPC_CVT_L_D:
5e755519 8285 check_cp1_64bitmode(ctx);
b6d96bed 8286 {
a7812ae4 8287 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8288
8289 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8290 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8291 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8292 tcg_temp_free_i64(fp0);
b6d96bed 8293 }
5a5012ec
TS
8294 opn = "cvt.l.d";
8295 break;
bf4120ad 8296 case OPC_CVT_S_W:
b6d96bed 8297 {
a7812ae4 8298 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8299
8300 gen_load_fpr32(fp0, fs);
895c2d04 8301 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8302 gen_store_fpr32(fp0, fd);
a7812ae4 8303 tcg_temp_free_i32(fp0);
b6d96bed 8304 }
5a5012ec 8305 opn = "cvt.s.w";
6ea83fed 8306 break;
bf4120ad 8307 case OPC_CVT_D_W:
5e755519 8308 check_cp1_registers(ctx, fd);
b6d96bed 8309 {
a7812ae4
PB
8310 TCGv_i32 fp32 = tcg_temp_new_i32();
8311 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8312
8313 gen_load_fpr32(fp32, fs);
895c2d04 8314 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8315 tcg_temp_free_i32(fp32);
b6d96bed 8316 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8317 tcg_temp_free_i64(fp64);
b6d96bed 8318 }
5a5012ec
TS
8319 opn = "cvt.d.w";
8320 break;
bf4120ad 8321 case OPC_CVT_S_L:
5e755519 8322 check_cp1_64bitmode(ctx);
b6d96bed 8323 {
a7812ae4
PB
8324 TCGv_i32 fp32 = tcg_temp_new_i32();
8325 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8326
8327 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8328 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8329 tcg_temp_free_i64(fp64);
b6d96bed 8330 gen_store_fpr32(fp32, fd);
a7812ae4 8331 tcg_temp_free_i32(fp32);
b6d96bed 8332 }
5a5012ec
TS
8333 opn = "cvt.s.l";
8334 break;
bf4120ad 8335 case OPC_CVT_D_L:
5e755519 8336 check_cp1_64bitmode(ctx);
b6d96bed 8337 {
a7812ae4 8338 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8339
8340 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8341 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8342 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8343 tcg_temp_free_i64(fp0);
b6d96bed 8344 }
5a5012ec
TS
8345 opn = "cvt.d.l";
8346 break;
bf4120ad 8347 case OPC_CVT_PS_PW:
5e755519 8348 check_cp1_64bitmode(ctx);
b6d96bed 8349 {
a7812ae4 8350 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8351
8352 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8353 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8354 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8355 tcg_temp_free_i64(fp0);
b6d96bed 8356 }
5a5012ec
TS
8357 opn = "cvt.ps.pw";
8358 break;
bf4120ad 8359 case OPC_ADD_PS:
5e755519 8360 check_cp1_64bitmode(ctx);
b6d96bed 8361 {
a7812ae4
PB
8362 TCGv_i64 fp0 = tcg_temp_new_i64();
8363 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8364
8365 gen_load_fpr64(ctx, fp0, fs);
8366 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8367 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8368 tcg_temp_free_i64(fp1);
b6d96bed 8369 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8370 tcg_temp_free_i64(fp0);
b6d96bed 8371 }
5a5012ec 8372 opn = "add.ps";
6ea83fed 8373 break;
bf4120ad 8374 case OPC_SUB_PS:
5e755519 8375 check_cp1_64bitmode(ctx);
b6d96bed 8376 {
a7812ae4
PB
8377 TCGv_i64 fp0 = tcg_temp_new_i64();
8378 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8379
8380 gen_load_fpr64(ctx, fp0, fs);
8381 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8382 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8383 tcg_temp_free_i64(fp1);
b6d96bed 8384 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8385 tcg_temp_free_i64(fp0);
b6d96bed 8386 }
5a5012ec 8387 opn = "sub.ps";
6ea83fed 8388 break;
bf4120ad 8389 case OPC_MUL_PS:
5e755519 8390 check_cp1_64bitmode(ctx);
b6d96bed 8391 {
a7812ae4
PB
8392 TCGv_i64 fp0 = tcg_temp_new_i64();
8393 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8394
8395 gen_load_fpr64(ctx, fp0, fs);
8396 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8397 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8398 tcg_temp_free_i64(fp1);
b6d96bed 8399 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8400 tcg_temp_free_i64(fp0);
b6d96bed 8401 }
5a5012ec 8402 opn = "mul.ps";
6ea83fed 8403 break;
bf4120ad 8404 case OPC_ABS_PS:
5e755519 8405 check_cp1_64bitmode(ctx);
b6d96bed 8406 {
a7812ae4 8407 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8408
8409 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8410 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8411 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8412 tcg_temp_free_i64(fp0);
b6d96bed 8413 }
5a5012ec 8414 opn = "abs.ps";
6ea83fed 8415 break;
bf4120ad 8416 case OPC_MOV_PS:
5e755519 8417 check_cp1_64bitmode(ctx);
b6d96bed 8418 {
a7812ae4 8419 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8420
8421 gen_load_fpr64(ctx, fp0, fs);
8422 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8423 tcg_temp_free_i64(fp0);
b6d96bed 8424 }
5a5012ec 8425 opn = "mov.ps";
6ea83fed 8426 break;
bf4120ad 8427 case OPC_NEG_PS:
5e755519 8428 check_cp1_64bitmode(ctx);
b6d96bed 8429 {
a7812ae4 8430 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8431
8432 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8433 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8434 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8435 tcg_temp_free_i64(fp0);
b6d96bed 8436 }
5a5012ec 8437 opn = "neg.ps";
6ea83fed 8438 break;
bf4120ad 8439 case OPC_MOVCF_PS:
5e755519 8440 check_cp1_64bitmode(ctx);
7f6613ce 8441 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8442 opn = "movcf.ps";
6ea83fed 8443 break;
bf4120ad 8444 case OPC_MOVZ_PS:
5e755519 8445 check_cp1_64bitmode(ctx);
a16336e4
TS
8446 {
8447 int l1 = gen_new_label();
30a3848b 8448 TCGv_i64 fp0;
a16336e4 8449
c9297f4d
AJ
8450 if (ft != 0)
8451 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8452 fp0 = tcg_temp_new_i64();
8453 gen_load_fpr64(ctx, fp0, fs);
8454 gen_store_fpr64(ctx, fp0, fd);
8455 tcg_temp_free_i64(fp0);
a16336e4
TS
8456 gen_set_label(l1);
8457 }
5a5012ec 8458 opn = "movz.ps";
6ea83fed 8459 break;
bf4120ad 8460 case OPC_MOVN_PS:
5e755519 8461 check_cp1_64bitmode(ctx);
a16336e4
TS
8462 {
8463 int l1 = gen_new_label();
30a3848b 8464 TCGv_i64 fp0;
c9297f4d
AJ
8465
8466 if (ft != 0) {
8467 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8468 fp0 = tcg_temp_new_i64();
8469 gen_load_fpr64(ctx, fp0, fs);
8470 gen_store_fpr64(ctx, fp0, fd);
8471 tcg_temp_free_i64(fp0);
8472 gen_set_label(l1);
8473 }
a16336e4 8474 }
5a5012ec 8475 opn = "movn.ps";
6ea83fed 8476 break;
bf4120ad 8477 case OPC_ADDR_PS:
5e755519 8478 check_cp1_64bitmode(ctx);
b6d96bed 8479 {
a7812ae4
PB
8480 TCGv_i64 fp0 = tcg_temp_new_i64();
8481 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8482
8483 gen_load_fpr64(ctx, fp0, ft);
8484 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8485 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8486 tcg_temp_free_i64(fp1);
b6d96bed 8487 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8488 tcg_temp_free_i64(fp0);
b6d96bed 8489 }
fbcc6828
TS
8490 opn = "addr.ps";
8491 break;
bf4120ad 8492 case OPC_MULR_PS:
5e755519 8493 check_cp1_64bitmode(ctx);
b6d96bed 8494 {
a7812ae4
PB
8495 TCGv_i64 fp0 = tcg_temp_new_i64();
8496 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8497
8498 gen_load_fpr64(ctx, fp0, ft);
8499 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8500 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8501 tcg_temp_free_i64(fp1);
b6d96bed 8502 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8503 tcg_temp_free_i64(fp0);
b6d96bed 8504 }
57fa1fb3
TS
8505 opn = "mulr.ps";
8506 break;
bf4120ad 8507 case OPC_RECIP2_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);
d22d7289 8514 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8515 gen_helper_float_recip2_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 = "recip2.ps";
8521 break;
bf4120ad 8522 case OPC_RECIP1_PS:
5e755519 8523 check_cp1_64bitmode(ctx);
b6d96bed 8524 {
a7812ae4 8525 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8526
8527 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8528 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8529 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8530 tcg_temp_free_i64(fp0);
b6d96bed 8531 }
57fa1fb3
TS
8532 opn = "recip1.ps";
8533 break;
bf4120ad 8534 case OPC_RSQRT1_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_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8541 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8542 tcg_temp_free_i64(fp0);
b6d96bed 8543 }
57fa1fb3
TS
8544 opn = "rsqrt1.ps";
8545 break;
bf4120ad 8546 case OPC_RSQRT2_PS:
5e755519 8547 check_cp1_64bitmode(ctx);
b6d96bed 8548 {
a7812ae4
PB
8549 TCGv_i64 fp0 = tcg_temp_new_i64();
8550 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8551
8552 gen_load_fpr64(ctx, fp0, fs);
8553 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8554 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8555 tcg_temp_free_i64(fp1);
b6d96bed 8556 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8557 tcg_temp_free_i64(fp0);
b6d96bed 8558 }
57fa1fb3
TS
8559 opn = "rsqrt2.ps";
8560 break;
bf4120ad 8561 case OPC_CVT_S_PU:
5e755519 8562 check_cp1_64bitmode(ctx);
b6d96bed 8563 {
a7812ae4 8564 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8565
7f6613ce 8566 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 8567 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8568 gen_store_fpr32(fp0, fd);
a7812ae4 8569 tcg_temp_free_i32(fp0);
b6d96bed 8570 }
5a5012ec 8571 opn = "cvt.s.pu";
dd016883 8572 break;
bf4120ad 8573 case OPC_CVT_PW_PS:
5e755519 8574 check_cp1_64bitmode(ctx);
b6d96bed 8575 {
a7812ae4 8576 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8577
8578 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8579 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8580 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8581 tcg_temp_free_i64(fp0);
b6d96bed 8582 }
5a5012ec 8583 opn = "cvt.pw.ps";
6ea83fed 8584 break;
bf4120ad 8585 case OPC_CVT_S_PL:
5e755519 8586 check_cp1_64bitmode(ctx);
b6d96bed 8587 {
a7812ae4 8588 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8589
8590 gen_load_fpr32(fp0, fs);
895c2d04 8591 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8592 gen_store_fpr32(fp0, fd);
a7812ae4 8593 tcg_temp_free_i32(fp0);
b6d96bed 8594 }
5a5012ec 8595 opn = "cvt.s.pl";
6ea83fed 8596 break;
bf4120ad 8597 case OPC_PLL_PS:
5e755519 8598 check_cp1_64bitmode(ctx);
b6d96bed 8599 {
a7812ae4
PB
8600 TCGv_i32 fp0 = tcg_temp_new_i32();
8601 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8602
8603 gen_load_fpr32(fp0, fs);
8604 gen_load_fpr32(fp1, ft);
7f6613ce 8605 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 8606 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8607 tcg_temp_free_i32(fp0);
8608 tcg_temp_free_i32(fp1);
b6d96bed 8609 }
5a5012ec 8610 opn = "pll.ps";
6ea83fed 8611 break;
bf4120ad 8612 case OPC_PLU_PS:
5e755519 8613 check_cp1_64bitmode(ctx);
b6d96bed 8614 {
a7812ae4
PB
8615 TCGv_i32 fp0 = tcg_temp_new_i32();
8616 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8617
8618 gen_load_fpr32(fp0, fs);
7f6613ce 8619 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8620 gen_store_fpr32(fp1, fd);
7f6613ce 8621 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8622 tcg_temp_free_i32(fp0);
8623 tcg_temp_free_i32(fp1);
b6d96bed 8624 }
5a5012ec
TS
8625 opn = "plu.ps";
8626 break;
bf4120ad 8627 case OPC_PUL_PS:
5e755519 8628 check_cp1_64bitmode(ctx);
b6d96bed 8629 {
a7812ae4
PB
8630 TCGv_i32 fp0 = tcg_temp_new_i32();
8631 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8632
7f6613ce 8633 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
8634 gen_load_fpr32(fp1, ft);
8635 gen_store_fpr32(fp1, fd);
7f6613ce 8636 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8637 tcg_temp_free_i32(fp0);
8638 tcg_temp_free_i32(fp1);
b6d96bed 8639 }
5a5012ec
TS
8640 opn = "pul.ps";
8641 break;
bf4120ad 8642 case OPC_PUU_PS:
5e755519 8643 check_cp1_64bitmode(ctx);
b6d96bed 8644 {
a7812ae4
PB
8645 TCGv_i32 fp0 = tcg_temp_new_i32();
8646 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8647
7f6613ce
PJ
8648 gen_load_fpr32h(ctx, fp0, fs);
8649 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8650 gen_store_fpr32(fp1, fd);
7f6613ce 8651 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8652 tcg_temp_free_i32(fp0);
8653 tcg_temp_free_i32(fp1);
b6d96bed 8654 }
5a5012ec
TS
8655 opn = "puu.ps";
8656 break;
bf4120ad
NF
8657 case OPC_CMP_F_PS:
8658 case OPC_CMP_UN_PS:
8659 case OPC_CMP_EQ_PS:
8660 case OPC_CMP_UEQ_PS:
8661 case OPC_CMP_OLT_PS:
8662 case OPC_CMP_ULT_PS:
8663 case OPC_CMP_OLE_PS:
8664 case OPC_CMP_ULE_PS:
8665 case OPC_CMP_SF_PS:
8666 case OPC_CMP_NGLE_PS:
8667 case OPC_CMP_SEQ_PS:
8668 case OPC_CMP_NGL_PS:
8669 case OPC_CMP_LT_PS:
8670 case OPC_CMP_NGE_PS:
8671 case OPC_CMP_LE_PS:
8672 case OPC_CMP_NGT_PS:
8153667c
NF
8673 if (ctx->opcode & (1 << 6)) {
8674 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8675 opn = condnames_abs[func-48];
8676 } else {
8677 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8678 opn = condnames[func-48];
5a1e8ffb 8679 }
6ea83fed 8680 break;
5a5012ec 8681 default:
923617a3 8682 MIPS_INVAL(opn);
e397ee33 8683 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8684 return;
8685 }
2abf314d 8686 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8687 switch (optype) {
8688 case BINOP:
6ea83fed 8689 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8690 break;
8691 case CMPOP:
8692 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8693 break;
8694 default:
6ea83fed 8695 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8696 break;
8697 }
6ea83fed 8698}
6af0bf9c 8699
5a5012ec 8700/* Coprocessor 3 (FPU) */
5e755519
TS
8701static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8702 int fd, int fs, int base, int index)
7a387fff 8703{
923617a3 8704 const char *opn = "extended float load/store";
93b12ccc 8705 int store = 0;
4e2474d6 8706 TCGv t0 = tcg_temp_new();
7a387fff 8707
93b12ccc 8708 if (base == 0) {
6c5c1e20 8709 gen_load_gpr(t0, index);
93b12ccc 8710 } else if (index == 0) {
6c5c1e20 8711 gen_load_gpr(t0, base);
93b12ccc 8712 } else {
05168674 8713 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8714 }
5a5012ec 8715 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8716 memory access. */
5a5012ec
TS
8717 switch (opc) {
8718 case OPC_LWXC1:
8c0ab41f 8719 check_cop1x(ctx);
b6d96bed 8720 {
a7812ae4 8721 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8722
5f68f5ae 8723 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 8724 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8725 gen_store_fpr32(fp0, fd);
a7812ae4 8726 tcg_temp_free_i32(fp0);
b6d96bed 8727 }
5a5012ec
TS
8728 opn = "lwxc1";
8729 break;
8730 case OPC_LDXC1:
8c0ab41f
AJ
8731 check_cop1x(ctx);
8732 check_cp1_registers(ctx, fd);
b6d96bed 8733 {
a7812ae4 8734 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 8735 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 8736 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8737 tcg_temp_free_i64(fp0);
b6d96bed 8738 }
5a5012ec
TS
8739 opn = "ldxc1";
8740 break;
8741 case OPC_LUXC1:
8c0ab41f 8742 check_cp1_64bitmode(ctx);
6c5c1e20 8743 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8744 {
a7812ae4 8745 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8746
5f68f5ae 8747 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 8748 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8749 tcg_temp_free_i64(fp0);
b6d96bed 8750 }
5a5012ec
TS
8751 opn = "luxc1";
8752 break;
8753 case OPC_SWXC1:
8c0ab41f 8754 check_cop1x(ctx);
b6d96bed 8755 {
a7812ae4 8756 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8757 gen_load_fpr32(fp0, fs);
5f68f5ae 8758 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 8759 tcg_temp_free_i32(fp0);
b6d96bed 8760 }
5a5012ec 8761 opn = "swxc1";
93b12ccc 8762 store = 1;
5a5012ec
TS
8763 break;
8764 case OPC_SDXC1:
8c0ab41f
AJ
8765 check_cop1x(ctx);
8766 check_cp1_registers(ctx, fs);
b6d96bed 8767 {
a7812ae4 8768 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8769 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 8770 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 8771 tcg_temp_free_i64(fp0);
b6d96bed 8772 }
5a5012ec 8773 opn = "sdxc1";
93b12ccc 8774 store = 1;
5a5012ec
TS
8775 break;
8776 case OPC_SUXC1:
8c0ab41f 8777 check_cp1_64bitmode(ctx);
6c5c1e20 8778 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8779 {
a7812ae4 8780 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8781 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 8782 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 8783 tcg_temp_free_i64(fp0);
b6d96bed 8784 }
5a5012ec 8785 opn = "suxc1";
93b12ccc 8786 store = 1;
5a5012ec 8787 break;
5a5012ec 8788 }
6c5c1e20 8789 tcg_temp_free(t0);
2abf314d 8790 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8791 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8792 regnames[index], regnames[base]);
5a5012ec
TS
8793}
8794
5e755519
TS
8795static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8796 int fd, int fr, int fs, int ft)
5a5012ec 8797{
923617a3 8798 const char *opn = "flt3_arith";
5a5012ec 8799
5a5012ec
TS
8800 switch (opc) {
8801 case OPC_ALNV_PS:
b8aa4598 8802 check_cp1_64bitmode(ctx);
a16336e4 8803 {
a7812ae4 8804 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8805 TCGv_i32 fp = tcg_temp_new_i32();
8806 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8807 int l1 = gen_new_label();
8808 int l2 = gen_new_label();
8809
6c5c1e20
TS
8810 gen_load_gpr(t0, fr);
8811 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8812
8813 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 8814 gen_load_fpr32(fp, fs);
7f6613ce 8815 gen_load_fpr32h(ctx, fph, fs);
c905fdac 8816 gen_store_fpr32(fp, fd);
7f6613ce 8817 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
8818 tcg_gen_br(l2);
8819 gen_set_label(l1);
6c5c1e20
TS
8820 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8821 tcg_temp_free(t0);
a16336e4 8822#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 8823 gen_load_fpr32(fp, fs);
7f6613ce
PJ
8824 gen_load_fpr32h(ctx, fph, ft);
8825 gen_store_fpr32h(ctx, fp, fd);
c905fdac 8826 gen_store_fpr32(fph, fd);
a16336e4 8827#else
7f6613ce 8828 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
8829 gen_load_fpr32(fp, ft);
8830 gen_store_fpr32(fph, fd);
7f6613ce 8831 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
8832#endif
8833 gen_set_label(l2);
c905fdac
AJ
8834 tcg_temp_free_i32(fp);
8835 tcg_temp_free_i32(fph);
a16336e4 8836 }
5a5012ec
TS
8837 opn = "alnv.ps";
8838 break;
8839 case OPC_MADD_S:
b8aa4598 8840 check_cop1x(ctx);
b6d96bed 8841 {
a7812ae4
PB
8842 TCGv_i32 fp0 = tcg_temp_new_i32();
8843 TCGv_i32 fp1 = tcg_temp_new_i32();
8844 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8845
8846 gen_load_fpr32(fp0, fs);
8847 gen_load_fpr32(fp1, ft);
8848 gen_load_fpr32(fp2, fr);
b3d6cd44 8849 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8850 tcg_temp_free_i32(fp0);
8851 tcg_temp_free_i32(fp1);
b6d96bed 8852 gen_store_fpr32(fp2, fd);
a7812ae4 8853 tcg_temp_free_i32(fp2);
b6d96bed 8854 }
5a5012ec
TS
8855 opn = "madd.s";
8856 break;
8857 case OPC_MADD_D:
b8aa4598
TS
8858 check_cop1x(ctx);
8859 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8860 {
a7812ae4
PB
8861 TCGv_i64 fp0 = tcg_temp_new_i64();
8862 TCGv_i64 fp1 = tcg_temp_new_i64();
8863 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8864
8865 gen_load_fpr64(ctx, fp0, fs);
8866 gen_load_fpr64(ctx, fp1, ft);
8867 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8868 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8869 tcg_temp_free_i64(fp0);
8870 tcg_temp_free_i64(fp1);
b6d96bed 8871 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8872 tcg_temp_free_i64(fp2);
b6d96bed 8873 }
5a5012ec
TS
8874 opn = "madd.d";
8875 break;
8876 case OPC_MADD_PS:
b8aa4598 8877 check_cp1_64bitmode(ctx);
b6d96bed 8878 {
a7812ae4
PB
8879 TCGv_i64 fp0 = tcg_temp_new_i64();
8880 TCGv_i64 fp1 = tcg_temp_new_i64();
8881 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8882
8883 gen_load_fpr64(ctx, fp0, fs);
8884 gen_load_fpr64(ctx, fp1, ft);
8885 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8886 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8887 tcg_temp_free_i64(fp0);
8888 tcg_temp_free_i64(fp1);
b6d96bed 8889 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8890 tcg_temp_free_i64(fp2);
b6d96bed 8891 }
5a5012ec
TS
8892 opn = "madd.ps";
8893 break;
8894 case OPC_MSUB_S:
b8aa4598 8895 check_cop1x(ctx);
b6d96bed 8896 {
a7812ae4
PB
8897 TCGv_i32 fp0 = tcg_temp_new_i32();
8898 TCGv_i32 fp1 = tcg_temp_new_i32();
8899 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8900
8901 gen_load_fpr32(fp0, fs);
8902 gen_load_fpr32(fp1, ft);
8903 gen_load_fpr32(fp2, fr);
b3d6cd44 8904 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8905 tcg_temp_free_i32(fp0);
8906 tcg_temp_free_i32(fp1);
b6d96bed 8907 gen_store_fpr32(fp2, fd);
a7812ae4 8908 tcg_temp_free_i32(fp2);
b6d96bed 8909 }
5a5012ec
TS
8910 opn = "msub.s";
8911 break;
8912 case OPC_MSUB_D:
b8aa4598
TS
8913 check_cop1x(ctx);
8914 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8915 {
a7812ae4
PB
8916 TCGv_i64 fp0 = tcg_temp_new_i64();
8917 TCGv_i64 fp1 = tcg_temp_new_i64();
8918 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8919
8920 gen_load_fpr64(ctx, fp0, fs);
8921 gen_load_fpr64(ctx, fp1, ft);
8922 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8923 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8924 tcg_temp_free_i64(fp0);
8925 tcg_temp_free_i64(fp1);
b6d96bed 8926 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8927 tcg_temp_free_i64(fp2);
b6d96bed 8928 }
5a5012ec
TS
8929 opn = "msub.d";
8930 break;
8931 case OPC_MSUB_PS:
b8aa4598 8932 check_cp1_64bitmode(ctx);
b6d96bed 8933 {
a7812ae4
PB
8934 TCGv_i64 fp0 = tcg_temp_new_i64();
8935 TCGv_i64 fp1 = tcg_temp_new_i64();
8936 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8937
8938 gen_load_fpr64(ctx, fp0, fs);
8939 gen_load_fpr64(ctx, fp1, ft);
8940 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8941 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8942 tcg_temp_free_i64(fp0);
8943 tcg_temp_free_i64(fp1);
b6d96bed 8944 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8945 tcg_temp_free_i64(fp2);
b6d96bed 8946 }
5a5012ec
TS
8947 opn = "msub.ps";
8948 break;
8949 case OPC_NMADD_S:
b8aa4598 8950 check_cop1x(ctx);
b6d96bed 8951 {
a7812ae4
PB
8952 TCGv_i32 fp0 = tcg_temp_new_i32();
8953 TCGv_i32 fp1 = tcg_temp_new_i32();
8954 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8955
8956 gen_load_fpr32(fp0, fs);
8957 gen_load_fpr32(fp1, ft);
8958 gen_load_fpr32(fp2, fr);
b3d6cd44 8959 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8960 tcg_temp_free_i32(fp0);
8961 tcg_temp_free_i32(fp1);
b6d96bed 8962 gen_store_fpr32(fp2, fd);
a7812ae4 8963 tcg_temp_free_i32(fp2);
b6d96bed 8964 }
5a5012ec
TS
8965 opn = "nmadd.s";
8966 break;
8967 case OPC_NMADD_D:
b8aa4598
TS
8968 check_cop1x(ctx);
8969 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8970 {
a7812ae4
PB
8971 TCGv_i64 fp0 = tcg_temp_new_i64();
8972 TCGv_i64 fp1 = tcg_temp_new_i64();
8973 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8974
8975 gen_load_fpr64(ctx, fp0, fs);
8976 gen_load_fpr64(ctx, fp1, ft);
8977 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8978 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8979 tcg_temp_free_i64(fp0);
8980 tcg_temp_free_i64(fp1);
b6d96bed 8981 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8982 tcg_temp_free_i64(fp2);
b6d96bed 8983 }
5a5012ec
TS
8984 opn = "nmadd.d";
8985 break;
8986 case OPC_NMADD_PS:
b8aa4598 8987 check_cp1_64bitmode(ctx);
b6d96bed 8988 {
a7812ae4
PB
8989 TCGv_i64 fp0 = tcg_temp_new_i64();
8990 TCGv_i64 fp1 = tcg_temp_new_i64();
8991 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8992
8993 gen_load_fpr64(ctx, fp0, fs);
8994 gen_load_fpr64(ctx, fp1, ft);
8995 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8996 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8997 tcg_temp_free_i64(fp0);
8998 tcg_temp_free_i64(fp1);
b6d96bed 8999 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9000 tcg_temp_free_i64(fp2);
b6d96bed 9001 }
5a5012ec
TS
9002 opn = "nmadd.ps";
9003 break;
9004 case OPC_NMSUB_S:
b8aa4598 9005 check_cop1x(ctx);
b6d96bed 9006 {
a7812ae4
PB
9007 TCGv_i32 fp0 = tcg_temp_new_i32();
9008 TCGv_i32 fp1 = tcg_temp_new_i32();
9009 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9010
9011 gen_load_fpr32(fp0, fs);
9012 gen_load_fpr32(fp1, ft);
9013 gen_load_fpr32(fp2, fr);
b3d6cd44 9014 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9015 tcg_temp_free_i32(fp0);
9016 tcg_temp_free_i32(fp1);
b6d96bed 9017 gen_store_fpr32(fp2, fd);
a7812ae4 9018 tcg_temp_free_i32(fp2);
b6d96bed 9019 }
5a5012ec
TS
9020 opn = "nmsub.s";
9021 break;
9022 case OPC_NMSUB_D:
b8aa4598
TS
9023 check_cop1x(ctx);
9024 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9025 {
a7812ae4
PB
9026 TCGv_i64 fp0 = tcg_temp_new_i64();
9027 TCGv_i64 fp1 = tcg_temp_new_i64();
9028 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9029
9030 gen_load_fpr64(ctx, fp0, fs);
9031 gen_load_fpr64(ctx, fp1, ft);
9032 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9033 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9034 tcg_temp_free_i64(fp0);
9035 tcg_temp_free_i64(fp1);
b6d96bed 9036 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9037 tcg_temp_free_i64(fp2);
b6d96bed 9038 }
5a5012ec
TS
9039 opn = "nmsub.d";
9040 break;
9041 case OPC_NMSUB_PS:
b8aa4598 9042 check_cp1_64bitmode(ctx);
b6d96bed 9043 {
a7812ae4
PB
9044 TCGv_i64 fp0 = tcg_temp_new_i64();
9045 TCGv_i64 fp1 = tcg_temp_new_i64();
9046 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9047
9048 gen_load_fpr64(ctx, fp0, fs);
9049 gen_load_fpr64(ctx, fp1, ft);
9050 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9051 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9052 tcg_temp_free_i64(fp0);
9053 tcg_temp_free_i64(fp1);
b6d96bed 9054 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9055 tcg_temp_free_i64(fp2);
b6d96bed 9056 }
5a5012ec
TS
9057 opn = "nmsub.ps";
9058 break;
923617a3
TS
9059 default:
9060 MIPS_INVAL(opn);
5a5012ec
TS
9061 generate_exception (ctx, EXCP_RI);
9062 return;
9063 }
2abf314d 9064 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9065 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9066 fregnames[fs], fregnames[ft]);
7a387fff
TS
9067}
9068
d75c135e 9069static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9070{
9071 TCGv t0;
9072
b3167288
RH
9073#if !defined(CONFIG_USER_ONLY)
9074 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9075 Therefore only check the ISA in system mode. */
d75c135e 9076 check_insn(ctx, ISA_MIPS32R2);
b3167288 9077#endif
26ebe468
NF
9078 t0 = tcg_temp_new();
9079
9080 switch (rd) {
9081 case 0:
9082 save_cpu_state(ctx, 1);
895c2d04 9083 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9084 gen_store_gpr(t0, rt);
9085 break;
9086 case 1:
9087 save_cpu_state(ctx, 1);
895c2d04 9088 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9089 gen_store_gpr(t0, rt);
9090 break;
9091 case 2:
9092 save_cpu_state(ctx, 1);
895c2d04 9093 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9094 gen_store_gpr(t0, rt);
9095 break;
9096 case 3:
9097 save_cpu_state(ctx, 1);
895c2d04 9098 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9099 gen_store_gpr(t0, rt);
9100 break;
9101 case 29:
9102#if defined(CONFIG_USER_ONLY)
d279279e
PJ
9103 tcg_gen_ld_tl(t0, cpu_env,
9104 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
9105 gen_store_gpr(t0, rt);
9106 break;
9107#else
d279279e
PJ
9108 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
9109 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
9110 tcg_gen_ld_tl(t0, cpu_env,
9111 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9112 gen_store_gpr(t0, rt);
9113 } else {
9114 generate_exception(ctx, EXCP_RI);
9115 }
9116 break;
26ebe468
NF
9117#endif
9118 default: /* Invalid */
9119 MIPS_INVAL("rdhwr");
9120 generate_exception(ctx, EXCP_RI);
9121 break;
9122 }
9123 tcg_temp_free(t0);
9124}
9125
d75c135e 9126static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9127{
9128 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9129 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9130 /* Branches completion */
9131 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9132 ctx->bstate = BS_BRANCH;
9133 save_cpu_state(ctx, 0);
9134 /* FIXME: Need to clear can_do_io. */
364d4831 9135 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9136 case MIPS_HFLAG_B:
9137 /* unconditional branch */
9138 MIPS_DEBUG("unconditional branch");
364d4831
NF
9139 if (proc_hflags & MIPS_HFLAG_BX) {
9140 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9141 }
c9602061
NF
9142 gen_goto_tb(ctx, 0, ctx->btarget);
9143 break;
9144 case MIPS_HFLAG_BL:
9145 /* blikely taken case */
9146 MIPS_DEBUG("blikely branch taken");
9147 gen_goto_tb(ctx, 0, ctx->btarget);
9148 break;
9149 case MIPS_HFLAG_BC:
9150 /* Conditional branch */
9151 MIPS_DEBUG("conditional branch");
9152 {
9153 int l1 = gen_new_label();
9154
9155 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9156 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9157 gen_set_label(l1);
9158 gen_goto_tb(ctx, 0, ctx->btarget);
9159 }
9160 break;
9161 case MIPS_HFLAG_BR:
9162 /* unconditional branch to register */
9163 MIPS_DEBUG("branch to register");
d75c135e 9164 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9165 TCGv t0 = tcg_temp_new();
9166 TCGv_i32 t1 = tcg_temp_new_i32();
9167
9168 tcg_gen_andi_tl(t0, btarget, 0x1);
9169 tcg_gen_trunc_tl_i32(t1, t0);
9170 tcg_temp_free(t0);
9171 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9172 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9173 tcg_gen_or_i32(hflags, hflags, t1);
9174 tcg_temp_free_i32(t1);
9175
9176 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9177 } else {
9178 tcg_gen_mov_tl(cpu_PC, btarget);
9179 }
c9602061
NF
9180 if (ctx->singlestep_enabled) {
9181 save_cpu_state(ctx, 0);
895c2d04 9182 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9183 }
9184 tcg_gen_exit_tb(0);
9185 break;
9186 default:
9187 MIPS_DEBUG("unknown branch");
9188 break;
9189 }
9190 }
9191}
9192
7a387fff 9193/* ISA extensions (ASEs) */
6af0bf9c 9194/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9195
9196/* MIPS16 major opcodes */
9197enum {
9198 M16_OPC_ADDIUSP = 0x00,
9199 M16_OPC_ADDIUPC = 0x01,
9200 M16_OPC_B = 0x02,
9201 M16_OPC_JAL = 0x03,
9202 M16_OPC_BEQZ = 0x04,
9203 M16_OPC_BNEQZ = 0x05,
9204 M16_OPC_SHIFT = 0x06,
9205 M16_OPC_LD = 0x07,
9206 M16_OPC_RRIA = 0x08,
9207 M16_OPC_ADDIU8 = 0x09,
9208 M16_OPC_SLTI = 0x0a,
9209 M16_OPC_SLTIU = 0x0b,
9210 M16_OPC_I8 = 0x0c,
9211 M16_OPC_LI = 0x0d,
9212 M16_OPC_CMPI = 0x0e,
9213 M16_OPC_SD = 0x0f,
9214 M16_OPC_LB = 0x10,
9215 M16_OPC_LH = 0x11,
9216 M16_OPC_LWSP = 0x12,
9217 M16_OPC_LW = 0x13,
9218 M16_OPC_LBU = 0x14,
9219 M16_OPC_LHU = 0x15,
9220 M16_OPC_LWPC = 0x16,
9221 M16_OPC_LWU = 0x17,
9222 M16_OPC_SB = 0x18,
9223 M16_OPC_SH = 0x19,
9224 M16_OPC_SWSP = 0x1a,
9225 M16_OPC_SW = 0x1b,
9226 M16_OPC_RRR = 0x1c,
9227 M16_OPC_RR = 0x1d,
9228 M16_OPC_EXTEND = 0x1e,
9229 M16_OPC_I64 = 0x1f
9230};
9231
9232/* I8 funct field */
9233enum {
9234 I8_BTEQZ = 0x0,
9235 I8_BTNEZ = 0x1,
9236 I8_SWRASP = 0x2,
9237 I8_ADJSP = 0x3,
9238 I8_SVRS = 0x4,
9239 I8_MOV32R = 0x5,
9240 I8_MOVR32 = 0x7
9241};
9242
9243/* RRR f field */
9244enum {
9245 RRR_DADDU = 0x0,
9246 RRR_ADDU = 0x1,
9247 RRR_DSUBU = 0x2,
9248 RRR_SUBU = 0x3
9249};
9250
9251/* RR funct field */
9252enum {
9253 RR_JR = 0x00,
9254 RR_SDBBP = 0x01,
9255 RR_SLT = 0x02,
9256 RR_SLTU = 0x03,
9257 RR_SLLV = 0x04,
9258 RR_BREAK = 0x05,
9259 RR_SRLV = 0x06,
9260 RR_SRAV = 0x07,
9261 RR_DSRL = 0x08,
9262 RR_CMP = 0x0a,
9263 RR_NEG = 0x0b,
9264 RR_AND = 0x0c,
9265 RR_OR = 0x0d,
9266 RR_XOR = 0x0e,
9267 RR_NOT = 0x0f,
9268 RR_MFHI = 0x10,
9269 RR_CNVT = 0x11,
9270 RR_MFLO = 0x12,
9271 RR_DSRA = 0x13,
9272 RR_DSLLV = 0x14,
9273 RR_DSRLV = 0x16,
9274 RR_DSRAV = 0x17,
9275 RR_MULT = 0x18,
9276 RR_MULTU = 0x19,
9277 RR_DIV = 0x1a,
9278 RR_DIVU = 0x1b,
9279 RR_DMULT = 0x1c,
9280 RR_DMULTU = 0x1d,
9281 RR_DDIV = 0x1e,
9282 RR_DDIVU = 0x1f
9283};
9284
9285/* I64 funct field */
9286enum {
9287 I64_LDSP = 0x0,
9288 I64_SDSP = 0x1,
9289 I64_SDRASP = 0x2,
9290 I64_DADJSP = 0x3,
9291 I64_LDPC = 0x4,
364d4831 9292 I64_DADDIU5 = 0x5,
6ea219d0
NF
9293 I64_DADDIUPC = 0x6,
9294 I64_DADDIUSP = 0x7
9295};
9296
9297/* RR ry field for CNVT */
9298enum {
9299 RR_RY_CNVT_ZEB = 0x0,
9300 RR_RY_CNVT_ZEH = 0x1,
9301 RR_RY_CNVT_ZEW = 0x2,
9302 RR_RY_CNVT_SEB = 0x4,
9303 RR_RY_CNVT_SEH = 0x5,
9304 RR_RY_CNVT_SEW = 0x6,
9305};
9306
364d4831
NF
9307static int xlat (int r)
9308{
9309 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9310
9311 return map[r];
9312}
9313
9314static void gen_mips16_save (DisasContext *ctx,
9315 int xsregs, int aregs,
9316 int do_ra, int do_s0, int do_s1,
9317 int framesize)
9318{
9319 TCGv t0 = tcg_temp_new();
9320 TCGv t1 = tcg_temp_new();
9321 int args, astatic;
9322
9323 switch (aregs) {
9324 case 0:
9325 case 1:
9326 case 2:
9327 case 3:
9328 case 11:
9329 args = 0;
9330 break;
9331 case 4:
9332 case 5:
9333 case 6:
9334 case 7:
9335 args = 1;
9336 break;
9337 case 8:
9338 case 9:
9339 case 10:
9340 args = 2;
9341 break;
9342 case 12:
9343 case 13:
9344 args = 3;
9345 break;
9346 case 14:
9347 args = 4;
9348 break;
9349 default:
9350 generate_exception(ctx, EXCP_RI);
9351 return;
9352 }
9353
9354 switch (args) {
9355 case 4:
9356 gen_base_offset_addr(ctx, t0, 29, 12);
9357 gen_load_gpr(t1, 7);
5f68f5ae 9358 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9359 /* Fall through */
9360 case 3:
9361 gen_base_offset_addr(ctx, t0, 29, 8);
9362 gen_load_gpr(t1, 6);
5f68f5ae 9363 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9364 /* Fall through */
9365 case 2:
9366 gen_base_offset_addr(ctx, t0, 29, 4);
9367 gen_load_gpr(t1, 5);
5f68f5ae 9368 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9369 /* Fall through */
9370 case 1:
9371 gen_base_offset_addr(ctx, t0, 29, 0);
9372 gen_load_gpr(t1, 4);
5f68f5ae 9373 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9374 }
9375
9376 gen_load_gpr(t0, 29);
9377
5f68f5ae
AJ
9378#define DECR_AND_STORE(reg) do { \
9379 tcg_gen_subi_tl(t0, t0, 4); \
9380 gen_load_gpr(t1, reg); \
9381 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
9382 } while (0)
9383
9384 if (do_ra) {
9385 DECR_AND_STORE(31);
9386 }
9387
9388 switch (xsregs) {
9389 case 7:
9390 DECR_AND_STORE(30);
9391 /* Fall through */
9392 case 6:
9393 DECR_AND_STORE(23);
9394 /* Fall through */
9395 case 5:
9396 DECR_AND_STORE(22);
9397 /* Fall through */
9398 case 4:
9399 DECR_AND_STORE(21);
9400 /* Fall through */
9401 case 3:
9402 DECR_AND_STORE(20);
9403 /* Fall through */
9404 case 2:
9405 DECR_AND_STORE(19);
9406 /* Fall through */
9407 case 1:
9408 DECR_AND_STORE(18);
9409 }
9410
9411 if (do_s1) {
9412 DECR_AND_STORE(17);
9413 }
9414 if (do_s0) {
9415 DECR_AND_STORE(16);
9416 }
9417
9418 switch (aregs) {
9419 case 0:
9420 case 4:
9421 case 8:
9422 case 12:
9423 case 14:
9424 astatic = 0;
9425 break;
9426 case 1:
9427 case 5:
9428 case 9:
9429 case 13:
9430 astatic = 1;
9431 break;
9432 case 2:
9433 case 6:
9434 case 10:
9435 astatic = 2;
9436 break;
9437 case 3:
9438 case 7:
9439 astatic = 3;
9440 break;
9441 case 11:
9442 astatic = 4;
9443 break;
9444 default:
9445 generate_exception(ctx, EXCP_RI);
9446 return;
9447 }
9448
9449 if (astatic > 0) {
9450 DECR_AND_STORE(7);
9451 if (astatic > 1) {
9452 DECR_AND_STORE(6);
9453 if (astatic > 2) {
9454 DECR_AND_STORE(5);
9455 if (astatic > 3) {
9456 DECR_AND_STORE(4);
9457 }
9458 }
9459 }
9460 }
9461#undef DECR_AND_STORE
9462
9463 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9464 tcg_temp_free(t0);
9465 tcg_temp_free(t1);
9466}
9467
9468static void gen_mips16_restore (DisasContext *ctx,
9469 int xsregs, int aregs,
9470 int do_ra, int do_s0, int do_s1,
9471 int framesize)
9472{
9473 int astatic;
9474 TCGv t0 = tcg_temp_new();
9475 TCGv t1 = tcg_temp_new();
9476
9477 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9478
5f68f5ae
AJ
9479#define DECR_AND_LOAD(reg) do { \
9480 tcg_gen_subi_tl(t0, t0, 4); \
9481 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9482 gen_store_gpr(t1, reg); \
364d4831
NF
9483 } while (0)
9484
9485 if (do_ra) {
9486 DECR_AND_LOAD(31);
9487 }
9488
9489 switch (xsregs) {
9490 case 7:
9491 DECR_AND_LOAD(30);
9492 /* Fall through */
9493 case 6:
9494 DECR_AND_LOAD(23);
9495 /* Fall through */
9496 case 5:
9497 DECR_AND_LOAD(22);
9498 /* Fall through */
9499 case 4:
9500 DECR_AND_LOAD(21);
9501 /* Fall through */
9502 case 3:
9503 DECR_AND_LOAD(20);
9504 /* Fall through */
9505 case 2:
9506 DECR_AND_LOAD(19);
9507 /* Fall through */
9508 case 1:
9509 DECR_AND_LOAD(18);
9510 }
9511
9512 if (do_s1) {
9513 DECR_AND_LOAD(17);
9514 }
9515 if (do_s0) {
9516 DECR_AND_LOAD(16);
9517 }
9518
9519 switch (aregs) {
9520 case 0:
9521 case 4:
9522 case 8:
9523 case 12:
9524 case 14:
9525 astatic = 0;
9526 break;
9527 case 1:
9528 case 5:
9529 case 9:
9530 case 13:
9531 astatic = 1;
9532 break;
9533 case 2:
9534 case 6:
9535 case 10:
9536 astatic = 2;
9537 break;
9538 case 3:
9539 case 7:
9540 astatic = 3;
9541 break;
9542 case 11:
9543 astatic = 4;
9544 break;
9545 default:
9546 generate_exception(ctx, EXCP_RI);
9547 return;
9548 }
9549
9550 if (astatic > 0) {
9551 DECR_AND_LOAD(7);
9552 if (astatic > 1) {
9553 DECR_AND_LOAD(6);
9554 if (astatic > 2) {
9555 DECR_AND_LOAD(5);
9556 if (astatic > 3) {
9557 DECR_AND_LOAD(4);
9558 }
9559 }
9560 }
9561 }
9562#undef DECR_AND_LOAD
9563
9564 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9565 tcg_temp_free(t0);
9566 tcg_temp_free(t1);
9567}
9568
9569static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9570 int is_64_bit, int extended)
9571{
9572 TCGv t0;
9573
9574 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9575 generate_exception(ctx, EXCP_RI);
9576 return;
9577 }
9578
9579 t0 = tcg_temp_new();
9580
9581 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9582 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9583 if (!is_64_bit) {
9584 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9585 }
9586
9587 tcg_temp_free(t0);
9588}
9589
9590#if defined(TARGET_MIPS64)
d75c135e 9591static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9592 int ry, int funct, int16_t offset,
9593 int extended)
9594{
9595 switch (funct) {
9596 case I64_LDSP:
9597 check_mips_64(ctx);
9598 offset = extended ? offset : offset << 3;
d75c135e 9599 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9600 break;
9601 case I64_SDSP:
9602 check_mips_64(ctx);
9603 offset = extended ? offset : offset << 3;
5c13fdfd 9604 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9605 break;
9606 case I64_SDRASP:
9607 check_mips_64(ctx);
9608 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9609 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9610 break;
9611 case I64_DADJSP:
9612 check_mips_64(ctx);
9613 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9614 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9615 break;
9616 case I64_LDPC:
9617 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9618 generate_exception(ctx, EXCP_RI);
9619 } else {
9620 offset = extended ? offset : offset << 3;
d75c135e 9621 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9622 }
9623 break;
9624 case I64_DADDIU5:
9625 check_mips_64(ctx);
9626 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9627 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9628 break;
9629 case I64_DADDIUPC:
9630 check_mips_64(ctx);
9631 offset = extended ? offset : offset << 2;
9632 gen_addiupc(ctx, ry, offset, 1, extended);
9633 break;
9634 case I64_DADDIUSP:
9635 check_mips_64(ctx);
9636 offset = extended ? offset : offset << 2;
d75c135e 9637 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9638 break;
9639 }
9640}
9641#endif
9642
240ce26a 9643static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 9644{
895c2d04 9645 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9646 int op, rx, ry, funct, sa;
9647 int16_t imm, offset;
9648
9649 ctx->opcode = (ctx->opcode << 16) | extend;
9650 op = (ctx->opcode >> 11) & 0x1f;
9651 sa = (ctx->opcode >> 22) & 0x1f;
9652 funct = (ctx->opcode >> 8) & 0x7;
9653 rx = xlat((ctx->opcode >> 8) & 0x7);
9654 ry = xlat((ctx->opcode >> 5) & 0x7);
9655 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9656 | ((ctx->opcode >> 21) & 0x3f) << 5
9657 | (ctx->opcode & 0x1f));
9658
9659 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9660 counterparts. */
9661 switch (op) {
9662 case M16_OPC_ADDIUSP:
d75c135e 9663 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9664 break;
9665 case M16_OPC_ADDIUPC:
9666 gen_addiupc(ctx, rx, imm, 0, 1);
9667 break;
9668 case M16_OPC_B:
9669 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9670 /* No delay slot, so just process as a normal instruction */
9671 break;
9672 case M16_OPC_BEQZ:
9673 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9674 /* No delay slot, so just process as a normal instruction */
9675 break;
9676 case M16_OPC_BNEQZ:
9677 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9678 /* No delay slot, so just process as a normal instruction */
9679 break;
9680 case M16_OPC_SHIFT:
9681 switch (ctx->opcode & 0x3) {
9682 case 0x0:
d75c135e 9683 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9684 break;
9685 case 0x1:
9686#if defined(TARGET_MIPS64)
9687 check_mips_64(ctx);
d75c135e 9688 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9689#else
9690 generate_exception(ctx, EXCP_RI);
9691#endif
9692 break;
9693 case 0x2:
d75c135e 9694 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9695 break;
9696 case 0x3:
d75c135e 9697 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9698 break;
9699 }
9700 break;
9701#if defined(TARGET_MIPS64)
9702 case M16_OPC_LD:
9703 check_mips_64(ctx);
d75c135e 9704 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9705 break;
9706#endif
9707 case M16_OPC_RRIA:
9708 imm = ctx->opcode & 0xf;
9709 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9710 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9711 imm = (int16_t) (imm << 1) >> 1;
9712 if ((ctx->opcode >> 4) & 0x1) {
9713#if defined(TARGET_MIPS64)
9714 check_mips_64(ctx);
d75c135e 9715 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9716#else
9717 generate_exception(ctx, EXCP_RI);
9718#endif
9719 } else {
d75c135e 9720 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9721 }
9722 break;
9723 case M16_OPC_ADDIU8:
d75c135e 9724 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9725 break;
9726 case M16_OPC_SLTI:
d75c135e 9727 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9728 break;
9729 case M16_OPC_SLTIU:
d75c135e 9730 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9731 break;
9732 case M16_OPC_I8:
9733 switch (funct) {
9734 case I8_BTEQZ:
9735 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9736 break;
9737 case I8_BTNEZ:
9738 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9739 break;
9740 case I8_SWRASP:
5c13fdfd 9741 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9742 break;
9743 case I8_ADJSP:
d75c135e 9744 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
9745 break;
9746 case I8_SVRS:
9747 {
9748 int xsregs = (ctx->opcode >> 24) & 0x7;
9749 int aregs = (ctx->opcode >> 16) & 0xf;
9750 int do_ra = (ctx->opcode >> 6) & 0x1;
9751 int do_s0 = (ctx->opcode >> 5) & 0x1;
9752 int do_s1 = (ctx->opcode >> 4) & 0x1;
9753 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9754 | (ctx->opcode & 0xf)) << 3;
9755
9756 if (ctx->opcode & (1 << 7)) {
9757 gen_mips16_save(ctx, xsregs, aregs,
9758 do_ra, do_s0, do_s1,
9759 framesize);
9760 } else {
9761 gen_mips16_restore(ctx, xsregs, aregs,
9762 do_ra, do_s0, do_s1,
9763 framesize);
9764 }
9765 }
9766 break;
9767 default:
9768 generate_exception(ctx, EXCP_RI);
9769 break;
9770 }
9771 break;
9772 case M16_OPC_LI:
9773 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9774 break;
9775 case M16_OPC_CMPI:
9776 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9777 break;
9778#if defined(TARGET_MIPS64)
9779 case M16_OPC_SD:
5c13fdfd 9780 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9781 break;
9782#endif
9783 case M16_OPC_LB:
d75c135e 9784 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9785 break;
9786 case M16_OPC_LH:
d75c135e 9787 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9788 break;
9789 case M16_OPC_LWSP:
d75c135e 9790 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9791 break;
9792 case M16_OPC_LW:
d75c135e 9793 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9794 break;
9795 case M16_OPC_LBU:
d75c135e 9796 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9797 break;
9798 case M16_OPC_LHU:
d75c135e 9799 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9800 break;
9801 case M16_OPC_LWPC:
d75c135e 9802 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9803 break;
9804#if defined(TARGET_MIPS64)
9805 case M16_OPC_LWU:
d75c135e 9806 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9807 break;
9808#endif
9809 case M16_OPC_SB:
5c13fdfd 9810 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9811 break;
9812 case M16_OPC_SH:
5c13fdfd 9813 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9814 break;
9815 case M16_OPC_SWSP:
5c13fdfd 9816 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9817 break;
9818 case M16_OPC_SW:
5c13fdfd 9819 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9820 break;
9821#if defined(TARGET_MIPS64)
9822 case M16_OPC_I64:
d75c135e 9823 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
9824 break;
9825#endif
9826 default:
9827 generate_exception(ctx, EXCP_RI);
9828 break;
9829 }
9830
9831 return 4;
9832}
9833
240ce26a 9834static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
9835{
9836 int rx, ry;
9837 int sa;
9838 int op, cnvt_op, op1, offset;
9839 int funct;
9840 int n_bytes;
9841
9842 op = (ctx->opcode >> 11) & 0x1f;
9843 sa = (ctx->opcode >> 2) & 0x7;
9844 sa = sa == 0 ? 8 : sa;
9845 rx = xlat((ctx->opcode >> 8) & 0x7);
9846 cnvt_op = (ctx->opcode >> 5) & 0x7;
9847 ry = xlat((ctx->opcode >> 5) & 0x7);
9848 op1 = offset = ctx->opcode & 0x1f;
9849
9850 n_bytes = 2;
9851
9852 switch (op) {
9853 case M16_OPC_ADDIUSP:
9854 {
9855 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9856
d75c135e 9857 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9858 }
9859 break;
9860 case M16_OPC_ADDIUPC:
9861 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9862 break;
9863 case M16_OPC_B:
9864 offset = (ctx->opcode & 0x7ff) << 1;
9865 offset = (int16_t)(offset << 4) >> 4;
9866 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9867 /* No delay slot, so just process as a normal instruction */
9868 break;
9869 case M16_OPC_JAL:
895c2d04 9870 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9871 offset = (((ctx->opcode & 0x1f) << 21)
9872 | ((ctx->opcode >> 5) & 0x1f) << 16
9873 | offset) << 2;
620e48f6 9874 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9875 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9876 n_bytes = 4;
364d4831
NF
9877 break;
9878 case M16_OPC_BEQZ:
9879 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9880 /* No delay slot, so just process as a normal instruction */
9881 break;
9882 case M16_OPC_BNEQZ:
9883 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9884 /* No delay slot, so just process as a normal instruction */
9885 break;
9886 case M16_OPC_SHIFT:
9887 switch (ctx->opcode & 0x3) {
9888 case 0x0:
d75c135e 9889 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9890 break;
9891 case 0x1:
9892#if defined(TARGET_MIPS64)
9893 check_mips_64(ctx);
d75c135e 9894 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9895#else
9896 generate_exception(ctx, EXCP_RI);
9897#endif
9898 break;
9899 case 0x2:
d75c135e 9900 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9901 break;
9902 case 0x3:
d75c135e 9903 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9904 break;
9905 }
9906 break;
9907#if defined(TARGET_MIPS64)
9908 case M16_OPC_LD:
9909 check_mips_64(ctx);
d75c135e 9910 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9911 break;
9912#endif
9913 case M16_OPC_RRIA:
9914 {
9915 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9916
9917 if ((ctx->opcode >> 4) & 1) {
9918#if defined(TARGET_MIPS64)
9919 check_mips_64(ctx);
d75c135e 9920 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9921#else
9922 generate_exception(ctx, EXCP_RI);
9923#endif
9924 } else {
d75c135e 9925 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9926 }
9927 }
9928 break;
9929 case M16_OPC_ADDIU8:
9930 {
9931 int16_t imm = (int8_t) ctx->opcode;
9932
d75c135e 9933 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9934 }
9935 break;
9936 case M16_OPC_SLTI:
9937 {
9938 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9939 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9940 }
9941 break;
9942 case M16_OPC_SLTIU:
9943 {
9944 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9945 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9946 }
9947 break;
9948 case M16_OPC_I8:
9949 {
9950 int reg32;
9951
9952 funct = (ctx->opcode >> 8) & 0x7;
9953 switch (funct) {
9954 case I8_BTEQZ:
9955 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9956 ((int8_t)ctx->opcode) << 1);
9957 break;
9958 case I8_BTNEZ:
9959 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9960 ((int8_t)ctx->opcode) << 1);
9961 break;
9962 case I8_SWRASP:
5c13fdfd 9963 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9964 break;
9965 case I8_ADJSP:
d75c135e 9966 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
9967 ((int8_t)ctx->opcode) << 3);
9968 break;
9969 case I8_SVRS:
9970 {
9971 int do_ra = ctx->opcode & (1 << 6);
9972 int do_s0 = ctx->opcode & (1 << 5);
9973 int do_s1 = ctx->opcode & (1 << 4);
9974 int framesize = ctx->opcode & 0xf;
9975
9976 if (framesize == 0) {
9977 framesize = 128;
9978 } else {
9979 framesize = framesize << 3;
9980 }
9981
9982 if (ctx->opcode & (1 << 7)) {
9983 gen_mips16_save(ctx, 0, 0,
9984 do_ra, do_s0, do_s1, framesize);
9985 } else {
9986 gen_mips16_restore(ctx, 0, 0,
9987 do_ra, do_s0, do_s1, framesize);
9988 }
9989 }
9990 break;
9991 case I8_MOV32R:
9992 {
9993 int rz = xlat(ctx->opcode & 0x7);
9994
9995 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9996 ((ctx->opcode >> 5) & 0x7);
d75c135e 9997 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
9998 }
9999 break;
10000 case I8_MOVR32:
10001 reg32 = ctx->opcode & 0x1f;
d75c135e 10002 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
10003 break;
10004 default:
10005 generate_exception(ctx, EXCP_RI);
10006 break;
10007 }
10008 }
10009 break;
10010 case M16_OPC_LI:
10011 {
10012 int16_t imm = (uint8_t) ctx->opcode;
10013
d75c135e 10014 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
10015 }
10016 break;
10017 case M16_OPC_CMPI:
10018 {
10019 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10020 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
10021 }
10022 break;
10023#if defined(TARGET_MIPS64)
10024 case M16_OPC_SD:
10025 check_mips_64(ctx);
5c13fdfd 10026 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
10027 break;
10028#endif
10029 case M16_OPC_LB:
d75c135e 10030 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10031 break;
10032 case M16_OPC_LH:
d75c135e 10033 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
10034 break;
10035 case M16_OPC_LWSP:
d75c135e 10036 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10037 break;
10038 case M16_OPC_LW:
d75c135e 10039 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10040 break;
10041 case M16_OPC_LBU:
d75c135e 10042 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10043 break;
10044 case M16_OPC_LHU:
d75c135e 10045 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10046 break;
10047 case M16_OPC_LWPC:
d75c135e 10048 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10049 break;
10050#if defined (TARGET_MIPS64)
10051 case M16_OPC_LWU:
10052 check_mips_64(ctx);
d75c135e 10053 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10054 break;
10055#endif
10056 case M16_OPC_SB:
5c13fdfd 10057 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10058 break;
10059 case M16_OPC_SH:
5c13fdfd 10060 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10061 break;
10062 case M16_OPC_SWSP:
5c13fdfd 10063 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10064 break;
10065 case M16_OPC_SW:
5c13fdfd 10066 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10067 break;
10068 case M16_OPC_RRR:
10069 {
10070 int rz = xlat((ctx->opcode >> 2) & 0x7);
10071 int mips32_op;
10072
10073 switch (ctx->opcode & 0x3) {
10074 case RRR_ADDU:
10075 mips32_op = OPC_ADDU;
10076 break;
10077 case RRR_SUBU:
10078 mips32_op = OPC_SUBU;
10079 break;
10080#if defined(TARGET_MIPS64)
10081 case RRR_DADDU:
10082 mips32_op = OPC_DADDU;
10083 check_mips_64(ctx);
10084 break;
10085 case RRR_DSUBU:
10086 mips32_op = OPC_DSUBU;
10087 check_mips_64(ctx);
10088 break;
10089#endif
10090 default:
10091 generate_exception(ctx, EXCP_RI);
10092 goto done;
10093 }
10094
d75c135e 10095 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10096 done:
10097 ;
10098 }
10099 break;
10100 case M16_OPC_RR:
10101 switch (op1) {
10102 case RR_JR:
10103 {
10104 int nd = (ctx->opcode >> 7) & 0x1;
10105 int link = (ctx->opcode >> 6) & 0x1;
10106 int ra = (ctx->opcode >> 5) & 0x1;
10107
10108 if (link) {
620e48f6 10109 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10110 } else {
10111 op = OPC_JR;
10112 }
10113
10114 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
364d4831
NF
10115 }
10116 break;
10117 case RR_SDBBP:
10118 /* XXX: not clear which exception should be raised
10119 * when in debug mode...
10120 */
d75c135e 10121 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10122 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10123 generate_exception(ctx, EXCP_DBp);
10124 } else {
10125 generate_exception(ctx, EXCP_DBp);
10126 }
10127 break;
10128 case RR_SLT:
d75c135e 10129 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10130 break;
10131 case RR_SLTU:
d75c135e 10132 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10133 break;
10134 case RR_BREAK:
10135 generate_exception(ctx, EXCP_BREAK);
10136 break;
10137 case RR_SLLV:
d75c135e 10138 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10139 break;
10140 case RR_SRLV:
d75c135e 10141 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10142 break;
10143 case RR_SRAV:
d75c135e 10144 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10145 break;
10146#if defined (TARGET_MIPS64)
10147 case RR_DSRL:
10148 check_mips_64(ctx);
d75c135e 10149 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10150 break;
10151#endif
10152 case RR_CMP:
d75c135e 10153 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10154 break;
10155 case RR_NEG:
d75c135e 10156 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10157 break;
10158 case RR_AND:
d75c135e 10159 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10160 break;
10161 case RR_OR:
d75c135e 10162 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10163 break;
10164 case RR_XOR:
d75c135e 10165 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10166 break;
10167 case RR_NOT:
d75c135e 10168 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10169 break;
10170 case RR_MFHI:
26135ead 10171 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
10172 break;
10173 case RR_CNVT:
10174 switch (cnvt_op) {
10175 case RR_RY_CNVT_ZEB:
10176 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10177 break;
10178 case RR_RY_CNVT_ZEH:
10179 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10180 break;
10181 case RR_RY_CNVT_SEB:
10182 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10183 break;
10184 case RR_RY_CNVT_SEH:
10185 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10186 break;
10187#if defined (TARGET_MIPS64)
10188 case RR_RY_CNVT_ZEW:
10189 check_mips_64(ctx);
10190 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10191 break;
10192 case RR_RY_CNVT_SEW:
10193 check_mips_64(ctx);
10194 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10195 break;
10196#endif
10197 default:
10198 generate_exception(ctx, EXCP_RI);
10199 break;
10200 }
10201 break;
10202 case RR_MFLO:
26135ead 10203 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
10204 break;
10205#if defined (TARGET_MIPS64)
10206 case RR_DSRA:
10207 check_mips_64(ctx);
d75c135e 10208 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10209 break;
10210 case RR_DSLLV:
10211 check_mips_64(ctx);
d75c135e 10212 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10213 break;
10214 case RR_DSRLV:
10215 check_mips_64(ctx);
d75c135e 10216 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10217 break;
10218 case RR_DSRAV:
10219 check_mips_64(ctx);
d75c135e 10220 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10221 break;
10222#endif
10223 case RR_MULT:
26135ead 10224 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
10225 break;
10226 case RR_MULTU:
26135ead 10227 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
10228 break;
10229 case RR_DIV:
26135ead 10230 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
10231 break;
10232 case RR_DIVU:
26135ead 10233 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
10234 break;
10235#if defined (TARGET_MIPS64)
10236 case RR_DMULT:
10237 check_mips_64(ctx);
26135ead 10238 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
10239 break;
10240 case RR_DMULTU:
10241 check_mips_64(ctx);
26135ead 10242 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
10243 break;
10244 case RR_DDIV:
10245 check_mips_64(ctx);
26135ead 10246 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
10247 break;
10248 case RR_DDIVU:
10249 check_mips_64(ctx);
26135ead 10250 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
10251 break;
10252#endif
10253 default:
10254 generate_exception(ctx, EXCP_RI);
10255 break;
10256 }
10257 break;
10258 case M16_OPC_EXTEND:
240ce26a 10259 decode_extended_mips16_opc(env, ctx);
364d4831
NF
10260 n_bytes = 4;
10261 break;
10262#if defined(TARGET_MIPS64)
10263 case M16_OPC_I64:
10264 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10265 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10266 break;
10267#endif
10268 default:
10269 generate_exception(ctx, EXCP_RI);
10270 break;
10271 }
10272
10273 return n_bytes;
10274}
10275
211da992 10276/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10277
211da992
CWR
10278/*
10279 * microMIPS32/microMIPS64 major opcodes
10280 *
10281 * 1. MIPS Architecture for Programmers Volume II-B:
10282 * The microMIPS32 Instruction Set (Revision 3.05)
10283 *
10284 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10285 *
10286 * 2. MIPS Architecture For Programmers Volume II-A:
10287 * The MIPS64 Instruction Set (Revision 3.51)
10288 */
6af0bf9c 10289
3c824109
NF
10290enum {
10291 POOL32A = 0x00,
10292 POOL16A = 0x01,
10293 LBU16 = 0x02,
10294 MOVE16 = 0x03,
10295 ADDI32 = 0x04,
10296 LBU32 = 0x05,
10297 SB32 = 0x06,
10298 LB32 = 0x07,
10299
10300 POOL32B = 0x08,
10301 POOL16B = 0x09,
10302 LHU16 = 0x0a,
10303 ANDI16 = 0x0b,
10304 ADDIU32 = 0x0c,
10305 LHU32 = 0x0d,
10306 SH32 = 0x0e,
10307 LH32 = 0x0f,
10308
10309 POOL32I = 0x10,
10310 POOL16C = 0x11,
10311 LWSP16 = 0x12,
10312 POOL16D = 0x13,
10313 ORI32 = 0x14,
10314 POOL32F = 0x15,
211da992
CWR
10315 POOL32S = 0x16, /* MIPS64 */
10316 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10317
211da992 10318 /* 0x1f is reserved */
3c824109
NF
10319 POOL32C = 0x18,
10320 LWGP16 = 0x19,
10321 LW16 = 0x1a,
10322 POOL16E = 0x1b,
10323 XORI32 = 0x1c,
10324 JALS32 = 0x1d,
10325 ADDIUPC = 0x1e,
3c824109
NF
10326
10327 /* 0x20 is reserved */
10328 RES_20 = 0x20,
10329 POOL16F = 0x21,
10330 SB16 = 0x22,
10331 BEQZ16 = 0x23,
10332 SLTI32 = 0x24,
10333 BEQ32 = 0x25,
10334 SWC132 = 0x26,
10335 LWC132 = 0x27,
10336
10337 /* 0x28 and 0x29 are reserved */
10338 RES_28 = 0x28,
10339 RES_29 = 0x29,
10340 SH16 = 0x2a,
10341 BNEZ16 = 0x2b,
10342 SLTIU32 = 0x2c,
10343 BNE32 = 0x2d,
10344 SDC132 = 0x2e,
10345 LDC132 = 0x2f,
10346
10347 /* 0x30 and 0x31 are reserved */
10348 RES_30 = 0x30,
10349 RES_31 = 0x31,
10350 SWSP16 = 0x32,
10351 B16 = 0x33,
10352 ANDI32 = 0x34,
10353 J32 = 0x35,
211da992
CWR
10354 SD32 = 0x36, /* MIPS64 */
10355 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10356
10357 /* 0x38 and 0x39 are reserved */
10358 RES_38 = 0x38,
10359 RES_39 = 0x39,
10360 SW16 = 0x3a,
10361 LI16 = 0x3b,
10362 JALX32 = 0x3c,
10363 JAL32 = 0x3d,
10364 SW32 = 0x3e,
10365 LW32 = 0x3f
10366};
10367
10368/* POOL32A encoding of minor opcode field */
10369
10370enum {
10371 /* These opcodes are distinguished only by bits 9..6; those bits are
10372 * what are recorded below. */
10373 SLL32 = 0x0,
10374 SRL32 = 0x1,
10375 SRA = 0x2,
10376 ROTR = 0x3,
10377
10378 SLLV = 0x0,
10379 SRLV = 0x1,
10380 SRAV = 0x2,
10381 ROTRV = 0x3,
10382 ADD = 0x4,
10383 ADDU32 = 0x5,
10384 SUB = 0x6,
10385 SUBU32 = 0x7,
10386 MUL = 0x8,
10387 AND = 0x9,
10388 OR32 = 0xa,
10389 NOR = 0xb,
10390 XOR32 = 0xc,
10391 SLT = 0xd,
10392 SLTU = 0xe,
10393
10394 MOVN = 0x0,
10395 MOVZ = 0x1,
10396 LWXS = 0x4,
10397
10398 /* The following can be distinguished by their lower 6 bits. */
10399 INS = 0x0c,
10400 EXT = 0x2c,
10401 POOL32AXF = 0x3c
10402};
10403
10404/* POOL32AXF encoding of minor opcode field extension */
10405
d132c79f
CWR
10406/*
10407 * 1. MIPS Architecture for Programmers Volume II-B:
10408 * The microMIPS32 Instruction Set (Revision 3.05)
10409 *
10410 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10411 *
10412 * 2. MIPS Architecture for Programmers VolumeIV-e:
10413 * The MIPS DSP Application-Specific Extension
10414 * to the microMIPS32 Architecture (Revision 2.34)
10415 *
10416 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10417 */
10418
3c824109
NF
10419enum {
10420 /* bits 11..6 */
10421 TEQ = 0x00,
10422 TGE = 0x08,
10423 TGEU = 0x10,
10424 TLT = 0x20,
10425 TLTU = 0x28,
10426 TNE = 0x30,
10427
10428 MFC0 = 0x03,
10429 MTC0 = 0x0b,
10430
d132c79f
CWR
10431 /* begin of microMIPS32 DSP */
10432
3c824109
NF
10433 /* bits 13..12 for 0x01 */
10434 MFHI_ACC = 0x0,
10435 MFLO_ACC = 0x1,
10436 MTHI_ACC = 0x2,
10437 MTLO_ACC = 0x3,
10438
10439 /* bits 13..12 for 0x2a */
10440 MADD_ACC = 0x0,
10441 MADDU_ACC = 0x1,
10442 MSUB_ACC = 0x2,
10443 MSUBU_ACC = 0x3,
10444
10445 /* bits 13..12 for 0x32 */
10446 MULT_ACC = 0x0,
6801038b 10447 MULTU_ACC = 0x1,
3c824109 10448
d132c79f
CWR
10449 /* end of microMIPS32 DSP */
10450
3c824109
NF
10451 /* bits 15..12 for 0x2c */
10452 SEB = 0x2,
10453 SEH = 0x3,
10454 CLO = 0x4,
10455 CLZ = 0x5,
10456 RDHWR = 0x6,
10457 WSBH = 0x7,
10458 MULT = 0x8,
10459 MULTU = 0x9,
10460 DIV = 0xa,
10461 DIVU = 0xb,
10462 MADD = 0xc,
10463 MADDU = 0xd,
10464 MSUB = 0xe,
10465 MSUBU = 0xf,
10466
10467 /* bits 15..12 for 0x34 */
10468 MFC2 = 0x4,
10469 MTC2 = 0x5,
10470 MFHC2 = 0x8,
10471 MTHC2 = 0x9,
10472 CFC2 = 0xc,
10473 CTC2 = 0xd,
10474
10475 /* bits 15..12 for 0x3c */
10476 JALR = 0x0,
10477 JR = 0x0, /* alias */
10478 JALR_HB = 0x1,
10479 JALRS = 0x4,
10480 JALRS_HB = 0x5,
10481
10482 /* bits 15..12 for 0x05 */
10483 RDPGPR = 0xe,
10484 WRPGPR = 0xf,
10485
10486 /* bits 15..12 for 0x0d */
10487 TLBP = 0x0,
10488 TLBR = 0x1,
10489 TLBWI = 0x2,
10490 TLBWR = 0x3,
10491 WAIT = 0x9,
10492 IRET = 0xd,
10493 DERET = 0xe,
10494 ERET = 0xf,
10495
10496 /* bits 15..12 for 0x15 */
10497 DMT = 0x0,
10498 DVPE = 0x1,
10499 EMT = 0x2,
10500 EVPE = 0x3,
10501
10502 /* bits 15..12 for 0x1d */
10503 DI = 0x4,
10504 EI = 0x5,
10505
10506 /* bits 15..12 for 0x2d */
10507 SYNC = 0x6,
10508 SYSCALL = 0x8,
10509 SDBBP = 0xd,
10510
10511 /* bits 15..12 for 0x35 */
10512 MFHI32 = 0x0,
10513 MFLO32 = 0x1,
10514 MTHI32 = 0x2,
10515 MTLO32 = 0x3,
10516};
10517
10518/* POOL32B encoding of minor opcode field (bits 15..12) */
10519
10520enum {
10521 LWC2 = 0x0,
10522 LWP = 0x1,
10523 LDP = 0x4,
10524 LWM32 = 0x5,
10525 CACHE = 0x6,
10526 LDM = 0x7,
10527 SWC2 = 0x8,
10528 SWP = 0x9,
10529 SDP = 0xc,
10530 SWM32 = 0xd,
10531 SDM = 0xf
10532};
10533
10534/* POOL32C encoding of minor opcode field (bits 15..12) */
10535
10536enum {
10537 LWL = 0x0,
10538 SWL = 0x8,
10539 LWR = 0x1,
10540 SWR = 0x9,
10541 PREF = 0x2,
10542 /* 0xa is reserved */
10543 LL = 0x3,
10544 SC = 0xb,
10545 LDL = 0x4,
10546 SDL = 0xc,
10547 LDR = 0x5,
10548 SDR = 0xd,
10549 /* 0x6 is reserved */
10550 LWU = 0xe,
10551 LLD = 0x7,
10552 SCD = 0xf
10553};
10554
10555/* POOL32F encoding of minor opcode field (bits 5..0) */
10556
10557enum {
10558 /* These are the bit 7..6 values */
10559 ADD_FMT = 0x0,
10560 MOVN_FMT = 0x0,
10561
10562 SUB_FMT = 0x1,
10563 MOVZ_FMT = 0x1,
10564
10565 MUL_FMT = 0x2,
10566
10567 DIV_FMT = 0x3,
10568
10569 /* These are the bit 8..6 values */
10570 RSQRT2_FMT = 0x0,
10571 MOVF_FMT = 0x0,
10572
10573 LWXC1 = 0x1,
10574 MOVT_FMT = 0x1,
10575
10576 PLL_PS = 0x2,
10577 SWXC1 = 0x2,
10578
10579 PLU_PS = 0x3,
10580 LDXC1 = 0x3,
10581
10582 PUL_PS = 0x4,
10583 SDXC1 = 0x4,
10584 RECIP2_FMT = 0x4,
10585
10586 PUU_PS = 0x5,
10587 LUXC1 = 0x5,
10588
10589 CVT_PS_S = 0x6,
10590 SUXC1 = 0x6,
10591 ADDR_PS = 0x6,
10592 PREFX = 0x6,
10593
10594 MULR_PS = 0x7,
10595
10596 MADD_S = 0x01,
10597 MADD_D = 0x09,
10598 MADD_PS = 0x11,
10599 ALNV_PS = 0x19,
10600 MSUB_S = 0x21,
10601 MSUB_D = 0x29,
10602 MSUB_PS = 0x31,
10603
10604 NMADD_S = 0x02,
10605 NMADD_D = 0x0a,
10606 NMADD_PS = 0x12,
10607 NMSUB_S = 0x22,
10608 NMSUB_D = 0x2a,
10609 NMSUB_PS = 0x32,
10610
10611 POOL32FXF = 0x3b,
10612
10613 CABS_COND_FMT = 0x1c, /* MIPS3D */
10614 C_COND_FMT = 0x3c
10615};
10616
10617/* POOL32Fxf encoding of minor opcode extension field */
10618
10619enum {
10620 CVT_L = 0x04,
10621 RSQRT_FMT = 0x08,
10622 FLOOR_L = 0x0c,
10623 CVT_PW_PS = 0x1c,
10624 CVT_W = 0x24,
10625 SQRT_FMT = 0x28,
10626 FLOOR_W = 0x2c,
10627 CVT_PS_PW = 0x3c,
10628 CFC1 = 0x40,
10629 RECIP_FMT = 0x48,
10630 CEIL_L = 0x4c,
10631 CTC1 = 0x60,
10632 CEIL_W = 0x6c,
10633 MFC1 = 0x80,
10634 CVT_S_PL = 0x84,
10635 TRUNC_L = 0x8c,
10636 MTC1 = 0xa0,
10637 CVT_S_PU = 0xa4,
10638 TRUNC_W = 0xac,
10639 MFHC1 = 0xc0,
10640 ROUND_L = 0xcc,
10641 MTHC1 = 0xe0,
10642 ROUND_W = 0xec,
10643
10644 MOV_FMT = 0x01,
10645 MOVF = 0x05,
10646 ABS_FMT = 0x0d,
10647 RSQRT1_FMT = 0x1d,
10648 MOVT = 0x25,
10649 NEG_FMT = 0x2d,
10650 CVT_D = 0x4d,
10651 RECIP1_FMT = 0x5d,
10652 CVT_S = 0x6d
10653};
10654
10655/* POOL32I encoding of minor opcode field (bits 25..21) */
10656
10657enum {
10658 BLTZ = 0x00,
10659 BLTZAL = 0x01,
10660 BGEZ = 0x02,
10661 BGEZAL = 0x03,
10662 BLEZ = 0x04,
10663 BNEZC = 0x05,
10664 BGTZ = 0x06,
10665 BEQZC = 0x07,
10666 TLTI = 0x08,
10667 TGEI = 0x09,
10668 TLTIU = 0x0a,
10669 TGEIU = 0x0b,
10670 TNEI = 0x0c,
10671 LUI = 0x0d,
10672 TEQI = 0x0e,
10673 SYNCI = 0x10,
10674 BLTZALS = 0x11,
10675 BGEZALS = 0x13,
10676 BC2F = 0x14,
10677 BC2T = 0x15,
10678 BPOSGE64 = 0x1a,
10679 BPOSGE32 = 0x1b,
10680 /* These overlap and are distinguished by bit16 of the instruction */
10681 BC1F = 0x1c,
10682 BC1T = 0x1d,
10683 BC1ANY2F = 0x1c,
10684 BC1ANY2T = 0x1d,
10685 BC1ANY4F = 0x1e,
10686 BC1ANY4T = 0x1f
10687};
10688
10689/* POOL16A encoding of minor opcode field */
10690
10691enum {
10692 ADDU16 = 0x0,
10693 SUBU16 = 0x1
10694};
10695
10696/* POOL16B encoding of minor opcode field */
10697
10698enum {
10699 SLL16 = 0x0,
10700 SRL16 = 0x1
10701};
10702
10703/* POOL16C encoding of minor opcode field */
10704
10705enum {
10706 NOT16 = 0x00,
10707 XOR16 = 0x04,
10708 AND16 = 0x08,
10709 OR16 = 0x0c,
10710 LWM16 = 0x10,
10711 SWM16 = 0x14,
10712 JR16 = 0x18,
10713 JRC16 = 0x1a,
10714 JALR16 = 0x1c,
10715 JALR16S = 0x1e,
10716 MFHI16 = 0x20,
10717 MFLO16 = 0x24,
10718 BREAK16 = 0x28,
10719 SDBBP16 = 0x2c,
10720 JRADDIUSP = 0x30
10721};
10722
10723/* POOL16D encoding of minor opcode field */
10724
10725enum {
10726 ADDIUS5 = 0x0,
10727 ADDIUSP = 0x1
10728};
10729
10730/* POOL16E encoding of minor opcode field */
10731
10732enum {
10733 ADDIUR2 = 0x0,
10734 ADDIUR1SP = 0x1
10735};
10736
10737static int mmreg (int r)
10738{
10739 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10740
10741 return map[r];
10742}
10743
10744/* Used for 16-bit store instructions. */
10745static int mmreg2 (int r)
10746{
10747 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10748
10749 return map[r];
10750}
10751
10752#define uMIPS_RD(op) ((op >> 7) & 0x7)
10753#define uMIPS_RS(op) ((op >> 4) & 0x7)
10754#define uMIPS_RS2(op) uMIPS_RS(op)
10755#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10756#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10757#define uMIPS_RS5(op) (op & 0x1f)
10758
10759/* Signed immediate */
10760#define SIMM(op, start, width) \
10761 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10762 << (32-width)) \
10763 >> (32-width))
10764/* Zero-extended immediate */
10765#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10766
d75c135e 10767static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
10768{
10769 int rd = mmreg(uMIPS_RD(ctx->opcode));
10770
d75c135e 10771 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
10772}
10773
d75c135e 10774static void gen_addiur2(DisasContext *ctx)
3c824109
NF
10775{
10776 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10777 int rd = mmreg(uMIPS_RD(ctx->opcode));
10778 int rs = mmreg(uMIPS_RS(ctx->opcode));
10779
d75c135e 10780 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
10781}
10782
d75c135e 10783static void gen_addiusp(DisasContext *ctx)
3c824109
NF
10784{
10785 int encoded = ZIMM(ctx->opcode, 1, 9);
10786 int decoded;
10787
10788 if (encoded <= 1) {
10789 decoded = 256 + encoded;
10790 } else if (encoded <= 255) {
10791 decoded = encoded;
10792 } else if (encoded <= 509) {
10793 decoded = encoded - 512;
10794 } else {
10795 decoded = encoded - 768;
10796 }
10797
d75c135e 10798 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
10799}
10800
d75c135e 10801static void gen_addius5(DisasContext *ctx)
3c824109
NF
10802{
10803 int imm = SIMM(ctx->opcode, 1, 4);
10804 int rd = (ctx->opcode >> 5) & 0x1f;
10805
d75c135e 10806 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
10807}
10808
d75c135e 10809static void gen_andi16(DisasContext *ctx)
3c824109
NF
10810{
10811 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10812 31, 32, 63, 64, 255, 32768, 65535 };
10813 int rd = mmreg(uMIPS_RD(ctx->opcode));
10814 int rs = mmreg(uMIPS_RS(ctx->opcode));
10815 int encoded = ZIMM(ctx->opcode, 0, 4);
10816
d75c135e 10817 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10818}
10819
10820static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10821 int base, int16_t offset)
10822{
e1050a76 10823 const char *opn = "ldst_multiple";
3c824109
NF
10824 TCGv t0, t1;
10825 TCGv_i32 t2;
10826
10827 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10828 generate_exception(ctx, EXCP_RI);
10829 return;
10830 }
10831
10832 t0 = tcg_temp_new();
10833
10834 gen_base_offset_addr(ctx, t0, base, offset);
10835
10836 t1 = tcg_const_tl(reglist);
10837 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10838
3c824109
NF
10839 save_cpu_state(ctx, 1);
10840 switch (opc) {
10841 case LWM32:
895c2d04 10842 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10843 opn = "lwm";
3c824109
NF
10844 break;
10845 case SWM32:
895c2d04 10846 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10847 opn = "swm";
3c824109
NF
10848 break;
10849#ifdef TARGET_MIPS64
10850 case LDM:
895c2d04 10851 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10852 opn = "ldm";
3c824109
NF
10853 break;
10854 case SDM:
895c2d04 10855 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10856 opn = "sdm";
3c824109 10857 break;
6af0bf9c 10858#endif
3c824109 10859 }
e1050a76 10860 (void)opn;
3c824109
NF
10861 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10862 tcg_temp_free(t0);
33087598 10863 tcg_temp_free(t1);
3c824109
NF
10864 tcg_temp_free_i32(t2);
10865}
6af0bf9c 10866
3c824109 10867
240ce26a 10868static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 10869{
3c824109
NF
10870 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10871 int rs = mmreg(ctx->opcode & 0x7);
10872 int opc;
6af0bf9c 10873
3c824109
NF
10874 switch (((ctx->opcode) >> 4) & 0x3f) {
10875 case NOT16 + 0:
10876 case NOT16 + 1:
10877 case NOT16 + 2:
10878 case NOT16 + 3:
d75c135e 10879 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10880 break;
10881 case XOR16 + 0:
10882 case XOR16 + 1:
10883 case XOR16 + 2:
10884 case XOR16 + 3:
d75c135e 10885 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10886 break;
10887 case AND16 + 0:
10888 case AND16 + 1:
10889 case AND16 + 2:
10890 case AND16 + 3:
d75c135e 10891 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10892 break;
10893 case OR16 + 0:
10894 case OR16 + 1:
10895 case OR16 + 2:
10896 case OR16 + 3:
d75c135e 10897 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10898 break;
10899 case LWM16 + 0:
10900 case LWM16 + 1:
10901 case LWM16 + 2:
10902 case LWM16 + 3:
10903 {
10904 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10905 int offset = ZIMM(ctx->opcode, 0, 4);
10906
10907 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10908 29, offset << 2);
10909 }
10910 break;
10911 case SWM16 + 0:
10912 case SWM16 + 1:
10913 case SWM16 + 2:
10914 case SWM16 + 3:
10915 {
10916 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10917 int offset = ZIMM(ctx->opcode, 0, 4);
10918
10919 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10920 29, offset << 2);
10921 }
10922 break;
10923 case JR16 + 0:
10924 case JR16 + 1:
10925 {
10926 int reg = ctx->opcode & 0x1f;
10927
10928 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10929 }
3c824109
NF
10930 break;
10931 case JRC16 + 0:
10932 case JRC16 + 1:
10933 {
10934 int reg = ctx->opcode & 0x1f;
10935
10936 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10937 /* Let normal delay slot handling in our caller take us
10938 to the branch target. */
10939 }
10940 break;
10941 case JALR16 + 0:
10942 case JALR16 + 1:
10943 opc = OPC_JALR;
10944 goto do_jalr;
10945 case JALR16S + 0:
10946 case JALR16S + 1:
10947 opc = OPC_JALRS;
10948 do_jalr:
10949 {
10950 int reg = ctx->opcode & 0x1f;
10951
10952 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10953 }
3c824109
NF
10954 break;
10955 case MFHI16 + 0:
10956 case MFHI16 + 1:
26135ead 10957 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10958 break;
10959 case MFLO16 + 0:
10960 case MFLO16 + 1:
26135ead 10961 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10962 break;
10963 case BREAK16:
10964 generate_exception(ctx, EXCP_BREAK);
10965 break;
10966 case SDBBP16:
10967 /* XXX: not clear which exception should be raised
10968 * when in debug mode...
10969 */
d75c135e 10970 check_insn(ctx, ISA_MIPS32);
3c824109
NF
10971 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10972 generate_exception(ctx, EXCP_DBp);
10973 } else {
10974 generate_exception(ctx, EXCP_DBp);
10975 }
10976 break;
10977 case JRADDIUSP + 0:
10978 case JRADDIUSP + 1:
10979 {
10980 int imm = ZIMM(ctx->opcode, 0, 5);
10981
10982 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 10983 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
10984 /* Let normal delay slot handling in our caller take us
10985 to the branch target. */
10986 }
10987 break;
10988 default:
10989 generate_exception(ctx, EXCP_RI);
10990 break;
10991 }
10992}
10993
10994static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10995{
10996 TCGv t0 = tcg_temp_new();
10997 TCGv t1 = tcg_temp_new();
10998
10999 gen_load_gpr(t0, base);
11000
11001 if (index != 0) {
11002 gen_load_gpr(t1, index);
11003 tcg_gen_shli_tl(t1, t1, 2);
11004 gen_op_addr_add(ctx, t0, t1, t0);
11005 }
11006
5f68f5ae 11007 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11008 gen_store_gpr(t1, rd);
11009
11010 tcg_temp_free(t0);
11011 tcg_temp_free(t1);
11012}
11013
11014static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
11015 int base, int16_t offset)
11016{
11017 const char *opn = "ldst_pair";
11018 TCGv t0, t1;
11019
36c6711b 11020 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 11021 generate_exception(ctx, EXCP_RI);
d796321b
FB
11022 return;
11023 }
11024
3c824109
NF
11025 t0 = tcg_temp_new();
11026 t1 = tcg_temp_new();
8e9ade68 11027
3c824109
NF
11028 gen_base_offset_addr(ctx, t0, base, offset);
11029
11030 switch (opc) {
11031 case LWP:
36c6711b
EJ
11032 if (rd == base) {
11033 generate_exception(ctx, EXCP_RI);
11034 return;
11035 }
5f68f5ae 11036 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11037 gen_store_gpr(t1, rd);
11038 tcg_gen_movi_tl(t1, 4);
11039 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11040 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11041 gen_store_gpr(t1, rd+1);
11042 opn = "lwp";
11043 break;
11044 case SWP:
3c824109 11045 gen_load_gpr(t1, rd);
5f68f5ae 11046 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11047 tcg_gen_movi_tl(t1, 4);
11048 gen_op_addr_add(ctx, t0, t0, t1);
11049 gen_load_gpr(t1, rd+1);
5f68f5ae 11050 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11051 opn = "swp";
11052 break;
11053#ifdef TARGET_MIPS64
11054 case LDP:
36c6711b
EJ
11055 if (rd == base) {
11056 generate_exception(ctx, EXCP_RI);
11057 return;
11058 }
5f68f5ae 11059 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11060 gen_store_gpr(t1, rd);
11061 tcg_gen_movi_tl(t1, 8);
11062 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11063 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11064 gen_store_gpr(t1, rd+1);
11065 opn = "ldp";
11066 break;
11067 case SDP:
3c824109 11068 gen_load_gpr(t1, rd);
5f68f5ae 11069 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11070 tcg_gen_movi_tl(t1, 8);
11071 gen_op_addr_add(ctx, t0, t0, t1);
11072 gen_load_gpr(t1, rd+1);
5f68f5ae 11073 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11074 opn = "sdp";
11075 break;
11076#endif
6af0bf9c 11077 }
2abf314d 11078 (void)opn; /* avoid a compiler warning */
3c824109
NF
11079 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11080 tcg_temp_free(t0);
11081 tcg_temp_free(t1);
11082}
618b0fe9 11083
240ce26a 11084static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
11085{
11086 int extension = (ctx->opcode >> 6) & 0x3f;
11087 int minor = (ctx->opcode >> 12) & 0xf;
11088 uint32_t mips32_op;
11089
11090 switch (extension) {
11091 case TEQ:
11092 mips32_op = OPC_TEQ;
11093 goto do_trap;
11094 case TGE:
11095 mips32_op = OPC_TGE;
11096 goto do_trap;
11097 case TGEU:
11098 mips32_op = OPC_TGEU;
11099 goto do_trap;
11100 case TLT:
11101 mips32_op = OPC_TLT;
11102 goto do_trap;
11103 case TLTU:
11104 mips32_op = OPC_TLTU;
11105 goto do_trap;
11106 case TNE:
11107 mips32_op = OPC_TNE;
11108 do_trap:
11109 gen_trap(ctx, mips32_op, rs, rt, -1);
11110 break;
11111#ifndef CONFIG_USER_ONLY
11112 case MFC0:
11113 case MFC0 + 32:
2e15497c 11114 check_cp0_enabled(ctx);
3c824109
NF
11115 if (rt == 0) {
11116 /* Treat as NOP. */
11117 break;
11118 }
d75c135e 11119 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11120 break;
11121 case MTC0:
11122 case MTC0 + 32:
2e15497c 11123 check_cp0_enabled(ctx);
3c824109
NF
11124 {
11125 TCGv t0 = tcg_temp_new();
618b0fe9 11126
3c824109 11127 gen_load_gpr(t0, rt);
d75c135e 11128 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11129 tcg_temp_free(t0);
11130 }
11131 break;
11132#endif
a1fc6246
LA
11133 case 0x2a:
11134 switch (minor & 3) {
11135 case MADD_ACC:
11136 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11137 break;
11138 case MADDU_ACC:
11139 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11140 break;
11141 case MSUB_ACC:
11142 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11143 break;
11144 case MSUBU_ACC:
11145 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11146 break;
11147 default:
11148 goto pool32axf_invalid;
11149 }
11150 break;
11151 case 0x32:
11152 switch (minor & 3) {
11153 case MULT_ACC:
11154 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11155 break;
11156 case MULTU_ACC:
11157 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11158 break;
11159 default:
11160 goto pool32axf_invalid;
11161 }
11162 break;
3c824109
NF
11163 case 0x2c:
11164 switch (minor) {
11165 case SEB:
11166 gen_bshfl(ctx, OPC_SEB, rs, rt);
11167 break;
11168 case SEH:
11169 gen_bshfl(ctx, OPC_SEH, rs, rt);
11170 break;
11171 case CLO:
11172 mips32_op = OPC_CLO;
11173 goto do_cl;
11174 case CLZ:
11175 mips32_op = OPC_CLZ;
11176 do_cl:
d75c135e 11177 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11178 gen_cl(ctx, mips32_op, rt, rs);
11179 break;
11180 case RDHWR:
d75c135e 11181 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11182 break;
11183 case WSBH:
11184 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11185 break;
11186 case MULT:
11187 mips32_op = OPC_MULT;
26135ead 11188 goto do_mul;
3c824109
NF
11189 case MULTU:
11190 mips32_op = OPC_MULTU;
26135ead 11191 goto do_mul;
3c824109
NF
11192 case DIV:
11193 mips32_op = OPC_DIV;
26135ead 11194 goto do_div;
3c824109
NF
11195 case DIVU:
11196 mips32_op = OPC_DIVU;
26135ead
RS
11197 goto do_div;
11198 do_div:
11199 check_insn(ctx, ISA_MIPS32);
11200 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11201 break;
3c824109
NF
11202 case MADD:
11203 mips32_op = OPC_MADD;
26135ead 11204 goto do_mul;
3c824109
NF
11205 case MADDU:
11206 mips32_op = OPC_MADDU;
26135ead 11207 goto do_mul;
3c824109
NF
11208 case MSUB:
11209 mips32_op = OPC_MSUB;
26135ead 11210 goto do_mul;
3c824109
NF
11211 case MSUBU:
11212 mips32_op = OPC_MSUBU;
26135ead 11213 do_mul:
d75c135e 11214 check_insn(ctx, ISA_MIPS32);
a1fc6246 11215 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
11216 break;
11217 default:
11218 goto pool32axf_invalid;
11219 }
11220 break;
11221 case 0x34:
11222 switch (minor) {
11223 case MFC2:
11224 case MTC2:
11225 case MFHC2:
11226 case MTHC2:
11227 case CFC2:
11228 case CTC2:
11229 generate_exception_err(ctx, EXCP_CpU, 2);
11230 break;
11231 default:
11232 goto pool32axf_invalid;
11233 }
11234 break;
11235 case 0x3c:
11236 switch (minor) {
11237 case JALR:
11238 case JALR_HB:
11239 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
3c824109
NF
11240 break;
11241 case JALRS:
11242 case JALRS_HB:
11243 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
3c824109
NF
11244 break;
11245 default:
11246 goto pool32axf_invalid;
11247 }
11248 break;
11249 case 0x05:
11250 switch (minor) {
11251 case RDPGPR:
2e15497c 11252 check_cp0_enabled(ctx);
d75c135e 11253 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11254 gen_load_srsgpr(rt, rs);
11255 break;
11256 case WRPGPR:
2e15497c 11257 check_cp0_enabled(ctx);
d75c135e 11258 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11259 gen_store_srsgpr(rt, rs);
11260 break;
11261 default:
11262 goto pool32axf_invalid;
11263 }
11264 break;
11265#ifndef CONFIG_USER_ONLY
11266 case 0x0d:
11267 switch (minor) {
11268 case TLBP:
11269 mips32_op = OPC_TLBP;
11270 goto do_cp0;
11271 case TLBR:
11272 mips32_op = OPC_TLBR;
11273 goto do_cp0;
11274 case TLBWI:
11275 mips32_op = OPC_TLBWI;
11276 goto do_cp0;
11277 case TLBWR:
11278 mips32_op = OPC_TLBWR;
11279 goto do_cp0;
11280 case WAIT:
11281 mips32_op = OPC_WAIT;
11282 goto do_cp0;
11283 case DERET:
11284 mips32_op = OPC_DERET;
11285 goto do_cp0;
11286 case ERET:
11287 mips32_op = OPC_ERET;
11288 do_cp0:
11289 gen_cp0(env, ctx, mips32_op, rt, rs);
11290 break;
11291 default:
11292 goto pool32axf_invalid;
11293 }
11294 break;
11295 case 0x1d:
11296 switch (minor) {
11297 case DI:
2e15497c 11298 check_cp0_enabled(ctx);
3c824109
NF
11299 {
11300 TCGv t0 = tcg_temp_new();
11301
11302 save_cpu_state(ctx, 1);
895c2d04 11303 gen_helper_di(t0, cpu_env);
3c824109
NF
11304 gen_store_gpr(t0, rs);
11305 /* Stop translation as we may have switched the execution mode */
11306 ctx->bstate = BS_STOP;
11307 tcg_temp_free(t0);
11308 }
11309 break;
11310 case EI:
2e15497c 11311 check_cp0_enabled(ctx);
3c824109
NF
11312 {
11313 TCGv t0 = tcg_temp_new();
11314
11315 save_cpu_state(ctx, 1);
895c2d04 11316 gen_helper_ei(t0, cpu_env);
3c824109
NF
11317 gen_store_gpr(t0, rs);
11318 /* Stop translation as we may have switched the execution mode */
11319 ctx->bstate = BS_STOP;
11320 tcg_temp_free(t0);
11321 }
11322 break;
11323 default:
11324 goto pool32axf_invalid;
11325 }
11326 break;
11327#endif
11328 case 0x2d:
11329 switch (minor) {
11330 case SYNC:
11331 /* NOP */
11332 break;
11333 case SYSCALL:
11334 generate_exception(ctx, EXCP_SYSCALL);
11335 ctx->bstate = BS_STOP;
11336 break;
11337 case SDBBP:
d75c135e 11338 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11339 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11340 generate_exception(ctx, EXCP_DBp);
11341 } else {
11342 generate_exception(ctx, EXCP_DBp);
11343 }
11344 break;
11345 default:
11346 goto pool32axf_invalid;
11347 }
11348 break;
a1fc6246 11349 case 0x01:
26135ead 11350 switch (minor & 3) {
a1fc6246 11351 case MFHI_ACC:
26135ead 11352 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 11353 break;
a1fc6246 11354 case MFLO_ACC:
26135ead 11355 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 11356 break;
a1fc6246 11357 case MTHI_ACC:
26135ead 11358 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 11359 break;
a1fc6246 11360 case MTLO_ACC:
26135ead 11361 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
11362 break;
11363 default:
11364 goto pool32axf_invalid;
11365 }
11366 break;
a1fc6246
LA
11367 case 0x35:
11368 switch (minor) {
11369 case MFHI32:
11370 gen_HILO(ctx, OPC_MFHI, 0, rs);
11371 break;
11372 case MFLO32:
11373 gen_HILO(ctx, OPC_MFLO, 0, rs);
11374 break;
11375 case MTHI32:
11376 gen_HILO(ctx, OPC_MTHI, 0, rs);
11377 break;
11378 case MTLO32:
11379 gen_HILO(ctx, OPC_MTLO, 0, rs);
11380 break;
11381 default:
11382 goto pool32axf_invalid;
11383 }
11384 break;
3c824109
NF
11385 default:
11386 pool32axf_invalid:
11387 MIPS_INVAL("pool32axf");
11388 generate_exception(ctx, EXCP_RI);
11389 break;
11390 }
11391}
11392
11393/* Values for microMIPS fmt field. Variable-width, depending on which
11394 formats the instruction supports. */
11395
11396enum {
11397 FMT_SD_S = 0,
11398 FMT_SD_D = 1,
11399
11400 FMT_SDPS_S = 0,
11401 FMT_SDPS_D = 1,
11402 FMT_SDPS_PS = 2,
11403
11404 FMT_SWL_S = 0,
11405 FMT_SWL_W = 1,
11406 FMT_SWL_L = 2,
11407
11408 FMT_DWL_D = 0,
11409 FMT_DWL_W = 1,
11410 FMT_DWL_L = 2
11411};
11412
d75c135e 11413static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11414{
11415 int extension = (ctx->opcode >> 6) & 0x3ff;
11416 uint32_t mips32_op;
11417
11418#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11419#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11420#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11421
11422 switch (extension) {
11423 case FLOAT_1BIT_FMT(CFC1, 0):
11424 mips32_op = OPC_CFC1;
11425 goto do_cp1;
11426 case FLOAT_1BIT_FMT(CTC1, 0):
11427 mips32_op = OPC_CTC1;
11428 goto do_cp1;
11429 case FLOAT_1BIT_FMT(MFC1, 0):
11430 mips32_op = OPC_MFC1;
11431 goto do_cp1;
11432 case FLOAT_1BIT_FMT(MTC1, 0):
11433 mips32_op = OPC_MTC1;
11434 goto do_cp1;
11435 case FLOAT_1BIT_FMT(MFHC1, 0):
11436 mips32_op = OPC_MFHC1;
11437 goto do_cp1;
11438 case FLOAT_1BIT_FMT(MTHC1, 0):
11439 mips32_op = OPC_MTHC1;
11440 do_cp1:
11441 gen_cp1(ctx, mips32_op, rt, rs);
11442 break;
11443
11444 /* Reciprocal square root */
11445 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11446 mips32_op = OPC_RSQRT_S;
11447 goto do_unaryfp;
11448 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11449 mips32_op = OPC_RSQRT_D;
11450 goto do_unaryfp;
11451
11452 /* Square root */
11453 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11454 mips32_op = OPC_SQRT_S;
11455 goto do_unaryfp;
11456 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11457 mips32_op = OPC_SQRT_D;
11458 goto do_unaryfp;
11459
11460 /* Reciprocal */
11461 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11462 mips32_op = OPC_RECIP_S;
11463 goto do_unaryfp;
11464 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11465 mips32_op = OPC_RECIP_D;
11466 goto do_unaryfp;
11467
11468 /* Floor */
11469 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11470 mips32_op = OPC_FLOOR_L_S;
11471 goto do_unaryfp;
11472 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11473 mips32_op = OPC_FLOOR_L_D;
11474 goto do_unaryfp;
11475 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11476 mips32_op = OPC_FLOOR_W_S;
11477 goto do_unaryfp;
11478 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11479 mips32_op = OPC_FLOOR_W_D;
11480 goto do_unaryfp;
11481
11482 /* Ceiling */
11483 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11484 mips32_op = OPC_CEIL_L_S;
11485 goto do_unaryfp;
11486 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11487 mips32_op = OPC_CEIL_L_D;
11488 goto do_unaryfp;
11489 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11490 mips32_op = OPC_CEIL_W_S;
11491 goto do_unaryfp;
11492 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11493 mips32_op = OPC_CEIL_W_D;
11494 goto do_unaryfp;
11495
11496 /* Truncation */
11497 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11498 mips32_op = OPC_TRUNC_L_S;
11499 goto do_unaryfp;
11500 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11501 mips32_op = OPC_TRUNC_L_D;
11502 goto do_unaryfp;
11503 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11504 mips32_op = OPC_TRUNC_W_S;
11505 goto do_unaryfp;
11506 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11507 mips32_op = OPC_TRUNC_W_D;
11508 goto do_unaryfp;
11509
11510 /* Round */
11511 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11512 mips32_op = OPC_ROUND_L_S;
11513 goto do_unaryfp;
11514 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11515 mips32_op = OPC_ROUND_L_D;
11516 goto do_unaryfp;
11517 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11518 mips32_op = OPC_ROUND_W_S;
11519 goto do_unaryfp;
11520 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11521 mips32_op = OPC_ROUND_W_D;
11522 goto do_unaryfp;
11523
11524 /* Integer to floating-point conversion */
11525 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11526 mips32_op = OPC_CVT_L_S;
11527 goto do_unaryfp;
11528 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11529 mips32_op = OPC_CVT_L_D;
11530 goto do_unaryfp;
11531 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11532 mips32_op = OPC_CVT_W_S;
11533 goto do_unaryfp;
11534 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11535 mips32_op = OPC_CVT_W_D;
11536 goto do_unaryfp;
11537
11538 /* Paired-foo conversions */
11539 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11540 mips32_op = OPC_CVT_S_PL;
11541 goto do_unaryfp;
11542 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11543 mips32_op = OPC_CVT_S_PU;
11544 goto do_unaryfp;
11545 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11546 mips32_op = OPC_CVT_PW_PS;
11547 goto do_unaryfp;
11548 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11549 mips32_op = OPC_CVT_PS_PW;
11550 goto do_unaryfp;
11551
11552 /* Floating-point moves */
11553 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11554 mips32_op = OPC_MOV_S;
11555 goto do_unaryfp;
11556 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11557 mips32_op = OPC_MOV_D;
11558 goto do_unaryfp;
11559 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11560 mips32_op = OPC_MOV_PS;
11561 goto do_unaryfp;
11562
11563 /* Absolute value */
11564 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11565 mips32_op = OPC_ABS_S;
11566 goto do_unaryfp;
11567 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11568 mips32_op = OPC_ABS_D;
11569 goto do_unaryfp;
11570 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11571 mips32_op = OPC_ABS_PS;
11572 goto do_unaryfp;
11573
11574 /* Negation */
11575 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11576 mips32_op = OPC_NEG_S;
11577 goto do_unaryfp;
11578 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11579 mips32_op = OPC_NEG_D;
11580 goto do_unaryfp;
11581 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11582 mips32_op = OPC_NEG_PS;
11583 goto do_unaryfp;
11584
11585 /* Reciprocal square root step */
11586 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11587 mips32_op = OPC_RSQRT1_S;
11588 goto do_unaryfp;
11589 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11590 mips32_op = OPC_RSQRT1_D;
11591 goto do_unaryfp;
11592 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11593 mips32_op = OPC_RSQRT1_PS;
11594 goto do_unaryfp;
11595
11596 /* Reciprocal step */
11597 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11598 mips32_op = OPC_RECIP1_S;
11599 goto do_unaryfp;
11600 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11601 mips32_op = OPC_RECIP1_S;
11602 goto do_unaryfp;
11603 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11604 mips32_op = OPC_RECIP1_PS;
11605 goto do_unaryfp;
11606
11607 /* Conversions from double */
11608 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11609 mips32_op = OPC_CVT_D_S;
11610 goto do_unaryfp;
11611 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11612 mips32_op = OPC_CVT_D_W;
11613 goto do_unaryfp;
11614 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11615 mips32_op = OPC_CVT_D_L;
11616 goto do_unaryfp;
11617
11618 /* Conversions from single */
11619 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11620 mips32_op = OPC_CVT_S_D;
11621 goto do_unaryfp;
11622 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11623 mips32_op = OPC_CVT_S_W;
11624 goto do_unaryfp;
11625 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11626 mips32_op = OPC_CVT_S_L;
11627 do_unaryfp:
11628 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11629 break;
11630
11631 /* Conditional moves on floating-point codes */
11632 case COND_FLOAT_MOV(MOVT, 0):
11633 case COND_FLOAT_MOV(MOVT, 1):
11634 case COND_FLOAT_MOV(MOVT, 2):
11635 case COND_FLOAT_MOV(MOVT, 3):
11636 case COND_FLOAT_MOV(MOVT, 4):
11637 case COND_FLOAT_MOV(MOVT, 5):
11638 case COND_FLOAT_MOV(MOVT, 6):
11639 case COND_FLOAT_MOV(MOVT, 7):
11640 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11641 break;
11642 case COND_FLOAT_MOV(MOVF, 0):
11643 case COND_FLOAT_MOV(MOVF, 1):
11644 case COND_FLOAT_MOV(MOVF, 2):
11645 case COND_FLOAT_MOV(MOVF, 3):
11646 case COND_FLOAT_MOV(MOVF, 4):
11647 case COND_FLOAT_MOV(MOVF, 5):
11648 case COND_FLOAT_MOV(MOVF, 6):
11649 case COND_FLOAT_MOV(MOVF, 7):
11650 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11651 break;
11652 default:
11653 MIPS_INVAL("pool32fxf");
11654 generate_exception(ctx, EXCP_RI);
11655 break;
11656 }
11657}
11658
7db13fae 11659static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 11660 uint16_t insn_hw1)
3c824109
NF
11661{
11662 int32_t offset;
11663 uint16_t insn;
11664 int rt, rs, rd, rr;
11665 int16_t imm;
11666 uint32_t op, minor, mips32_op;
11667 uint32_t cond, fmt, cc;
11668
895c2d04 11669 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11670 ctx->opcode = (ctx->opcode << 16) | insn;
11671
11672 rt = (ctx->opcode >> 21) & 0x1f;
11673 rs = (ctx->opcode >> 16) & 0x1f;
11674 rd = (ctx->opcode >> 11) & 0x1f;
11675 rr = (ctx->opcode >> 6) & 0x1f;
11676 imm = (int16_t) ctx->opcode;
11677
11678 op = (ctx->opcode >> 26) & 0x3f;
11679 switch (op) {
11680 case POOL32A:
11681 minor = ctx->opcode & 0x3f;
11682 switch (minor) {
11683 case 0x00:
11684 minor = (ctx->opcode >> 6) & 0xf;
11685 switch (minor) {
11686 case SLL32:
11687 mips32_op = OPC_SLL;
11688 goto do_shifti;
11689 case SRA:
11690 mips32_op = OPC_SRA;
11691 goto do_shifti;
11692 case SRL32:
11693 mips32_op = OPC_SRL;
11694 goto do_shifti;
11695 case ROTR:
11696 mips32_op = OPC_ROTR;
11697 do_shifti:
d75c135e 11698 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
11699 break;
11700 default:
11701 goto pool32a_invalid;
11702 }
11703 break;
11704 case 0x10:
11705 minor = (ctx->opcode >> 6) & 0xf;
11706 switch (minor) {
11707 /* Arithmetic */
11708 case ADD:
11709 mips32_op = OPC_ADD;
11710 goto do_arith;
11711 case ADDU32:
11712 mips32_op = OPC_ADDU;
11713 goto do_arith;
11714 case SUB:
11715 mips32_op = OPC_SUB;
11716 goto do_arith;
11717 case SUBU32:
11718 mips32_op = OPC_SUBU;
11719 goto do_arith;
11720 case MUL:
11721 mips32_op = OPC_MUL;
11722 do_arith:
d75c135e 11723 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11724 break;
11725 /* Shifts */
11726 case SLLV:
11727 mips32_op = OPC_SLLV;
11728 goto do_shift;
11729 case SRLV:
11730 mips32_op = OPC_SRLV;
11731 goto do_shift;
11732 case SRAV:
11733 mips32_op = OPC_SRAV;
11734 goto do_shift;
11735 case ROTRV:
11736 mips32_op = OPC_ROTRV;
11737 do_shift:
d75c135e 11738 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11739 break;
11740 /* Logical operations */
11741 case AND:
11742 mips32_op = OPC_AND;
11743 goto do_logic;
11744 case OR32:
11745 mips32_op = OPC_OR;
11746 goto do_logic;
11747 case NOR:
11748 mips32_op = OPC_NOR;
11749 goto do_logic;
11750 case XOR32:
11751 mips32_op = OPC_XOR;
11752 do_logic:
d75c135e 11753 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11754 break;
11755 /* Set less than */
11756 case SLT:
11757 mips32_op = OPC_SLT;
11758 goto do_slt;
11759 case SLTU:
11760 mips32_op = OPC_SLTU;
11761 do_slt:
d75c135e 11762 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11763 break;
11764 default:
11765 goto pool32a_invalid;
11766 }
11767 break;
11768 case 0x18:
11769 minor = (ctx->opcode >> 6) & 0xf;
11770 switch (minor) {
11771 /* Conditional moves */
11772 case MOVN:
11773 mips32_op = OPC_MOVN;
11774 goto do_cmov;
11775 case MOVZ:
11776 mips32_op = OPC_MOVZ;
11777 do_cmov:
d75c135e 11778 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11779 break;
11780 case LWXS:
11781 gen_ldxs(ctx, rs, rt, rd);
11782 break;
11783 default:
11784 goto pool32a_invalid;
11785 }
11786 break;
11787 case INS:
11788 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11789 return;
11790 case EXT:
11791 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11792 return;
11793 case POOL32AXF:
240ce26a 11794 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
11795 break;
11796 case 0x07:
11797 generate_exception(ctx, EXCP_BREAK);
11798 break;
11799 default:
11800 pool32a_invalid:
11801 MIPS_INVAL("pool32a");
11802 generate_exception(ctx, EXCP_RI);
11803 break;
11804 }
11805 break;
11806 case POOL32B:
11807 minor = (ctx->opcode >> 12) & 0xf;
11808 switch (minor) {
11809 case CACHE:
2e15497c 11810 check_cp0_enabled(ctx);
3c824109
NF
11811 /* Treat as no-op. */
11812 break;
11813 case LWC2:
11814 case SWC2:
11815 /* COP2: Not implemented. */
11816 generate_exception_err(ctx, EXCP_CpU, 2);
11817 break;
11818 case LWP:
11819 case SWP:
11820#ifdef TARGET_MIPS64
11821 case LDP:
11822 case SDP:
11823#endif
11824 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11825 break;
11826 case LWM32:
11827 case SWM32:
11828#ifdef TARGET_MIPS64
11829 case LDM:
11830 case SDM:
11831#endif
11832 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11833 break;
11834 default:
11835 MIPS_INVAL("pool32b");
11836 generate_exception(ctx, EXCP_RI);
11837 break;
11838 }
11839 break;
11840 case POOL32F:
11841 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11842 minor = ctx->opcode & 0x3f;
11843 check_cp1_enabled(ctx);
11844 switch (minor) {
11845 case ALNV_PS:
11846 mips32_op = OPC_ALNV_PS;
11847 goto do_madd;
11848 case MADD_S:
11849 mips32_op = OPC_MADD_S;
11850 goto do_madd;
11851 case MADD_D:
11852 mips32_op = OPC_MADD_D;
11853 goto do_madd;
11854 case MADD_PS:
11855 mips32_op = OPC_MADD_PS;
11856 goto do_madd;
11857 case MSUB_S:
11858 mips32_op = OPC_MSUB_S;
11859 goto do_madd;
11860 case MSUB_D:
11861 mips32_op = OPC_MSUB_D;
11862 goto do_madd;
11863 case MSUB_PS:
11864 mips32_op = OPC_MSUB_PS;
11865 goto do_madd;
11866 case NMADD_S:
11867 mips32_op = OPC_NMADD_S;
11868 goto do_madd;
11869 case NMADD_D:
11870 mips32_op = OPC_NMADD_D;
11871 goto do_madd;
11872 case NMADD_PS:
11873 mips32_op = OPC_NMADD_PS;
11874 goto do_madd;
11875 case NMSUB_S:
11876 mips32_op = OPC_NMSUB_S;
11877 goto do_madd;
11878 case NMSUB_D:
11879 mips32_op = OPC_NMSUB_D;
11880 goto do_madd;
11881 case NMSUB_PS:
11882 mips32_op = OPC_NMSUB_PS;
11883 do_madd:
11884 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11885 break;
11886 case CABS_COND_FMT:
11887 cond = (ctx->opcode >> 6) & 0xf;
11888 cc = (ctx->opcode >> 13) & 0x7;
11889 fmt = (ctx->opcode >> 10) & 0x3;
11890 switch (fmt) {
11891 case 0x0:
11892 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11893 break;
11894 case 0x1:
11895 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11896 break;
11897 case 0x2:
11898 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11899 break;
11900 default:
11901 goto pool32f_invalid;
11902 }
11903 break;
11904 case C_COND_FMT:
11905 cond = (ctx->opcode >> 6) & 0xf;
11906 cc = (ctx->opcode >> 13) & 0x7;
11907 fmt = (ctx->opcode >> 10) & 0x3;
11908 switch (fmt) {
11909 case 0x0:
11910 gen_cmp_s(ctx, cond, rt, rs, cc);
11911 break;
11912 case 0x1:
11913 gen_cmp_d(ctx, cond, rt, rs, cc);
11914 break;
11915 case 0x2:
11916 gen_cmp_ps(ctx, cond, rt, rs, cc);
11917 break;
11918 default:
11919 goto pool32f_invalid;
11920 }
11921 break;
11922 case POOL32FXF:
d75c135e 11923 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
11924 break;
11925 case 0x00:
11926 /* PLL foo */
11927 switch ((ctx->opcode >> 6) & 0x7) {
11928 case PLL_PS:
11929 mips32_op = OPC_PLL_PS;
11930 goto do_ps;
11931 case PLU_PS:
11932 mips32_op = OPC_PLU_PS;
11933 goto do_ps;
11934 case PUL_PS:
11935 mips32_op = OPC_PUL_PS;
11936 goto do_ps;
11937 case PUU_PS:
11938 mips32_op = OPC_PUU_PS;
11939 goto do_ps;
11940 case CVT_PS_S:
11941 mips32_op = OPC_CVT_PS_S;
11942 do_ps:
11943 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11944 break;
11945 default:
11946 goto pool32f_invalid;
11947 }
11948 break;
11949 case 0x08:
11950 /* [LS][WDU]XC1 */
11951 switch ((ctx->opcode >> 6) & 0x7) {
11952 case LWXC1:
11953 mips32_op = OPC_LWXC1;
11954 goto do_ldst_cp1;
11955 case SWXC1:
11956 mips32_op = OPC_SWXC1;
11957 goto do_ldst_cp1;
11958 case LDXC1:
11959 mips32_op = OPC_LDXC1;
11960 goto do_ldst_cp1;
11961 case SDXC1:
11962 mips32_op = OPC_SDXC1;
11963 goto do_ldst_cp1;
11964 case LUXC1:
11965 mips32_op = OPC_LUXC1;
11966 goto do_ldst_cp1;
11967 case SUXC1:
11968 mips32_op = OPC_SUXC1;
11969 do_ldst_cp1:
11970 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11971 break;
11972 default:
11973 goto pool32f_invalid;
11974 }
11975 break;
11976 case 0x18:
11977 /* 3D insns */
11978 fmt = (ctx->opcode >> 9) & 0x3;
11979 switch ((ctx->opcode >> 6) & 0x7) {
11980 case RSQRT2_FMT:
11981 switch (fmt) {
11982 case FMT_SDPS_S:
11983 mips32_op = OPC_RSQRT2_S;
11984 goto do_3d;
11985 case FMT_SDPS_D:
11986 mips32_op = OPC_RSQRT2_D;
11987 goto do_3d;
11988 case FMT_SDPS_PS:
11989 mips32_op = OPC_RSQRT2_PS;
11990 goto do_3d;
11991 default:
11992 goto pool32f_invalid;
11993 }
11994 break;
11995 case RECIP2_FMT:
11996 switch (fmt) {
11997 case FMT_SDPS_S:
11998 mips32_op = OPC_RECIP2_S;
11999 goto do_3d;
12000 case FMT_SDPS_D:
12001 mips32_op = OPC_RECIP2_D;
12002 goto do_3d;
12003 case FMT_SDPS_PS:
12004 mips32_op = OPC_RECIP2_PS;
12005 goto do_3d;
12006 default:
12007 goto pool32f_invalid;
12008 }
12009 break;
12010 case ADDR_PS:
12011 mips32_op = OPC_ADDR_PS;
12012 goto do_3d;
12013 case MULR_PS:
12014 mips32_op = OPC_MULR_PS;
12015 do_3d:
12016 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12017 break;
12018 default:
12019 goto pool32f_invalid;
12020 }
12021 break;
12022 case 0x20:
12023 /* MOV[FT].fmt and PREFX */
12024 cc = (ctx->opcode >> 13) & 0x7;
12025 fmt = (ctx->opcode >> 9) & 0x3;
12026 switch ((ctx->opcode >> 6) & 0x7) {
12027 case MOVF_FMT:
12028 switch (fmt) {
12029 case FMT_SDPS_S:
12030 gen_movcf_s(rs, rt, cc, 0);
12031 break;
12032 case FMT_SDPS_D:
12033 gen_movcf_d(ctx, rs, rt, cc, 0);
12034 break;
12035 case FMT_SDPS_PS:
7f6613ce 12036 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
12037 break;
12038 default:
12039 goto pool32f_invalid;
12040 }
12041 break;
12042 case MOVT_FMT:
12043 switch (fmt) {
12044 case FMT_SDPS_S:
12045 gen_movcf_s(rs, rt, cc, 1);
12046 break;
12047 case FMT_SDPS_D:
12048 gen_movcf_d(ctx, rs, rt, cc, 1);
12049 break;
12050 case FMT_SDPS_PS:
7f6613ce 12051 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
12052 break;
12053 default:
12054 goto pool32f_invalid;
12055 }
12056 break;
12057 case PREFX:
12058 break;
12059 default:
12060 goto pool32f_invalid;
12061 }
12062 break;
12063#define FINSN_3ARG_SDPS(prfx) \
12064 switch ((ctx->opcode >> 8) & 0x3) { \
12065 case FMT_SDPS_S: \
12066 mips32_op = OPC_##prfx##_S; \
12067 goto do_fpop; \
12068 case FMT_SDPS_D: \
12069 mips32_op = OPC_##prfx##_D; \
12070 goto do_fpop; \
12071 case FMT_SDPS_PS: \
12072 mips32_op = OPC_##prfx##_PS; \
12073 goto do_fpop; \
12074 default: \
12075 goto pool32f_invalid; \
12076 }
12077 case 0x30:
12078 /* regular FP ops */
12079 switch ((ctx->opcode >> 6) & 0x3) {
12080 case ADD_FMT:
12081 FINSN_3ARG_SDPS(ADD);
12082 break;
12083 case SUB_FMT:
12084 FINSN_3ARG_SDPS(SUB);
12085 break;
12086 case MUL_FMT:
12087 FINSN_3ARG_SDPS(MUL);
12088 break;
12089 case DIV_FMT:
12090 fmt = (ctx->opcode >> 8) & 0x3;
12091 if (fmt == 1) {
12092 mips32_op = OPC_DIV_D;
12093 } else if (fmt == 0) {
12094 mips32_op = OPC_DIV_S;
12095 } else {
12096 goto pool32f_invalid;
12097 }
12098 goto do_fpop;
12099 default:
12100 goto pool32f_invalid;
12101 }
12102 break;
12103 case 0x38:
12104 /* cmovs */
12105 switch ((ctx->opcode >> 6) & 0x3) {
12106 case MOVN_FMT:
12107 FINSN_3ARG_SDPS(MOVN);
12108 break;
12109 case MOVZ_FMT:
12110 FINSN_3ARG_SDPS(MOVZ);
12111 break;
12112 default:
12113 goto pool32f_invalid;
12114 }
12115 break;
12116 do_fpop:
12117 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12118 break;
12119 default:
12120 pool32f_invalid:
12121 MIPS_INVAL("pool32f");
12122 generate_exception(ctx, EXCP_RI);
12123 break;
12124 }
12125 } else {
12126 generate_exception_err(ctx, EXCP_CpU, 1);
12127 }
12128 break;
12129 case POOL32I:
12130 minor = (ctx->opcode >> 21) & 0x1f;
12131 switch (minor) {
12132 case BLTZ:
12133 mips32_op = OPC_BLTZ;
12134 goto do_branch;
12135 case BLTZAL:
12136 mips32_op = OPC_BLTZAL;
12137 goto do_branch;
12138 case BLTZALS:
12139 mips32_op = OPC_BLTZALS;
12140 goto do_branch;
12141 case BGEZ:
12142 mips32_op = OPC_BGEZ;
12143 goto do_branch;
12144 case BGEZAL:
12145 mips32_op = OPC_BGEZAL;
12146 goto do_branch;
12147 case BGEZALS:
12148 mips32_op = OPC_BGEZALS;
12149 goto do_branch;
12150 case BLEZ:
12151 mips32_op = OPC_BLEZ;
12152 goto do_branch;
12153 case BGTZ:
12154 mips32_op = OPC_BGTZ;
12155 do_branch:
12156 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
3c824109
NF
12157 break;
12158
12159 /* Traps */
12160 case TLTI:
12161 mips32_op = OPC_TLTI;
12162 goto do_trapi;
12163 case TGEI:
12164 mips32_op = OPC_TGEI;
12165 goto do_trapi;
12166 case TLTIU:
12167 mips32_op = OPC_TLTIU;
12168 goto do_trapi;
12169 case TGEIU:
12170 mips32_op = OPC_TGEIU;
12171 goto do_trapi;
12172 case TNEI:
12173 mips32_op = OPC_TNEI;
12174 goto do_trapi;
12175 case TEQI:
12176 mips32_op = OPC_TEQI;
12177 do_trapi:
12178 gen_trap(ctx, mips32_op, rs, -1, imm);
12179 break;
12180
12181 case BNEZC:
12182 case BEQZC:
12183 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12184 4, rs, 0, imm << 1);
12185 /* Compact branches don't have a delay slot, so just let
12186 the normal delay slot handling take us to the branch
12187 target. */
12188 break;
12189 case LUI:
d75c135e 12190 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12191 break;
12192 case SYNCI:
12193 break;
12194 case BC2F:
12195 case BC2T:
12196 /* COP2: Not implemented. */
12197 generate_exception_err(ctx, EXCP_CpU, 2);
12198 break;
12199 case BC1F:
12200 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12201 goto do_cp1branch;
12202 case BC1T:
12203 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12204 goto do_cp1branch;
12205 case BC1ANY4F:
12206 mips32_op = OPC_BC1FANY4;
12207 goto do_cp1mips3d;
12208 case BC1ANY4T:
12209 mips32_op = OPC_BC1TANY4;
12210 do_cp1mips3d:
12211 check_cop1x(ctx);
d75c135e 12212 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12213 /* Fall through */
12214 do_cp1branch:
d75c135e 12215 gen_compute_branch1(ctx, mips32_op,
3c824109 12216 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
12217 break;
12218 case BPOSGE64:
12219 case BPOSGE32:
12220 /* MIPS DSP: not implemented */
12221 /* Fall through */
12222 default:
12223 MIPS_INVAL("pool32i");
12224 generate_exception(ctx, EXCP_RI);
12225 break;
12226 }
12227 break;
12228 case POOL32C:
12229 minor = (ctx->opcode >> 12) & 0xf;
12230 switch (minor) {
12231 case LWL:
12232 mips32_op = OPC_LWL;
5c13fdfd 12233 goto do_ld_lr;
3c824109
NF
12234 case SWL:
12235 mips32_op = OPC_SWL;
5c13fdfd 12236 goto do_st_lr;
3c824109
NF
12237 case LWR:
12238 mips32_op = OPC_LWR;
5c13fdfd 12239 goto do_ld_lr;
3c824109
NF
12240 case SWR:
12241 mips32_op = OPC_SWR;
5c13fdfd 12242 goto do_st_lr;
3c824109
NF
12243#if defined(TARGET_MIPS64)
12244 case LDL:
12245 mips32_op = OPC_LDL;
5c13fdfd 12246 goto do_ld_lr;
3c824109
NF
12247 case SDL:
12248 mips32_op = OPC_SDL;
5c13fdfd 12249 goto do_st_lr;
3c824109
NF
12250 case LDR:
12251 mips32_op = OPC_LDR;
5c13fdfd 12252 goto do_ld_lr;
3c824109
NF
12253 case SDR:
12254 mips32_op = OPC_SDR;
5c13fdfd 12255 goto do_st_lr;
3c824109
NF
12256 case LWU:
12257 mips32_op = OPC_LWU;
5c13fdfd 12258 goto do_ld_lr;
3c824109
NF
12259 case LLD:
12260 mips32_op = OPC_LLD;
5c13fdfd 12261 goto do_ld_lr;
3c824109
NF
12262#endif
12263 case LL:
12264 mips32_op = OPC_LL;
5c13fdfd
AJ
12265 goto do_ld_lr;
12266 do_ld_lr:
d75c135e 12267 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12268 break;
12269 do_st_lr:
12270 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12271 break;
12272 case SC:
12273 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12274 break;
12275#if defined(TARGET_MIPS64)
12276 case SCD:
12277 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12278 break;
12279#endif
12280 case PREF:
12281 /* Treat as no-op */
12282 break;
12283 default:
12284 MIPS_INVAL("pool32c");
12285 generate_exception(ctx, EXCP_RI);
12286 break;
12287 }
12288 break;
12289 case ADDI32:
12290 mips32_op = OPC_ADDI;
12291 goto do_addi;
12292 case ADDIU32:
12293 mips32_op = OPC_ADDIU;
12294 do_addi:
d75c135e 12295 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12296 break;
12297
12298 /* Logical operations */
12299 case ORI32:
12300 mips32_op = OPC_ORI;
12301 goto do_logici;
12302 case XORI32:
12303 mips32_op = OPC_XORI;
12304 goto do_logici;
12305 case ANDI32:
12306 mips32_op = OPC_ANDI;
12307 do_logici:
d75c135e 12308 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12309 break;
12310
12311 /* Set less than immediate */
12312 case SLTI32:
12313 mips32_op = OPC_SLTI;
12314 goto do_slti;
12315 case SLTIU32:
12316 mips32_op = OPC_SLTIU;
12317 do_slti:
d75c135e 12318 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12319 break;
12320 case JALX32:
12321 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12322 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
3c824109
NF
12323 break;
12324 case JALS32:
12325 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12326 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
3c824109
NF
12327 break;
12328 case BEQ32:
12329 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
3c824109
NF
12330 break;
12331 case BNE32:
12332 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
3c824109
NF
12333 break;
12334 case J32:
12335 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12336 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12337 break;
12338 case JAL32:
12339 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12340 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12341 break;
12342 /* Floating point (COP1) */
12343 case LWC132:
12344 mips32_op = OPC_LWC1;
12345 goto do_cop1;
12346 case LDC132:
12347 mips32_op = OPC_LDC1;
12348 goto do_cop1;
12349 case SWC132:
12350 mips32_op = OPC_SWC1;
12351 goto do_cop1;
12352 case SDC132:
12353 mips32_op = OPC_SDC1;
12354 do_cop1:
12355 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12356 break;
12357 case ADDIUPC:
12358 {
12359 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12360 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12361
12362 gen_addiupc(ctx, reg, offset, 0, 0);
12363 }
12364 break;
12365 /* Loads and stores */
12366 case LB32:
12367 mips32_op = OPC_LB;
5c13fdfd 12368 goto do_ld;
3c824109
NF
12369 case LBU32:
12370 mips32_op = OPC_LBU;
5c13fdfd 12371 goto do_ld;
3c824109
NF
12372 case LH32:
12373 mips32_op = OPC_LH;
5c13fdfd 12374 goto do_ld;
3c824109
NF
12375 case LHU32:
12376 mips32_op = OPC_LHU;
5c13fdfd 12377 goto do_ld;
3c824109
NF
12378 case LW32:
12379 mips32_op = OPC_LW;
5c13fdfd 12380 goto do_ld;
3c824109
NF
12381#ifdef TARGET_MIPS64
12382 case LD32:
12383 mips32_op = OPC_LD;
5c13fdfd 12384 goto do_ld;
3c824109
NF
12385 case SD32:
12386 mips32_op = OPC_SD;
5c13fdfd 12387 goto do_st;
3c824109
NF
12388#endif
12389 case SB32:
12390 mips32_op = OPC_SB;
5c13fdfd 12391 goto do_st;
3c824109
NF
12392 case SH32:
12393 mips32_op = OPC_SH;
5c13fdfd 12394 goto do_st;
3c824109
NF
12395 case SW32:
12396 mips32_op = OPC_SW;
5c13fdfd
AJ
12397 goto do_st;
12398 do_ld:
d75c135e 12399 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12400 break;
12401 do_st:
12402 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12403 break;
12404 default:
12405 generate_exception(ctx, EXCP_RI);
12406 break;
12407 }
12408}
12409
240ce26a 12410static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
12411{
12412 uint32_t op;
12413
12414 /* make sure instructions are on a halfword boundary */
12415 if (ctx->pc & 0x1) {
12416 env->CP0_BadVAddr = ctx->pc;
12417 generate_exception(ctx, EXCP_AdEL);
12418 ctx->bstate = BS_STOP;
12419 return 2;
12420 }
12421
12422 op = (ctx->opcode >> 10) & 0x3f;
12423 /* Enforce properly-sized instructions in a delay slot */
12424 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12425 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12426
12427 switch (op) {
12428 case POOL32A:
12429 case POOL32B:
12430 case POOL32I:
12431 case POOL32C:
12432 case ADDI32:
12433 case ADDIU32:
12434 case ORI32:
12435 case XORI32:
12436 case SLTI32:
12437 case SLTIU32:
12438 case ANDI32:
12439 case JALX32:
12440 case LBU32:
12441 case LHU32:
12442 case POOL32F:
12443 case JALS32:
12444 case BEQ32:
12445 case BNE32:
12446 case J32:
12447 case JAL32:
12448 case SB32:
12449 case SH32:
12450 case POOL32S:
12451 case ADDIUPC:
12452 case SWC132:
12453 case SDC132:
12454 case SD32:
12455 case SW32:
12456 case LB32:
12457 case LH32:
12458 case DADDIU32:
3c824109
NF
12459 case LWC132:
12460 case LDC132:
12461 case LD32:
12462 case LW32:
12463 if (bits & MIPS_HFLAG_BDS16) {
12464 generate_exception(ctx, EXCP_RI);
12465 /* Just stop translation; the user is confused. */
12466 ctx->bstate = BS_STOP;
12467 return 2;
12468 }
12469 break;
12470 case POOL16A:
12471 case POOL16B:
12472 case POOL16C:
12473 case LWGP16:
12474 case POOL16F:
12475 case LBU16:
12476 case LHU16:
12477 case LWSP16:
12478 case LW16:
12479 case SB16:
12480 case SH16:
12481 case SWSP16:
12482 case SW16:
12483 case MOVE16:
12484 case ANDI16:
12485 case POOL16D:
12486 case POOL16E:
12487 case BEQZ16:
12488 case BNEZ16:
12489 case B16:
12490 case LI16:
12491 if (bits & MIPS_HFLAG_BDS32) {
12492 generate_exception(ctx, EXCP_RI);
12493 /* Just stop translation; the user is confused. */
12494 ctx->bstate = BS_STOP;
12495 return 2;
12496 }
12497 break;
12498 default:
12499 break;
12500 }
12501 }
12502 switch (op) {
12503 case POOL16A:
12504 {
12505 int rd = mmreg(uMIPS_RD(ctx->opcode));
12506 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12507 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12508 uint32_t opc = 0;
12509
12510 switch (ctx->opcode & 0x1) {
12511 case ADDU16:
12512 opc = OPC_ADDU;
12513 break;
12514 case SUBU16:
12515 opc = OPC_SUBU;
12516 break;
12517 }
12518
d75c135e 12519 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12520 }
12521 break;
12522 case POOL16B:
12523 {
12524 int rd = mmreg(uMIPS_RD(ctx->opcode));
12525 int rs = mmreg(uMIPS_RS(ctx->opcode));
12526 int amount = (ctx->opcode >> 1) & 0x7;
12527 uint32_t opc = 0;
12528 amount = amount == 0 ? 8 : amount;
12529
12530 switch (ctx->opcode & 0x1) {
12531 case SLL16:
12532 opc = OPC_SLL;
12533 break;
12534 case SRL16:
12535 opc = OPC_SRL;
12536 break;
12537 }
12538
d75c135e 12539 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12540 }
12541 break;
12542 case POOL16C:
240ce26a 12543 gen_pool16c_insn(ctx);
3c824109
NF
12544 break;
12545 case LWGP16:
12546 {
12547 int rd = mmreg(uMIPS_RD(ctx->opcode));
12548 int rb = 28; /* GP */
12549 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12550
d75c135e 12551 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12552 }
12553 break;
12554 case POOL16F:
12555 if (ctx->opcode & 1) {
12556 generate_exception(ctx, EXCP_RI);
12557 } else {
12558 /* MOVEP */
12559 int enc_dest = uMIPS_RD(ctx->opcode);
12560 int enc_rt = uMIPS_RS2(ctx->opcode);
12561 int enc_rs = uMIPS_RS1(ctx->opcode);
12562 int rd, rs, re, rt;
12563 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12564 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12565 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12566
12567 rd = rd_enc[enc_dest];
12568 re = re_enc[enc_dest];
12569 rs = rs_rt_enc[enc_rs];
12570 rt = rs_rt_enc[enc_rt];
12571
d75c135e
AJ
12572 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12573 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12574 }
12575 break;
12576 case LBU16:
12577 {
12578 int rd = mmreg(uMIPS_RD(ctx->opcode));
12579 int rb = mmreg(uMIPS_RS(ctx->opcode));
12580 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12581 offset = (offset == 0xf ? -1 : offset);
12582
d75c135e 12583 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12584 }
12585 break;
12586 case LHU16:
12587 {
12588 int rd = mmreg(uMIPS_RD(ctx->opcode));
12589 int rb = mmreg(uMIPS_RS(ctx->opcode));
12590 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12591
d75c135e 12592 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12593 }
12594 break;
12595 case LWSP16:
12596 {
12597 int rd = (ctx->opcode >> 5) & 0x1f;
12598 int rb = 29; /* SP */
12599 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12600
d75c135e 12601 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12602 }
12603 break;
12604 case LW16:
12605 {
12606 int rd = mmreg(uMIPS_RD(ctx->opcode));
12607 int rb = mmreg(uMIPS_RS(ctx->opcode));
12608 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12609
d75c135e 12610 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12611 }
12612 break;
12613 case SB16:
12614 {
12615 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12616 int rb = mmreg(uMIPS_RS(ctx->opcode));
12617 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12618
5c13fdfd 12619 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12620 }
12621 break;
12622 case SH16:
12623 {
12624 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12625 int rb = mmreg(uMIPS_RS(ctx->opcode));
12626 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12627
5c13fdfd 12628 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12629 }
12630 break;
12631 case SWSP16:
12632 {
12633 int rd = (ctx->opcode >> 5) & 0x1f;
12634 int rb = 29; /* SP */
12635 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12636
5c13fdfd 12637 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12638 }
12639 break;
12640 case SW16:
12641 {
12642 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12643 int rb = mmreg(uMIPS_RS(ctx->opcode));
12644 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12645
5c13fdfd 12646 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12647 }
12648 break;
12649 case MOVE16:
12650 {
12651 int rd = uMIPS_RD5(ctx->opcode);
12652 int rs = uMIPS_RS5(ctx->opcode);
12653
d75c135e 12654 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12655 }
12656 break;
12657 case ANDI16:
d75c135e 12658 gen_andi16(ctx);
3c824109
NF
12659 break;
12660 case POOL16D:
12661 switch (ctx->opcode & 0x1) {
12662 case ADDIUS5:
d75c135e 12663 gen_addius5(ctx);
3c824109
NF
12664 break;
12665 case ADDIUSP:
d75c135e 12666 gen_addiusp(ctx);
3c824109
NF
12667 break;
12668 }
12669 break;
12670 case POOL16E:
12671 switch (ctx->opcode & 0x1) {
12672 case ADDIUR2:
d75c135e 12673 gen_addiur2(ctx);
3c824109
NF
12674 break;
12675 case ADDIUR1SP:
d75c135e 12676 gen_addiur1sp(ctx);
3c824109
NF
12677 break;
12678 }
12679 break;
12680 case B16:
12681 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12682 SIMM(ctx->opcode, 0, 10) << 1);
3c824109
NF
12683 break;
12684 case BNEZ16:
12685 case BEQZ16:
12686 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12687 mmreg(uMIPS_RD(ctx->opcode)),
12688 0, SIMM(ctx->opcode, 0, 7) << 1);
3c824109
NF
12689 break;
12690 case LI16:
12691 {
12692 int reg = mmreg(uMIPS_RD(ctx->opcode));
12693 int imm = ZIMM(ctx->opcode, 0, 7);
12694
12695 imm = (imm == 0x7f ? -1 : imm);
12696 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12697 }
12698 break;
12699 case RES_20:
12700 case RES_28:
12701 case RES_29:
12702 case RES_30:
12703 case RES_31:
12704 case RES_38:
12705 case RES_39:
12706 generate_exception(ctx, EXCP_RI);
12707 break;
12708 default:
240ce26a 12709 decode_micromips32_opc (env, ctx, op);
3c824109
NF
12710 return 4;
12711 }
12712
12713 return 2;
12714}
12715
12716/* SmartMIPS extension to MIPS32 */
12717
12718#if defined(TARGET_MIPS64)
12719
12720/* MDMX extension to MIPS64 */
12721
12722#endif
12723
9b1a1d68 12724/* MIPSDSP functions. */
d75c135e 12725static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12726 int rd, int base, int offset)
12727{
12728 const char *opn = "ldx";
12729 TCGv t0;
12730
9b1a1d68
JL
12731 check_dsp(ctx);
12732 t0 = tcg_temp_new();
12733
12734 if (base == 0) {
12735 gen_load_gpr(t0, offset);
12736 } else if (offset == 0) {
12737 gen_load_gpr(t0, base);
12738 } else {
12739 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12740 }
12741
9b1a1d68
JL
12742 switch (opc) {
12743 case OPC_LBUX:
5f68f5ae 12744 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
12745 gen_store_gpr(t0, rd);
12746 opn = "lbux";
12747 break;
12748 case OPC_LHX:
5f68f5ae 12749 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
12750 gen_store_gpr(t0, rd);
12751 opn = "lhx";
12752 break;
12753 case OPC_LWX:
5f68f5ae 12754 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
12755 gen_store_gpr(t0, rd);
12756 opn = "lwx";
12757 break;
12758#if defined(TARGET_MIPS64)
12759 case OPC_LDX:
5f68f5ae 12760 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
12761 gen_store_gpr(t0, rd);
12762 opn = "ldx";
12763 break;
12764#endif
12765 }
12766 (void)opn; /* avoid a compiler warning */
12767 MIPS_DEBUG("%s %s, %s(%s)", opn,
12768 regnames[rd], regnames[offset], regnames[base]);
12769 tcg_temp_free(t0);
12770}
12771
461c08df
JL
12772static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12773 int ret, int v1, int v2)
12774{
12775 const char *opn = "mipsdsp arith";
12776 TCGv v1_t;
12777 TCGv v2_t;
12778
12779 if (ret == 0) {
12780 /* Treat as NOP. */
12781 MIPS_DEBUG("NOP");
12782 return;
12783 }
12784
12785 v1_t = tcg_temp_new();
12786 v2_t = tcg_temp_new();
12787
12788 gen_load_gpr(v1_t, v1);
12789 gen_load_gpr(v2_t, v2);
12790
12791 switch (op1) {
12792 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12793 case OPC_MULT_G_2E:
12794 check_dspr2(ctx);
12795 switch (op2) {
12796 case OPC_ADDUH_QB:
12797 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12798 break;
12799 case OPC_ADDUH_R_QB:
12800 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12801 break;
12802 case OPC_ADDQH_PH:
12803 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12804 break;
12805 case OPC_ADDQH_R_PH:
12806 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12807 break;
12808 case OPC_ADDQH_W:
12809 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12810 break;
12811 case OPC_ADDQH_R_W:
12812 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12813 break;
12814 case OPC_SUBUH_QB:
12815 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12816 break;
12817 case OPC_SUBUH_R_QB:
12818 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12819 break;
12820 case OPC_SUBQH_PH:
12821 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12822 break;
12823 case OPC_SUBQH_R_PH:
12824 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12825 break;
12826 case OPC_SUBQH_W:
12827 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12828 break;
12829 case OPC_SUBQH_R_W:
12830 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12831 break;
12832 }
12833 break;
12834 case OPC_ABSQ_S_PH_DSP:
12835 switch (op2) {
12836 case OPC_ABSQ_S_QB:
12837 check_dspr2(ctx);
12838 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12839 break;
12840 case OPC_ABSQ_S_PH:
12841 check_dsp(ctx);
12842 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12843 break;
12844 case OPC_ABSQ_S_W:
12845 check_dsp(ctx);
12846 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12847 break;
12848 case OPC_PRECEQ_W_PHL:
12849 check_dsp(ctx);
12850 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12851 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12852 break;
12853 case OPC_PRECEQ_W_PHR:
12854 check_dsp(ctx);
12855 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12856 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12857 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12858 break;
12859 case OPC_PRECEQU_PH_QBL:
12860 check_dsp(ctx);
12861 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12862 break;
12863 case OPC_PRECEQU_PH_QBR:
12864 check_dsp(ctx);
12865 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12866 break;
12867 case OPC_PRECEQU_PH_QBLA:
12868 check_dsp(ctx);
12869 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12870 break;
12871 case OPC_PRECEQU_PH_QBRA:
12872 check_dsp(ctx);
12873 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12874 break;
12875 case OPC_PRECEU_PH_QBL:
12876 check_dsp(ctx);
12877 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12878 break;
12879 case OPC_PRECEU_PH_QBR:
12880 check_dsp(ctx);
12881 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12882 break;
12883 case OPC_PRECEU_PH_QBLA:
12884 check_dsp(ctx);
12885 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12886 break;
12887 case OPC_PRECEU_PH_QBRA:
12888 check_dsp(ctx);
12889 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12890 break;
12891 }
12892 break;
12893 case OPC_ADDU_QB_DSP:
12894 switch (op2) {
12895 case OPC_ADDQ_PH:
12896 check_dsp(ctx);
12897 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12898 break;
12899 case OPC_ADDQ_S_PH:
12900 check_dsp(ctx);
12901 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12902 break;
12903 case OPC_ADDQ_S_W:
12904 check_dsp(ctx);
12905 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12906 break;
12907 case OPC_ADDU_QB:
12908 check_dsp(ctx);
12909 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12910 break;
12911 case OPC_ADDU_S_QB:
12912 check_dsp(ctx);
12913 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12914 break;
12915 case OPC_ADDU_PH:
12916 check_dspr2(ctx);
12917 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12918 break;
12919 case OPC_ADDU_S_PH:
12920 check_dspr2(ctx);
12921 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12922 break;
12923 case OPC_SUBQ_PH:
12924 check_dsp(ctx);
12925 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12926 break;
12927 case OPC_SUBQ_S_PH:
12928 check_dsp(ctx);
12929 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12930 break;
12931 case OPC_SUBQ_S_W:
12932 check_dsp(ctx);
12933 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12934 break;
12935 case OPC_SUBU_QB:
12936 check_dsp(ctx);
12937 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12938 break;
12939 case OPC_SUBU_S_QB:
12940 check_dsp(ctx);
12941 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12942 break;
12943 case OPC_SUBU_PH:
12944 check_dspr2(ctx);
12945 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12946 break;
12947 case OPC_SUBU_S_PH:
12948 check_dspr2(ctx);
12949 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12950 break;
12951 case OPC_ADDSC:
12952 check_dsp(ctx);
12953 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12954 break;
12955 case OPC_ADDWC:
12956 check_dsp(ctx);
12957 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12958 break;
12959 case OPC_MODSUB:
12960 check_dsp(ctx);
12961 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12962 break;
12963 case OPC_RADDU_W_QB:
12964 check_dsp(ctx);
12965 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12966 break;
12967 }
12968 break;
12969 case OPC_CMPU_EQ_QB_DSP:
12970 switch (op2) {
12971 case OPC_PRECR_QB_PH:
12972 check_dspr2(ctx);
12973 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12974 break;
12975 case OPC_PRECRQ_QB_PH:
12976 check_dsp(ctx);
12977 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12978 break;
12979 case OPC_PRECR_SRA_PH_W:
12980 check_dspr2(ctx);
12981 {
12982 TCGv_i32 sa_t = tcg_const_i32(v2);
12983 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12984 cpu_gpr[ret]);
12985 tcg_temp_free_i32(sa_t);
12986 break;
12987 }
12988 case OPC_PRECR_SRA_R_PH_W:
12989 check_dspr2(ctx);
12990 {
12991 TCGv_i32 sa_t = tcg_const_i32(v2);
12992 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12993 cpu_gpr[ret]);
12994 tcg_temp_free_i32(sa_t);
12995 break;
12996 }
12997 case OPC_PRECRQ_PH_W:
12998 check_dsp(ctx);
12999 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
13000 break;
13001 case OPC_PRECRQ_RS_PH_W:
13002 check_dsp(ctx);
13003 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13004 break;
13005 case OPC_PRECRQU_S_QB_PH:
13006 check_dsp(ctx);
13007 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13008 break;
13009 }
13010 break;
13011#ifdef TARGET_MIPS64
13012 case OPC_ABSQ_S_QH_DSP:
13013 switch (op2) {
13014 case OPC_PRECEQ_L_PWL:
13015 check_dsp(ctx);
13016 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
13017 break;
13018 case OPC_PRECEQ_L_PWR:
13019 check_dsp(ctx);
13020 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
13021 break;
13022 case OPC_PRECEQ_PW_QHL:
13023 check_dsp(ctx);
13024 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
13025 break;
13026 case OPC_PRECEQ_PW_QHR:
13027 check_dsp(ctx);
13028 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
13029 break;
13030 case OPC_PRECEQ_PW_QHLA:
13031 check_dsp(ctx);
13032 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
13033 break;
13034 case OPC_PRECEQ_PW_QHRA:
13035 check_dsp(ctx);
13036 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
13037 break;
13038 case OPC_PRECEQU_QH_OBL:
13039 check_dsp(ctx);
13040 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
13041 break;
13042 case OPC_PRECEQU_QH_OBR:
13043 check_dsp(ctx);
13044 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
13045 break;
13046 case OPC_PRECEQU_QH_OBLA:
13047 check_dsp(ctx);
13048 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13049 break;
13050 case OPC_PRECEQU_QH_OBRA:
13051 check_dsp(ctx);
13052 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13053 break;
13054 case OPC_PRECEU_QH_OBL:
13055 check_dsp(ctx);
13056 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13057 break;
13058 case OPC_PRECEU_QH_OBR:
13059 check_dsp(ctx);
13060 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13061 break;
13062 case OPC_PRECEU_QH_OBLA:
13063 check_dsp(ctx);
13064 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13065 break;
13066 case OPC_PRECEU_QH_OBRA:
13067 check_dsp(ctx);
13068 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13069 break;
13070 case OPC_ABSQ_S_OB:
13071 check_dspr2(ctx);
13072 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13073 break;
13074 case OPC_ABSQ_S_PW:
13075 check_dsp(ctx);
13076 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13077 break;
13078 case OPC_ABSQ_S_QH:
13079 check_dsp(ctx);
13080 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13081 break;
13082 }
13083 break;
13084 case OPC_ADDU_OB_DSP:
13085 switch (op2) {
13086 case OPC_RADDU_L_OB:
13087 check_dsp(ctx);
13088 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13089 break;
13090 case OPC_SUBQ_PW:
13091 check_dsp(ctx);
13092 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13093 break;
13094 case OPC_SUBQ_S_PW:
13095 check_dsp(ctx);
13096 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13097 break;
13098 case OPC_SUBQ_QH:
13099 check_dsp(ctx);
13100 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13101 break;
13102 case OPC_SUBQ_S_QH:
13103 check_dsp(ctx);
13104 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13105 break;
13106 case OPC_SUBU_OB:
13107 check_dsp(ctx);
13108 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13109 break;
13110 case OPC_SUBU_S_OB:
13111 check_dsp(ctx);
13112 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13113 break;
13114 case OPC_SUBU_QH:
13115 check_dspr2(ctx);
13116 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13117 break;
13118 case OPC_SUBU_S_QH:
13119 check_dspr2(ctx);
13120 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13121 break;
13122 case OPC_SUBUH_OB:
13123 check_dspr2(ctx);
13124 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13125 break;
13126 case OPC_SUBUH_R_OB:
13127 check_dspr2(ctx);
13128 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13129 break;
13130 case OPC_ADDQ_PW:
13131 check_dsp(ctx);
13132 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13133 break;
13134 case OPC_ADDQ_S_PW:
13135 check_dsp(ctx);
13136 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13137 break;
13138 case OPC_ADDQ_QH:
13139 check_dsp(ctx);
13140 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13141 break;
13142 case OPC_ADDQ_S_QH:
13143 check_dsp(ctx);
13144 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13145 break;
13146 case OPC_ADDU_OB:
13147 check_dsp(ctx);
13148 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13149 break;
13150 case OPC_ADDU_S_OB:
13151 check_dsp(ctx);
13152 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13153 break;
13154 case OPC_ADDU_QH:
13155 check_dspr2(ctx);
13156 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13157 break;
13158 case OPC_ADDU_S_QH:
13159 check_dspr2(ctx);
13160 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13161 break;
13162 case OPC_ADDUH_OB:
13163 check_dspr2(ctx);
13164 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13165 break;
13166 case OPC_ADDUH_R_OB:
13167 check_dspr2(ctx);
13168 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13169 break;
13170 }
13171 break;
13172 case OPC_CMPU_EQ_OB_DSP:
13173 switch (op2) {
13174 case OPC_PRECR_OB_QH:
13175 check_dspr2(ctx);
13176 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13177 break;
13178 case OPC_PRECR_SRA_QH_PW:
13179 check_dspr2(ctx);
13180 {
13181 TCGv_i32 ret_t = tcg_const_i32(ret);
13182 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13183 tcg_temp_free_i32(ret_t);
13184 break;
13185 }
13186 case OPC_PRECR_SRA_R_QH_PW:
13187 check_dspr2(ctx);
13188 {
13189 TCGv_i32 sa_v = tcg_const_i32(ret);
13190 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13191 tcg_temp_free_i32(sa_v);
13192 break;
13193 }
13194 case OPC_PRECRQ_OB_QH:
13195 check_dsp(ctx);
13196 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13197 break;
13198 case OPC_PRECRQ_PW_L:
13199 check_dsp(ctx);
13200 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13201 break;
13202 case OPC_PRECRQ_QH_PW:
13203 check_dsp(ctx);
13204 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13205 break;
13206 case OPC_PRECRQ_RS_QH_PW:
13207 check_dsp(ctx);
13208 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13209 break;
13210 case OPC_PRECRQU_S_OB_QH:
13211 check_dsp(ctx);
13212 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13213 break;
13214 }
13215 break;
13216#endif
13217 }
13218
13219 tcg_temp_free(v1_t);
13220 tcg_temp_free(v2_t);
13221
13222 (void)opn; /* avoid a compiler warning */
13223 MIPS_DEBUG("%s", opn);
13224}
9b1a1d68 13225
77c5fa8b
JL
13226static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13227 int ret, int v1, int v2)
13228{
13229 uint32_t op2;
13230 const char *opn = "mipsdsp shift";
13231 TCGv t0;
13232 TCGv v1_t;
13233 TCGv v2_t;
13234
13235 if (ret == 0) {
13236 /* Treat as NOP. */
13237 MIPS_DEBUG("NOP");
13238 return;
13239 }
13240
13241 t0 = tcg_temp_new();
13242 v1_t = tcg_temp_new();
13243 v2_t = tcg_temp_new();
13244
13245 tcg_gen_movi_tl(t0, v1);
13246 gen_load_gpr(v1_t, v1);
13247 gen_load_gpr(v2_t, v2);
13248
13249 switch (opc) {
13250 case OPC_SHLL_QB_DSP:
13251 {
13252 op2 = MASK_SHLL_QB(ctx->opcode);
13253 switch (op2) {
13254 case OPC_SHLL_QB:
13255 check_dsp(ctx);
13256 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13257 break;
13258 case OPC_SHLLV_QB:
13259 check_dsp(ctx);
13260 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13261 break;
13262 case OPC_SHLL_PH:
13263 check_dsp(ctx);
13264 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13265 break;
13266 case OPC_SHLLV_PH:
13267 check_dsp(ctx);
13268 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13269 break;
13270 case OPC_SHLL_S_PH:
13271 check_dsp(ctx);
13272 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13273 break;
13274 case OPC_SHLLV_S_PH:
13275 check_dsp(ctx);
13276 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13277 break;
13278 case OPC_SHLL_S_W:
13279 check_dsp(ctx);
13280 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13281 break;
13282 case OPC_SHLLV_S_W:
13283 check_dsp(ctx);
13284 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13285 break;
13286 case OPC_SHRL_QB:
13287 check_dsp(ctx);
13288 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13289 break;
13290 case OPC_SHRLV_QB:
13291 check_dsp(ctx);
13292 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13293 break;
13294 case OPC_SHRL_PH:
13295 check_dspr2(ctx);
13296 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13297 break;
13298 case OPC_SHRLV_PH:
13299 check_dspr2(ctx);
13300 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13301 break;
13302 case OPC_SHRA_QB:
13303 check_dspr2(ctx);
13304 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13305 break;
13306 case OPC_SHRA_R_QB:
13307 check_dspr2(ctx);
13308 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13309 break;
13310 case OPC_SHRAV_QB:
13311 check_dspr2(ctx);
13312 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13313 break;
13314 case OPC_SHRAV_R_QB:
13315 check_dspr2(ctx);
13316 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13317 break;
13318 case OPC_SHRA_PH:
13319 check_dsp(ctx);
13320 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13321 break;
13322 case OPC_SHRA_R_PH:
13323 check_dsp(ctx);
13324 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13325 break;
13326 case OPC_SHRAV_PH:
13327 check_dsp(ctx);
13328 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13329 break;
13330 case OPC_SHRAV_R_PH:
13331 check_dsp(ctx);
13332 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13333 break;
13334 case OPC_SHRA_R_W:
13335 check_dsp(ctx);
13336 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13337 break;
13338 case OPC_SHRAV_R_W:
13339 check_dsp(ctx);
13340 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13341 break;
13342 default: /* Invalid */
13343 MIPS_INVAL("MASK SHLL.QB");
13344 generate_exception(ctx, EXCP_RI);
13345 break;
13346 }
13347 break;
13348 }
13349#ifdef TARGET_MIPS64
13350 case OPC_SHLL_OB_DSP:
13351 op2 = MASK_SHLL_OB(ctx->opcode);
13352 switch (op2) {
13353 case OPC_SHLL_PW:
13354 check_dsp(ctx);
13355 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13356 break;
13357 case OPC_SHLLV_PW:
13358 check_dsp(ctx);
13359 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13360 break;
13361 case OPC_SHLL_S_PW:
13362 check_dsp(ctx);
13363 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13364 break;
13365 case OPC_SHLLV_S_PW:
13366 check_dsp(ctx);
13367 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13368 break;
13369 case OPC_SHLL_OB:
13370 check_dsp(ctx);
13371 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13372 break;
13373 case OPC_SHLLV_OB:
13374 check_dsp(ctx);
13375 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13376 break;
13377 case OPC_SHLL_QH:
13378 check_dsp(ctx);
13379 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13380 break;
13381 case OPC_SHLLV_QH:
13382 check_dsp(ctx);
13383 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13384 break;
13385 case OPC_SHLL_S_QH:
13386 check_dsp(ctx);
13387 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13388 break;
13389 case OPC_SHLLV_S_QH:
13390 check_dsp(ctx);
13391 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13392 break;
13393 case OPC_SHRA_OB:
13394 check_dspr2(ctx);
13395 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13396 break;
13397 case OPC_SHRAV_OB:
13398 check_dspr2(ctx);
13399 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13400 break;
13401 case OPC_SHRA_R_OB:
13402 check_dspr2(ctx);
13403 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13404 break;
13405 case OPC_SHRAV_R_OB:
13406 check_dspr2(ctx);
13407 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13408 break;
13409 case OPC_SHRA_PW:
13410 check_dsp(ctx);
13411 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13412 break;
13413 case OPC_SHRAV_PW:
13414 check_dsp(ctx);
13415 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13416 break;
13417 case OPC_SHRA_R_PW:
13418 check_dsp(ctx);
13419 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13420 break;
13421 case OPC_SHRAV_R_PW:
13422 check_dsp(ctx);
13423 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13424 break;
13425 case OPC_SHRA_QH:
13426 check_dsp(ctx);
13427 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13428 break;
13429 case OPC_SHRAV_QH:
13430 check_dsp(ctx);
13431 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13432 break;
13433 case OPC_SHRA_R_QH:
13434 check_dsp(ctx);
13435 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13436 break;
13437 case OPC_SHRAV_R_QH:
13438 check_dsp(ctx);
13439 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13440 break;
13441 case OPC_SHRL_OB:
13442 check_dsp(ctx);
13443 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13444 break;
13445 case OPC_SHRLV_OB:
13446 check_dsp(ctx);
13447 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13448 break;
13449 case OPC_SHRL_QH:
13450 check_dspr2(ctx);
13451 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13452 break;
13453 case OPC_SHRLV_QH:
13454 check_dspr2(ctx);
13455 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13456 break;
13457 default: /* Invalid */
13458 MIPS_INVAL("MASK SHLL.OB");
13459 generate_exception(ctx, EXCP_RI);
13460 break;
13461 }
13462 break;
13463#endif
13464 }
13465
13466 tcg_temp_free(t0);
13467 tcg_temp_free(v1_t);
13468 tcg_temp_free(v2_t);
13469 (void)opn; /* avoid a compiler warning */
13470 MIPS_DEBUG("%s", opn);
13471}
13472
a22260ae
JL
13473static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13474 int ret, int v1, int v2, int check_ret)
13475{
13476 const char *opn = "mipsdsp multiply";
13477 TCGv_i32 t0;
13478 TCGv v1_t;
13479 TCGv v2_t;
13480
13481 if ((ret == 0) && (check_ret == 1)) {
13482 /* Treat as NOP. */
13483 MIPS_DEBUG("NOP");
13484 return;
13485 }
13486
13487 t0 = tcg_temp_new_i32();
13488 v1_t = tcg_temp_new();
13489 v2_t = tcg_temp_new();
13490
13491 tcg_gen_movi_i32(t0, ret);
13492 gen_load_gpr(v1_t, v1);
13493 gen_load_gpr(v2_t, v2);
13494
13495 switch (op1) {
13496 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13497 * the same mask and op1. */
13498 case OPC_MULT_G_2E:
639eadb9 13499 check_dspr2(ctx);
a22260ae
JL
13500 switch (op2) {
13501 case OPC_MUL_PH:
13502 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13503 break;
13504 case OPC_MUL_S_PH:
13505 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13506 break;
13507 case OPC_MULQ_S_W:
13508 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13509 break;
13510 case OPC_MULQ_RS_W:
13511 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13512 break;
13513 }
13514 break;
13515 case OPC_DPA_W_PH_DSP:
13516 switch (op2) {
13517 case OPC_DPAU_H_QBL:
13518 check_dsp(ctx);
13519 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13520 break;
13521 case OPC_DPAU_H_QBR:
13522 check_dsp(ctx);
13523 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13524 break;
13525 case OPC_DPSU_H_QBL:
13526 check_dsp(ctx);
13527 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13528 break;
13529 case OPC_DPSU_H_QBR:
13530 check_dsp(ctx);
13531 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13532 break;
13533 case OPC_DPA_W_PH:
13534 check_dspr2(ctx);
13535 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13536 break;
13537 case OPC_DPAX_W_PH:
13538 check_dspr2(ctx);
13539 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13540 break;
13541 case OPC_DPAQ_S_W_PH:
13542 check_dsp(ctx);
13543 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13544 break;
13545 case OPC_DPAQX_S_W_PH:
13546 check_dspr2(ctx);
13547 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13548 break;
13549 case OPC_DPAQX_SA_W_PH:
13550 check_dspr2(ctx);
13551 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13552 break;
13553 case OPC_DPS_W_PH:
13554 check_dspr2(ctx);
13555 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13556 break;
13557 case OPC_DPSX_W_PH:
13558 check_dspr2(ctx);
13559 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13560 break;
13561 case OPC_DPSQ_S_W_PH:
13562 check_dsp(ctx);
13563 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13564 break;
13565 case OPC_DPSQX_S_W_PH:
13566 check_dspr2(ctx);
13567 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13568 break;
13569 case OPC_DPSQX_SA_W_PH:
13570 check_dspr2(ctx);
13571 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13572 break;
13573 case OPC_MULSAQ_S_W_PH:
13574 check_dsp(ctx);
13575 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13576 break;
13577 case OPC_DPAQ_SA_L_W:
13578 check_dsp(ctx);
13579 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13580 break;
13581 case OPC_DPSQ_SA_L_W:
13582 check_dsp(ctx);
13583 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13584 break;
13585 case OPC_MAQ_S_W_PHL:
13586 check_dsp(ctx);
13587 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13588 break;
13589 case OPC_MAQ_S_W_PHR:
13590 check_dsp(ctx);
13591 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13592 break;
13593 case OPC_MAQ_SA_W_PHL:
13594 check_dsp(ctx);
13595 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13596 break;
13597 case OPC_MAQ_SA_W_PHR:
13598 check_dsp(ctx);
13599 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13600 break;
13601 case OPC_MULSA_W_PH:
13602 check_dspr2(ctx);
13603 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13604 break;
13605 }
13606 break;
13607#ifdef TARGET_MIPS64
13608 case OPC_DPAQ_W_QH_DSP:
13609 {
13610 int ac = ret & 0x03;
13611 tcg_gen_movi_i32(t0, ac);
13612
13613 switch (op2) {
13614 case OPC_DMADD:
13615 check_dsp(ctx);
13616 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13617 break;
13618 case OPC_DMADDU:
13619 check_dsp(ctx);
13620 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13621 break;
13622 case OPC_DMSUB:
13623 check_dsp(ctx);
13624 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13625 break;
13626 case OPC_DMSUBU:
13627 check_dsp(ctx);
13628 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13629 break;
13630 case OPC_DPA_W_QH:
13631 check_dspr2(ctx);
13632 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13633 break;
13634 case OPC_DPAQ_S_W_QH:
13635 check_dsp(ctx);
13636 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13637 break;
13638 case OPC_DPAQ_SA_L_PW:
13639 check_dsp(ctx);
13640 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13641 break;
13642 case OPC_DPAU_H_OBL:
13643 check_dsp(ctx);
13644 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13645 break;
13646 case OPC_DPAU_H_OBR:
13647 check_dsp(ctx);
13648 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13649 break;
13650 case OPC_DPS_W_QH:
13651 check_dspr2(ctx);
13652 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13653 break;
13654 case OPC_DPSQ_S_W_QH:
13655 check_dsp(ctx);
13656 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13657 break;
13658 case OPC_DPSQ_SA_L_PW:
13659 check_dsp(ctx);
13660 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13661 break;
13662 case OPC_DPSU_H_OBL:
13663 check_dsp(ctx);
13664 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13665 break;
13666 case OPC_DPSU_H_OBR:
13667 check_dsp(ctx);
13668 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13669 break;
13670 case OPC_MAQ_S_L_PWL:
13671 check_dsp(ctx);
13672 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13673 break;
13674 case OPC_MAQ_S_L_PWR:
13675 check_dsp(ctx);
13676 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13677 break;
13678 case OPC_MAQ_S_W_QHLL:
13679 check_dsp(ctx);
13680 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13681 break;
13682 case OPC_MAQ_SA_W_QHLL:
13683 check_dsp(ctx);
13684 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13685 break;
13686 case OPC_MAQ_S_W_QHLR:
13687 check_dsp(ctx);
13688 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13689 break;
13690 case OPC_MAQ_SA_W_QHLR:
13691 check_dsp(ctx);
13692 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13693 break;
13694 case OPC_MAQ_S_W_QHRL:
13695 check_dsp(ctx);
13696 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13697 break;
13698 case OPC_MAQ_SA_W_QHRL:
13699 check_dsp(ctx);
13700 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13701 break;
13702 case OPC_MAQ_S_W_QHRR:
13703 check_dsp(ctx);
13704 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13705 break;
13706 case OPC_MAQ_SA_W_QHRR:
13707 check_dsp(ctx);
13708 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13709 break;
13710 case OPC_MULSAQ_S_L_PW:
13711 check_dsp(ctx);
13712 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13713 break;
13714 case OPC_MULSAQ_S_W_QH:
13715 check_dsp(ctx);
13716 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13717 break;
13718 }
13719 }
13720 break;
13721#endif
13722 case OPC_ADDU_QB_DSP:
13723 switch (op2) {
13724 case OPC_MULEU_S_PH_QBL:
13725 check_dsp(ctx);
13726 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13727 break;
13728 case OPC_MULEU_S_PH_QBR:
13729 check_dsp(ctx);
13730 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13731 break;
13732 case OPC_MULQ_RS_PH:
13733 check_dsp(ctx);
13734 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13735 break;
13736 case OPC_MULEQ_S_W_PHL:
13737 check_dsp(ctx);
13738 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13739 break;
13740 case OPC_MULEQ_S_W_PHR:
13741 check_dsp(ctx);
13742 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13743 break;
13744 case OPC_MULQ_S_PH:
13745 check_dspr2(ctx);
13746 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13747 break;
13748 }
13749 break;
13750#ifdef TARGET_MIPS64
13751 case OPC_ADDU_OB_DSP:
13752 switch (op2) {
13753 case OPC_MULEQ_S_PW_QHL:
13754 check_dsp(ctx);
13755 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13756 break;
13757 case OPC_MULEQ_S_PW_QHR:
13758 check_dsp(ctx);
13759 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13760 break;
13761 case OPC_MULEU_S_QH_OBL:
13762 check_dsp(ctx);
13763 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13764 break;
13765 case OPC_MULEU_S_QH_OBR:
13766 check_dsp(ctx);
13767 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13768 break;
13769 case OPC_MULQ_RS_QH:
13770 check_dsp(ctx);
13771 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13772 break;
13773 }
13774 break;
13775#endif
13776 }
13777
13778 tcg_temp_free_i32(t0);
13779 tcg_temp_free(v1_t);
13780 tcg_temp_free(v2_t);
13781
13782 (void)opn; /* avoid a compiler warning */
13783 MIPS_DEBUG("%s", opn);
13784
13785}
13786
d75c135e 13787static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13788 int ret, int val)
13789{
13790 const char *opn = "mipsdsp Bit/ Manipulation";
13791 int16_t imm;
13792 TCGv t0;
13793 TCGv val_t;
13794
13795 if (ret == 0) {
13796 /* Treat as NOP. */
13797 MIPS_DEBUG("NOP");
13798 return;
13799 }
13800
13801 t0 = tcg_temp_new();
13802 val_t = tcg_temp_new();
13803 gen_load_gpr(val_t, val);
13804
13805 switch (op1) {
13806 case OPC_ABSQ_S_PH_DSP:
13807 switch (op2) {
13808 case OPC_BITREV:
13809 check_dsp(ctx);
13810 gen_helper_bitrev(cpu_gpr[ret], val_t);
13811 break;
13812 case OPC_REPL_QB:
13813 check_dsp(ctx);
13814 {
13815 target_long result;
13816 imm = (ctx->opcode >> 16) & 0xFF;
13817 result = (uint32_t)imm << 24 |
13818 (uint32_t)imm << 16 |
13819 (uint32_t)imm << 8 |
13820 (uint32_t)imm;
13821 result = (int32_t)result;
13822 tcg_gen_movi_tl(cpu_gpr[ret], result);
13823 }
13824 break;
13825 case OPC_REPLV_QB:
13826 check_dsp(ctx);
13827 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13828 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13829 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13830 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13831 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13832 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13833 break;
13834 case OPC_REPL_PH:
13835 check_dsp(ctx);
13836 {
13837 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13838 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13839 tcg_gen_movi_tl(cpu_gpr[ret], \
13840 (target_long)((int32_t)imm << 16 | \
c4aaba92 13841 (uint16_t)imm));
1cb6686c
JL
13842 }
13843 break;
13844 case OPC_REPLV_PH:
13845 check_dsp(ctx);
13846 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13847 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13848 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13849 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13850 break;
13851 }
13852 break;
13853#ifdef TARGET_MIPS64
13854 case OPC_ABSQ_S_QH_DSP:
13855 switch (op2) {
13856 case OPC_REPL_OB:
13857 check_dsp(ctx);
13858 {
13859 target_long temp;
13860
13861 imm = (ctx->opcode >> 16) & 0xFF;
13862 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13863 temp = (temp << 16) | temp;
13864 temp = (temp << 32) | temp;
13865 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13866 break;
13867 }
13868 case OPC_REPL_PW:
13869 check_dsp(ctx);
13870 {
13871 target_long temp;
13872
13873 imm = (ctx->opcode >> 16) & 0x03FF;
13874 imm = (int16_t)(imm << 6) >> 6;
13875 temp = ((target_long)imm << 32) \
13876 | ((target_long)imm & 0xFFFFFFFF);
13877 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13878 break;
13879 }
13880 case OPC_REPL_QH:
13881 check_dsp(ctx);
13882 {
13883 target_long temp;
13884
13885 imm = (ctx->opcode >> 16) & 0x03FF;
13886 imm = (int16_t)(imm << 6) >> 6;
13887
13888 temp = ((uint64_t)(uint16_t)imm << 48) |
13889 ((uint64_t)(uint16_t)imm << 32) |
13890 ((uint64_t)(uint16_t)imm << 16) |
13891 (uint64_t)(uint16_t)imm;
13892 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13893 break;
13894 }
13895 case OPC_REPLV_OB:
13896 check_dsp(ctx);
13897 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13898 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13899 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13900 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13901 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13902 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13903 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13904 break;
13905 case OPC_REPLV_PW:
13906 check_dsp(ctx);
13907 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13908 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13909 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13910 break;
13911 case OPC_REPLV_QH:
13912 check_dsp(ctx);
13913 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13914 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13915 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13916 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13917 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13918 break;
13919 }
13920 break;
13921#endif
13922 }
13923 tcg_temp_free(t0);
13924 tcg_temp_free(val_t);
13925
13926 (void)opn; /* avoid a compiler warning */
13927 MIPS_DEBUG("%s", opn);
13928}
13929
26690560
JL
13930static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13931 uint32_t op1, uint32_t op2,
13932 int ret, int v1, int v2, int check_ret)
13933{
13934 const char *opn = "mipsdsp add compare pick";
26690560
JL
13935 TCGv t1;
13936 TCGv v1_t;
13937 TCGv v2_t;
13938
13939 if ((ret == 0) && (check_ret == 1)) {
13940 /* Treat as NOP. */
13941 MIPS_DEBUG("NOP");
13942 return;
13943 }
13944
26690560
JL
13945 t1 = tcg_temp_new();
13946 v1_t = tcg_temp_new();
13947 v2_t = tcg_temp_new();
13948
13949 gen_load_gpr(v1_t, v1);
13950 gen_load_gpr(v2_t, v2);
13951
13952 switch (op1) {
26690560
JL
13953 case OPC_CMPU_EQ_QB_DSP:
13954 switch (op2) {
13955 case OPC_CMPU_EQ_QB:
13956 check_dsp(ctx);
13957 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13958 break;
13959 case OPC_CMPU_LT_QB:
13960 check_dsp(ctx);
13961 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13962 break;
13963 case OPC_CMPU_LE_QB:
13964 check_dsp(ctx);
13965 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13966 break;
13967 case OPC_CMPGU_EQ_QB:
13968 check_dsp(ctx);
13969 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13970 break;
13971 case OPC_CMPGU_LT_QB:
13972 check_dsp(ctx);
13973 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13974 break;
13975 case OPC_CMPGU_LE_QB:
13976 check_dsp(ctx);
13977 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13978 break;
13979 case OPC_CMPGDU_EQ_QB:
13980 check_dspr2(ctx);
13981 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13982 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13983 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13984 tcg_gen_shli_tl(t1, t1, 24);
13985 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13986 break;
13987 case OPC_CMPGDU_LT_QB:
13988 check_dspr2(ctx);
13989 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13990 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13991 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13992 tcg_gen_shli_tl(t1, t1, 24);
13993 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13994 break;
13995 case OPC_CMPGDU_LE_QB:
13996 check_dspr2(ctx);
13997 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13998 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13999 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14000 tcg_gen_shli_tl(t1, t1, 24);
14001 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14002 break;
14003 case OPC_CMP_EQ_PH:
14004 check_dsp(ctx);
14005 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
14006 break;
14007 case OPC_CMP_LT_PH:
14008 check_dsp(ctx);
14009 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
14010 break;
14011 case OPC_CMP_LE_PH:
14012 check_dsp(ctx);
14013 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
14014 break;
14015 case OPC_PICK_QB:
14016 check_dsp(ctx);
14017 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14018 break;
14019 case OPC_PICK_PH:
14020 check_dsp(ctx);
14021 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14022 break;
14023 case OPC_PACKRL_PH:
14024 check_dsp(ctx);
14025 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
14026 break;
14027 }
14028 break;
14029#ifdef TARGET_MIPS64
14030 case OPC_CMPU_EQ_OB_DSP:
14031 switch (op2) {
14032 case OPC_CMP_EQ_PW:
14033 check_dsp(ctx);
14034 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
14035 break;
14036 case OPC_CMP_LT_PW:
14037 check_dsp(ctx);
14038 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14039 break;
14040 case OPC_CMP_LE_PW:
14041 check_dsp(ctx);
14042 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14043 break;
14044 case OPC_CMP_EQ_QH:
14045 check_dsp(ctx);
14046 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14047 break;
14048 case OPC_CMP_LT_QH:
14049 check_dsp(ctx);
14050 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14051 break;
14052 case OPC_CMP_LE_QH:
14053 check_dsp(ctx);
14054 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14055 break;
14056 case OPC_CMPGDU_EQ_OB:
14057 check_dspr2(ctx);
14058 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14059 break;
14060 case OPC_CMPGDU_LT_OB:
14061 check_dspr2(ctx);
14062 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14063 break;
14064 case OPC_CMPGDU_LE_OB:
14065 check_dspr2(ctx);
14066 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14067 break;
14068 case OPC_CMPGU_EQ_OB:
14069 check_dsp(ctx);
14070 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14071 break;
14072 case OPC_CMPGU_LT_OB:
14073 check_dsp(ctx);
14074 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14075 break;
14076 case OPC_CMPGU_LE_OB:
14077 check_dsp(ctx);
14078 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14079 break;
14080 case OPC_CMPU_EQ_OB:
14081 check_dsp(ctx);
14082 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14083 break;
14084 case OPC_CMPU_LT_OB:
14085 check_dsp(ctx);
14086 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14087 break;
14088 case OPC_CMPU_LE_OB:
14089 check_dsp(ctx);
14090 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14091 break;
14092 case OPC_PACKRL_PW:
14093 check_dsp(ctx);
14094 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14095 break;
14096 case OPC_PICK_OB:
14097 check_dsp(ctx);
14098 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14099 break;
14100 case OPC_PICK_PW:
14101 check_dsp(ctx);
14102 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14103 break;
14104 case OPC_PICK_QH:
14105 check_dsp(ctx);
14106 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14107 break;
14108 }
14109 break;
df6126a7
AJ
14110#endif
14111 }
14112
14113 tcg_temp_free(t1);
14114 tcg_temp_free(v1_t);
14115 tcg_temp_free(v2_t);
14116
14117 (void)opn; /* avoid a compiler warning */
14118 MIPS_DEBUG("%s", opn);
14119}
14120
14121static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14122 uint32_t op1, int rt, int rs, int sa)
14123{
14124 const char *opn = "mipsdsp append/dappend";
14125 TCGv t0;
14126
14127 check_dspr2(ctx);
14128
14129 if (rt == 0) {
14130 /* Treat as NOP. */
14131 MIPS_DEBUG("NOP");
14132 return;
14133 }
14134
14135 t0 = tcg_temp_new();
14136 gen_load_gpr(t0, rs);
14137
14138 switch (op1) {
14139 case OPC_APPEND_DSP:
14140 switch (MASK_APPEND(ctx->opcode)) {
14141 case OPC_APPEND:
14142 if (sa != 0) {
14143 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14144 }
14145 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14146 break;
14147 case OPC_PREPEND:
14148 if (sa != 0) {
14149 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14150 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14151 tcg_gen_shli_tl(t0, t0, 32 - sa);
14152 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14153 }
14154 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14155 break;
14156 case OPC_BALIGN:
14157 sa &= 3;
14158 if (sa != 0 && sa != 2) {
14159 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14160 tcg_gen_ext32u_tl(t0, t0);
14161 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14162 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14163 }
14164 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14165 break;
14166 default: /* Invalid */
14167 MIPS_INVAL("MASK APPEND");
14168 generate_exception(ctx, EXCP_RI);
14169 break;
14170 }
14171 break;
14172#ifdef TARGET_MIPS64
26690560 14173 case OPC_DAPPEND_DSP:
df6126a7 14174 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14175 case OPC_DAPPEND:
df6126a7
AJ
14176 if (sa != 0) {
14177 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14178 }
26690560
JL
14179 break;
14180 case OPC_PREPENDD:
df6126a7
AJ
14181 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14182 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14183 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14184 break;
14185 case OPC_PREPENDW:
df6126a7
AJ
14186 if (sa != 0) {
14187 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14188 tcg_gen_shli_tl(t0, t0, 64 - sa);
14189 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14190 }
26690560
JL
14191 break;
14192 case OPC_DBALIGN:
df6126a7
AJ
14193 sa &= 7;
14194 if (sa != 0 && sa != 2 && sa != 4) {
14195 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14196 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14197 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14198 }
26690560
JL
14199 break;
14200 default: /* Invalid */
14201 MIPS_INVAL("MASK DAPPEND");
14202 generate_exception(ctx, EXCP_RI);
14203 break;
14204 }
14205 break;
14206#endif
14207 }
df6126a7 14208 tcg_temp_free(t0);
26690560
JL
14209 (void)opn; /* avoid a compiler warning */
14210 MIPS_DEBUG("%s", opn);
14211}
14212
b53371ed
JL
14213static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14214 int ret, int v1, int v2, int check_ret)
14215
14216{
14217 const char *opn = "mipsdsp accumulator";
14218 TCGv t0;
14219 TCGv t1;
14220 TCGv v1_t;
14221 TCGv v2_t;
14222 int16_t imm;
14223
14224 if ((ret == 0) && (check_ret == 1)) {
14225 /* Treat as NOP. */
14226 MIPS_DEBUG("NOP");
14227 return;
14228 }
14229
14230 t0 = tcg_temp_new();
14231 t1 = tcg_temp_new();
14232 v1_t = tcg_temp_new();
14233 v2_t = tcg_temp_new();
14234
14235 gen_load_gpr(v1_t, v1);
14236 gen_load_gpr(v2_t, v2);
14237
14238 switch (op1) {
14239 case OPC_EXTR_W_DSP:
14240 check_dsp(ctx);
14241 switch (op2) {
14242 case OPC_EXTR_W:
14243 tcg_gen_movi_tl(t0, v2);
14244 tcg_gen_movi_tl(t1, v1);
14245 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14246 break;
14247 case OPC_EXTR_R_W:
14248 tcg_gen_movi_tl(t0, v2);
14249 tcg_gen_movi_tl(t1, v1);
14250 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14251 break;
14252 case OPC_EXTR_RS_W:
14253 tcg_gen_movi_tl(t0, v2);
14254 tcg_gen_movi_tl(t1, v1);
14255 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14256 break;
14257 case OPC_EXTR_S_H:
14258 tcg_gen_movi_tl(t0, v2);
14259 tcg_gen_movi_tl(t1, v1);
14260 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14261 break;
14262 case OPC_EXTRV_S_H:
14263 tcg_gen_movi_tl(t0, v2);
14264 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14265 break;
14266 case OPC_EXTRV_W:
14267 tcg_gen_movi_tl(t0, v2);
14268 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14269 break;
14270 case OPC_EXTRV_R_W:
14271 tcg_gen_movi_tl(t0, v2);
14272 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14273 break;
14274 case OPC_EXTRV_RS_W:
14275 tcg_gen_movi_tl(t0, v2);
14276 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14277 break;
14278 case OPC_EXTP:
14279 tcg_gen_movi_tl(t0, v2);
14280 tcg_gen_movi_tl(t1, v1);
14281 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14282 break;
14283 case OPC_EXTPV:
14284 tcg_gen_movi_tl(t0, v2);
14285 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14286 break;
14287 case OPC_EXTPDP:
14288 tcg_gen_movi_tl(t0, v2);
14289 tcg_gen_movi_tl(t1, v1);
14290 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14291 break;
14292 case OPC_EXTPDPV:
14293 tcg_gen_movi_tl(t0, v2);
14294 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14295 break;
14296 case OPC_SHILO:
14297 imm = (ctx->opcode >> 20) & 0x3F;
14298 tcg_gen_movi_tl(t0, ret);
14299 tcg_gen_movi_tl(t1, imm);
14300 gen_helper_shilo(t0, t1, cpu_env);
14301 break;
14302 case OPC_SHILOV:
14303 tcg_gen_movi_tl(t0, ret);
14304 gen_helper_shilo(t0, v1_t, cpu_env);
14305 break;
14306 case OPC_MTHLIP:
14307 tcg_gen_movi_tl(t0, ret);
14308 gen_helper_mthlip(t0, v1_t, cpu_env);
14309 break;
14310 case OPC_WRDSP:
14311 imm = (ctx->opcode >> 11) & 0x3FF;
14312 tcg_gen_movi_tl(t0, imm);
14313 gen_helper_wrdsp(v1_t, t0, cpu_env);
14314 break;
14315 case OPC_RDDSP:
14316 imm = (ctx->opcode >> 16) & 0x03FF;
14317 tcg_gen_movi_tl(t0, imm);
14318 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14319 break;
14320 }
14321 break;
14322#ifdef TARGET_MIPS64
14323 case OPC_DEXTR_W_DSP:
14324 check_dsp(ctx);
14325 switch (op2) {
14326 case OPC_DMTHLIP:
14327 tcg_gen_movi_tl(t0, ret);
14328 gen_helper_dmthlip(v1_t, t0, cpu_env);
14329 break;
14330 case OPC_DSHILO:
14331 {
14332 int shift = (ctx->opcode >> 19) & 0x7F;
14333 int ac = (ctx->opcode >> 11) & 0x03;
14334 tcg_gen_movi_tl(t0, shift);
14335 tcg_gen_movi_tl(t1, ac);
14336 gen_helper_dshilo(t0, t1, cpu_env);
14337 break;
14338 }
14339 case OPC_DSHILOV:
14340 {
14341 int ac = (ctx->opcode >> 11) & 0x03;
14342 tcg_gen_movi_tl(t0, ac);
14343 gen_helper_dshilo(v1_t, t0, cpu_env);
14344 break;
14345 }
14346 case OPC_DEXTP:
14347 tcg_gen_movi_tl(t0, v2);
14348 tcg_gen_movi_tl(t1, v1);
14349
14350 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14351 break;
14352 case OPC_DEXTPV:
14353 tcg_gen_movi_tl(t0, v2);
14354 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14355 break;
14356 case OPC_DEXTPDP:
14357 tcg_gen_movi_tl(t0, v2);
14358 tcg_gen_movi_tl(t1, v1);
14359 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14360 break;
14361 case OPC_DEXTPDPV:
14362 tcg_gen_movi_tl(t0, v2);
14363 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14364 break;
14365 case OPC_DEXTR_L:
14366 tcg_gen_movi_tl(t0, v2);
14367 tcg_gen_movi_tl(t1, v1);
14368 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14369 break;
14370 case OPC_DEXTR_R_L:
14371 tcg_gen_movi_tl(t0, v2);
14372 tcg_gen_movi_tl(t1, v1);
14373 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14374 break;
14375 case OPC_DEXTR_RS_L:
14376 tcg_gen_movi_tl(t0, v2);
14377 tcg_gen_movi_tl(t1, v1);
14378 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14379 break;
14380 case OPC_DEXTR_W:
14381 tcg_gen_movi_tl(t0, v2);
14382 tcg_gen_movi_tl(t1, v1);
14383 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14384 break;
14385 case OPC_DEXTR_R_W:
14386 tcg_gen_movi_tl(t0, v2);
14387 tcg_gen_movi_tl(t1, v1);
14388 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14389 break;
14390 case OPC_DEXTR_RS_W:
14391 tcg_gen_movi_tl(t0, v2);
14392 tcg_gen_movi_tl(t1, v1);
14393 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14394 break;
14395 case OPC_DEXTR_S_H:
14396 tcg_gen_movi_tl(t0, v2);
14397 tcg_gen_movi_tl(t1, v1);
14398 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14399 break;
14400 case OPC_DEXTRV_S_H:
14401 tcg_gen_movi_tl(t0, v2);
14402 tcg_gen_movi_tl(t1, v1);
14403 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14404 break;
14405 case OPC_DEXTRV_L:
14406 tcg_gen_movi_tl(t0, v2);
14407 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14408 break;
14409 case OPC_DEXTRV_R_L:
14410 tcg_gen_movi_tl(t0, v2);
14411 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14412 break;
14413 case OPC_DEXTRV_RS_L:
14414 tcg_gen_movi_tl(t0, v2);
14415 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14416 break;
14417 case OPC_DEXTRV_W:
14418 tcg_gen_movi_tl(t0, v2);
14419 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14420 break;
14421 case OPC_DEXTRV_R_W:
14422 tcg_gen_movi_tl(t0, v2);
14423 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14424 break;
14425 case OPC_DEXTRV_RS_W:
14426 tcg_gen_movi_tl(t0, v2);
14427 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14428 break;
14429 }
14430 break;
14431#endif
14432 }
14433
14434 tcg_temp_free(t0);
14435 tcg_temp_free(t1);
14436 tcg_temp_free(v1_t);
14437 tcg_temp_free(v2_t);
14438
14439 (void)opn; /* avoid a compiler warning */
14440 MIPS_DEBUG("%s", opn);
14441}
14442
9b1a1d68
JL
14443/* End MIPSDSP functions. */
14444
240ce26a 14445static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14446{
14447 int32_t offset;
14448 int rs, rt, rd, sa;
14449 uint32_t op, op1, op2;
14450 int16_t imm;
14451
14452 /* make sure instructions are on a word boundary */
14453 if (ctx->pc & 0x3) {
14454 env->CP0_BadVAddr = ctx->pc;
14455 generate_exception(ctx, EXCP_AdEL);
14456 return;
14457 }
14458
14459 /* Handle blikely not taken case */
14460 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14461 int l1 = gen_new_label();
14462
14463 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14464 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14465 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14466 gen_goto_tb(ctx, 1, ctx->pc + 4);
14467 gen_set_label(l1);
14468 }
14469
fdefe51c 14470 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14471 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14472 }
3c824109
NF
14473
14474 op = MASK_OP_MAJOR(ctx->opcode);
14475 rs = (ctx->opcode >> 21) & 0x1f;
14476 rt = (ctx->opcode >> 16) & 0x1f;
14477 rd = (ctx->opcode >> 11) & 0x1f;
14478 sa = (ctx->opcode >> 6) & 0x1f;
14479 imm = (int16_t)ctx->opcode;
14480 switch (op) {
7a387fff
TS
14481 case OPC_SPECIAL:
14482 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14483 switch (op1) {
324d9e32
AJ
14484 case OPC_SLL: /* Shift with immediate */
14485 case OPC_SRA:
d75c135e 14486 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14487 break;
ea63e2c3
NF
14488 case OPC_SRL:
14489 switch ((ctx->opcode >> 21) & 0x1f) {
14490 case 1:
14491 /* rotr is decoded as srl on non-R2 CPUs */
d75c135e 14492 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14493 op1 = OPC_ROTR;
14494 }
14495 /* Fallthrough */
14496 case 0:
d75c135e 14497 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14498 break;
14499 default:
14500 generate_exception(ctx, EXCP_RI);
14501 break;
14502 }
14503 break;
460f00c4
AJ
14504 case OPC_MOVN: /* Conditional move */
14505 case OPC_MOVZ:
d75c135e 14506 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
aa8f4009 14507 INSN_LOONGSON2E | INSN_LOONGSON2F);
d75c135e 14508 gen_cond_move(ctx, op1, rd, rs, rt);
460f00c4
AJ
14509 break;
14510 case OPC_ADD ... OPC_SUBU:
d75c135e 14511 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14512 break;
460f00c4 14513 case OPC_SLLV: /* Shifts */
460f00c4 14514 case OPC_SRAV:
d75c135e 14515 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14516 break;
ea63e2c3
NF
14517 case OPC_SRLV:
14518 switch ((ctx->opcode >> 6) & 0x1f) {
14519 case 1:
14520 /* rotrv is decoded as srlv on non-R2 CPUs */
d75c135e 14521 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14522 op1 = OPC_ROTRV;
14523 }
14524 /* Fallthrough */
14525 case 0:
d75c135e 14526 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14527 break;
14528 default:
14529 generate_exception(ctx, EXCP_RI);
14530 break;
14531 }
14532 break;
460f00c4
AJ
14533 case OPC_SLT: /* Set on less than */
14534 case OPC_SLTU:
d75c135e 14535 gen_slt(ctx, op1, rd, rs, rt);
460f00c4
AJ
14536 break;
14537 case OPC_AND: /* Logic*/
14538 case OPC_OR:
14539 case OPC_NOR:
14540 case OPC_XOR:
d75c135e 14541 gen_logic(ctx, op1, rd, rs, rt);
460f00c4 14542 break;
26135ead
RS
14543 case OPC_MULT:
14544 case OPC_MULTU:
e9c71dd1 14545 if (sa) {
d75c135e 14546 check_insn(ctx, INSN_VR54XX);
e9c71dd1
TS
14547 op1 = MASK_MUL_VR54XX(ctx->opcode);
14548 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
26135ead
RS
14549 } else {
14550 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14551 }
14552 break;
14553 case OPC_DIV:
14554 case OPC_DIVU:
14555 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff
TS
14556 break;
14557 case OPC_JR ... OPC_JALR:
7dca4ad0 14558 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061 14559 break;
7a387fff
TS
14560 case OPC_TGE ... OPC_TEQ: /* Traps */
14561 case OPC_TNE:
14562 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14563 break;
7a387fff
TS
14564 case OPC_MFHI: /* Move from HI/LO */
14565 case OPC_MFLO:
26135ead 14566 gen_HILO(ctx, op1, rs & 3, rd);
6af0bf9c 14567 break;
7a387fff
TS
14568 case OPC_MTHI:
14569 case OPC_MTLO: /* Move to HI/LO */
26135ead 14570 gen_HILO(ctx, op1, rd & 3, rs);
6af0bf9c 14571 break;
b48cfdff
TS
14572 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14573#ifdef MIPS_STRICT_STANDARD
14574 MIPS_INVAL("PMON / selsl");
14575 generate_exception(ctx, EXCP_RI);
14576#else
895c2d04 14577 gen_helper_0e0i(pmon, sa);
b48cfdff 14578#endif
7a387fff
TS
14579 break;
14580 case OPC_SYSCALL:
6af0bf9c 14581 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14582 ctx->bstate = BS_STOP;
6af0bf9c 14583 break;
7a387fff 14584 case OPC_BREAK:
6af0bf9c
FB
14585 generate_exception(ctx, EXCP_BREAK);
14586 break;
b48cfdff
TS
14587 case OPC_SPIM:
14588#ifdef MIPS_STRICT_STANDARD
14589 MIPS_INVAL("SPIM");
14590 generate_exception(ctx, EXCP_RI);
14591#else
7a387fff
TS
14592 /* Implemented as RI exception for now. */
14593 MIPS_INVAL("spim (unofficial)");
14594 generate_exception(ctx, EXCP_RI);
b48cfdff 14595#endif
6af0bf9c 14596 break;
7a387fff 14597 case OPC_SYNC:
ead9360e 14598 /* Treat as NOP. */
6af0bf9c 14599 break;
4ad40f36 14600
7a387fff 14601 case OPC_MOVCI:
d75c135e 14602 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14603 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14604 check_cp1_enabled(ctx);
36d23958
TS
14605 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14606 (ctx->opcode >> 16) & 1);
14607 } else {
e397ee33 14608 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14609 }
4ad40f36
FB
14610 break;
14611
d26bc211 14612#if defined(TARGET_MIPS64)
7a387fff
TS
14613 /* MIPS64 specific opcodes */
14614 case OPC_DSLL:
324d9e32 14615 case OPC_DSRA:
7a387fff 14616 case OPC_DSLL32:
324d9e32 14617 case OPC_DSRA32:
d75c135e 14618 check_insn(ctx, ISA_MIPS3);
e189e748 14619 check_mips_64(ctx);
d75c135e 14620 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14621 break;
ea63e2c3
NF
14622 case OPC_DSRL:
14623 switch ((ctx->opcode >> 21) & 0x1f) {
14624 case 1:
14625 /* drotr is decoded as dsrl on non-R2 CPUs */
d75c135e 14626 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14627 op1 = OPC_DROTR;
14628 }
14629 /* Fallthrough */
14630 case 0:
d75c135e 14631 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14632 check_mips_64(ctx);
d75c135e 14633 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14634 break;
14635 default:
14636 generate_exception(ctx, EXCP_RI);
14637 break;
14638 }
14639 break;
14640 case OPC_DSRL32:
14641 switch ((ctx->opcode >> 21) & 0x1f) {
14642 case 1:
14643 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
d75c135e 14644 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14645 op1 = OPC_DROTR32;
14646 }
14647 /* Fallthrough */
14648 case 0:
d75c135e 14649 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14650 check_mips_64(ctx);
d75c135e 14651 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14652 break;
14653 default:
14654 generate_exception(ctx, EXCP_RI);
14655 break;
14656 }
14657 break;
7a387fff 14658 case OPC_DADD ... OPC_DSUBU:
d75c135e 14659 check_insn(ctx, ISA_MIPS3);
e189e748 14660 check_mips_64(ctx);
d75c135e 14661 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14662 break;
460f00c4
AJ
14663 case OPC_DSLLV:
14664 case OPC_DSRAV:
d75c135e 14665 check_insn(ctx, ISA_MIPS3);
460f00c4 14666 check_mips_64(ctx);
d75c135e 14667 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14668 break;
ea63e2c3
NF
14669 case OPC_DSRLV:
14670 switch ((ctx->opcode >> 6) & 0x1f) {
14671 case 1:
14672 /* drotrv is decoded as dsrlv on non-R2 CPUs */
d75c135e 14673 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14674 op1 = OPC_DROTRV;
14675 }
14676 /* Fallthrough */
14677 case 0:
d75c135e 14678 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14679 check_mips_64(ctx);
d75c135e 14680 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14681 break;
14682 default:
14683 generate_exception(ctx, EXCP_RI);
14684 break;
14685 }
14686 break;
7a387fff 14687 case OPC_DMULT ... OPC_DDIVU:
d75c135e 14688 check_insn(ctx, ISA_MIPS3);
e189e748 14689 check_mips_64(ctx);
26135ead 14690 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff 14691 break;
6af0bf9c
FB
14692#endif
14693 default: /* Invalid */
14694 MIPS_INVAL("special");
14695 generate_exception(ctx, EXCP_RI);
14696 break;
14697 }
14698 break;
7a387fff
TS
14699 case OPC_SPECIAL2:
14700 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14701 switch (op1) {
7a387fff
TS
14702 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14703 case OPC_MSUB ... OPC_MSUBU:
d75c135e 14704 check_insn(ctx, ISA_MIPS32);
26135ead 14705 gen_muldiv(ctx, op1, rd & 3, rs, rt);
6af0bf9c 14706 break;
7a387fff 14707 case OPC_MUL:
d75c135e 14708 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 14709 break;
20e1fb52
AJ
14710 case OPC_CLO:
14711 case OPC_CLZ:
d75c135e 14712 check_insn(ctx, ISA_MIPS32);
7a387fff 14713 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14714 break;
7a387fff 14715 case OPC_SDBBP:
6af0bf9c
FB
14716 /* XXX: not clear which exception should be raised
14717 * when in debug mode...
14718 */
d75c135e 14719 check_insn(ctx, ISA_MIPS32);
6af0bf9c
FB
14720 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14721 generate_exception(ctx, EXCP_DBp);
14722 } else {
14723 generate_exception(ctx, EXCP_DBp);
14724 }
ead9360e 14725 /* Treat as NOP. */
6af0bf9c 14726 break;
161f85e6
AJ
14727 case OPC_DIV_G_2F:
14728 case OPC_DIVU_G_2F:
14729 case OPC_MULT_G_2F:
14730 case OPC_MULTU_G_2F:
14731 case OPC_MOD_G_2F:
14732 case OPC_MODU_G_2F:
d75c135e 14733 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14734 gen_loongson_integer(ctx, op1, rd, rs, rt);
14735 break;
d26bc211 14736#if defined(TARGET_MIPS64)
20e1fb52
AJ
14737 case OPC_DCLO:
14738 case OPC_DCLZ:
d75c135e 14739 check_insn(ctx, ISA_MIPS64);
e189e748 14740 check_mips_64(ctx);
7a387fff
TS
14741 gen_cl(ctx, op1, rd, rs);
14742 break;
161f85e6
AJ
14743 case OPC_DMULT_G_2F:
14744 case OPC_DMULTU_G_2F:
14745 case OPC_DDIV_G_2F:
14746 case OPC_DDIVU_G_2F:
14747 case OPC_DMOD_G_2F:
14748 case OPC_DMODU_G_2F:
d75c135e 14749 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14750 gen_loongson_integer(ctx, op1, rd, rs, rt);
14751 break;
7a387fff 14752#endif
6af0bf9c
FB
14753 default: /* Invalid */
14754 MIPS_INVAL("special2");
14755 generate_exception(ctx, EXCP_RI);
14756 break;
14757 }
14758 break;
7a387fff 14759 case OPC_SPECIAL3:
2b0233ab
TS
14760 op1 = MASK_SPECIAL3(ctx->opcode);
14761 switch (op1) {
14762 case OPC_EXT:
14763 case OPC_INS:
d75c135e 14764 check_insn(ctx, ISA_MIPS32R2);
2b0233ab
TS
14765 gen_bitops(ctx, op1, rt, rs, sa, rd);
14766 break;
14767 case OPC_BSHFL:
d75c135e 14768 check_insn(ctx, ISA_MIPS32R2);
2b0233ab 14769 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14770 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14771 break;
1579a72e 14772 case OPC_RDHWR:
d75c135e 14773 gen_rdhwr(ctx, rt, rd);
1579a72e 14774 break;
ead9360e 14775 case OPC_FORK:
d75c135e 14776 check_insn(ctx, ASE_MT);
6c5c1e20 14777 {
35fbce2c
AJ
14778 TCGv t0 = tcg_temp_new();
14779 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14780
14781 gen_load_gpr(t0, rt);
14782 gen_load_gpr(t1, rs);
a7812ae4 14783 gen_helper_fork(t0, t1);
6c5c1e20
TS
14784 tcg_temp_free(t0);
14785 tcg_temp_free(t1);
14786 }
ead9360e
TS
14787 break;
14788 case OPC_YIELD:
d75c135e 14789 check_insn(ctx, ASE_MT);
6c5c1e20 14790 {
35fbce2c 14791 TCGv t0 = tcg_temp_new();
6c5c1e20 14792
35fbce2c 14793 save_cpu_state(ctx, 1);
6c5c1e20 14794 gen_load_gpr(t0, rs);
895c2d04 14795 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14796 gen_store_gpr(t0, rd);
14797 tcg_temp_free(t0);
14798 }
ead9360e 14799 break;
161f85e6 14800 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14801 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14802 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14803 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14804 * the same mask and op1. */
d75c135e 14805 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
461c08df
JL
14806 op2 = MASK_ADDUH_QB(ctx->opcode);
14807 switch (op2) {
14808 case OPC_ADDUH_QB:
14809 case OPC_ADDUH_R_QB:
14810 case OPC_ADDQH_PH:
14811 case OPC_ADDQH_R_PH:
14812 case OPC_ADDQH_W:
14813 case OPC_ADDQH_R_W:
14814 case OPC_SUBUH_QB:
14815 case OPC_SUBUH_R_QB:
14816 case OPC_SUBQH_PH:
14817 case OPC_SUBQH_R_PH:
14818 case OPC_SUBQH_W:
14819 case OPC_SUBQH_R_W:
14820 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14821 break;
a22260ae
JL
14822 case OPC_MUL_PH:
14823 case OPC_MUL_S_PH:
14824 case OPC_MULQ_S_W:
14825 case OPC_MULQ_RS_W:
14826 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14827 break;
461c08df
JL
14828 default:
14829 MIPS_INVAL("MASK ADDUH.QB");
14830 generate_exception(ctx, EXCP_RI);
14831 break;
14832 }
d75c135e 14833 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
461c08df
JL
14834 gen_loongson_integer(ctx, op1, rd, rs, rt);
14835 } else {
14836 generate_exception(ctx, EXCP_RI);
14837 }
161f85e6 14838 break;
9b1a1d68
JL
14839 case OPC_LX_DSP:
14840 op2 = MASK_LX(ctx->opcode);
14841 switch (op2) {
14842#if defined(TARGET_MIPS64)
14843 case OPC_LDX:
14844#endif
14845 case OPC_LBUX:
14846 case OPC_LHX:
14847 case OPC_LWX:
d75c135e 14848 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
9b1a1d68
JL
14849 break;
14850 default: /* Invalid */
14851 MIPS_INVAL("MASK LX");
14852 generate_exception(ctx, EXCP_RI);
14853 break;
14854 }
14855 break;
461c08df
JL
14856 case OPC_ABSQ_S_PH_DSP:
14857 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14858 switch (op2) {
14859 case OPC_ABSQ_S_QB:
14860 case OPC_ABSQ_S_PH:
14861 case OPC_ABSQ_S_W:
14862 case OPC_PRECEQ_W_PHL:
14863 case OPC_PRECEQ_W_PHR:
14864 case OPC_PRECEQU_PH_QBL:
14865 case OPC_PRECEQU_PH_QBR:
14866 case OPC_PRECEQU_PH_QBLA:
14867 case OPC_PRECEQU_PH_QBRA:
14868 case OPC_PRECEU_PH_QBL:
14869 case OPC_PRECEU_PH_QBR:
14870 case OPC_PRECEU_PH_QBLA:
14871 case OPC_PRECEU_PH_QBRA:
14872 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14873 break;
1cb6686c
JL
14874 case OPC_BITREV:
14875 case OPC_REPL_QB:
14876 case OPC_REPLV_QB:
14877 case OPC_REPL_PH:
14878 case OPC_REPLV_PH:
d75c135e 14879 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14880 break;
461c08df
JL
14881 default:
14882 MIPS_INVAL("MASK ABSQ_S.PH");
14883 generate_exception(ctx, EXCP_RI);
14884 break;
14885 }
14886 break;
14887 case OPC_ADDU_QB_DSP:
14888 op2 = MASK_ADDU_QB(ctx->opcode);
14889 switch (op2) {
14890 case OPC_ADDQ_PH:
14891 case OPC_ADDQ_S_PH:
14892 case OPC_ADDQ_S_W:
14893 case OPC_ADDU_QB:
14894 case OPC_ADDU_S_QB:
14895 case OPC_ADDU_PH:
14896 case OPC_ADDU_S_PH:
14897 case OPC_SUBQ_PH:
14898 case OPC_SUBQ_S_PH:
14899 case OPC_SUBQ_S_W:
14900 case OPC_SUBU_QB:
14901 case OPC_SUBU_S_QB:
14902 case OPC_SUBU_PH:
14903 case OPC_SUBU_S_PH:
14904 case OPC_ADDSC:
14905 case OPC_ADDWC:
14906 case OPC_MODSUB:
14907 case OPC_RADDU_W_QB:
14908 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14909 break;
a22260ae
JL
14910 case OPC_MULEU_S_PH_QBL:
14911 case OPC_MULEU_S_PH_QBR:
14912 case OPC_MULQ_RS_PH:
14913 case OPC_MULEQ_S_W_PHL:
14914 case OPC_MULEQ_S_W_PHR:
14915 case OPC_MULQ_S_PH:
14916 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14917 break;
461c08df
JL
14918 default: /* Invalid */
14919 MIPS_INVAL("MASK ADDU.QB");
14920 generate_exception(ctx, EXCP_RI);
14921 break;
14922
14923 }
14924 break;
14925 case OPC_CMPU_EQ_QB_DSP:
14926 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14927 switch (op2) {
14928 case OPC_PRECR_SRA_PH_W:
14929 case OPC_PRECR_SRA_R_PH_W:
14930 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14931 break;
14932 case OPC_PRECR_QB_PH:
14933 case OPC_PRECRQ_QB_PH:
14934 case OPC_PRECRQ_PH_W:
14935 case OPC_PRECRQ_RS_PH_W:
14936 case OPC_PRECRQU_S_QB_PH:
14937 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14938 break;
26690560
JL
14939 case OPC_CMPU_EQ_QB:
14940 case OPC_CMPU_LT_QB:
14941 case OPC_CMPU_LE_QB:
14942 case OPC_CMP_EQ_PH:
14943 case OPC_CMP_LT_PH:
14944 case OPC_CMP_LE_PH:
14945 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14946 break;
14947 case OPC_CMPGU_EQ_QB:
14948 case OPC_CMPGU_LT_QB:
14949 case OPC_CMPGU_LE_QB:
14950 case OPC_CMPGDU_EQ_QB:
14951 case OPC_CMPGDU_LT_QB:
14952 case OPC_CMPGDU_LE_QB:
14953 case OPC_PICK_QB:
14954 case OPC_PICK_PH:
14955 case OPC_PACKRL_PH:
14956 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14957 break;
461c08df
JL
14958 default: /* Invalid */
14959 MIPS_INVAL("MASK CMPU.EQ.QB");
14960 generate_exception(ctx, EXCP_RI);
14961 break;
14962 }
14963 break;
77c5fa8b
JL
14964 case OPC_SHLL_QB_DSP:
14965 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14966 break;
a22260ae
JL
14967 case OPC_DPA_W_PH_DSP:
14968 op2 = MASK_DPA_W_PH(ctx->opcode);
14969 switch (op2) {
14970 case OPC_DPAU_H_QBL:
14971 case OPC_DPAU_H_QBR:
14972 case OPC_DPSU_H_QBL:
14973 case OPC_DPSU_H_QBR:
14974 case OPC_DPA_W_PH:
14975 case OPC_DPAX_W_PH:
14976 case OPC_DPAQ_S_W_PH:
14977 case OPC_DPAQX_S_W_PH:
14978 case OPC_DPAQX_SA_W_PH:
14979 case OPC_DPS_W_PH:
14980 case OPC_DPSX_W_PH:
14981 case OPC_DPSQ_S_W_PH:
14982 case OPC_DPSQX_S_W_PH:
14983 case OPC_DPSQX_SA_W_PH:
14984 case OPC_MULSAQ_S_W_PH:
14985 case OPC_DPAQ_SA_L_W:
14986 case OPC_DPSQ_SA_L_W:
14987 case OPC_MAQ_S_W_PHL:
14988 case OPC_MAQ_S_W_PHR:
14989 case OPC_MAQ_SA_W_PHL:
14990 case OPC_MAQ_SA_W_PHR:
14991 case OPC_MULSA_W_PH:
14992 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14993 break;
14994 default: /* Invalid */
14995 MIPS_INVAL("MASK DPAW.PH");
14996 generate_exception(ctx, EXCP_RI);
14997 break;
14998 }
14999 break;
1cb6686c
JL
15000 case OPC_INSV_DSP:
15001 op2 = MASK_INSV(ctx->opcode);
15002 switch (op2) {
15003 case OPC_INSV:
15004 check_dsp(ctx);
15005 {
15006 TCGv t0, t1;
15007
15008 if (rt == 0) {
15009 MIPS_DEBUG("NOP");
15010 break;
15011 }
15012
15013 t0 = tcg_temp_new();
15014 t1 = tcg_temp_new();
15015
15016 gen_load_gpr(t0, rt);
15017 gen_load_gpr(t1, rs);
15018
15019 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
15020
15021 tcg_temp_free(t0);
15022 tcg_temp_free(t1);
15023 break;
15024 }
15025 default: /* Invalid */
15026 MIPS_INVAL("MASK INSV");
15027 generate_exception(ctx, EXCP_RI);
15028 break;
15029 }
15030 break;
26690560 15031 case OPC_APPEND_DSP:
df6126a7 15032 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15033 break;
b53371ed
JL
15034 case OPC_EXTR_W_DSP:
15035 op2 = MASK_EXTR_W(ctx->opcode);
15036 switch (op2) {
15037 case OPC_EXTR_W:
15038 case OPC_EXTR_R_W:
15039 case OPC_EXTR_RS_W:
15040 case OPC_EXTR_S_H:
15041 case OPC_EXTRV_S_H:
15042 case OPC_EXTRV_W:
15043 case OPC_EXTRV_R_W:
15044 case OPC_EXTRV_RS_W:
15045 case OPC_EXTP:
15046 case OPC_EXTPV:
15047 case OPC_EXTPDP:
15048 case OPC_EXTPDPV:
15049 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15050 break;
15051 case OPC_RDDSP:
15052 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
15053 break;
15054 case OPC_SHILO:
15055 case OPC_SHILOV:
15056 case OPC_MTHLIP:
15057 case OPC_WRDSP:
15058 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15059 break;
15060 default: /* Invalid */
15061 MIPS_INVAL("MASK EXTR.W");
15062 generate_exception(ctx, EXCP_RI);
15063 break;
15064 }
15065 break;
d26bc211 15066#if defined(TARGET_MIPS64)
1579a72e
TS
15067 case OPC_DEXTM ... OPC_DEXT:
15068 case OPC_DINSM ... OPC_DINS:
d75c135e 15069 check_insn(ctx, ISA_MIPS64R2);
e189e748 15070 check_mips_64(ctx);
1579a72e 15071 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 15072 break;
1579a72e 15073 case OPC_DBSHFL:
d75c135e 15074 check_insn(ctx, ISA_MIPS64R2);
e189e748 15075 check_mips_64(ctx);
1579a72e 15076 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 15077 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 15078 break;
161f85e6
AJ
15079 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15080 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15081 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
d75c135e 15082 check_insn(ctx, INSN_LOONGSON2E);
161f85e6
AJ
15083 gen_loongson_integer(ctx, op1, rd, rs, rt);
15084 break;
461c08df
JL
15085 case OPC_ABSQ_S_QH_DSP:
15086 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15087 switch (op2) {
15088 case OPC_PRECEQ_L_PWL:
15089 case OPC_PRECEQ_L_PWR:
15090 case OPC_PRECEQ_PW_QHL:
15091 case OPC_PRECEQ_PW_QHR:
15092 case OPC_PRECEQ_PW_QHLA:
15093 case OPC_PRECEQ_PW_QHRA:
15094 case OPC_PRECEQU_QH_OBL:
15095 case OPC_PRECEQU_QH_OBR:
15096 case OPC_PRECEQU_QH_OBLA:
15097 case OPC_PRECEQU_QH_OBRA:
15098 case OPC_PRECEU_QH_OBL:
15099 case OPC_PRECEU_QH_OBR:
15100 case OPC_PRECEU_QH_OBLA:
15101 case OPC_PRECEU_QH_OBRA:
15102 case OPC_ABSQ_S_OB:
15103 case OPC_ABSQ_S_PW:
15104 case OPC_ABSQ_S_QH:
15105 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15106 break;
1cb6686c
JL
15107 case OPC_REPL_OB:
15108 case OPC_REPL_PW:
15109 case OPC_REPL_QH:
15110 case OPC_REPLV_OB:
15111 case OPC_REPLV_PW:
15112 case OPC_REPLV_QH:
d75c135e 15113 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 15114 break;
461c08df
JL
15115 default: /* Invalid */
15116 MIPS_INVAL("MASK ABSQ_S.QH");
15117 generate_exception(ctx, EXCP_RI);
15118 break;
15119 }
15120 break;
15121 case OPC_ADDU_OB_DSP:
15122 op2 = MASK_ADDU_OB(ctx->opcode);
15123 switch (op2) {
15124 case OPC_RADDU_L_OB:
15125 case OPC_SUBQ_PW:
15126 case OPC_SUBQ_S_PW:
15127 case OPC_SUBQ_QH:
15128 case OPC_SUBQ_S_QH:
15129 case OPC_SUBU_OB:
15130 case OPC_SUBU_S_OB:
15131 case OPC_SUBU_QH:
15132 case OPC_SUBU_S_QH:
15133 case OPC_SUBUH_OB:
15134 case OPC_SUBUH_R_OB:
15135 case OPC_ADDQ_PW:
15136 case OPC_ADDQ_S_PW:
15137 case OPC_ADDQ_QH:
15138 case OPC_ADDQ_S_QH:
15139 case OPC_ADDU_OB:
15140 case OPC_ADDU_S_OB:
15141 case OPC_ADDU_QH:
15142 case OPC_ADDU_S_QH:
15143 case OPC_ADDUH_OB:
15144 case OPC_ADDUH_R_OB:
15145 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15146 break;
a22260ae
JL
15147 case OPC_MULEQ_S_PW_QHL:
15148 case OPC_MULEQ_S_PW_QHR:
15149 case OPC_MULEU_S_QH_OBL:
15150 case OPC_MULEU_S_QH_OBR:
15151 case OPC_MULQ_RS_QH:
15152 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15153 break;
461c08df
JL
15154 default: /* Invalid */
15155 MIPS_INVAL("MASK ADDU.OB");
15156 generate_exception(ctx, EXCP_RI);
15157 break;
15158 }
15159 break;
15160 case OPC_CMPU_EQ_OB_DSP:
15161 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15162 switch (op2) {
15163 case OPC_PRECR_SRA_QH_PW:
15164 case OPC_PRECR_SRA_R_QH_PW:
15165 /* Return value is rt. */
15166 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15167 break;
15168 case OPC_PRECR_OB_QH:
15169 case OPC_PRECRQ_OB_QH:
15170 case OPC_PRECRQ_PW_L:
15171 case OPC_PRECRQ_QH_PW:
15172 case OPC_PRECRQ_RS_QH_PW:
15173 case OPC_PRECRQU_S_OB_QH:
15174 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15175 break;
26690560
JL
15176 case OPC_CMPU_EQ_OB:
15177 case OPC_CMPU_LT_OB:
15178 case OPC_CMPU_LE_OB:
15179 case OPC_CMP_EQ_QH:
15180 case OPC_CMP_LT_QH:
15181 case OPC_CMP_LE_QH:
15182 case OPC_CMP_EQ_PW:
15183 case OPC_CMP_LT_PW:
15184 case OPC_CMP_LE_PW:
15185 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15186 break;
15187 case OPC_CMPGDU_EQ_OB:
15188 case OPC_CMPGDU_LT_OB:
15189 case OPC_CMPGDU_LE_OB:
15190 case OPC_CMPGU_EQ_OB:
15191 case OPC_CMPGU_LT_OB:
15192 case OPC_CMPGU_LE_OB:
15193 case OPC_PACKRL_PW:
15194 case OPC_PICK_OB:
15195 case OPC_PICK_PW:
15196 case OPC_PICK_QH:
15197 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15198 break;
461c08df
JL
15199 default: /* Invalid */
15200 MIPS_INVAL("MASK CMPU_EQ.OB");
15201 generate_exception(ctx, EXCP_RI);
15202 break;
15203 }
15204 break;
26690560 15205 case OPC_DAPPEND_DSP:
df6126a7 15206 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15207 break;
b53371ed
JL
15208 case OPC_DEXTR_W_DSP:
15209 op2 = MASK_DEXTR_W(ctx->opcode);
15210 switch (op2) {
15211 case OPC_DEXTP:
15212 case OPC_DEXTPDP:
15213 case OPC_DEXTPDPV:
15214 case OPC_DEXTPV:
15215 case OPC_DEXTR_L:
15216 case OPC_DEXTR_R_L:
15217 case OPC_DEXTR_RS_L:
15218 case OPC_DEXTR_W:
15219 case OPC_DEXTR_R_W:
15220 case OPC_DEXTR_RS_W:
15221 case OPC_DEXTR_S_H:
15222 case OPC_DEXTRV_L:
15223 case OPC_DEXTRV_R_L:
15224 case OPC_DEXTRV_RS_L:
15225 case OPC_DEXTRV_S_H:
15226 case OPC_DEXTRV_W:
15227 case OPC_DEXTRV_R_W:
15228 case OPC_DEXTRV_RS_W:
15229 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15230 break;
15231 case OPC_DMTHLIP:
15232 case OPC_DSHILO:
15233 case OPC_DSHILOV:
15234 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15235 break;
15236 default: /* Invalid */
15237 MIPS_INVAL("MASK EXTR.W");
15238 generate_exception(ctx, EXCP_RI);
15239 break;
15240 }
15241 break;
a22260ae
JL
15242 case OPC_DPAQ_W_QH_DSP:
15243 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15244 switch (op2) {
15245 case OPC_DPAU_H_OBL:
15246 case OPC_DPAU_H_OBR:
15247 case OPC_DPSU_H_OBL:
15248 case OPC_DPSU_H_OBR:
15249 case OPC_DPA_W_QH:
15250 case OPC_DPAQ_S_W_QH:
15251 case OPC_DPS_W_QH:
15252 case OPC_DPSQ_S_W_QH:
15253 case OPC_MULSAQ_S_W_QH:
15254 case OPC_DPAQ_SA_L_PW:
15255 case OPC_DPSQ_SA_L_PW:
15256 case OPC_MULSAQ_S_L_PW:
15257 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15258 break;
15259 case OPC_MAQ_S_W_QHLL:
15260 case OPC_MAQ_S_W_QHLR:
15261 case OPC_MAQ_S_W_QHRL:
15262 case OPC_MAQ_S_W_QHRR:
15263 case OPC_MAQ_SA_W_QHLL:
15264 case OPC_MAQ_SA_W_QHLR:
15265 case OPC_MAQ_SA_W_QHRL:
15266 case OPC_MAQ_SA_W_QHRR:
15267 case OPC_MAQ_S_L_PWL:
15268 case OPC_MAQ_S_L_PWR:
15269 case OPC_DMADD:
15270 case OPC_DMADDU:
15271 case OPC_DMSUB:
15272 case OPC_DMSUBU:
15273 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15274 break;
15275 default: /* Invalid */
15276 MIPS_INVAL("MASK DPAQ.W.QH");
15277 generate_exception(ctx, EXCP_RI);
15278 break;
15279 }
15280 break;
1cb6686c
JL
15281 case OPC_DINSV_DSP:
15282 op2 = MASK_INSV(ctx->opcode);
15283 switch (op2) {
15284 case OPC_DINSV:
15285 {
15286 TCGv t0, t1;
15287
15288 if (rt == 0) {
15289 MIPS_DEBUG("NOP");
15290 break;
15291 }
15292 check_dsp(ctx);
15293
15294 t0 = tcg_temp_new();
15295 t1 = tcg_temp_new();
15296
15297 gen_load_gpr(t0, rt);
15298 gen_load_gpr(t1, rs);
15299
15300 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15301 break;
15302 }
15303 default: /* Invalid */
15304 MIPS_INVAL("MASK DINSV");
15305 generate_exception(ctx, EXCP_RI);
15306 break;
15307 }
15308 break;
77c5fa8b
JL
15309 case OPC_SHLL_OB_DSP:
15310 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15311 break;
7a387fff
TS
15312#endif
15313 default: /* Invalid */
15314 MIPS_INVAL("special3");
15315 generate_exception(ctx, EXCP_RI);
15316 break;
15317 }
15318 break;
15319 case OPC_REGIMM:
15320 op1 = MASK_REGIMM(ctx->opcode);
15321 switch (op1) {
15322 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15323 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15324 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061 15325 break;
7a387fff
TS
15326 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15327 case OPC_TNEI:
15328 gen_trap(ctx, op1, rs, -1, imm);
15329 break;
15330 case OPC_SYNCI:
d75c135e 15331 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15332 /* Treat as NOP. */
6af0bf9c 15333 break;
e45a93e2
JL
15334 case OPC_BPOSGE32: /* MIPS DSP branch */
15335#if defined(TARGET_MIPS64)
15336 case OPC_BPOSGE64:
15337#endif
15338 check_dsp(ctx);
15339 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
e45a93e2 15340 break;
6af0bf9c 15341 default: /* Invalid */
923617a3 15342 MIPS_INVAL("regimm");
6af0bf9c
FB
15343 generate_exception(ctx, EXCP_RI);
15344 break;
15345 }
15346 break;
7a387fff 15347 case OPC_CP0:
387a8fe5 15348 check_cp0_enabled(ctx);
7a387fff 15349 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15350 switch (op1) {
7a387fff
TS
15351 case OPC_MFC0:
15352 case OPC_MTC0:
ead9360e
TS
15353 case OPC_MFTR:
15354 case OPC_MTTR:
d26bc211 15355#if defined(TARGET_MIPS64)
7a387fff
TS
15356 case OPC_DMFC0:
15357 case OPC_DMTC0:
15358#endif
f1aa6320 15359#ifndef CONFIG_USER_ONLY
932e71cd 15360 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15361#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15362 break;
15363 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15364#ifndef CONFIG_USER_ONLY
932e71cd 15365 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15366#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15367 break;
15368 case OPC_MFMC0:
8706c382 15369#ifndef CONFIG_USER_ONLY
932e71cd 15370 {
35fbce2c 15371 TCGv t0 = tcg_temp_new();
6c5c1e20 15372
0eaef5aa 15373 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15374 switch (op2) {
15375 case OPC_DMT:
d75c135e 15376 check_insn(ctx, ASE_MT);
9ed5726c 15377 gen_helper_dmt(t0);
35fbce2c 15378 gen_store_gpr(t0, rt);
6c5c1e20
TS
15379 break;
15380 case OPC_EMT:
d75c135e 15381 check_insn(ctx, ASE_MT);
9ed5726c 15382 gen_helper_emt(t0);
35fbce2c 15383 gen_store_gpr(t0, rt);
da80682b 15384 break;
6c5c1e20 15385 case OPC_DVPE:
d75c135e 15386 check_insn(ctx, ASE_MT);
895c2d04 15387 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15388 gen_store_gpr(t0, rt);
6c5c1e20
TS
15389 break;
15390 case OPC_EVPE:
d75c135e 15391 check_insn(ctx, ASE_MT);
895c2d04 15392 gen_helper_evpe(t0, cpu_env);
35fbce2c 15393 gen_store_gpr(t0, rt);
6c5c1e20
TS
15394 break;
15395 case OPC_DI:
d75c135e 15396 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15397 save_cpu_state(ctx, 1);
895c2d04 15398 gen_helper_di(t0, cpu_env);
35fbce2c 15399 gen_store_gpr(t0, rt);
6c5c1e20
TS
15400 /* Stop translation as we may have switched the execution mode */
15401 ctx->bstate = BS_STOP;
15402 break;
15403 case OPC_EI:
d75c135e 15404 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15405 save_cpu_state(ctx, 1);
895c2d04 15406 gen_helper_ei(t0, cpu_env);
35fbce2c 15407 gen_store_gpr(t0, rt);
6c5c1e20
TS
15408 /* Stop translation as we may have switched the execution mode */
15409 ctx->bstate = BS_STOP;
15410 break;
15411 default: /* Invalid */
15412 MIPS_INVAL("mfmc0");
15413 generate_exception(ctx, EXCP_RI);
15414 break;
15415 }
6c5c1e20 15416 tcg_temp_free(t0);
7a387fff 15417 }
0eaef5aa 15418#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15419 break;
7a387fff 15420 case OPC_RDPGPR:
d75c135e 15421 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15422 gen_load_srsgpr(rt, rd);
ead9360e 15423 break;
7a387fff 15424 case OPC_WRPGPR:
d75c135e 15425 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15426 gen_store_srsgpr(rt, rd);
38121543 15427 break;
6af0bf9c 15428 default:
923617a3 15429 MIPS_INVAL("cp0");
7a387fff 15430 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15431 break;
15432 }
15433 break;
324d9e32
AJ
15434 case OPC_ADDI: /* Arithmetic with immediate opcode */
15435 case OPC_ADDIU:
d75c135e 15436 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15437 break;
324d9e32
AJ
15438 case OPC_SLTI: /* Set on less than with immediate opcode */
15439 case OPC_SLTIU:
d75c135e 15440 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15441 break;
15442 case OPC_ANDI: /* Arithmetic with immediate opcode */
15443 case OPC_LUI:
15444 case OPC_ORI:
15445 case OPC_XORI:
d75c135e 15446 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15447 break;
7a387fff
TS
15448 case OPC_J ... OPC_JAL: /* Jump */
15449 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15450 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061 15451 break;
7a387fff
TS
15452 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15453 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15454 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061 15455 break;
7a387fff 15456 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15457 case OPC_LL:
d75c135e 15458 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15459 break;
7a387fff
TS
15460 case OPC_SB ... OPC_SW:
15461 case OPC_SWR:
5c13fdfd 15462 gen_st(ctx, op, rt, rs, imm);
7a387fff 15463 break;
d66c7132
AJ
15464 case OPC_SC:
15465 gen_st_cond(ctx, op, rt, rs, imm);
15466 break;
7a387fff 15467 case OPC_CACHE:
2e15497c 15468 check_cp0_enabled(ctx);
d75c135e 15469 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15470 /* Treat as NOP. */
34ae7b51 15471 break;
7a387fff 15472 case OPC_PREF:
d75c135e 15473 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15474 /* Treat as NOP. */
6af0bf9c 15475 break;
4ad40f36 15476
923617a3 15477 /* Floating point (COP1). */
7a387fff
TS
15478 case OPC_LWC1:
15479 case OPC_LDC1:
15480 case OPC_SWC1:
15481 case OPC_SDC1:
26ebe468 15482 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15483 break;
15484
7a387fff 15485 case OPC_CP1:
36d23958 15486 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15487 check_cp1_enabled(ctx);
36d23958
TS
15488 op1 = MASK_CP1(ctx->opcode);
15489 switch (op1) {
3a95e3a7
TS
15490 case OPC_MFHC1:
15491 case OPC_MTHC1:
d75c135e 15492 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
15493 case OPC_MFC1:
15494 case OPC_CFC1:
15495 case OPC_MTC1:
15496 case OPC_CTC1:
e189e748
TS
15497 gen_cp1(ctx, op1, rt, rd);
15498 break;
d26bc211 15499#if defined(TARGET_MIPS64)
36d23958
TS
15500 case OPC_DMFC1:
15501 case OPC_DMTC1:
d75c135e 15502 check_insn(ctx, ISA_MIPS3);
36d23958
TS
15503 gen_cp1(ctx, op1, rt, rd);
15504 break;
e189e748 15505#endif
fbcc6828
TS
15506 case OPC_BC1ANY2:
15507 case OPC_BC1ANY4:
b8aa4598 15508 check_cop1x(ctx);
d75c135e 15509 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
15510 /* fall through */
15511 case OPC_BC1:
d75c135e 15512 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15513 (rt >> 2) & 0x7, imm << 2);
c9602061 15514 break;
36d23958
TS
15515 case OPC_S_FMT:
15516 case OPC_D_FMT:
15517 case OPC_W_FMT:
15518 case OPC_L_FMT:
5a5012ec 15519 case OPC_PS_FMT:
bf4120ad 15520 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15521 (imm >> 8) & 0x7);
36d23958
TS
15522 break;
15523 default:
923617a3 15524 MIPS_INVAL("cp1");
e397ee33 15525 generate_exception (ctx, EXCP_RI);
36d23958
TS
15526 break;
15527 }
15528 } else {
15529 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15530 }
4ad40f36
FB
15531 break;
15532
15533 /* COP2. */
7a387fff
TS
15534 case OPC_LWC2:
15535 case OPC_LDC2:
15536 case OPC_SWC2:
15537 case OPC_SDC2:
7a387fff 15538 /* COP2: Not implemented. */
4ad40f36
FB
15539 generate_exception_err(ctx, EXCP_CpU, 2);
15540 break;
bd277fa1 15541 case OPC_CP2:
d75c135e 15542 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
15543 /* Note that these instructions use different fields. */
15544 gen_loongson_multimedia(ctx, sa, rd, rt);
15545 break;
4ad40f36 15546
7a387fff 15547 case OPC_CP3:
36d23958 15548 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15549 check_cp1_enabled(ctx);
36d23958
TS
15550 op1 = MASK_CP3(ctx->opcode);
15551 switch (op1) {
5a5012ec
TS
15552 case OPC_LWXC1:
15553 case OPC_LDXC1:
15554 case OPC_LUXC1:
15555 case OPC_SWXC1:
15556 case OPC_SDXC1:
15557 case OPC_SUXC1:
93b12ccc 15558 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15559 break;
e0c84da7 15560 case OPC_PREFX:
ead9360e 15561 /* Treat as NOP. */
e0c84da7 15562 break;
5a5012ec
TS
15563 case OPC_ALNV_PS:
15564 case OPC_MADD_S:
15565 case OPC_MADD_D:
15566 case OPC_MADD_PS:
15567 case OPC_MSUB_S:
15568 case OPC_MSUB_D:
15569 case OPC_MSUB_PS:
15570 case OPC_NMADD_S:
15571 case OPC_NMADD_D:
15572 case OPC_NMADD_PS:
15573 case OPC_NMSUB_S:
15574 case OPC_NMSUB_D:
15575 case OPC_NMSUB_PS:
15576 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15577 break;
36d23958 15578 default:
923617a3 15579 MIPS_INVAL("cp3");
e397ee33 15580 generate_exception (ctx, EXCP_RI);
36d23958
TS
15581 break;
15582 }
15583 } else {
e397ee33 15584 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15585 }
4ad40f36
FB
15586 break;
15587
d26bc211 15588#if defined(TARGET_MIPS64)
7a387fff
TS
15589 /* MIPS64 opcodes */
15590 case OPC_LWU:
15591 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15592 case OPC_LLD:
15593 case OPC_LD:
d75c135e 15594 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15595 check_mips_64(ctx);
d75c135e 15596 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
15597 break;
15598 case OPC_SDL ... OPC_SDR:
7a387fff 15599 case OPC_SD:
d75c135e 15600 check_insn(ctx, ISA_MIPS3);
e189e748 15601 check_mips_64(ctx);
5c13fdfd 15602 gen_st(ctx, op, rt, rs, imm);
7a387fff 15603 break;
d66c7132 15604 case OPC_SCD:
d75c135e 15605 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
15606 check_mips_64(ctx);
15607 gen_st_cond(ctx, op, rt, rs, imm);
15608 break;
324d9e32
AJ
15609 case OPC_DADDI:
15610 case OPC_DADDIU:
d75c135e 15611 check_insn(ctx, ISA_MIPS3);
e189e748 15612 check_mips_64(ctx);
d75c135e 15613 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15614 break;
6af0bf9c 15615#endif
7a387fff 15616 case OPC_JALX:
d75c135e 15617 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15618 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15619 gen_compute_branch(ctx, op, 4, rs, rt, offset);
364d4831 15620 break;
7a387fff 15621 case OPC_MDMX:
d75c135e 15622 check_insn(ctx, ASE_MDMX);
7a387fff 15623 /* MDMX: Not implemented. */
6af0bf9c 15624 default: /* Invalid */
923617a3 15625 MIPS_INVAL("major opcode");
6af0bf9c
FB
15626 generate_exception(ctx, EXCP_RI);
15627 break;
15628 }
6af0bf9c
FB
15629}
15630
2cfc5f17 15631static inline void
6429db34
AF
15632gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15633 bool search_pc)
6af0bf9c 15634{
ed2803da 15635 CPUState *cs = CPU(cpu);
6429db34 15636 CPUMIPSState *env = &cpu->env;
278d0702 15637 DisasContext ctx;
6af0bf9c
FB
15638 target_ulong pc_start;
15639 uint16_t *gen_opc_end;
a1d1bb31 15640 CPUBreakpoint *bp;
6af0bf9c 15641 int j, lj = -1;
2e70f6ef
PB
15642 int num_insns;
15643 int max_insns;
c9602061 15644 int insn_bytes;
240ce26a 15645 int is_delay;
6af0bf9c 15646
93fcfe39
AL
15647 if (search_pc)
15648 qemu_log("search pc %d\n", search_pc);
4ad40f36 15649
6af0bf9c 15650 pc_start = tb->pc;
92414b31 15651 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15652 ctx.pc = pc_start;
4ad40f36 15653 ctx.saved_pc = -1;
ed2803da 15654 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 15655 ctx.insn_flags = env->insn_flags;
6af0bf9c
FB
15656 ctx.tb = tb;
15657 ctx.bstate = BS_NONE;
4ad40f36 15658 /* Restore delay slot state from the tb context. */
c068688b 15659 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
d279279e 15660 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
fd4a04eb 15661 restore_cpu_state(env, &ctx);
932e71cd 15662#ifdef CONFIG_USER_ONLY
0eaef5aa 15663 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15664#else
0eaef5aa 15665 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15666#endif
2e70f6ef
PB
15667 num_insns = 0;
15668 max_insns = tb->cflags & CF_COUNT_MASK;
15669 if (max_insns == 0)
15670 max_insns = CF_COUNT_MASK;
d12d51d5 15671 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 15672 gen_tb_start();
faf7aaa9 15673 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
15674 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
15675 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 15676 if (bp->pc == ctx.pc) {
278d0702 15677 save_cpu_state(&ctx, 1);
4ad40f36 15678 ctx.bstate = BS_BRANCH;
895c2d04 15679 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15680 /* Include the breakpoint location or the tb won't
15681 * be flushed when it must be. */
15682 ctx.pc += 4;
4ad40f36
FB
15683 goto done_generating;
15684 }
15685 }
15686 }
15687
6af0bf9c 15688 if (search_pc) {
92414b31 15689 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15690 if (lj < j) {
15691 lj++;
15692 while (lj < j)
ab1103de 15693 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15694 }
25983cad 15695 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15696 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15697 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15698 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15699 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15700 }
2e70f6ef
PB
15701 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15702 gen_io_start();
c9602061 15703
240ce26a 15704 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 15705 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15706 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 15707 insn_bytes = 4;
240ce26a 15708 decode_opc(env, &ctx);
d75c135e 15709 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 15710 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 15711 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 15712 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 15713 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 15714 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
15715 } else {
15716 generate_exception(&ctx, EXCP_RI);
3c824109 15717 ctx.bstate = BS_STOP;
c9602061
NF
15718 break;
15719 }
240ce26a 15720 if (is_delay) {
d75c135e 15721 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
15722 }
15723 ctx.pc += insn_bytes;
15724
2e70f6ef 15725 num_insns++;
4ad40f36 15726
7b270ef2
NF
15727 /* Execute a branch and its delay slot as a single instruction.
15728 This is what GDB expects and is consistent with what the
15729 hardware does (e.g. if a delay slot instruction faults, the
15730 reported PC is the PC of the branch). */
ed2803da 15731 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 15732 break;
ed2803da 15733 }
4ad40f36 15734
6af0bf9c
FB
15735 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15736 break;
4ad40f36 15737
efd7f486 15738 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15739 break;
efd7f486 15740 }
faf7aaa9 15741
2e70f6ef
PB
15742 if (num_insns >= max_insns)
15743 break;
1b530a6d
AJ
15744
15745 if (singlestep)
15746 break;
6af0bf9c 15747 }
ed2803da 15748 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 15749 gen_io_end();
ed2803da
AF
15750 }
15751 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15752 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15753 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15754 } else {
6958549d 15755 switch (ctx.bstate) {
16c00cb2 15756 case BS_STOP:
df1561e2
TS
15757 gen_goto_tb(&ctx, 0, ctx.pc);
15758 break;
16c00cb2 15759 case BS_NONE:
278d0702 15760 save_cpu_state(&ctx, 0);
16c00cb2
TS
15761 gen_goto_tb(&ctx, 0, ctx.pc);
15762 break;
5a5012ec 15763 case BS_EXCP:
57fec1fe 15764 tcg_gen_exit_tb(0);
16c00cb2 15765 break;
5a5012ec
TS
15766 case BS_BRANCH:
15767 default:
15768 break;
6958549d 15769 }
6af0bf9c 15770 }
4ad40f36 15771done_generating:
806f352d 15772 gen_tb_end(tb, num_insns);
efd7f486 15773 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15774 if (search_pc) {
92414b31 15775 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15776 lj++;
15777 while (lj <= j)
ab1103de 15778 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15779 } else {
15780 tb->size = ctx.pc - pc_start;
2e70f6ef 15781 tb->icount = num_insns;
6af0bf9c
FB
15782 }
15783#ifdef DEBUG_DISAS
d12d51d5 15784 LOG_DISAS("\n");
8fec2b8c 15785 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15786 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15787 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15788 qemu_log("\n");
6af0bf9c
FB
15789 }
15790#endif
6af0bf9c
FB
15791}
15792
7db13fae 15793void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15794{
6429db34 15795 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
15796}
15797
7db13fae 15798void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15799{
6429db34 15800 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
15801}
15802
7db13fae 15803static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15804 int flags)
6ea83fed
FB
15805{
15806 int i;
5e755519 15807 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15808
2a5612e6
SW
15809#define printfpr(fp) \
15810 do { \
15811 if (is_fpu64) \
15812 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15813 " fd:%13g fs:%13g psu: %13g\n", \
15814 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15815 (double)(fp)->fd, \
15816 (double)(fp)->fs[FP_ENDIAN_IDX], \
15817 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15818 else { \
15819 fpr_t tmp; \
15820 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15821 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15822 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15823 " fd:%13g fs:%13g psu:%13g\n", \
15824 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15825 (double)tmp.fd, \
15826 (double)tmp.fs[FP_ENDIAN_IDX], \
15827 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15828 } \
6ea83fed
FB
15829 } while(0)
15830
5a5012ec 15831
9a78eead
SW
15832 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15833 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15834 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15835 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15836 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15837 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15838 }
15839
15840#undef printfpr
15841}
15842
d26bc211 15843#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15844/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15845 sign-extended values on 64bit machines. */
c570fd16
TS
15846
15847#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15848
8706c382 15849static void
7db13fae 15850cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15851 fprintf_function cpu_fprintf,
8706c382 15852 int flags)
c570fd16
TS
15853{
15854 int i;
15855
b5dc7732
TS
15856 if (!SIGN_EXT_P(env->active_tc.PC))
15857 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15858 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15859 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15860 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15861 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15862 if (!SIGN_EXT_P(env->btarget))
3594c774 15863 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15864
15865 for (i = 0; i < 32; i++) {
b5dc7732
TS
15866 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15867 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15868 }
15869
15870 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15871 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15872 if (!SIGN_EXT_P(env->lladdr))
15873 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15874}
15875#endif
15876
878096ee
AF
15877void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15878 int flags)
6af0bf9c 15879{
878096ee
AF
15880 MIPSCPU *cpu = MIPS_CPU(cs);
15881 CPUMIPSState *env = &cpu->env;
6af0bf9c 15882 int i;
3b46e624 15883
a7200c9f
SW
15884 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15885 " LO=0x" TARGET_FMT_lx " ds %04x "
15886 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15887 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15888 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15889 for (i = 0; i < 32; i++) {
15890 if ((i & 3) == 0)
15891 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15892 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15893 if ((i & 3) == 3)
15894 cpu_fprintf(f, "\n");
15895 }
568b600d 15896
3594c774 15897 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15898 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15899 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15900 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15901 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15902 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15903#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15904 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15905#endif
6af0bf9c
FB
15906}
15907
78ce64f4 15908void mips_tcg_init(void)
39454628 15909{
f01be154 15910 int i;
39454628
TS
15911 static int inited;
15912
15913 /* Initialize various static tables. */
15914 if (inited)
6958549d 15915 return;
39454628 15916
a7812ae4 15917 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15918 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15919 for (i = 1; i < 32; i++)
a7812ae4 15920 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15921 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15922 regnames[i]);
d73ee8a2
RH
15923
15924 for (i = 0; i < 32; i++) {
15925 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15926 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15927 }
15928
a7812ae4 15929 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15930 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15931 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15932 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15933 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15934 regnames_HI[i]);
a7812ae4 15935 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15936 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15937 regnames_LO[i]);
a7812ae4 15938 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15939 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15940 regnames_ACX[i]);
15941 }
a7812ae4 15942 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15943 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15944 "DSPControl");
1ba74fb8 15945 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15946 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15947 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15948 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15949 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15950 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15951
a7812ae4 15952 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15953 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15954 "fcr0");
15955 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15956 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15957 "fcr31");
39454628
TS
15958
15959 inited = 1;
15960}
15961
aaed909a
FB
15962#include "translate_init.c"
15963
30bf942d 15964MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15965{
0f71a709 15966 MIPSCPU *cpu;
6af0bf9c 15967 CPUMIPSState *env;
c227f099 15968 const mips_def_t *def;
6af0bf9c 15969
aaed909a
FB
15970 def = cpu_mips_find_by_name(cpu_model);
15971 if (!def)
15972 return NULL;
0f71a709
AF
15973 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15974 env = &cpu->env;
aaed909a
FB
15975 env->cpu_model = def;
15976
51cc2e78
BS
15977#ifndef CONFIG_USER_ONLY
15978 mmu_init(env, def);
15979#endif
15980 fpu_init(env, def);
15981 mvp_init(env, def);
c1caf1d9
AF
15982
15983 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15984
30bf942d 15985 return cpu;
6ae81775
TS
15986}
15987
1bba0dc9 15988void cpu_state_reset(CPUMIPSState *env)
6ae81775 15989{
55e5c285
AF
15990 MIPSCPU *cpu = mips_env_get_cpu(env);
15991 CPUState *cs = CPU(cpu);
6ae81775 15992
51cc2e78
BS
15993 /* Reset registers to their default values */
15994 env->CP0_PRid = env->cpu_model->CP0_PRid;
15995 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15996#ifdef TARGET_WORDS_BIGENDIAN
15997 env->CP0_Config0 |= (1 << CP0C0_BE);
15998#endif
15999 env->CP0_Config1 = env->cpu_model->CP0_Config1;
16000 env->CP0_Config2 = env->cpu_model->CP0_Config2;
16001 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
16002 env->CP0_Config4 = env->cpu_model->CP0_Config4;
16003 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
16004 env->CP0_Config5 = env->cpu_model->CP0_Config5;
16005 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
16006 env->CP0_Config6 = env->cpu_model->CP0_Config6;
16007 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
16008 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
16009 << env->cpu_model->CP0_LLAddr_shift;
16010 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
16011 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
16012 env->CCRes = env->cpu_model->CCRes;
16013 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
16014 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
16015 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
16016 env->current_tc = 0;
16017 env->SEGBITS = env->cpu_model->SEGBITS;
16018 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
16019#if defined(TARGET_MIPS64)
16020 if (env->cpu_model->insn_flags & ISA_MIPS3) {
16021 env->SEGMask |= 3ULL << 62;
16022 }
16023#endif
16024 env->PABITS = env->cpu_model->PABITS;
16025 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
16026 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
16027 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
16028 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
16029 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
16030 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
16031 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
16032 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
16033 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
16034 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
16035 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 16036 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
16037 env->insn_flags = env->cpu_model->insn_flags;
16038
0eaef5aa 16039#if defined(CONFIG_USER_ONLY)
03e6e501 16040 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
16041# ifdef TARGET_MIPS64
16042 /* Enable 64-bit register mode. */
16043 env->CP0_Status |= (1 << CP0St_PX);
16044# endif
16045# ifdef TARGET_ABI_MIPSN64
16046 /* Enable 64-bit address mode. */
16047 env->CP0_Status |= (1 << CP0St_UX);
16048# endif
94159135
MI
16049 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16050 hardware registers. */
16051 env->CP0_HWREna |= 0x0000000F;
91a75935 16052 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 16053 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 16054 }
6f0af304
PJ
16055 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
16056 env->CP0_Status |= (1 << CP0St_MX);
853c3240 16057 }
4d66261f
PJ
16058# if defined(TARGET_MIPS64)
16059 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16060 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16061 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
16062 env->CP0_Status |= (1 << CP0St_FR);
16063 }
4d66261f 16064# endif
932e71cd
AJ
16065#else
16066 if (env->hflags & MIPS_HFLAG_BMASK) {
16067 /* If the exception was raised from a delay slot,
16068 come back to the jump. */
16069 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 16070 } else {
932e71cd
AJ
16071 env->CP0_ErrorEPC = env->active_tc.PC;
16072 }
16073 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
16074 env->CP0_Random = env->tlb->nb_tlb - 1;
16075 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 16076 env->CP0_Wired = 0;
55e5c285 16077 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
932e71cd
AJ
16078 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16079 /* vectored interrupts not implemented, timer on int 7,
16080 no performance counters. */
16081 env->CP0_IntCtl = 0xe0000000;
16082 {
16083 int i;
16084
16085 for (i = 0; i < 7; i++) {
16086 env->CP0_WatchLo[i] = 0;
16087 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 16088 }
932e71cd
AJ
16089 env->CP0_WatchLo[7] = 0;
16090 env->CP0_WatchHi[7] = 0;
fd88b6ab 16091 }
932e71cd
AJ
16092 /* Count register increments in debug mode, EJTAG version 1 */
16093 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 16094
4b69c7e2
JH
16095 cpu_mips_store_count(env, 1);
16096
9e56e756
EI
16097 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16098 int i;
16099
16100 /* Only TC0 on VPE 0 starts as active. */
16101 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16102 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16103 env->tcs[i].CP0_TCHalt = 1;
16104 }
16105 env->active_tc.CP0_TCHalt = 1;
259186a7 16106 cs->halted = 1;
9e56e756 16107
55e5c285 16108 if (cs->cpu_index == 0) {
9e56e756
EI
16109 /* VPE0 starts up enabled. */
16110 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16111 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16112
16113 /* TC0 starts up unhalted. */
259186a7 16114 cs->halted = 0;
9e56e756
EI
16115 env->active_tc.CP0_TCHalt = 0;
16116 env->tcs[0].CP0_TCHalt = 0;
16117 /* With thread 0 active. */
16118 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16119 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16120 }
16121 }
51cc2e78 16122#endif
03e6e501 16123 compute_hflags(env);
27103424 16124 cs->exception_index = EXCP_NONE;
6af0bf9c 16125}
d2856f1a 16126
7db13fae 16127void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16128{
25983cad 16129 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16130 env->hflags &= ~MIPS_HFLAG_BMASK;
16131 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16132 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16133 case MIPS_HFLAG_BR:
16134 break;
16135 case MIPS_HFLAG_BC:
16136 case MIPS_HFLAG_BL:
16137 case MIPS_HFLAG_B:
16138 env->btarget = gen_opc_btarget[pc_pos];
16139 break;
16140 }
d2856f1a 16141}