QError: Introduce QERR_QMP_EXTRA_MEMBER
[qemu/ar7.git] / target-mips / translate.c
blob804b6e4bc46bfdba8219d575beb589b960d867e3
1 /*
2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <inttypes.h>
29 #include "cpu.h"
30 #include "exec-all.h"
31 #include "disas.h"
32 #include "tcg-op.h"
33 #include "qemu-common.h"
35 #include "helper.h"
36 #define GEN_HELPER 1
37 #include "helper.h"
39 //#define MIPS_DEBUG_DISAS
40 //#define MIPS_DEBUG_SIGN_EXTENSIONS
42 /* MIPS major opcodes */
43 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
45 enum {
46 /* indirect opcode tables */
47 OPC_SPECIAL = (0x00 << 26),
48 OPC_REGIMM = (0x01 << 26),
49 OPC_CP0 = (0x10 << 26),
50 OPC_CP1 = (0x11 << 26),
51 OPC_CP2 = (0x12 << 26),
52 OPC_CP3 = (0x13 << 26),
53 OPC_SPECIAL2 = (0x1C << 26),
54 OPC_SPECIAL3 = (0x1F << 26),
55 /* arithmetic with immediate */
56 OPC_ADDI = (0x08 << 26),
57 OPC_ADDIU = (0x09 << 26),
58 OPC_SLTI = (0x0A << 26),
59 OPC_SLTIU = (0x0B << 26),
60 /* logic with immediate */
61 OPC_ANDI = (0x0C << 26),
62 OPC_ORI = (0x0D << 26),
63 OPC_XORI = (0x0E << 26),
64 OPC_LUI = (0x0F << 26),
65 /* arithmetic with immediate */
66 OPC_DADDI = (0x18 << 26),
67 OPC_DADDIU = (0x19 << 26),
68 /* Jump and branches */
69 OPC_J = (0x02 << 26),
70 OPC_JAL = (0x03 << 26),
71 OPC_JALS = OPC_JAL | 0x5,
72 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
73 OPC_BEQL = (0x14 << 26),
74 OPC_BNE = (0x05 << 26),
75 OPC_BNEL = (0x15 << 26),
76 OPC_BLEZ = (0x06 << 26),
77 OPC_BLEZL = (0x16 << 26),
78 OPC_BGTZ = (0x07 << 26),
79 OPC_BGTZL = (0x17 << 26),
80 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
81 OPC_JALXS = OPC_JALX | 0x5,
82 /* Load and stores */
83 OPC_LDL = (0x1A << 26),
84 OPC_LDR = (0x1B << 26),
85 OPC_LB = (0x20 << 26),
86 OPC_LH = (0x21 << 26),
87 OPC_LWL = (0x22 << 26),
88 OPC_LW = (0x23 << 26),
89 OPC_LWPC = OPC_LW | 0x5,
90 OPC_LBU = (0x24 << 26),
91 OPC_LHU = (0x25 << 26),
92 OPC_LWR = (0x26 << 26),
93 OPC_LWU = (0x27 << 26),
94 OPC_SB = (0x28 << 26),
95 OPC_SH = (0x29 << 26),
96 OPC_SWL = (0x2A << 26),
97 OPC_SW = (0x2B << 26),
98 OPC_SDL = (0x2C << 26),
99 OPC_SDR = (0x2D << 26),
100 OPC_SWR = (0x2E << 26),
101 OPC_LL = (0x30 << 26),
102 OPC_LLD = (0x34 << 26),
103 OPC_LD = (0x37 << 26),
104 OPC_LDPC = OPC_LD | 0x5,
105 OPC_SC = (0x38 << 26),
106 OPC_SCD = (0x3C << 26),
107 OPC_SD = (0x3F << 26),
108 /* Floating point load/store */
109 OPC_LWC1 = (0x31 << 26),
110 OPC_LWC2 = (0x32 << 26),
111 OPC_LDC1 = (0x35 << 26),
112 OPC_LDC2 = (0x36 << 26),
113 OPC_SWC1 = (0x39 << 26),
114 OPC_SWC2 = (0x3A << 26),
115 OPC_SDC1 = (0x3D << 26),
116 OPC_SDC2 = (0x3E << 26),
117 /* MDMX ASE specific */
118 OPC_MDMX = (0x1E << 26),
119 /* Cache and prefetch */
120 OPC_CACHE = (0x2F << 26),
121 OPC_PREF = (0x33 << 26),
122 /* Reserved major opcode */
123 OPC_MAJOR3B_RESERVED = (0x3B << 26),
126 /* MIPS special opcodes */
127 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
129 enum {
130 /* Shifts */
131 OPC_SLL = 0x00 | OPC_SPECIAL,
132 /* NOP is SLL r0, r0, 0 */
133 /* SSNOP is SLL r0, r0, 1 */
134 /* EHB is SLL r0, r0, 3 */
135 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
136 OPC_ROTR = OPC_SRL | (1 << 21),
137 OPC_SRA = 0x03 | OPC_SPECIAL,
138 OPC_SLLV = 0x04 | OPC_SPECIAL,
139 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
140 OPC_ROTRV = OPC_SRLV | (1 << 6),
141 OPC_SRAV = 0x07 | OPC_SPECIAL,
142 OPC_DSLLV = 0x14 | OPC_SPECIAL,
143 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
144 OPC_DROTRV = OPC_DSRLV | (1 << 6),
145 OPC_DSRAV = 0x17 | OPC_SPECIAL,
146 OPC_DSLL = 0x38 | OPC_SPECIAL,
147 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
148 OPC_DROTR = OPC_DSRL | (1 << 21),
149 OPC_DSRA = 0x3B | OPC_SPECIAL,
150 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
151 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
152 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
153 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
154 /* Multiplication / division */
155 OPC_MULT = 0x18 | OPC_SPECIAL,
156 OPC_MULTU = 0x19 | OPC_SPECIAL,
157 OPC_DIV = 0x1A | OPC_SPECIAL,
158 OPC_DIVU = 0x1B | OPC_SPECIAL,
159 OPC_DMULT = 0x1C | OPC_SPECIAL,
160 OPC_DMULTU = 0x1D | OPC_SPECIAL,
161 OPC_DDIV = 0x1E | OPC_SPECIAL,
162 OPC_DDIVU = 0x1F | OPC_SPECIAL,
163 /* 2 registers arithmetic / logic */
164 OPC_ADD = 0x20 | OPC_SPECIAL,
165 OPC_ADDU = 0x21 | OPC_SPECIAL,
166 OPC_SUB = 0x22 | OPC_SPECIAL,
167 OPC_SUBU = 0x23 | OPC_SPECIAL,
168 OPC_AND = 0x24 | OPC_SPECIAL,
169 OPC_OR = 0x25 | OPC_SPECIAL,
170 OPC_XOR = 0x26 | OPC_SPECIAL,
171 OPC_NOR = 0x27 | OPC_SPECIAL,
172 OPC_SLT = 0x2A | OPC_SPECIAL,
173 OPC_SLTU = 0x2B | OPC_SPECIAL,
174 OPC_DADD = 0x2C | OPC_SPECIAL,
175 OPC_DADDU = 0x2D | OPC_SPECIAL,
176 OPC_DSUB = 0x2E | OPC_SPECIAL,
177 OPC_DSUBU = 0x2F | OPC_SPECIAL,
178 /* Jumps */
179 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
180 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
181 OPC_JALRC = OPC_JALR | (0x5 << 6),
182 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
183 /* Traps */
184 OPC_TGE = 0x30 | OPC_SPECIAL,
185 OPC_TGEU = 0x31 | OPC_SPECIAL,
186 OPC_TLT = 0x32 | OPC_SPECIAL,
187 OPC_TLTU = 0x33 | OPC_SPECIAL,
188 OPC_TEQ = 0x34 | OPC_SPECIAL,
189 OPC_TNE = 0x36 | OPC_SPECIAL,
190 /* HI / LO registers load & stores */
191 OPC_MFHI = 0x10 | OPC_SPECIAL,
192 OPC_MTHI = 0x11 | OPC_SPECIAL,
193 OPC_MFLO = 0x12 | OPC_SPECIAL,
194 OPC_MTLO = 0x13 | OPC_SPECIAL,
195 /* Conditional moves */
196 OPC_MOVZ = 0x0A | OPC_SPECIAL,
197 OPC_MOVN = 0x0B | OPC_SPECIAL,
199 OPC_MOVCI = 0x01 | OPC_SPECIAL,
201 /* Special */
202 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
203 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
204 OPC_BREAK = 0x0D | OPC_SPECIAL,
205 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
206 OPC_SYNC = 0x0F | OPC_SPECIAL,
208 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
209 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
210 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
211 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
212 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
213 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
214 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
217 /* Multiplication variants of the vr54xx. */
218 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
220 enum {
221 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
222 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
223 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
224 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
225 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
226 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
227 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
228 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
229 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
230 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
231 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
232 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
233 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
234 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
237 /* REGIMM (rt field) opcodes */
238 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
240 enum {
241 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
242 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
243 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
244 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
245 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
246 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
247 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
248 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
249 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
250 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
251 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
252 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
253 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
254 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
255 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
256 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
257 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
260 /* Special2 opcodes */
261 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
263 enum {
264 /* Multiply & xxx operations */
265 OPC_MADD = 0x00 | OPC_SPECIAL2,
266 OPC_MADDU = 0x01 | OPC_SPECIAL2,
267 OPC_MUL = 0x02 | OPC_SPECIAL2,
268 OPC_MSUB = 0x04 | OPC_SPECIAL2,
269 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
270 /* Misc */
271 OPC_CLZ = 0x20 | OPC_SPECIAL2,
272 OPC_CLO = 0x21 | OPC_SPECIAL2,
273 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
274 OPC_DCLO = 0x25 | OPC_SPECIAL2,
275 /* Special */
276 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
279 /* Special3 opcodes */
280 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
282 enum {
283 OPC_EXT = 0x00 | OPC_SPECIAL3,
284 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
285 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
286 OPC_DEXT = 0x03 | OPC_SPECIAL3,
287 OPC_INS = 0x04 | OPC_SPECIAL3,
288 OPC_DINSM = 0x05 | OPC_SPECIAL3,
289 OPC_DINSU = 0x06 | OPC_SPECIAL3,
290 OPC_DINS = 0x07 | OPC_SPECIAL3,
291 OPC_FORK = 0x08 | OPC_SPECIAL3,
292 OPC_YIELD = 0x09 | OPC_SPECIAL3,
293 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
294 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
295 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
298 /* BSHFL opcodes */
299 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
301 enum {
302 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
303 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
304 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
307 /* DBSHFL opcodes */
308 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
310 enum {
311 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
312 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
315 /* Coprocessor 0 (rs field) */
316 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
318 enum {
319 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
320 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
321 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
322 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
323 OPC_MFTR = (0x08 << 21) | OPC_CP0,
324 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
325 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
326 OPC_MTTR = (0x0C << 21) | OPC_CP0,
327 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
328 OPC_C0 = (0x10 << 21) | OPC_CP0,
329 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
330 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
333 /* MFMC0 opcodes */
334 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
336 enum {
337 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
338 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
339 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
340 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
341 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
342 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
345 /* Coprocessor 0 (with rs == C0) */
346 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
348 enum {
349 OPC_TLBR = 0x01 | OPC_C0,
350 OPC_TLBWI = 0x02 | OPC_C0,
351 OPC_TLBWR = 0x06 | OPC_C0,
352 OPC_TLBP = 0x08 | OPC_C0,
353 OPC_RFE = 0x10 | OPC_C0,
354 OPC_ERET = 0x18 | OPC_C0,
355 OPC_DERET = 0x1F | OPC_C0,
356 OPC_WAIT = 0x20 | OPC_C0,
359 /* Coprocessor 1 (rs field) */
360 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
362 /* Values for the fmt field in FP instructions */
363 enum {
364 /* 0 - 15 are reserved */
365 FMT_S = 16, /* single fp */
366 FMT_D = 17, /* double fp */
367 FMT_E = 18, /* extended fp */
368 FMT_Q = 19, /* quad fp */
369 FMT_W = 20, /* 32-bit fixed */
370 FMT_L = 21, /* 64-bit fixed */
371 FMT_PS = 22, /* paired single fp */
372 /* 23 - 31 are reserved */
375 enum {
376 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
377 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
378 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
379 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
380 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
381 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
382 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
383 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
384 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
385 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
386 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
387 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
388 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
389 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
390 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
391 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
392 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
393 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
396 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
397 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
399 enum {
400 OPC_BC1F = (0x00 << 16) | OPC_BC1,
401 OPC_BC1T = (0x01 << 16) | OPC_BC1,
402 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
403 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
406 enum {
407 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
408 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
411 enum {
412 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
413 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
416 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
418 enum {
419 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
420 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
421 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
422 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
423 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
424 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
425 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
426 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
427 OPC_BC2 = (0x08 << 21) | OPC_CP2,
430 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
432 enum {
433 OPC_LWXC1 = 0x00 | OPC_CP3,
434 OPC_LDXC1 = 0x01 | OPC_CP3,
435 OPC_LUXC1 = 0x05 | OPC_CP3,
436 OPC_SWXC1 = 0x08 | OPC_CP3,
437 OPC_SDXC1 = 0x09 | OPC_CP3,
438 OPC_SUXC1 = 0x0D | OPC_CP3,
439 OPC_PREFX = 0x0F | OPC_CP3,
440 OPC_ALNV_PS = 0x1E | OPC_CP3,
441 OPC_MADD_S = 0x20 | OPC_CP3,
442 OPC_MADD_D = 0x21 | OPC_CP3,
443 OPC_MADD_PS = 0x26 | OPC_CP3,
444 OPC_MSUB_S = 0x28 | OPC_CP3,
445 OPC_MSUB_D = 0x29 | OPC_CP3,
446 OPC_MSUB_PS = 0x2E | OPC_CP3,
447 OPC_NMADD_S = 0x30 | OPC_CP3,
448 OPC_NMADD_D = 0x31 | OPC_CP3,
449 OPC_NMADD_PS= 0x36 | OPC_CP3,
450 OPC_NMSUB_S = 0x38 | OPC_CP3,
451 OPC_NMSUB_D = 0x39 | OPC_CP3,
452 OPC_NMSUB_PS= 0x3E | OPC_CP3,
455 /* global register indices */
456 static TCGv_ptr cpu_env;
457 static TCGv cpu_gpr[32], cpu_PC;
458 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
459 static TCGv cpu_dspctrl, btarget, bcond;
460 static TCGv_i32 hflags;
461 static TCGv_i32 fpu_fcr0, fpu_fcr31;
463 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
465 #include "gen-icount.h"
467 #define gen_helper_0i(name, arg) do { \
468 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
469 gen_helper_##name(helper_tmp); \
470 tcg_temp_free_i32(helper_tmp); \
471 } while(0)
473 #define gen_helper_1i(name, arg1, arg2) do { \
474 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
475 gen_helper_##name(arg1, helper_tmp); \
476 tcg_temp_free_i32(helper_tmp); \
477 } while(0)
479 #define gen_helper_2i(name, arg1, arg2, arg3) do { \
480 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
481 gen_helper_##name(arg1, arg2, helper_tmp); \
482 tcg_temp_free_i32(helper_tmp); \
483 } while(0)
485 #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do { \
486 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
487 gen_helper_##name(arg1, arg2, arg3, helper_tmp); \
488 tcg_temp_free_i32(helper_tmp); \
489 } while(0)
491 typedef struct DisasContext {
492 struct TranslationBlock *tb;
493 target_ulong pc, saved_pc;
494 uint32_t opcode;
495 int singlestep_enabled;
496 /* Routine used to access memory */
497 int mem_idx;
498 uint32_t hflags, saved_hflags;
499 int bstate;
500 target_ulong btarget;
501 } DisasContext;
503 enum {
504 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
505 * exception condition */
506 BS_STOP = 1, /* We want to stop translation for any reason */
507 BS_BRANCH = 2, /* We reached a branch condition */
508 BS_EXCP = 3, /* We reached an exception condition */
511 static const char *regnames[] =
512 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
513 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
514 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
515 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
517 static const char *regnames_HI[] =
518 { "HI0", "HI1", "HI2", "HI3", };
520 static const char *regnames_LO[] =
521 { "LO0", "LO1", "LO2", "LO3", };
523 static const char *regnames_ACX[] =
524 { "ACX0", "ACX1", "ACX2", "ACX3", };
526 static const char *fregnames[] =
527 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
528 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
529 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
530 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
532 #ifdef MIPS_DEBUG_DISAS
533 #define MIPS_DEBUG(fmt, ...) \
534 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
535 TARGET_FMT_lx ": %08x " fmt "\n", \
536 ctx->pc, ctx->opcode , ## __VA_ARGS__)
537 #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
538 #else
539 #define MIPS_DEBUG(fmt, ...) do { } while(0)
540 #define LOG_DISAS(...) do { } while (0)
541 #endif
543 #define MIPS_INVAL(op) \
544 do { \
545 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
546 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
547 } while (0)
549 /* General purpose registers moves. */
550 static inline void gen_load_gpr (TCGv t, int reg)
552 if (reg == 0)
553 tcg_gen_movi_tl(t, 0);
554 else
555 tcg_gen_mov_tl(t, cpu_gpr[reg]);
558 static inline void gen_store_gpr (TCGv t, int reg)
560 if (reg != 0)
561 tcg_gen_mov_tl(cpu_gpr[reg], t);
564 /* Moves to/from ACX register. */
565 static inline void gen_load_ACX (TCGv t, int reg)
567 tcg_gen_mov_tl(t, cpu_ACX[reg]);
570 static inline void gen_store_ACX (TCGv t, int reg)
572 tcg_gen_mov_tl(cpu_ACX[reg], t);
575 /* Moves to/from shadow registers. */
576 static inline void gen_load_srsgpr (int from, int to)
578 TCGv t0 = tcg_temp_new();
580 if (from == 0)
581 tcg_gen_movi_tl(t0, 0);
582 else {
583 TCGv_i32 t2 = tcg_temp_new_i32();
584 TCGv_ptr addr = tcg_temp_new_ptr();
586 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
587 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
588 tcg_gen_andi_i32(t2, t2, 0xf);
589 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
590 tcg_gen_ext_i32_ptr(addr, t2);
591 tcg_gen_add_ptr(addr, cpu_env, addr);
593 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
594 tcg_temp_free_ptr(addr);
595 tcg_temp_free_i32(t2);
597 gen_store_gpr(t0, to);
598 tcg_temp_free(t0);
601 static inline void gen_store_srsgpr (int from, int to)
603 if (to != 0) {
604 TCGv t0 = tcg_temp_new();
605 TCGv_i32 t2 = tcg_temp_new_i32();
606 TCGv_ptr addr = tcg_temp_new_ptr();
608 gen_load_gpr(t0, from);
609 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
610 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
611 tcg_gen_andi_i32(t2, t2, 0xf);
612 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
613 tcg_gen_ext_i32_ptr(addr, t2);
614 tcg_gen_add_ptr(addr, cpu_env, addr);
616 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
617 tcg_temp_free_ptr(addr);
618 tcg_temp_free_i32(t2);
619 tcg_temp_free(t0);
623 /* Floating point register moves. */
624 static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
626 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
629 static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
631 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
634 static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
636 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
639 static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
641 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
644 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
646 if (ctx->hflags & MIPS_HFLAG_F64) {
647 tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
648 } else {
649 TCGv_i32 t0 = tcg_temp_new_i32();
650 TCGv_i32 t1 = tcg_temp_new_i32();
651 gen_load_fpr32(t0, reg & ~1);
652 gen_load_fpr32(t1, reg | 1);
653 tcg_gen_concat_i32_i64(t, t0, t1);
654 tcg_temp_free_i32(t0);
655 tcg_temp_free_i32(t1);
659 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
661 if (ctx->hflags & MIPS_HFLAG_F64) {
662 tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
663 } else {
664 TCGv_i64 t0 = tcg_temp_new_i64();
665 TCGv_i32 t1 = tcg_temp_new_i32();
666 tcg_gen_trunc_i64_i32(t1, t);
667 gen_store_fpr32(t1, reg & ~1);
668 tcg_gen_shri_i64(t0, t, 32);
669 tcg_gen_trunc_i64_i32(t1, t0);
670 gen_store_fpr32(t1, reg | 1);
671 tcg_temp_free_i32(t1);
672 tcg_temp_free_i64(t0);
676 static inline int get_fp_bit (int cc)
678 if (cc)
679 return 24 + cc;
680 else
681 return 23;
684 /* Tests */
685 static inline void gen_save_pc(target_ulong pc)
687 tcg_gen_movi_tl(cpu_PC, pc);
690 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
692 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
693 if (do_save_pc && ctx->pc != ctx->saved_pc) {
694 gen_save_pc(ctx->pc);
695 ctx->saved_pc = ctx->pc;
697 if (ctx->hflags != ctx->saved_hflags) {
698 tcg_gen_movi_i32(hflags, ctx->hflags);
699 ctx->saved_hflags = ctx->hflags;
700 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
701 case MIPS_HFLAG_BR:
702 break;
703 case MIPS_HFLAG_BC:
704 case MIPS_HFLAG_BL:
705 case MIPS_HFLAG_B:
706 tcg_gen_movi_tl(btarget, ctx->btarget);
707 break;
712 static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
714 ctx->saved_hflags = ctx->hflags;
715 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
716 case MIPS_HFLAG_BR:
717 break;
718 case MIPS_HFLAG_BC:
719 case MIPS_HFLAG_BL:
720 case MIPS_HFLAG_B:
721 ctx->btarget = env->btarget;
722 break;
726 static inline void
727 generate_exception_err (DisasContext *ctx, int excp, int err)
729 TCGv_i32 texcp = tcg_const_i32(excp);
730 TCGv_i32 terr = tcg_const_i32(err);
731 save_cpu_state(ctx, 1);
732 gen_helper_raise_exception_err(texcp, terr);
733 tcg_temp_free_i32(terr);
734 tcg_temp_free_i32(texcp);
737 static inline void
738 generate_exception (DisasContext *ctx, int excp)
740 save_cpu_state(ctx, 1);
741 gen_helper_0i(raise_exception, excp);
744 /* Addresses computation */
745 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
747 tcg_gen_add_tl(ret, arg0, arg1);
749 #if defined(TARGET_MIPS64)
750 /* For compatibility with 32-bit code, data reference in user mode
751 with Status_UX = 0 should be casted to 32-bit and sign extended.
752 See the MIPS64 PRA manual, section 4.10. */
753 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
754 !(ctx->hflags & MIPS_HFLAG_UX)) {
755 tcg_gen_ext32s_i64(ret, ret);
757 #endif
760 static inline void check_cp0_enabled(DisasContext *ctx)
762 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
763 generate_exception_err(ctx, EXCP_CpU, 0);
766 static inline void check_cp1_enabled(DisasContext *ctx)
768 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
769 generate_exception_err(ctx, EXCP_CpU, 1);
772 /* Verify that the processor is running with COP1X instructions enabled.
773 This is associated with the nabla symbol in the MIPS32 and MIPS64
774 opcode tables. */
776 static inline void check_cop1x(DisasContext *ctx)
778 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
779 generate_exception(ctx, EXCP_RI);
782 /* Verify that the processor is running with 64-bit floating-point
783 operations enabled. */
785 static inline void check_cp1_64bitmode(DisasContext *ctx)
787 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
788 generate_exception(ctx, EXCP_RI);
792 * Verify if floating point register is valid; an operation is not defined
793 * if bit 0 of any register specification is set and the FR bit in the
794 * Status register equals zero, since the register numbers specify an
795 * even-odd pair of adjacent coprocessor general registers. When the FR bit
796 * in the Status register equals one, both even and odd register numbers
797 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
799 * Multiple 64 bit wide registers can be checked by calling
800 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
802 static inline void check_cp1_registers(DisasContext *ctx, int regs)
804 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
805 generate_exception(ctx, EXCP_RI);
808 /* This code generates a "reserved instruction" exception if the
809 CPU does not support the instruction set corresponding to flags. */
810 static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
812 if (unlikely(!(env->insn_flags & flags)))
813 generate_exception(ctx, EXCP_RI);
816 /* This code generates a "reserved instruction" exception if 64-bit
817 instructions are not enabled. */
818 static inline void check_mips_64(DisasContext *ctx)
820 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
821 generate_exception(ctx, EXCP_RI);
824 /* Define small wrappers for gen_load_fpr* so that we have a uniform
825 calling interface for 32 and 64-bit FPRs. No sense in changing
826 all callers for gen_load_fpr32 when we need the CTX parameter for
827 this one use. */
828 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
829 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
830 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
831 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
832 int ft, int fs, int cc) \
834 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
835 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
836 switch (ifmt) { \
837 case FMT_PS: \
838 check_cp1_64bitmode(ctx); \
839 break; \
840 case FMT_D: \
841 if (abs) { \
842 check_cop1x(ctx); \
844 check_cp1_registers(ctx, fs | ft); \
845 break; \
846 case FMT_S: \
847 if (abs) { \
848 check_cop1x(ctx); \
850 break; \
852 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
853 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
854 switch (n) { \
855 case 0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
856 case 1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
857 case 2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
858 case 3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
859 case 4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
860 case 5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
861 case 6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
862 case 7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
863 case 8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
864 case 9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
865 case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
866 case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
867 case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
868 case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
869 case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
870 case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
871 default: abort(); \
873 tcg_temp_free_i##bits (fp0); \
874 tcg_temp_free_i##bits (fp1); \
877 FOP_CONDS(, 0, d, FMT_D, 64)
878 FOP_CONDS(abs, 1, d, FMT_D, 64)
879 FOP_CONDS(, 0, s, FMT_S, 32)
880 FOP_CONDS(abs, 1, s, FMT_S, 32)
881 FOP_CONDS(, 0, ps, FMT_PS, 64)
882 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
883 #undef FOP_CONDS
884 #undef gen_ldcmp_fpr32
885 #undef gen_ldcmp_fpr64
887 /* load/store instructions. */
888 #define OP_LD(insn,fname) \
889 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
891 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
893 OP_LD(lb,ld8s);
894 OP_LD(lbu,ld8u);
895 OP_LD(lh,ld16s);
896 OP_LD(lhu,ld16u);
897 OP_LD(lw,ld32s);
898 #if defined(TARGET_MIPS64)
899 OP_LD(lwu,ld32u);
900 OP_LD(ld,ld64);
901 #endif
902 #undef OP_LD
904 #define OP_ST(insn,fname) \
905 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
907 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
909 OP_ST(sb,st8);
910 OP_ST(sh,st16);
911 OP_ST(sw,st32);
912 #if defined(TARGET_MIPS64)
913 OP_ST(sd,st64);
914 #endif
915 #undef OP_ST
917 #ifdef CONFIG_USER_ONLY
918 #define OP_LD_ATOMIC(insn,fname) \
919 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
921 TCGv t0 = tcg_temp_new(); \
922 tcg_gen_mov_tl(t0, arg1); \
923 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
924 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
925 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval)); \
926 tcg_temp_free(t0); \
928 #else
929 #define OP_LD_ATOMIC(insn,fname) \
930 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
932 gen_helper_2i(insn, ret, arg1, ctx->mem_idx); \
934 #endif
935 OP_LD_ATOMIC(ll,ld32s);
936 #if defined(TARGET_MIPS64)
937 OP_LD_ATOMIC(lld,ld64);
938 #endif
939 #undef OP_LD_ATOMIC
941 #ifdef CONFIG_USER_ONLY
942 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
943 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
945 TCGv t0 = tcg_temp_new(); \
946 int l1 = gen_new_label(); \
947 int l2 = gen_new_label(); \
949 tcg_gen_andi_tl(t0, arg2, almask); \
950 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
951 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
952 generate_exception(ctx, EXCP_AdES); \
953 gen_set_label(l1); \
954 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
955 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
956 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
957 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg)); \
958 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval)); \
959 gen_helper_0i(raise_exception, EXCP_SC); \
960 gen_set_label(l2); \
961 tcg_gen_movi_tl(t0, 0); \
962 gen_store_gpr(t0, rt); \
963 tcg_temp_free(t0); \
965 #else
966 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
967 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
969 TCGv t0 = tcg_temp_new(); \
970 gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx); \
971 gen_store_gpr(t0, rt); \
972 tcg_temp_free(t0); \
974 #endif
975 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
976 #if defined(TARGET_MIPS64)
977 OP_ST_ATOMIC(scd,st64,ld64,0x7);
978 #endif
979 #undef OP_ST_ATOMIC
981 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
982 int base, int16_t offset)
984 if (base == 0) {
985 tcg_gen_movi_tl(addr, offset);
986 } else if (offset == 0) {
987 gen_load_gpr(addr, base);
988 } else {
989 tcg_gen_movi_tl(addr, offset);
990 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
994 static target_ulong pc_relative_pc (DisasContext *ctx)
996 target_ulong pc = ctx->pc;
998 if (ctx->hflags & MIPS_HFLAG_BMASK) {
999 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1001 pc -= branch_bytes;
1004 pc &= ~(target_ulong)3;
1005 return pc;
1008 /* Load and store */
1009 static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1010 int base, int16_t offset)
1012 const char *opn = "ldst";
1013 TCGv t0 = tcg_temp_new();
1014 TCGv t1 = tcg_temp_new();
1016 gen_base_offset_addr(ctx, t0, base, offset);
1017 /* Don't do NOP if destination is zero: we must perform the actual
1018 memory access. */
1019 switch (opc) {
1020 #if defined(TARGET_MIPS64)
1021 case OPC_LWU:
1022 save_cpu_state(ctx, 0);
1023 op_ldst_lwu(t0, t0, ctx);
1024 gen_store_gpr(t0, rt);
1025 opn = "lwu";
1026 break;
1027 case OPC_LD:
1028 save_cpu_state(ctx, 0);
1029 op_ldst_ld(t0, t0, ctx);
1030 gen_store_gpr(t0, rt);
1031 opn = "ld";
1032 break;
1033 case OPC_LLD:
1034 save_cpu_state(ctx, 0);
1035 op_ldst_lld(t0, t0, ctx);
1036 gen_store_gpr(t0, rt);
1037 opn = "lld";
1038 break;
1039 case OPC_SD:
1040 save_cpu_state(ctx, 0);
1041 gen_load_gpr(t1, rt);
1042 op_ldst_sd(t1, t0, ctx);
1043 opn = "sd";
1044 break;
1045 case OPC_LDL:
1046 save_cpu_state(ctx, 1);
1047 gen_load_gpr(t1, rt);
1048 gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1049 gen_store_gpr(t1, rt);
1050 opn = "ldl";
1051 break;
1052 case OPC_SDL:
1053 save_cpu_state(ctx, 1);
1054 gen_load_gpr(t1, rt);
1055 gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1056 opn = "sdl";
1057 break;
1058 case OPC_LDR:
1059 save_cpu_state(ctx, 1);
1060 gen_load_gpr(t1, rt);
1061 gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1062 gen_store_gpr(t1, rt);
1063 opn = "ldr";
1064 break;
1065 case OPC_SDR:
1066 save_cpu_state(ctx, 1);
1067 gen_load_gpr(t1, rt);
1068 gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1069 opn = "sdr";
1070 break;
1071 case OPC_LDPC:
1072 save_cpu_state(ctx, 1);
1073 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1074 gen_op_addr_add(ctx, t0, t0, t1);
1075 op_ldst_ld(t0, t0, ctx);
1076 gen_store_gpr(t0, rt);
1077 break;
1078 #endif
1079 case OPC_LWPC:
1080 save_cpu_state(ctx, 1);
1081 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1082 gen_op_addr_add(ctx, t0, t0, t1);
1083 op_ldst_lw(t0, t0, ctx);
1084 gen_store_gpr(t0, rt);
1085 break;
1086 case OPC_LW:
1087 save_cpu_state(ctx, 0);
1088 op_ldst_lw(t0, t0, ctx);
1089 gen_store_gpr(t0, rt);
1090 opn = "lw";
1091 break;
1092 case OPC_SW:
1093 save_cpu_state(ctx, 0);
1094 gen_load_gpr(t1, rt);
1095 op_ldst_sw(t1, t0, ctx);
1096 opn = "sw";
1097 break;
1098 case OPC_LH:
1099 save_cpu_state(ctx, 0);
1100 op_ldst_lh(t0, t0, ctx);
1101 gen_store_gpr(t0, rt);
1102 opn = "lh";
1103 break;
1104 case OPC_SH:
1105 save_cpu_state(ctx, 0);
1106 gen_load_gpr(t1, rt);
1107 op_ldst_sh(t1, t0, ctx);
1108 opn = "sh";
1109 break;
1110 case OPC_LHU:
1111 save_cpu_state(ctx, 0);
1112 op_ldst_lhu(t0, t0, ctx);
1113 gen_store_gpr(t0, rt);
1114 opn = "lhu";
1115 break;
1116 case OPC_LB:
1117 save_cpu_state(ctx, 0);
1118 op_ldst_lb(t0, t0, ctx);
1119 gen_store_gpr(t0, rt);
1120 opn = "lb";
1121 break;
1122 case OPC_SB:
1123 save_cpu_state(ctx, 0);
1124 gen_load_gpr(t1, rt);
1125 op_ldst_sb(t1, t0, ctx);
1126 opn = "sb";
1127 break;
1128 case OPC_LBU:
1129 save_cpu_state(ctx, 0);
1130 op_ldst_lbu(t0, t0, ctx);
1131 gen_store_gpr(t0, rt);
1132 opn = "lbu";
1133 break;
1134 case OPC_LWL:
1135 save_cpu_state(ctx, 1);
1136 gen_load_gpr(t1, rt);
1137 gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1138 gen_store_gpr(t1, rt);
1139 opn = "lwl";
1140 break;
1141 case OPC_SWL:
1142 save_cpu_state(ctx, 1);
1143 gen_load_gpr(t1, rt);
1144 gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1145 opn = "swr";
1146 break;
1147 case OPC_LWR:
1148 save_cpu_state(ctx, 1);
1149 gen_load_gpr(t1, rt);
1150 gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1151 gen_store_gpr(t1, rt);
1152 opn = "lwr";
1153 break;
1154 case OPC_SWR:
1155 save_cpu_state(ctx, 1);
1156 gen_load_gpr(t1, rt);
1157 gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1158 opn = "swr";
1159 break;
1160 case OPC_LL:
1161 save_cpu_state(ctx, 1);
1162 op_ldst_ll(t0, t0, ctx);
1163 gen_store_gpr(t0, rt);
1164 opn = "ll";
1165 break;
1167 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1168 tcg_temp_free(t0);
1169 tcg_temp_free(t1);
1172 /* Store conditional */
1173 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1174 int base, int16_t offset)
1176 const char *opn = "st_cond";
1177 TCGv t0, t1;
1179 t0 = tcg_temp_local_new();
1181 gen_base_offset_addr(ctx, t0, base, offset);
1182 /* Don't do NOP if destination is zero: we must perform the actual
1183 memory access. */
1185 t1 = tcg_temp_local_new();
1186 gen_load_gpr(t1, rt);
1187 switch (opc) {
1188 #if defined(TARGET_MIPS64)
1189 case OPC_SCD:
1190 save_cpu_state(ctx, 0);
1191 op_ldst_scd(t1, t0, rt, ctx);
1192 opn = "scd";
1193 break;
1194 #endif
1195 case OPC_SC:
1196 save_cpu_state(ctx, 1);
1197 op_ldst_sc(t1, t0, rt, ctx);
1198 opn = "sc";
1199 break;
1201 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1202 tcg_temp_free(t1);
1203 tcg_temp_free(t0);
1206 /* Load and store */
1207 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1208 int base, int16_t offset)
1210 const char *opn = "flt_ldst";
1211 TCGv t0 = tcg_temp_new();
1213 gen_base_offset_addr(ctx, t0, base, offset);
1214 /* Don't do NOP if destination is zero: we must perform the actual
1215 memory access. */
1216 switch (opc) {
1217 case OPC_LWC1:
1219 TCGv_i32 fp0 = tcg_temp_new_i32();
1221 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1222 tcg_gen_trunc_tl_i32(fp0, t0);
1223 gen_store_fpr32(fp0, ft);
1224 tcg_temp_free_i32(fp0);
1226 opn = "lwc1";
1227 break;
1228 case OPC_SWC1:
1230 TCGv_i32 fp0 = tcg_temp_new_i32();
1231 TCGv t1 = tcg_temp_new();
1233 gen_load_fpr32(fp0, ft);
1234 tcg_gen_extu_i32_tl(t1, fp0);
1235 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1236 tcg_temp_free(t1);
1237 tcg_temp_free_i32(fp0);
1239 opn = "swc1";
1240 break;
1241 case OPC_LDC1:
1243 TCGv_i64 fp0 = tcg_temp_new_i64();
1245 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1246 gen_store_fpr64(ctx, fp0, ft);
1247 tcg_temp_free_i64(fp0);
1249 opn = "ldc1";
1250 break;
1251 case OPC_SDC1:
1253 TCGv_i64 fp0 = tcg_temp_new_i64();
1255 gen_load_fpr64(ctx, fp0, ft);
1256 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1257 tcg_temp_free_i64(fp0);
1259 opn = "sdc1";
1260 break;
1261 default:
1262 MIPS_INVAL(opn);
1263 generate_exception(ctx, EXCP_RI);
1264 goto out;
1266 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1267 out:
1268 tcg_temp_free(t0);
1271 static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1272 uint32_t op, int rt, int rs, int16_t imm)
1274 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1275 check_cp1_enabled(ctx);
1276 gen_flt_ldst(ctx, op, rt, rs, imm);
1277 } else {
1278 generate_exception_err(ctx, EXCP_CpU, 1);
1282 /* Arithmetic with immediate operand */
1283 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1284 int rt, int rs, int16_t imm)
1286 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1287 const char *opn = "imm arith";
1289 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1290 /* If no destination, treat it as a NOP.
1291 For addi, we must generate the overflow exception when needed. */
1292 MIPS_DEBUG("NOP");
1293 return;
1295 switch (opc) {
1296 case OPC_ADDI:
1298 TCGv t0 = tcg_temp_local_new();
1299 TCGv t1 = tcg_temp_new();
1300 TCGv t2 = tcg_temp_new();
1301 int l1 = gen_new_label();
1303 gen_load_gpr(t1, rs);
1304 tcg_gen_addi_tl(t0, t1, uimm);
1305 tcg_gen_ext32s_tl(t0, t0);
1307 tcg_gen_xori_tl(t1, t1, ~uimm);
1308 tcg_gen_xori_tl(t2, t0, uimm);
1309 tcg_gen_and_tl(t1, t1, t2);
1310 tcg_temp_free(t2);
1311 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1312 tcg_temp_free(t1);
1313 /* operands of same sign, result different sign */
1314 generate_exception(ctx, EXCP_OVERFLOW);
1315 gen_set_label(l1);
1316 tcg_gen_ext32s_tl(t0, t0);
1317 gen_store_gpr(t0, rt);
1318 tcg_temp_free(t0);
1320 opn = "addi";
1321 break;
1322 case OPC_ADDIU:
1323 if (rs != 0) {
1324 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1325 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1326 } else {
1327 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1329 opn = "addiu";
1330 break;
1331 #if defined(TARGET_MIPS64)
1332 case OPC_DADDI:
1334 TCGv t0 = tcg_temp_local_new();
1335 TCGv t1 = tcg_temp_new();
1336 TCGv t2 = tcg_temp_new();
1337 int l1 = gen_new_label();
1339 gen_load_gpr(t1, rs);
1340 tcg_gen_addi_tl(t0, t1, uimm);
1342 tcg_gen_xori_tl(t1, t1, ~uimm);
1343 tcg_gen_xori_tl(t2, t0, uimm);
1344 tcg_gen_and_tl(t1, t1, t2);
1345 tcg_temp_free(t2);
1346 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1347 tcg_temp_free(t1);
1348 /* operands of same sign, result different sign */
1349 generate_exception(ctx, EXCP_OVERFLOW);
1350 gen_set_label(l1);
1351 gen_store_gpr(t0, rt);
1352 tcg_temp_free(t0);
1354 opn = "daddi";
1355 break;
1356 case OPC_DADDIU:
1357 if (rs != 0) {
1358 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1359 } else {
1360 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1362 opn = "daddiu";
1363 break;
1364 #endif
1366 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1369 /* Logic with immediate operand */
1370 static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1372 target_ulong uimm;
1373 const char *opn = "imm logic";
1375 if (rt == 0) {
1376 /* If no destination, treat it as a NOP. */
1377 MIPS_DEBUG("NOP");
1378 return;
1380 uimm = (uint16_t)imm;
1381 switch (opc) {
1382 case OPC_ANDI:
1383 if (likely(rs != 0))
1384 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1385 else
1386 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1387 opn = "andi";
1388 break;
1389 case OPC_ORI:
1390 if (rs != 0)
1391 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1392 else
1393 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1394 opn = "ori";
1395 break;
1396 case OPC_XORI:
1397 if (likely(rs != 0))
1398 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1399 else
1400 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1401 opn = "xori";
1402 break;
1403 case OPC_LUI:
1404 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1405 opn = "lui";
1406 break;
1408 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1411 /* Set on less than with immediate operand */
1412 static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1414 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1415 const char *opn = "imm arith";
1416 TCGv t0;
1418 if (rt == 0) {
1419 /* If no destination, treat it as a NOP. */
1420 MIPS_DEBUG("NOP");
1421 return;
1423 t0 = tcg_temp_new();
1424 gen_load_gpr(t0, rs);
1425 switch (opc) {
1426 case OPC_SLTI:
1427 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1428 opn = "slti";
1429 break;
1430 case OPC_SLTIU:
1431 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1432 opn = "sltiu";
1433 break;
1435 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1436 tcg_temp_free(t0);
1439 /* Shifts with immediate operand */
1440 static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1441 int rt, int rs, int16_t imm)
1443 target_ulong uimm = ((uint16_t)imm) & 0x1f;
1444 const char *opn = "imm shift";
1445 TCGv t0;
1447 if (rt == 0) {
1448 /* If no destination, treat it as a NOP. */
1449 MIPS_DEBUG("NOP");
1450 return;
1453 t0 = tcg_temp_new();
1454 gen_load_gpr(t0, rs);
1455 switch (opc) {
1456 case OPC_SLL:
1457 tcg_gen_shli_tl(t0, t0, uimm);
1458 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1459 opn = "sll";
1460 break;
1461 case OPC_SRA:
1462 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1463 opn = "sra";
1464 break;
1465 case OPC_SRL:
1466 if (uimm != 0) {
1467 tcg_gen_ext32u_tl(t0, t0);
1468 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1469 } else {
1470 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1472 opn = "srl";
1473 break;
1474 case OPC_ROTR:
1475 if (uimm != 0) {
1476 TCGv_i32 t1 = tcg_temp_new_i32();
1478 tcg_gen_trunc_tl_i32(t1, t0);
1479 tcg_gen_rotri_i32(t1, t1, uimm);
1480 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1481 tcg_temp_free_i32(t1);
1482 } else {
1483 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1485 opn = "rotr";
1486 break;
1487 #if defined(TARGET_MIPS64)
1488 case OPC_DSLL:
1489 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1490 opn = "dsll";
1491 break;
1492 case OPC_DSRA:
1493 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1494 opn = "dsra";
1495 break;
1496 case OPC_DSRL:
1497 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1498 opn = "dsrl";
1499 break;
1500 case OPC_DROTR:
1501 if (uimm != 0) {
1502 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1503 } else {
1504 tcg_gen_mov_tl(cpu_gpr[rt], t0);
1506 opn = "drotr";
1507 break;
1508 case OPC_DSLL32:
1509 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1510 opn = "dsll32";
1511 break;
1512 case OPC_DSRA32:
1513 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1514 opn = "dsra32";
1515 break;
1516 case OPC_DSRL32:
1517 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1518 opn = "dsrl32";
1519 break;
1520 case OPC_DROTR32:
1521 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1522 opn = "drotr32";
1523 break;
1524 #endif
1526 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1527 tcg_temp_free(t0);
1530 /* Arithmetic */
1531 static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1532 int rd, int rs, int rt)
1534 const char *opn = "arith";
1536 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1537 && opc != OPC_DADD && opc != OPC_DSUB) {
1538 /* If no destination, treat it as a NOP.
1539 For add & sub, we must generate the overflow exception when needed. */
1540 MIPS_DEBUG("NOP");
1541 return;
1544 switch (opc) {
1545 case OPC_ADD:
1547 TCGv t0 = tcg_temp_local_new();
1548 TCGv t1 = tcg_temp_new();
1549 TCGv t2 = tcg_temp_new();
1550 int l1 = gen_new_label();
1552 gen_load_gpr(t1, rs);
1553 gen_load_gpr(t2, rt);
1554 tcg_gen_add_tl(t0, t1, t2);
1555 tcg_gen_ext32s_tl(t0, t0);
1556 tcg_gen_xor_tl(t1, t1, t2);
1557 tcg_gen_xor_tl(t2, t0, t2);
1558 tcg_gen_andc_tl(t1, t2, t1);
1559 tcg_temp_free(t2);
1560 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1561 tcg_temp_free(t1);
1562 /* operands of same sign, result different sign */
1563 generate_exception(ctx, EXCP_OVERFLOW);
1564 gen_set_label(l1);
1565 gen_store_gpr(t0, rd);
1566 tcg_temp_free(t0);
1568 opn = "add";
1569 break;
1570 case OPC_ADDU:
1571 if (rs != 0 && rt != 0) {
1572 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1573 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1574 } else if (rs == 0 && rt != 0) {
1575 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1576 } else if (rs != 0 && rt == 0) {
1577 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1578 } else {
1579 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1581 opn = "addu";
1582 break;
1583 case OPC_SUB:
1585 TCGv t0 = tcg_temp_local_new();
1586 TCGv t1 = tcg_temp_new();
1587 TCGv t2 = tcg_temp_new();
1588 int l1 = gen_new_label();
1590 gen_load_gpr(t1, rs);
1591 gen_load_gpr(t2, rt);
1592 tcg_gen_sub_tl(t0, t1, t2);
1593 tcg_gen_ext32s_tl(t0, t0);
1594 tcg_gen_xor_tl(t2, t1, t2);
1595 tcg_gen_xor_tl(t1, t0, t1);
1596 tcg_gen_and_tl(t1, t1, t2);
1597 tcg_temp_free(t2);
1598 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1599 tcg_temp_free(t1);
1600 /* operands of different sign, first operand and result different sign */
1601 generate_exception(ctx, EXCP_OVERFLOW);
1602 gen_set_label(l1);
1603 gen_store_gpr(t0, rd);
1604 tcg_temp_free(t0);
1606 opn = "sub";
1607 break;
1608 case OPC_SUBU:
1609 if (rs != 0 && rt != 0) {
1610 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1611 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1612 } else if (rs == 0 && rt != 0) {
1613 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1614 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1615 } else if (rs != 0 && rt == 0) {
1616 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1617 } else {
1618 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1620 opn = "subu";
1621 break;
1622 #if defined(TARGET_MIPS64)
1623 case OPC_DADD:
1625 TCGv t0 = tcg_temp_local_new();
1626 TCGv t1 = tcg_temp_new();
1627 TCGv t2 = tcg_temp_new();
1628 int l1 = gen_new_label();
1630 gen_load_gpr(t1, rs);
1631 gen_load_gpr(t2, rt);
1632 tcg_gen_add_tl(t0, t1, t2);
1633 tcg_gen_xor_tl(t1, t1, t2);
1634 tcg_gen_xor_tl(t2, t0, t2);
1635 tcg_gen_andc_tl(t1, t2, t1);
1636 tcg_temp_free(t2);
1637 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1638 tcg_temp_free(t1);
1639 /* operands of same sign, result different sign */
1640 generate_exception(ctx, EXCP_OVERFLOW);
1641 gen_set_label(l1);
1642 gen_store_gpr(t0, rd);
1643 tcg_temp_free(t0);
1645 opn = "dadd";
1646 break;
1647 case OPC_DADDU:
1648 if (rs != 0 && rt != 0) {
1649 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1650 } else if (rs == 0 && rt != 0) {
1651 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1652 } else if (rs != 0 && rt == 0) {
1653 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1654 } else {
1655 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1657 opn = "daddu";
1658 break;
1659 case OPC_DSUB:
1661 TCGv t0 = tcg_temp_local_new();
1662 TCGv t1 = tcg_temp_new();
1663 TCGv t2 = tcg_temp_new();
1664 int l1 = gen_new_label();
1666 gen_load_gpr(t1, rs);
1667 gen_load_gpr(t2, rt);
1668 tcg_gen_sub_tl(t0, t1, t2);
1669 tcg_gen_xor_tl(t2, t1, t2);
1670 tcg_gen_xor_tl(t1, t0, t1);
1671 tcg_gen_and_tl(t1, t1, t2);
1672 tcg_temp_free(t2);
1673 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1674 tcg_temp_free(t1);
1675 /* operands of different sign, first operand and result different sign */
1676 generate_exception(ctx, EXCP_OVERFLOW);
1677 gen_set_label(l1);
1678 gen_store_gpr(t0, rd);
1679 tcg_temp_free(t0);
1681 opn = "dsub";
1682 break;
1683 case OPC_DSUBU:
1684 if (rs != 0 && rt != 0) {
1685 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1686 } else if (rs == 0 && rt != 0) {
1687 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1688 } else if (rs != 0 && rt == 0) {
1689 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1690 } else {
1691 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1693 opn = "dsubu";
1694 break;
1695 #endif
1696 case OPC_MUL:
1697 if (likely(rs != 0 && rt != 0)) {
1698 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1699 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1700 } else {
1701 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1703 opn = "mul";
1704 break;
1706 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1709 /* Conditional move */
1710 static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1712 const char *opn = "cond move";
1713 int l1;
1715 if (rd == 0) {
1716 /* If no destination, treat it as a NOP.
1717 For add & sub, we must generate the overflow exception when needed. */
1718 MIPS_DEBUG("NOP");
1719 return;
1722 l1 = gen_new_label();
1723 switch (opc) {
1724 case OPC_MOVN:
1725 if (likely(rt != 0))
1726 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1727 else
1728 tcg_gen_br(l1);
1729 opn = "movn";
1730 break;
1731 case OPC_MOVZ:
1732 if (likely(rt != 0))
1733 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1734 opn = "movz";
1735 break;
1737 if (rs != 0)
1738 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1739 else
1740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1741 gen_set_label(l1);
1743 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1746 /* Logic */
1747 static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1749 const char *opn = "logic";
1751 if (rd == 0) {
1752 /* If no destination, treat it as a NOP. */
1753 MIPS_DEBUG("NOP");
1754 return;
1757 switch (opc) {
1758 case OPC_AND:
1759 if (likely(rs != 0 && rt != 0)) {
1760 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1761 } else {
1762 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1764 opn = "and";
1765 break;
1766 case OPC_NOR:
1767 if (rs != 0 && rt != 0) {
1768 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1769 } else if (rs == 0 && rt != 0) {
1770 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1771 } else if (rs != 0 && rt == 0) {
1772 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1773 } else {
1774 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1776 opn = "nor";
1777 break;
1778 case OPC_OR:
1779 if (likely(rs != 0 && rt != 0)) {
1780 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1781 } else if (rs == 0 && rt != 0) {
1782 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1783 } else if (rs != 0 && rt == 0) {
1784 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1785 } else {
1786 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1788 opn = "or";
1789 break;
1790 case OPC_XOR:
1791 if (likely(rs != 0 && rt != 0)) {
1792 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1793 } else if (rs == 0 && rt != 0) {
1794 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1795 } else if (rs != 0 && rt == 0) {
1796 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1797 } else {
1798 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1800 opn = "xor";
1801 break;
1803 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1806 /* Set on lower than */
1807 static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1809 const char *opn = "slt";
1810 TCGv t0, t1;
1812 if (rd == 0) {
1813 /* If no destination, treat it as a NOP. */
1814 MIPS_DEBUG("NOP");
1815 return;
1818 t0 = tcg_temp_new();
1819 t1 = tcg_temp_new();
1820 gen_load_gpr(t0, rs);
1821 gen_load_gpr(t1, rt);
1822 switch (opc) {
1823 case OPC_SLT:
1824 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1825 opn = "slt";
1826 break;
1827 case OPC_SLTU:
1828 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1829 opn = "sltu";
1830 break;
1832 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1833 tcg_temp_free(t0);
1834 tcg_temp_free(t1);
1837 /* Shifts */
1838 static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1839 int rd, int rs, int rt)
1841 const char *opn = "shifts";
1842 TCGv t0, t1;
1844 if (rd == 0) {
1845 /* If no destination, treat it as a NOP.
1846 For add & sub, we must generate the overflow exception when needed. */
1847 MIPS_DEBUG("NOP");
1848 return;
1851 t0 = tcg_temp_new();
1852 t1 = tcg_temp_new();
1853 gen_load_gpr(t0, rs);
1854 gen_load_gpr(t1, rt);
1855 switch (opc) {
1856 case OPC_SLLV:
1857 tcg_gen_andi_tl(t0, t0, 0x1f);
1858 tcg_gen_shl_tl(t0, t1, t0);
1859 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1860 opn = "sllv";
1861 break;
1862 case OPC_SRAV:
1863 tcg_gen_andi_tl(t0, t0, 0x1f);
1864 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1865 opn = "srav";
1866 break;
1867 case OPC_SRLV:
1868 tcg_gen_ext32u_tl(t1, t1);
1869 tcg_gen_andi_tl(t0, t0, 0x1f);
1870 tcg_gen_shr_tl(t0, t1, t0);
1871 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1872 opn = "srlv";
1873 break;
1874 case OPC_ROTRV:
1876 TCGv_i32 t2 = tcg_temp_new_i32();
1877 TCGv_i32 t3 = tcg_temp_new_i32();
1879 tcg_gen_trunc_tl_i32(t2, t0);
1880 tcg_gen_trunc_tl_i32(t3, t1);
1881 tcg_gen_andi_i32(t2, t2, 0x1f);
1882 tcg_gen_rotr_i32(t2, t3, t2);
1883 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1884 tcg_temp_free_i32(t2);
1885 tcg_temp_free_i32(t3);
1886 opn = "rotrv";
1888 break;
1889 #if defined(TARGET_MIPS64)
1890 case OPC_DSLLV:
1891 tcg_gen_andi_tl(t0, t0, 0x3f);
1892 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1893 opn = "dsllv";
1894 break;
1895 case OPC_DSRAV:
1896 tcg_gen_andi_tl(t0, t0, 0x3f);
1897 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1898 opn = "dsrav";
1899 break;
1900 case OPC_DSRLV:
1901 tcg_gen_andi_tl(t0, t0, 0x3f);
1902 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1903 opn = "dsrlv";
1904 break;
1905 case OPC_DROTRV:
1906 tcg_gen_andi_tl(t0, t0, 0x3f);
1907 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1908 opn = "drotrv";
1909 break;
1910 #endif
1912 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1913 tcg_temp_free(t0);
1914 tcg_temp_free(t1);
1917 /* Arithmetic on HI/LO registers */
1918 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1920 const char *opn = "hilo";
1922 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1923 /* Treat as NOP. */
1924 MIPS_DEBUG("NOP");
1925 return;
1927 switch (opc) {
1928 case OPC_MFHI:
1929 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1930 opn = "mfhi";
1931 break;
1932 case OPC_MFLO:
1933 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1934 opn = "mflo";
1935 break;
1936 case OPC_MTHI:
1937 if (reg != 0)
1938 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1939 else
1940 tcg_gen_movi_tl(cpu_HI[0], 0);
1941 opn = "mthi";
1942 break;
1943 case OPC_MTLO:
1944 if (reg != 0)
1945 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1946 else
1947 tcg_gen_movi_tl(cpu_LO[0], 0);
1948 opn = "mtlo";
1949 break;
1951 MIPS_DEBUG("%s %s", opn, regnames[reg]);
1954 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1955 int rs, int rt)
1957 const char *opn = "mul/div";
1958 TCGv t0, t1;
1960 switch (opc) {
1961 case OPC_DIV:
1962 case OPC_DIVU:
1963 #if defined(TARGET_MIPS64)
1964 case OPC_DDIV:
1965 case OPC_DDIVU:
1966 #endif
1967 t0 = tcg_temp_local_new();
1968 t1 = tcg_temp_local_new();
1969 break;
1970 default:
1971 t0 = tcg_temp_new();
1972 t1 = tcg_temp_new();
1973 break;
1976 gen_load_gpr(t0, rs);
1977 gen_load_gpr(t1, rt);
1978 switch (opc) {
1979 case OPC_DIV:
1981 int l1 = gen_new_label();
1982 int l2 = gen_new_label();
1984 tcg_gen_ext32s_tl(t0, t0);
1985 tcg_gen_ext32s_tl(t1, t1);
1986 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1987 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1988 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1990 tcg_gen_mov_tl(cpu_LO[0], t0);
1991 tcg_gen_movi_tl(cpu_HI[0], 0);
1992 tcg_gen_br(l1);
1993 gen_set_label(l2);
1994 tcg_gen_div_tl(cpu_LO[0], t0, t1);
1995 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1996 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1997 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1998 gen_set_label(l1);
2000 opn = "div";
2001 break;
2002 case OPC_DIVU:
2004 int l1 = gen_new_label();
2006 tcg_gen_ext32u_tl(t0, t0);
2007 tcg_gen_ext32u_tl(t1, t1);
2008 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2009 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2010 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2011 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2012 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2013 gen_set_label(l1);
2015 opn = "divu";
2016 break;
2017 case OPC_MULT:
2019 TCGv_i64 t2 = tcg_temp_new_i64();
2020 TCGv_i64 t3 = tcg_temp_new_i64();
2022 tcg_gen_ext_tl_i64(t2, t0);
2023 tcg_gen_ext_tl_i64(t3, t1);
2024 tcg_gen_mul_i64(t2, t2, t3);
2025 tcg_temp_free_i64(t3);
2026 tcg_gen_trunc_i64_tl(t0, t2);
2027 tcg_gen_shri_i64(t2, t2, 32);
2028 tcg_gen_trunc_i64_tl(t1, t2);
2029 tcg_temp_free_i64(t2);
2030 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2031 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2033 opn = "mult";
2034 break;
2035 case OPC_MULTU:
2037 TCGv_i64 t2 = tcg_temp_new_i64();
2038 TCGv_i64 t3 = tcg_temp_new_i64();
2040 tcg_gen_ext32u_tl(t0, t0);
2041 tcg_gen_ext32u_tl(t1, t1);
2042 tcg_gen_extu_tl_i64(t2, t0);
2043 tcg_gen_extu_tl_i64(t3, t1);
2044 tcg_gen_mul_i64(t2, t2, t3);
2045 tcg_temp_free_i64(t3);
2046 tcg_gen_trunc_i64_tl(t0, t2);
2047 tcg_gen_shri_i64(t2, t2, 32);
2048 tcg_gen_trunc_i64_tl(t1, t2);
2049 tcg_temp_free_i64(t2);
2050 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2051 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2053 opn = "multu";
2054 break;
2055 #if defined(TARGET_MIPS64)
2056 case OPC_DDIV:
2058 int l1 = gen_new_label();
2059 int l2 = gen_new_label();
2061 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2062 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2063 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2064 tcg_gen_mov_tl(cpu_LO[0], t0);
2065 tcg_gen_movi_tl(cpu_HI[0], 0);
2066 tcg_gen_br(l1);
2067 gen_set_label(l2);
2068 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2069 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2070 gen_set_label(l1);
2072 opn = "ddiv";
2073 break;
2074 case OPC_DDIVU:
2076 int l1 = gen_new_label();
2078 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2079 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2080 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2081 gen_set_label(l1);
2083 opn = "ddivu";
2084 break;
2085 case OPC_DMULT:
2086 gen_helper_dmult(t0, t1);
2087 opn = "dmult";
2088 break;
2089 case OPC_DMULTU:
2090 gen_helper_dmultu(t0, t1);
2091 opn = "dmultu";
2092 break;
2093 #endif
2094 case OPC_MADD:
2096 TCGv_i64 t2 = tcg_temp_new_i64();
2097 TCGv_i64 t3 = tcg_temp_new_i64();
2099 tcg_gen_ext_tl_i64(t2, t0);
2100 tcg_gen_ext_tl_i64(t3, t1);
2101 tcg_gen_mul_i64(t2, t2, t3);
2102 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2103 tcg_gen_add_i64(t2, t2, t3);
2104 tcg_temp_free_i64(t3);
2105 tcg_gen_trunc_i64_tl(t0, t2);
2106 tcg_gen_shri_i64(t2, t2, 32);
2107 tcg_gen_trunc_i64_tl(t1, t2);
2108 tcg_temp_free_i64(t2);
2109 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2110 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2112 opn = "madd";
2113 break;
2114 case OPC_MADDU:
2116 TCGv_i64 t2 = tcg_temp_new_i64();
2117 TCGv_i64 t3 = tcg_temp_new_i64();
2119 tcg_gen_ext32u_tl(t0, t0);
2120 tcg_gen_ext32u_tl(t1, t1);
2121 tcg_gen_extu_tl_i64(t2, t0);
2122 tcg_gen_extu_tl_i64(t3, t1);
2123 tcg_gen_mul_i64(t2, t2, t3);
2124 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2125 tcg_gen_add_i64(t2, t2, t3);
2126 tcg_temp_free_i64(t3);
2127 tcg_gen_trunc_i64_tl(t0, t2);
2128 tcg_gen_shri_i64(t2, t2, 32);
2129 tcg_gen_trunc_i64_tl(t1, t2);
2130 tcg_temp_free_i64(t2);
2131 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2132 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2134 opn = "maddu";
2135 break;
2136 case OPC_MSUB:
2138 TCGv_i64 t2 = tcg_temp_new_i64();
2139 TCGv_i64 t3 = tcg_temp_new_i64();
2141 tcg_gen_ext_tl_i64(t2, t0);
2142 tcg_gen_ext_tl_i64(t3, t1);
2143 tcg_gen_mul_i64(t2, t2, t3);
2144 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2145 tcg_gen_sub_i64(t2, t3, t2);
2146 tcg_temp_free_i64(t3);
2147 tcg_gen_trunc_i64_tl(t0, t2);
2148 tcg_gen_shri_i64(t2, t2, 32);
2149 tcg_gen_trunc_i64_tl(t1, t2);
2150 tcg_temp_free_i64(t2);
2151 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2152 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2154 opn = "msub";
2155 break;
2156 case OPC_MSUBU:
2158 TCGv_i64 t2 = tcg_temp_new_i64();
2159 TCGv_i64 t3 = tcg_temp_new_i64();
2161 tcg_gen_ext32u_tl(t0, t0);
2162 tcg_gen_ext32u_tl(t1, t1);
2163 tcg_gen_extu_tl_i64(t2, t0);
2164 tcg_gen_extu_tl_i64(t3, t1);
2165 tcg_gen_mul_i64(t2, t2, t3);
2166 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2167 tcg_gen_sub_i64(t2, t3, t2);
2168 tcg_temp_free_i64(t3);
2169 tcg_gen_trunc_i64_tl(t0, t2);
2170 tcg_gen_shri_i64(t2, t2, 32);
2171 tcg_gen_trunc_i64_tl(t1, t2);
2172 tcg_temp_free_i64(t2);
2173 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2174 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2176 opn = "msubu";
2177 break;
2178 default:
2179 MIPS_INVAL(opn);
2180 generate_exception(ctx, EXCP_RI);
2181 goto out;
2183 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2184 out:
2185 tcg_temp_free(t0);
2186 tcg_temp_free(t1);
2189 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2190 int rd, int rs, int rt)
2192 const char *opn = "mul vr54xx";
2193 TCGv t0 = tcg_temp_new();
2194 TCGv t1 = tcg_temp_new();
2196 gen_load_gpr(t0, rs);
2197 gen_load_gpr(t1, rt);
2199 switch (opc) {
2200 case OPC_VR54XX_MULS:
2201 gen_helper_muls(t0, t0, t1);
2202 opn = "muls";
2203 break;
2204 case OPC_VR54XX_MULSU:
2205 gen_helper_mulsu(t0, t0, t1);
2206 opn = "mulsu";
2207 break;
2208 case OPC_VR54XX_MACC:
2209 gen_helper_macc(t0, t0, t1);
2210 opn = "macc";
2211 break;
2212 case OPC_VR54XX_MACCU:
2213 gen_helper_maccu(t0, t0, t1);
2214 opn = "maccu";
2215 break;
2216 case OPC_VR54XX_MSAC:
2217 gen_helper_msac(t0, t0, t1);
2218 opn = "msac";
2219 break;
2220 case OPC_VR54XX_MSACU:
2221 gen_helper_msacu(t0, t0, t1);
2222 opn = "msacu";
2223 break;
2224 case OPC_VR54XX_MULHI:
2225 gen_helper_mulhi(t0, t0, t1);
2226 opn = "mulhi";
2227 break;
2228 case OPC_VR54XX_MULHIU:
2229 gen_helper_mulhiu(t0, t0, t1);
2230 opn = "mulhiu";
2231 break;
2232 case OPC_VR54XX_MULSHI:
2233 gen_helper_mulshi(t0, t0, t1);
2234 opn = "mulshi";
2235 break;
2236 case OPC_VR54XX_MULSHIU:
2237 gen_helper_mulshiu(t0, t0, t1);
2238 opn = "mulshiu";
2239 break;
2240 case OPC_VR54XX_MACCHI:
2241 gen_helper_macchi(t0, t0, t1);
2242 opn = "macchi";
2243 break;
2244 case OPC_VR54XX_MACCHIU:
2245 gen_helper_macchiu(t0, t0, t1);
2246 opn = "macchiu";
2247 break;
2248 case OPC_VR54XX_MSACHI:
2249 gen_helper_msachi(t0, t0, t1);
2250 opn = "msachi";
2251 break;
2252 case OPC_VR54XX_MSACHIU:
2253 gen_helper_msachiu(t0, t0, t1);
2254 opn = "msachiu";
2255 break;
2256 default:
2257 MIPS_INVAL("mul vr54xx");
2258 generate_exception(ctx, EXCP_RI);
2259 goto out;
2261 gen_store_gpr(t0, rd);
2262 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2264 out:
2265 tcg_temp_free(t0);
2266 tcg_temp_free(t1);
2269 static void gen_cl (DisasContext *ctx, uint32_t opc,
2270 int rd, int rs)
2272 const char *opn = "CLx";
2273 TCGv t0;
2275 if (rd == 0) {
2276 /* Treat as NOP. */
2277 MIPS_DEBUG("NOP");
2278 return;
2280 t0 = tcg_temp_new();
2281 gen_load_gpr(t0, rs);
2282 switch (opc) {
2283 case OPC_CLO:
2284 gen_helper_clo(cpu_gpr[rd], t0);
2285 opn = "clo";
2286 break;
2287 case OPC_CLZ:
2288 gen_helper_clz(cpu_gpr[rd], t0);
2289 opn = "clz";
2290 break;
2291 #if defined(TARGET_MIPS64)
2292 case OPC_DCLO:
2293 gen_helper_dclo(cpu_gpr[rd], t0);
2294 opn = "dclo";
2295 break;
2296 case OPC_DCLZ:
2297 gen_helper_dclz(cpu_gpr[rd], t0);
2298 opn = "dclz";
2299 break;
2300 #endif
2302 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2303 tcg_temp_free(t0);
2306 /* Traps */
2307 static void gen_trap (DisasContext *ctx, uint32_t opc,
2308 int rs, int rt, int16_t imm)
2310 int cond;
2311 TCGv t0 = tcg_temp_new();
2312 TCGv t1 = tcg_temp_new();
2314 cond = 0;
2315 /* Load needed operands */
2316 switch (opc) {
2317 case OPC_TEQ:
2318 case OPC_TGE:
2319 case OPC_TGEU:
2320 case OPC_TLT:
2321 case OPC_TLTU:
2322 case OPC_TNE:
2323 /* Compare two registers */
2324 if (rs != rt) {
2325 gen_load_gpr(t0, rs);
2326 gen_load_gpr(t1, rt);
2327 cond = 1;
2329 break;
2330 case OPC_TEQI:
2331 case OPC_TGEI:
2332 case OPC_TGEIU:
2333 case OPC_TLTI:
2334 case OPC_TLTIU:
2335 case OPC_TNEI:
2336 /* Compare register to immediate */
2337 if (rs != 0 || imm != 0) {
2338 gen_load_gpr(t0, rs);
2339 tcg_gen_movi_tl(t1, (int32_t)imm);
2340 cond = 1;
2342 break;
2344 if (cond == 0) {
2345 switch (opc) {
2346 case OPC_TEQ: /* rs == rs */
2347 case OPC_TEQI: /* r0 == 0 */
2348 case OPC_TGE: /* rs >= rs */
2349 case OPC_TGEI: /* r0 >= 0 */
2350 case OPC_TGEU: /* rs >= rs unsigned */
2351 case OPC_TGEIU: /* r0 >= 0 unsigned */
2352 /* Always trap */
2353 generate_exception(ctx, EXCP_TRAP);
2354 break;
2355 case OPC_TLT: /* rs < rs */
2356 case OPC_TLTI: /* r0 < 0 */
2357 case OPC_TLTU: /* rs < rs unsigned */
2358 case OPC_TLTIU: /* r0 < 0 unsigned */
2359 case OPC_TNE: /* rs != rs */
2360 case OPC_TNEI: /* r0 != 0 */
2361 /* Never trap: treat as NOP. */
2362 break;
2364 } else {
2365 int l1 = gen_new_label();
2367 switch (opc) {
2368 case OPC_TEQ:
2369 case OPC_TEQI:
2370 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2371 break;
2372 case OPC_TGE:
2373 case OPC_TGEI:
2374 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2375 break;
2376 case OPC_TGEU:
2377 case OPC_TGEIU:
2378 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2379 break;
2380 case OPC_TLT:
2381 case OPC_TLTI:
2382 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2383 break;
2384 case OPC_TLTU:
2385 case OPC_TLTIU:
2386 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2387 break;
2388 case OPC_TNE:
2389 case OPC_TNEI:
2390 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2391 break;
2393 generate_exception(ctx, EXCP_TRAP);
2394 gen_set_label(l1);
2396 tcg_temp_free(t0);
2397 tcg_temp_free(t1);
2400 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2402 TranslationBlock *tb;
2403 tb = ctx->tb;
2404 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2405 likely(!ctx->singlestep_enabled)) {
2406 tcg_gen_goto_tb(n);
2407 gen_save_pc(dest);
2408 tcg_gen_exit_tb((long)tb + n);
2409 } else {
2410 gen_save_pc(dest);
2411 if (ctx->singlestep_enabled) {
2412 save_cpu_state(ctx, 0);
2413 gen_helper_0i(raise_exception, EXCP_DEBUG);
2415 tcg_gen_exit_tb(0);
2419 /* Branches (before delay slot) */
2420 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2421 int insn_bytes,
2422 int rs, int rt, int32_t offset)
2424 target_ulong btgt = -1;
2425 int blink = 0;
2426 int bcond_compute = 0;
2427 TCGv t0 = tcg_temp_new();
2428 TCGv t1 = tcg_temp_new();
2430 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2431 #ifdef MIPS_DEBUG_DISAS
2432 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2433 #endif
2434 generate_exception(ctx, EXCP_RI);
2435 goto out;
2438 /* Load needed operands */
2439 switch (opc) {
2440 case OPC_BEQ:
2441 case OPC_BEQL:
2442 case OPC_BNE:
2443 case OPC_BNEL:
2444 /* Compare two registers */
2445 if (rs != rt) {
2446 gen_load_gpr(t0, rs);
2447 gen_load_gpr(t1, rt);
2448 bcond_compute = 1;
2450 btgt = ctx->pc + insn_bytes + offset;
2451 break;
2452 case OPC_BGEZ:
2453 case OPC_BGEZAL:
2454 case OPC_BGEZALS:
2455 case OPC_BGEZALL:
2456 case OPC_BGEZL:
2457 case OPC_BGTZ:
2458 case OPC_BGTZL:
2459 case OPC_BLEZ:
2460 case OPC_BLEZL:
2461 case OPC_BLTZ:
2462 case OPC_BLTZAL:
2463 case OPC_BLTZALS:
2464 case OPC_BLTZALL:
2465 case OPC_BLTZL:
2466 /* Compare to zero */
2467 if (rs != 0) {
2468 gen_load_gpr(t0, rs);
2469 bcond_compute = 1;
2471 btgt = ctx->pc + insn_bytes + offset;
2472 break;
2473 case OPC_J:
2474 case OPC_JAL:
2475 case OPC_JALX:
2476 case OPC_JALS:
2477 case OPC_JALXS:
2478 /* Jump to immediate */
2479 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2480 break;
2481 case OPC_JR:
2482 case OPC_JALR:
2483 case OPC_JALRC:
2484 case OPC_JALRS:
2485 /* Jump to register */
2486 if (offset != 0 && offset != 16) {
2487 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2488 others are reserved. */
2489 MIPS_INVAL("jump hint");
2490 generate_exception(ctx, EXCP_RI);
2491 goto out;
2493 gen_load_gpr(btarget, rs);
2494 break;
2495 default:
2496 MIPS_INVAL("branch/jump");
2497 generate_exception(ctx, EXCP_RI);
2498 goto out;
2500 if (bcond_compute == 0) {
2501 /* No condition to be computed */
2502 switch (opc) {
2503 case OPC_BEQ: /* rx == rx */
2504 case OPC_BEQL: /* rx == rx likely */
2505 case OPC_BGEZ: /* 0 >= 0 */
2506 case OPC_BGEZL: /* 0 >= 0 likely */
2507 case OPC_BLEZ: /* 0 <= 0 */
2508 case OPC_BLEZL: /* 0 <= 0 likely */
2509 /* Always take */
2510 ctx->hflags |= MIPS_HFLAG_B;
2511 MIPS_DEBUG("balways");
2512 break;
2513 case OPC_BGEZALS:
2514 case OPC_BGEZAL: /* 0 >= 0 */
2515 case OPC_BGEZALL: /* 0 >= 0 likely */
2516 ctx->hflags |= (opc == OPC_BGEZALS
2517 ? MIPS_HFLAG_BDS16
2518 : MIPS_HFLAG_BDS32);
2519 /* Always take and link */
2520 blink = 31;
2521 ctx->hflags |= MIPS_HFLAG_B;
2522 MIPS_DEBUG("balways and link");
2523 break;
2524 case OPC_BNE: /* rx != rx */
2525 case OPC_BGTZ: /* 0 > 0 */
2526 case OPC_BLTZ: /* 0 < 0 */
2527 /* Treat as NOP. */
2528 MIPS_DEBUG("bnever (NOP)");
2529 goto out;
2530 case OPC_BLTZALS:
2531 case OPC_BLTZAL: /* 0 < 0 */
2532 ctx->hflags |= (opc == OPC_BLTZALS
2533 ? MIPS_HFLAG_BDS16
2534 : MIPS_HFLAG_BDS32);
2535 /* Handle as an unconditional branch to get correct delay
2536 slot checking. */
2537 blink = 31;
2538 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2539 ctx->hflags |= MIPS_HFLAG_B;
2540 MIPS_DEBUG("bnever and link");
2541 break;
2542 case OPC_BLTZALL: /* 0 < 0 likely */
2543 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2544 /* Skip the instruction in the delay slot */
2545 MIPS_DEBUG("bnever, link and skip");
2546 ctx->pc += 4;
2547 goto out;
2548 case OPC_BNEL: /* rx != rx likely */
2549 case OPC_BGTZL: /* 0 > 0 likely */
2550 case OPC_BLTZL: /* 0 < 0 likely */
2551 /* Skip the instruction in the delay slot */
2552 MIPS_DEBUG("bnever and skip");
2553 ctx->pc += 4;
2554 goto out;
2555 case OPC_J:
2556 ctx->hflags |= MIPS_HFLAG_B;
2557 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2558 break;
2559 case OPC_JALXS:
2560 case OPC_JALX:
2561 ctx->hflags |= MIPS_HFLAG_BX;
2562 /* Fallthrough */
2563 case OPC_JALS:
2564 case OPC_JAL:
2565 blink = 31;
2566 ctx->hflags |= MIPS_HFLAG_B;
2567 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2568 ? MIPS_HFLAG_BDS16
2569 : MIPS_HFLAG_BDS32);
2570 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2571 break;
2572 case OPC_JR:
2573 ctx->hflags |= MIPS_HFLAG_BR;
2574 if (insn_bytes == 4)
2575 ctx->hflags |= MIPS_HFLAG_BDS32;
2576 MIPS_DEBUG("jr %s", regnames[rs]);
2577 break;
2578 case OPC_JALRS:
2579 case OPC_JALR:
2580 case OPC_JALRC:
2581 blink = rt;
2582 ctx->hflags |= MIPS_HFLAG_BR;
2583 ctx->hflags |= (opc == OPC_JALRS
2584 ? MIPS_HFLAG_BDS16
2585 : MIPS_HFLAG_BDS32);
2586 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2587 break;
2588 default:
2589 MIPS_INVAL("branch/jump");
2590 generate_exception(ctx, EXCP_RI);
2591 goto out;
2593 } else {
2594 switch (opc) {
2595 case OPC_BEQ:
2596 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2597 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2598 regnames[rs], regnames[rt], btgt);
2599 goto not_likely;
2600 case OPC_BEQL:
2601 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2602 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2603 regnames[rs], regnames[rt], btgt);
2604 goto likely;
2605 case OPC_BNE:
2606 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2607 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2608 regnames[rs], regnames[rt], btgt);
2609 goto not_likely;
2610 case OPC_BNEL:
2611 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2612 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2613 regnames[rs], regnames[rt], btgt);
2614 goto likely;
2615 case OPC_BGEZ:
2616 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2617 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2618 goto not_likely;
2619 case OPC_BGEZL:
2620 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2621 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2622 goto likely;
2623 case OPC_BGEZALS:
2624 case OPC_BGEZAL:
2625 ctx->hflags |= (opc == OPC_BGEZALS
2626 ? MIPS_HFLAG_BDS16
2627 : MIPS_HFLAG_BDS32);
2628 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2629 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2630 blink = 31;
2631 goto not_likely;
2632 case OPC_BGEZALL:
2633 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2634 blink = 31;
2635 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2636 goto likely;
2637 case OPC_BGTZ:
2638 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2639 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2640 goto not_likely;
2641 case OPC_BGTZL:
2642 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2643 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2644 goto likely;
2645 case OPC_BLEZ:
2646 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2647 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2648 goto not_likely;
2649 case OPC_BLEZL:
2650 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2651 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2652 goto likely;
2653 case OPC_BLTZ:
2654 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2655 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2656 goto not_likely;
2657 case OPC_BLTZL:
2658 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2659 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2660 goto likely;
2661 case OPC_BLTZALS:
2662 case OPC_BLTZAL:
2663 ctx->hflags |= (opc == OPC_BLTZALS
2664 ? MIPS_HFLAG_BDS16
2665 : MIPS_HFLAG_BDS32);
2666 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2667 blink = 31;
2668 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2669 not_likely:
2670 ctx->hflags |= MIPS_HFLAG_BC;
2671 break;
2672 case OPC_BLTZALL:
2673 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2674 blink = 31;
2675 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2676 likely:
2677 ctx->hflags |= MIPS_HFLAG_BL;
2678 break;
2679 default:
2680 MIPS_INVAL("conditional branch/jump");
2681 generate_exception(ctx, EXCP_RI);
2682 goto out;
2685 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2686 blink, ctx->hflags, btgt);
2688 ctx->btarget = btgt;
2689 if (blink > 0) {
2690 int post_delay = insn_bytes;
2691 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2693 if (opc != OPC_JALRC)
2694 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2696 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2699 out:
2700 if (insn_bytes == 2)
2701 ctx->hflags |= MIPS_HFLAG_B16;
2702 tcg_temp_free(t0);
2703 tcg_temp_free(t1);
2706 /* special3 bitfield operations */
2707 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2708 int rs, int lsb, int msb)
2710 TCGv t0 = tcg_temp_new();
2711 TCGv t1 = tcg_temp_new();
2712 target_ulong mask;
2714 gen_load_gpr(t1, rs);
2715 switch (opc) {
2716 case OPC_EXT:
2717 if (lsb + msb > 31)
2718 goto fail;
2719 tcg_gen_shri_tl(t0, t1, lsb);
2720 if (msb != 31) {
2721 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2722 } else {
2723 tcg_gen_ext32s_tl(t0, t0);
2725 break;
2726 #if defined(TARGET_MIPS64)
2727 case OPC_DEXTM:
2728 tcg_gen_shri_tl(t0, t1, lsb);
2729 if (msb != 31) {
2730 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2732 break;
2733 case OPC_DEXTU:
2734 tcg_gen_shri_tl(t0, t1, lsb + 32);
2735 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2736 break;
2737 case OPC_DEXT:
2738 tcg_gen_shri_tl(t0, t1, lsb);
2739 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2740 break;
2741 #endif
2742 case OPC_INS:
2743 if (lsb > msb)
2744 goto fail;
2745 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2746 gen_load_gpr(t0, rt);
2747 tcg_gen_andi_tl(t0, t0, ~mask);
2748 tcg_gen_shli_tl(t1, t1, lsb);
2749 tcg_gen_andi_tl(t1, t1, mask);
2750 tcg_gen_or_tl(t0, t0, t1);
2751 tcg_gen_ext32s_tl(t0, t0);
2752 break;
2753 #if defined(TARGET_MIPS64)
2754 case OPC_DINSM:
2755 if (lsb > msb)
2756 goto fail;
2757 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2758 gen_load_gpr(t0, rt);
2759 tcg_gen_andi_tl(t0, t0, ~mask);
2760 tcg_gen_shli_tl(t1, t1, lsb);
2761 tcg_gen_andi_tl(t1, t1, mask);
2762 tcg_gen_or_tl(t0, t0, t1);
2763 break;
2764 case OPC_DINSU:
2765 if (lsb > msb)
2766 goto fail;
2767 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
2768 gen_load_gpr(t0, rt);
2769 tcg_gen_andi_tl(t0, t0, ~mask);
2770 tcg_gen_shli_tl(t1, t1, lsb + 32);
2771 tcg_gen_andi_tl(t1, t1, mask);
2772 tcg_gen_or_tl(t0, t0, t1);
2773 break;
2774 case OPC_DINS:
2775 if (lsb > msb)
2776 goto fail;
2777 gen_load_gpr(t0, rt);
2778 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2779 gen_load_gpr(t0, rt);
2780 tcg_gen_andi_tl(t0, t0, ~mask);
2781 tcg_gen_shli_tl(t1, t1, lsb);
2782 tcg_gen_andi_tl(t1, t1, mask);
2783 tcg_gen_or_tl(t0, t0, t1);
2784 break;
2785 #endif
2786 default:
2787 fail:
2788 MIPS_INVAL("bitops");
2789 generate_exception(ctx, EXCP_RI);
2790 tcg_temp_free(t0);
2791 tcg_temp_free(t1);
2792 return;
2794 gen_store_gpr(t0, rt);
2795 tcg_temp_free(t0);
2796 tcg_temp_free(t1);
2799 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2801 TCGv t0;
2803 if (rd == 0) {
2804 /* If no destination, treat it as a NOP. */
2805 MIPS_DEBUG("NOP");
2806 return;
2809 t0 = tcg_temp_new();
2810 gen_load_gpr(t0, rt);
2811 switch (op2) {
2812 case OPC_WSBH:
2814 TCGv t1 = tcg_temp_new();
2816 tcg_gen_shri_tl(t1, t0, 8);
2817 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2818 tcg_gen_shli_tl(t0, t0, 8);
2819 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2820 tcg_gen_or_tl(t0, t0, t1);
2821 tcg_temp_free(t1);
2822 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2824 break;
2825 case OPC_SEB:
2826 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2827 break;
2828 case OPC_SEH:
2829 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2830 break;
2831 #if defined(TARGET_MIPS64)
2832 case OPC_DSBH:
2834 TCGv t1 = tcg_temp_new();
2836 tcg_gen_shri_tl(t1, t0, 8);
2837 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2838 tcg_gen_shli_tl(t0, t0, 8);
2839 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2840 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2841 tcg_temp_free(t1);
2843 break;
2844 case OPC_DSHD:
2846 TCGv t1 = tcg_temp_new();
2848 tcg_gen_shri_tl(t1, t0, 16);
2849 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2850 tcg_gen_shli_tl(t0, t0, 16);
2851 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2852 tcg_gen_or_tl(t0, t0, t1);
2853 tcg_gen_shri_tl(t1, t0, 32);
2854 tcg_gen_shli_tl(t0, t0, 32);
2855 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2856 tcg_temp_free(t1);
2858 break;
2859 #endif
2860 default:
2861 MIPS_INVAL("bsfhl");
2862 generate_exception(ctx, EXCP_RI);
2863 tcg_temp_free(t0);
2864 return;
2866 tcg_temp_free(t0);
2869 #ifndef CONFIG_USER_ONLY
2870 /* CP0 (MMU and control) */
2871 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2873 TCGv_i32 t0 = tcg_temp_new_i32();
2875 tcg_gen_ld_i32(t0, cpu_env, off);
2876 tcg_gen_ext_i32_tl(arg, t0);
2877 tcg_temp_free_i32(t0);
2880 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2882 tcg_gen_ld_tl(arg, cpu_env, off);
2883 tcg_gen_ext32s_tl(arg, arg);
2886 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2888 TCGv_i32 t0 = tcg_temp_new_i32();
2890 tcg_gen_trunc_tl_i32(t0, arg);
2891 tcg_gen_st_i32(t0, cpu_env, off);
2892 tcg_temp_free_i32(t0);
2895 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2897 tcg_gen_ext32s_tl(arg, arg);
2898 tcg_gen_st_tl(arg, cpu_env, off);
2901 static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2903 const char *rn = "invalid";
2905 if (sel != 0)
2906 check_insn(env, ctx, ISA_MIPS32);
2908 switch (reg) {
2909 case 0:
2910 switch (sel) {
2911 case 0:
2912 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
2913 rn = "Index";
2914 break;
2915 case 1:
2916 check_insn(env, ctx, ASE_MT);
2917 gen_helper_mfc0_mvpcontrol(arg);
2918 rn = "MVPControl";
2919 break;
2920 case 2:
2921 check_insn(env, ctx, ASE_MT);
2922 gen_helper_mfc0_mvpconf0(arg);
2923 rn = "MVPConf0";
2924 break;
2925 case 3:
2926 check_insn(env, ctx, ASE_MT);
2927 gen_helper_mfc0_mvpconf1(arg);
2928 rn = "MVPConf1";
2929 break;
2930 default:
2931 goto die;
2933 break;
2934 case 1:
2935 switch (sel) {
2936 case 0:
2937 gen_helper_mfc0_random(arg);
2938 rn = "Random";
2939 break;
2940 case 1:
2941 check_insn(env, ctx, ASE_MT);
2942 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
2943 rn = "VPEControl";
2944 break;
2945 case 2:
2946 check_insn(env, ctx, ASE_MT);
2947 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
2948 rn = "VPEConf0";
2949 break;
2950 case 3:
2951 check_insn(env, ctx, ASE_MT);
2952 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
2953 rn = "VPEConf1";
2954 break;
2955 case 4:
2956 check_insn(env, ctx, ASE_MT);
2957 gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
2958 rn = "YQMask";
2959 break;
2960 case 5:
2961 check_insn(env, ctx, ASE_MT);
2962 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
2963 rn = "VPESchedule";
2964 break;
2965 case 6:
2966 check_insn(env, ctx, ASE_MT);
2967 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
2968 rn = "VPEScheFBack";
2969 break;
2970 case 7:
2971 check_insn(env, ctx, ASE_MT);
2972 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
2973 rn = "VPEOpt";
2974 break;
2975 default:
2976 goto die;
2978 break;
2979 case 2:
2980 switch (sel) {
2981 case 0:
2982 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2983 tcg_gen_ext32s_tl(arg, arg);
2984 rn = "EntryLo0";
2985 break;
2986 case 1:
2987 check_insn(env, ctx, ASE_MT);
2988 gen_helper_mfc0_tcstatus(arg);
2989 rn = "TCStatus";
2990 break;
2991 case 2:
2992 check_insn(env, ctx, ASE_MT);
2993 gen_helper_mfc0_tcbind(arg);
2994 rn = "TCBind";
2995 break;
2996 case 3:
2997 check_insn(env, ctx, ASE_MT);
2998 gen_helper_mfc0_tcrestart(arg);
2999 rn = "TCRestart";
3000 break;
3001 case 4:
3002 check_insn(env, ctx, ASE_MT);
3003 gen_helper_mfc0_tchalt(arg);
3004 rn = "TCHalt";
3005 break;
3006 case 5:
3007 check_insn(env, ctx, ASE_MT);
3008 gen_helper_mfc0_tccontext(arg);
3009 rn = "TCContext";
3010 break;
3011 case 6:
3012 check_insn(env, ctx, ASE_MT);
3013 gen_helper_mfc0_tcschedule(arg);
3014 rn = "TCSchedule";
3015 break;
3016 case 7:
3017 check_insn(env, ctx, ASE_MT);
3018 gen_helper_mfc0_tcschefback(arg);
3019 rn = "TCScheFBack";
3020 break;
3021 default:
3022 goto die;
3024 break;
3025 case 3:
3026 switch (sel) {
3027 case 0:
3028 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3029 tcg_gen_ext32s_tl(arg, arg);
3030 rn = "EntryLo1";
3031 break;
3032 default:
3033 goto die;
3035 break;
3036 case 4:
3037 switch (sel) {
3038 case 0:
3039 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3040 tcg_gen_ext32s_tl(arg, arg);
3041 rn = "Context";
3042 break;
3043 case 1:
3044 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3045 rn = "ContextConfig";
3046 // break;
3047 default:
3048 goto die;
3050 break;
3051 case 5:
3052 switch (sel) {
3053 case 0:
3054 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3055 rn = "PageMask";
3056 break;
3057 case 1:
3058 check_insn(env, ctx, ISA_MIPS32R2);
3059 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3060 rn = "PageGrain";
3061 break;
3062 default:
3063 goto die;
3065 break;
3066 case 6:
3067 switch (sel) {
3068 case 0:
3069 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3070 rn = "Wired";
3071 break;
3072 case 1:
3073 check_insn(env, ctx, ISA_MIPS32R2);
3074 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3075 rn = "SRSConf0";
3076 break;
3077 case 2:
3078 check_insn(env, ctx, ISA_MIPS32R2);
3079 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3080 rn = "SRSConf1";
3081 break;
3082 case 3:
3083 check_insn(env, ctx, ISA_MIPS32R2);
3084 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3085 rn = "SRSConf2";
3086 break;
3087 case 4:
3088 check_insn(env, ctx, ISA_MIPS32R2);
3089 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3090 rn = "SRSConf3";
3091 break;
3092 case 5:
3093 check_insn(env, ctx, ISA_MIPS32R2);
3094 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3095 rn = "SRSConf4";
3096 break;
3097 default:
3098 goto die;
3100 break;
3101 case 7:
3102 switch (sel) {
3103 case 0:
3104 check_insn(env, ctx, ISA_MIPS32R2);
3105 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3106 rn = "HWREna";
3107 break;
3108 default:
3109 goto die;
3111 break;
3112 case 8:
3113 switch (sel) {
3114 case 0:
3115 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3116 tcg_gen_ext32s_tl(arg, arg);
3117 rn = "BadVAddr";
3118 break;
3119 default:
3120 goto die;
3122 break;
3123 case 9:
3124 switch (sel) {
3125 case 0:
3126 /* Mark as an IO operation because we read the time. */
3127 if (use_icount)
3128 gen_io_start();
3129 gen_helper_mfc0_count(arg);
3130 if (use_icount) {
3131 gen_io_end();
3132 ctx->bstate = BS_STOP;
3134 rn = "Count";
3135 break;
3136 /* 6,7 are implementation dependent */
3137 default:
3138 goto die;
3140 break;
3141 case 10:
3142 switch (sel) {
3143 case 0:
3144 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3145 tcg_gen_ext32s_tl(arg, arg);
3146 rn = "EntryHi";
3147 break;
3148 default:
3149 goto die;
3151 break;
3152 case 11:
3153 switch (sel) {
3154 case 0:
3155 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3156 rn = "Compare";
3157 break;
3158 /* 6,7 are implementation dependent */
3159 default:
3160 goto die;
3162 break;
3163 case 12:
3164 switch (sel) {
3165 case 0:
3166 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3167 rn = "Status";
3168 break;
3169 case 1:
3170 check_insn(env, ctx, ISA_MIPS32R2);
3171 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3172 rn = "IntCtl";
3173 break;
3174 case 2:
3175 check_insn(env, ctx, ISA_MIPS32R2);
3176 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3177 rn = "SRSCtl";
3178 break;
3179 case 3:
3180 check_insn(env, ctx, ISA_MIPS32R2);
3181 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3182 rn = "SRSMap";
3183 break;
3184 default:
3185 goto die;
3187 break;
3188 case 13:
3189 switch (sel) {
3190 case 0:
3191 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3192 rn = "Cause";
3193 break;
3194 default:
3195 goto die;
3197 break;
3198 case 14:
3199 switch (sel) {
3200 case 0:
3201 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3202 tcg_gen_ext32s_tl(arg, arg);
3203 rn = "EPC";
3204 break;
3205 default:
3206 goto die;
3208 break;
3209 case 15:
3210 switch (sel) {
3211 case 0:
3212 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3213 rn = "PRid";
3214 break;
3215 case 1:
3216 check_insn(env, ctx, ISA_MIPS32R2);
3217 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3218 rn = "EBase";
3219 break;
3220 default:
3221 goto die;
3223 break;
3224 case 16:
3225 switch (sel) {
3226 case 0:
3227 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3228 rn = "Config";
3229 break;
3230 case 1:
3231 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3232 rn = "Config1";
3233 break;
3234 case 2:
3235 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3236 rn = "Config2";
3237 break;
3238 case 3:
3239 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3240 rn = "Config3";
3241 break;
3242 /* 4,5 are reserved */
3243 /* 6,7 are implementation dependent */
3244 case 6:
3245 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3246 rn = "Config6";
3247 break;
3248 case 7:
3249 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3250 rn = "Config7";
3251 break;
3252 default:
3253 goto die;
3255 break;
3256 case 17:
3257 switch (sel) {
3258 case 0:
3259 gen_helper_mfc0_lladdr(arg);
3260 rn = "LLAddr";
3261 break;
3262 default:
3263 goto die;
3265 break;
3266 case 18:
3267 switch (sel) {
3268 case 0 ... 7:
3269 gen_helper_1i(mfc0_watchlo, arg, sel);
3270 rn = "WatchLo";
3271 break;
3272 default:
3273 goto die;
3275 break;
3276 case 19:
3277 switch (sel) {
3278 case 0 ...7:
3279 gen_helper_1i(mfc0_watchhi, arg, sel);
3280 rn = "WatchHi";
3281 break;
3282 default:
3283 goto die;
3285 break;
3286 case 20:
3287 switch (sel) {
3288 case 0:
3289 #if defined(TARGET_MIPS64)
3290 check_insn(env, ctx, ISA_MIPS3);
3291 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3292 tcg_gen_ext32s_tl(arg, arg);
3293 rn = "XContext";
3294 break;
3295 #endif
3296 default:
3297 goto die;
3299 break;
3300 case 21:
3301 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3302 switch (sel) {
3303 case 0:
3304 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3305 rn = "Framemask";
3306 break;
3307 default:
3308 goto die;
3310 break;
3311 case 22:
3312 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3313 rn = "'Diagnostic"; /* implementation dependent */
3314 break;
3315 case 23:
3316 switch (sel) {
3317 case 0:
3318 gen_helper_mfc0_debug(arg); /* EJTAG support */
3319 rn = "Debug";
3320 break;
3321 case 1:
3322 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3323 rn = "TraceControl";
3324 // break;
3325 case 2:
3326 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3327 rn = "TraceControl2";
3328 // break;
3329 case 3:
3330 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3331 rn = "UserTraceData";
3332 // break;
3333 case 4:
3334 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3335 rn = "TraceBPC";
3336 // break;
3337 default:
3338 goto die;
3340 break;
3341 case 24:
3342 switch (sel) {
3343 case 0:
3344 /* EJTAG support */
3345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3346 tcg_gen_ext32s_tl(arg, arg);
3347 rn = "DEPC";
3348 break;
3349 default:
3350 goto die;
3352 break;
3353 case 25:
3354 switch (sel) {
3355 case 0:
3356 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3357 rn = "Performance0";
3358 break;
3359 case 1:
3360 // gen_helper_mfc0_performance1(arg);
3361 rn = "Performance1";
3362 // break;
3363 case 2:
3364 // gen_helper_mfc0_performance2(arg);
3365 rn = "Performance2";
3366 // break;
3367 case 3:
3368 // gen_helper_mfc0_performance3(arg);
3369 rn = "Performance3";
3370 // break;
3371 case 4:
3372 // gen_helper_mfc0_performance4(arg);
3373 rn = "Performance4";
3374 // break;
3375 case 5:
3376 // gen_helper_mfc0_performance5(arg);
3377 rn = "Performance5";
3378 // break;
3379 case 6:
3380 // gen_helper_mfc0_performance6(arg);
3381 rn = "Performance6";
3382 // break;
3383 case 7:
3384 // gen_helper_mfc0_performance7(arg);
3385 rn = "Performance7";
3386 // break;
3387 default:
3388 goto die;
3390 break;
3391 case 26:
3392 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3393 rn = "ECC";
3394 break;
3395 case 27:
3396 switch (sel) {
3397 case 0 ... 3:
3398 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3399 rn = "CacheErr";
3400 break;
3401 default:
3402 goto die;
3404 break;
3405 case 28:
3406 switch (sel) {
3407 case 0:
3408 case 2:
3409 case 4:
3410 case 6:
3411 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3412 rn = "TagLo";
3413 break;
3414 case 1:
3415 case 3:
3416 case 5:
3417 case 7:
3418 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3419 rn = "DataLo";
3420 break;
3421 default:
3422 goto die;
3424 break;
3425 case 29:
3426 switch (sel) {
3427 case 0:
3428 case 2:
3429 case 4:
3430 case 6:
3431 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3432 rn = "TagHi";
3433 break;
3434 case 1:
3435 case 3:
3436 case 5:
3437 case 7:
3438 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3439 rn = "DataHi";
3440 break;
3441 default:
3442 goto die;
3444 break;
3445 case 30:
3446 switch (sel) {
3447 case 0:
3448 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3449 tcg_gen_ext32s_tl(arg, arg);
3450 rn = "ErrorEPC";
3451 break;
3452 default:
3453 goto die;
3455 break;
3456 case 31:
3457 switch (sel) {
3458 case 0:
3459 /* EJTAG support */
3460 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3461 rn = "DESAVE";
3462 break;
3463 default:
3464 goto die;
3466 break;
3467 default:
3468 goto die;
3470 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3471 return;
3473 die:
3474 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3475 generate_exception(ctx, EXCP_RI);
3478 static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3480 const char *rn = "invalid";
3482 if (sel != 0)
3483 check_insn(env, ctx, ISA_MIPS32);
3485 if (use_icount)
3486 gen_io_start();
3488 switch (reg) {
3489 case 0:
3490 switch (sel) {
3491 case 0:
3492 gen_helper_mtc0_index(arg);
3493 rn = "Index";
3494 break;
3495 case 1:
3496 check_insn(env, ctx, ASE_MT);
3497 gen_helper_mtc0_mvpcontrol(arg);
3498 rn = "MVPControl";
3499 break;
3500 case 2:
3501 check_insn(env, ctx, ASE_MT);
3502 /* ignored */
3503 rn = "MVPConf0";
3504 break;
3505 case 3:
3506 check_insn(env, ctx, ASE_MT);
3507 /* ignored */
3508 rn = "MVPConf1";
3509 break;
3510 default:
3511 goto die;
3513 break;
3514 case 1:
3515 switch (sel) {
3516 case 0:
3517 /* ignored */
3518 rn = "Random";
3519 break;
3520 case 1:
3521 check_insn(env, ctx, ASE_MT);
3522 gen_helper_mtc0_vpecontrol(arg);
3523 rn = "VPEControl";
3524 break;
3525 case 2:
3526 check_insn(env, ctx, ASE_MT);
3527 gen_helper_mtc0_vpeconf0(arg);
3528 rn = "VPEConf0";
3529 break;
3530 case 3:
3531 check_insn(env, ctx, ASE_MT);
3532 gen_helper_mtc0_vpeconf1(arg);
3533 rn = "VPEConf1";
3534 break;
3535 case 4:
3536 check_insn(env, ctx, ASE_MT);
3537 gen_helper_mtc0_yqmask(arg);
3538 rn = "YQMask";
3539 break;
3540 case 5:
3541 check_insn(env, ctx, ASE_MT);
3542 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3543 rn = "VPESchedule";
3544 break;
3545 case 6:
3546 check_insn(env, ctx, ASE_MT);
3547 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3548 rn = "VPEScheFBack";
3549 break;
3550 case 7:
3551 check_insn(env, ctx, ASE_MT);
3552 gen_helper_mtc0_vpeopt(arg);
3553 rn = "VPEOpt";
3554 break;
3555 default:
3556 goto die;
3558 break;
3559 case 2:
3560 switch (sel) {
3561 case 0:
3562 gen_helper_mtc0_entrylo0(arg);
3563 rn = "EntryLo0";
3564 break;
3565 case 1:
3566 check_insn(env, ctx, ASE_MT);
3567 gen_helper_mtc0_tcstatus(arg);
3568 rn = "TCStatus";
3569 break;
3570 case 2:
3571 check_insn(env, ctx, ASE_MT);
3572 gen_helper_mtc0_tcbind(arg);
3573 rn = "TCBind";
3574 break;
3575 case 3:
3576 check_insn(env, ctx, ASE_MT);
3577 gen_helper_mtc0_tcrestart(arg);
3578 rn = "TCRestart";
3579 break;
3580 case 4:
3581 check_insn(env, ctx, ASE_MT);
3582 gen_helper_mtc0_tchalt(arg);
3583 rn = "TCHalt";
3584 break;
3585 case 5:
3586 check_insn(env, ctx, ASE_MT);
3587 gen_helper_mtc0_tccontext(arg);
3588 rn = "TCContext";
3589 break;
3590 case 6:
3591 check_insn(env, ctx, ASE_MT);
3592 gen_helper_mtc0_tcschedule(arg);
3593 rn = "TCSchedule";
3594 break;
3595 case 7:
3596 check_insn(env, ctx, ASE_MT);
3597 gen_helper_mtc0_tcschefback(arg);
3598 rn = "TCScheFBack";
3599 break;
3600 default:
3601 goto die;
3603 break;
3604 case 3:
3605 switch (sel) {
3606 case 0:
3607 gen_helper_mtc0_entrylo1(arg);
3608 rn = "EntryLo1";
3609 break;
3610 default:
3611 goto die;
3613 break;
3614 case 4:
3615 switch (sel) {
3616 case 0:
3617 gen_helper_mtc0_context(arg);
3618 rn = "Context";
3619 break;
3620 case 1:
3621 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3622 rn = "ContextConfig";
3623 // break;
3624 default:
3625 goto die;
3627 break;
3628 case 5:
3629 switch (sel) {
3630 case 0:
3631 gen_helper_mtc0_pagemask(arg);
3632 rn = "PageMask";
3633 break;
3634 case 1:
3635 check_insn(env, ctx, ISA_MIPS32R2);
3636 gen_helper_mtc0_pagegrain(arg);
3637 rn = "PageGrain";
3638 break;
3639 default:
3640 goto die;
3642 break;
3643 case 6:
3644 switch (sel) {
3645 case 0:
3646 gen_helper_mtc0_wired(arg);
3647 rn = "Wired";
3648 break;
3649 case 1:
3650 check_insn(env, ctx, ISA_MIPS32R2);
3651 gen_helper_mtc0_srsconf0(arg);
3652 rn = "SRSConf0";
3653 break;
3654 case 2:
3655 check_insn(env, ctx, ISA_MIPS32R2);
3656 gen_helper_mtc0_srsconf1(arg);
3657 rn = "SRSConf1";
3658 break;
3659 case 3:
3660 check_insn(env, ctx, ISA_MIPS32R2);
3661 gen_helper_mtc0_srsconf2(arg);
3662 rn = "SRSConf2";
3663 break;
3664 case 4:
3665 check_insn(env, ctx, ISA_MIPS32R2);
3666 gen_helper_mtc0_srsconf3(arg);
3667 rn = "SRSConf3";
3668 break;
3669 case 5:
3670 check_insn(env, ctx, ISA_MIPS32R2);
3671 gen_helper_mtc0_srsconf4(arg);
3672 rn = "SRSConf4";
3673 break;
3674 default:
3675 goto die;
3677 break;
3678 case 7:
3679 switch (sel) {
3680 case 0:
3681 check_insn(env, ctx, ISA_MIPS32R2);
3682 gen_helper_mtc0_hwrena(arg);
3683 rn = "HWREna";
3684 break;
3685 default:
3686 goto die;
3688 break;
3689 case 8:
3690 /* ignored */
3691 rn = "BadVAddr";
3692 break;
3693 case 9:
3694 switch (sel) {
3695 case 0:
3696 gen_helper_mtc0_count(arg);
3697 rn = "Count";
3698 break;
3699 /* 6,7 are implementation dependent */
3700 default:
3701 goto die;
3703 break;
3704 case 10:
3705 switch (sel) {
3706 case 0:
3707 gen_helper_mtc0_entryhi(arg);
3708 rn = "EntryHi";
3709 break;
3710 default:
3711 goto die;
3713 break;
3714 case 11:
3715 switch (sel) {
3716 case 0:
3717 gen_helper_mtc0_compare(arg);
3718 rn = "Compare";
3719 break;
3720 /* 6,7 are implementation dependent */
3721 default:
3722 goto die;
3724 break;
3725 case 12:
3726 switch (sel) {
3727 case 0:
3728 save_cpu_state(ctx, 1);
3729 gen_helper_mtc0_status(arg);
3730 /* BS_STOP isn't good enough here, hflags may have changed. */
3731 gen_save_pc(ctx->pc + 4);
3732 ctx->bstate = BS_EXCP;
3733 rn = "Status";
3734 break;
3735 case 1:
3736 check_insn(env, ctx, ISA_MIPS32R2);
3737 gen_helper_mtc0_intctl(arg);
3738 /* Stop translation as we may have switched the execution mode */
3739 ctx->bstate = BS_STOP;
3740 rn = "IntCtl";
3741 break;
3742 case 2:
3743 check_insn(env, ctx, ISA_MIPS32R2);
3744 gen_helper_mtc0_srsctl(arg);
3745 /* Stop translation as we may have switched the execution mode */
3746 ctx->bstate = BS_STOP;
3747 rn = "SRSCtl";
3748 break;
3749 case 3:
3750 check_insn(env, ctx, ISA_MIPS32R2);
3751 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
3752 /* Stop translation as we may have switched the execution mode */
3753 ctx->bstate = BS_STOP;
3754 rn = "SRSMap";
3755 break;
3756 default:
3757 goto die;
3759 break;
3760 case 13:
3761 switch (sel) {
3762 case 0:
3763 save_cpu_state(ctx, 1);
3764 gen_helper_mtc0_cause(arg);
3765 rn = "Cause";
3766 break;
3767 default:
3768 goto die;
3770 break;
3771 case 14:
3772 switch (sel) {
3773 case 0:
3774 gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
3775 rn = "EPC";
3776 break;
3777 default:
3778 goto die;
3780 break;
3781 case 15:
3782 switch (sel) {
3783 case 0:
3784 /* ignored */
3785 rn = "PRid";
3786 break;
3787 case 1:
3788 check_insn(env, ctx, ISA_MIPS32R2);
3789 gen_helper_mtc0_ebase(arg);
3790 rn = "EBase";
3791 break;
3792 default:
3793 goto die;
3795 break;
3796 case 16:
3797 switch (sel) {
3798 case 0:
3799 gen_helper_mtc0_config0(arg);
3800 rn = "Config";
3801 /* Stop translation as we may have switched the execution mode */
3802 ctx->bstate = BS_STOP;
3803 break;
3804 case 1:
3805 /* ignored, read only */
3806 rn = "Config1";
3807 break;
3808 case 2:
3809 gen_helper_mtc0_config2(arg);
3810 rn = "Config2";
3811 /* Stop translation as we may have switched the execution mode */
3812 ctx->bstate = BS_STOP;
3813 break;
3814 case 3:
3815 /* ignored, read only */
3816 rn = "Config3";
3817 break;
3818 /* 4,5 are reserved */
3819 /* 6,7 are implementation dependent */
3820 case 6:
3821 /* ignored */
3822 rn = "Config6";
3823 break;
3824 case 7:
3825 /* ignored */
3826 rn = "Config7";
3827 break;
3828 default:
3829 rn = "Invalid config selector";
3830 goto die;
3832 break;
3833 case 17:
3834 switch (sel) {
3835 case 0:
3836 gen_helper_mtc0_lladdr(arg);
3837 rn = "LLAddr";
3838 break;
3839 default:
3840 goto die;
3842 break;
3843 case 18:
3844 switch (sel) {
3845 case 0 ... 7:
3846 gen_helper_1i(mtc0_watchlo, arg, sel);
3847 rn = "WatchLo";
3848 break;
3849 default:
3850 goto die;
3852 break;
3853 case 19:
3854 switch (sel) {
3855 case 0 ... 7:
3856 gen_helper_1i(mtc0_watchhi, arg, sel);
3857 rn = "WatchHi";
3858 break;
3859 default:
3860 goto die;
3862 break;
3863 case 20:
3864 switch (sel) {
3865 case 0:
3866 #if defined(TARGET_MIPS64)
3867 check_insn(env, ctx, ISA_MIPS3);
3868 gen_helper_mtc0_xcontext(arg);
3869 rn = "XContext";
3870 break;
3871 #endif
3872 default:
3873 goto die;
3875 break;
3876 case 21:
3877 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3878 switch (sel) {
3879 case 0:
3880 gen_helper_mtc0_framemask(arg);
3881 rn = "Framemask";
3882 break;
3883 default:
3884 goto die;
3886 break;
3887 case 22:
3888 /* ignored */
3889 rn = "Diagnostic"; /* implementation dependent */
3890 break;
3891 case 23:
3892 switch (sel) {
3893 case 0:
3894 gen_helper_mtc0_debug(arg); /* EJTAG support */
3895 /* BS_STOP isn't good enough here, hflags may have changed. */
3896 gen_save_pc(ctx->pc + 4);
3897 ctx->bstate = BS_EXCP;
3898 rn = "Debug";
3899 break;
3900 case 1:
3901 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
3902 rn = "TraceControl";
3903 /* Stop translation as we may have switched the execution mode */
3904 ctx->bstate = BS_STOP;
3905 // break;
3906 case 2:
3907 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
3908 rn = "TraceControl2";
3909 /* Stop translation as we may have switched the execution mode */
3910 ctx->bstate = BS_STOP;
3911 // break;
3912 case 3:
3913 /* Stop translation as we may have switched the execution mode */
3914 ctx->bstate = BS_STOP;
3915 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
3916 rn = "UserTraceData";
3917 /* Stop translation as we may have switched the execution mode */
3918 ctx->bstate = BS_STOP;
3919 // break;
3920 case 4:
3921 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
3922 /* Stop translation as we may have switched the execution mode */
3923 ctx->bstate = BS_STOP;
3924 rn = "TraceBPC";
3925 // break;
3926 default:
3927 goto die;
3929 break;
3930 case 24:
3931 switch (sel) {
3932 case 0:
3933 /* EJTAG support */
3934 gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
3935 rn = "DEPC";
3936 break;
3937 default:
3938 goto die;
3940 break;
3941 case 25:
3942 switch (sel) {
3943 case 0:
3944 gen_helper_mtc0_performance0(arg);
3945 rn = "Performance0";
3946 break;
3947 case 1:
3948 // gen_helper_mtc0_performance1(arg);
3949 rn = "Performance1";
3950 // break;
3951 case 2:
3952 // gen_helper_mtc0_performance2(arg);
3953 rn = "Performance2";
3954 // break;
3955 case 3:
3956 // gen_helper_mtc0_performance3(arg);
3957 rn = "Performance3";
3958 // break;
3959 case 4:
3960 // gen_helper_mtc0_performance4(arg);
3961 rn = "Performance4";
3962 // break;
3963 case 5:
3964 // gen_helper_mtc0_performance5(arg);
3965 rn = "Performance5";
3966 // break;
3967 case 6:
3968 // gen_helper_mtc0_performance6(arg);
3969 rn = "Performance6";
3970 // break;
3971 case 7:
3972 // gen_helper_mtc0_performance7(arg);
3973 rn = "Performance7";
3974 // break;
3975 default:
3976 goto die;
3978 break;
3979 case 26:
3980 /* ignored */
3981 rn = "ECC";
3982 break;
3983 case 27:
3984 switch (sel) {
3985 case 0 ... 3:
3986 /* ignored */
3987 rn = "CacheErr";
3988 break;
3989 default:
3990 goto die;
3992 break;
3993 case 28:
3994 switch (sel) {
3995 case 0:
3996 case 2:
3997 case 4:
3998 case 6:
3999 gen_helper_mtc0_taglo(arg);
4000 rn = "TagLo";
4001 break;
4002 case 1:
4003 case 3:
4004 case 5:
4005 case 7:
4006 gen_helper_mtc0_datalo(arg);
4007 rn = "DataLo";
4008 break;
4009 default:
4010 goto die;
4012 break;
4013 case 29:
4014 switch (sel) {
4015 case 0:
4016 case 2:
4017 case 4:
4018 case 6:
4019 gen_helper_mtc0_taghi(arg);
4020 rn = "TagHi";
4021 break;
4022 case 1:
4023 case 3:
4024 case 5:
4025 case 7:
4026 gen_helper_mtc0_datahi(arg);
4027 rn = "DataHi";
4028 break;
4029 default:
4030 rn = "invalid sel";
4031 goto die;
4033 break;
4034 case 30:
4035 switch (sel) {
4036 case 0:
4037 gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4038 rn = "ErrorEPC";
4039 break;
4040 default:
4041 goto die;
4043 break;
4044 case 31:
4045 switch (sel) {
4046 case 0:
4047 /* EJTAG support */
4048 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4049 rn = "DESAVE";
4050 break;
4051 default:
4052 goto die;
4054 /* Stop translation as we may have switched the execution mode */
4055 ctx->bstate = BS_STOP;
4056 break;
4057 default:
4058 goto die;
4060 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4061 /* For simplicity assume that all writes can cause interrupts. */
4062 if (use_icount) {
4063 gen_io_end();
4064 ctx->bstate = BS_STOP;
4066 return;
4068 die:
4069 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4070 generate_exception(ctx, EXCP_RI);
4073 #if defined(TARGET_MIPS64)
4074 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4076 const char *rn = "invalid";
4078 if (sel != 0)
4079 check_insn(env, ctx, ISA_MIPS64);
4081 switch (reg) {
4082 case 0:
4083 switch (sel) {
4084 case 0:
4085 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4086 rn = "Index";
4087 break;
4088 case 1:
4089 check_insn(env, ctx, ASE_MT);
4090 gen_helper_mfc0_mvpcontrol(arg);
4091 rn = "MVPControl";
4092 break;
4093 case 2:
4094 check_insn(env, ctx, ASE_MT);
4095 gen_helper_mfc0_mvpconf0(arg);
4096 rn = "MVPConf0";
4097 break;
4098 case 3:
4099 check_insn(env, ctx, ASE_MT);
4100 gen_helper_mfc0_mvpconf1(arg);
4101 rn = "MVPConf1";
4102 break;
4103 default:
4104 goto die;
4106 break;
4107 case 1:
4108 switch (sel) {
4109 case 0:
4110 gen_helper_mfc0_random(arg);
4111 rn = "Random";
4112 break;
4113 case 1:
4114 check_insn(env, ctx, ASE_MT);
4115 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4116 rn = "VPEControl";
4117 break;
4118 case 2:
4119 check_insn(env, ctx, ASE_MT);
4120 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4121 rn = "VPEConf0";
4122 break;
4123 case 3:
4124 check_insn(env, ctx, ASE_MT);
4125 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4126 rn = "VPEConf1";
4127 break;
4128 case 4:
4129 check_insn(env, ctx, ASE_MT);
4130 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4131 rn = "YQMask";
4132 break;
4133 case 5:
4134 check_insn(env, ctx, ASE_MT);
4135 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4136 rn = "VPESchedule";
4137 break;
4138 case 6:
4139 check_insn(env, ctx, ASE_MT);
4140 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4141 rn = "VPEScheFBack";
4142 break;
4143 case 7:
4144 check_insn(env, ctx, ASE_MT);
4145 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4146 rn = "VPEOpt";
4147 break;
4148 default:
4149 goto die;
4151 break;
4152 case 2:
4153 switch (sel) {
4154 case 0:
4155 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4156 rn = "EntryLo0";
4157 break;
4158 case 1:
4159 check_insn(env, ctx, ASE_MT);
4160 gen_helper_mfc0_tcstatus(arg);
4161 rn = "TCStatus";
4162 break;
4163 case 2:
4164 check_insn(env, ctx, ASE_MT);
4165 gen_helper_mfc0_tcbind(arg);
4166 rn = "TCBind";
4167 break;
4168 case 3:
4169 check_insn(env, ctx, ASE_MT);
4170 gen_helper_dmfc0_tcrestart(arg);
4171 rn = "TCRestart";
4172 break;
4173 case 4:
4174 check_insn(env, ctx, ASE_MT);
4175 gen_helper_dmfc0_tchalt(arg);
4176 rn = "TCHalt";
4177 break;
4178 case 5:
4179 check_insn(env, ctx, ASE_MT);
4180 gen_helper_dmfc0_tccontext(arg);
4181 rn = "TCContext";
4182 break;
4183 case 6:
4184 check_insn(env, ctx, ASE_MT);
4185 gen_helper_dmfc0_tcschedule(arg);
4186 rn = "TCSchedule";
4187 break;
4188 case 7:
4189 check_insn(env, ctx, ASE_MT);
4190 gen_helper_dmfc0_tcschefback(arg);
4191 rn = "TCScheFBack";
4192 break;
4193 default:
4194 goto die;
4196 break;
4197 case 3:
4198 switch (sel) {
4199 case 0:
4200 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4201 rn = "EntryLo1";
4202 break;
4203 default:
4204 goto die;
4206 break;
4207 case 4:
4208 switch (sel) {
4209 case 0:
4210 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4211 rn = "Context";
4212 break;
4213 case 1:
4214 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4215 rn = "ContextConfig";
4216 // break;
4217 default:
4218 goto die;
4220 break;
4221 case 5:
4222 switch (sel) {
4223 case 0:
4224 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4225 rn = "PageMask";
4226 break;
4227 case 1:
4228 check_insn(env, ctx, ISA_MIPS32R2);
4229 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4230 rn = "PageGrain";
4231 break;
4232 default:
4233 goto die;
4235 break;
4236 case 6:
4237 switch (sel) {
4238 case 0:
4239 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4240 rn = "Wired";
4241 break;
4242 case 1:
4243 check_insn(env, ctx, ISA_MIPS32R2);
4244 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4245 rn = "SRSConf0";
4246 break;
4247 case 2:
4248 check_insn(env, ctx, ISA_MIPS32R2);
4249 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4250 rn = "SRSConf1";
4251 break;
4252 case 3:
4253 check_insn(env, ctx, ISA_MIPS32R2);
4254 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4255 rn = "SRSConf2";
4256 break;
4257 case 4:
4258 check_insn(env, ctx, ISA_MIPS32R2);
4259 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4260 rn = "SRSConf3";
4261 break;
4262 case 5:
4263 check_insn(env, ctx, ISA_MIPS32R2);
4264 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4265 rn = "SRSConf4";
4266 break;
4267 default:
4268 goto die;
4270 break;
4271 case 7:
4272 switch (sel) {
4273 case 0:
4274 check_insn(env, ctx, ISA_MIPS32R2);
4275 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4276 rn = "HWREna";
4277 break;
4278 default:
4279 goto die;
4281 break;
4282 case 8:
4283 switch (sel) {
4284 case 0:
4285 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4286 rn = "BadVAddr";
4287 break;
4288 default:
4289 goto die;
4291 break;
4292 case 9:
4293 switch (sel) {
4294 case 0:
4295 /* Mark as an IO operation because we read the time. */
4296 if (use_icount)
4297 gen_io_start();
4298 gen_helper_mfc0_count(arg);
4299 if (use_icount) {
4300 gen_io_end();
4301 ctx->bstate = BS_STOP;
4303 rn = "Count";
4304 break;
4305 /* 6,7 are implementation dependent */
4306 default:
4307 goto die;
4309 break;
4310 case 10:
4311 switch (sel) {
4312 case 0:
4313 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4314 rn = "EntryHi";
4315 break;
4316 default:
4317 goto die;
4319 break;
4320 case 11:
4321 switch (sel) {
4322 case 0:
4323 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4324 rn = "Compare";
4325 break;
4326 /* 6,7 are implementation dependent */
4327 default:
4328 goto die;
4330 break;
4331 case 12:
4332 switch (sel) {
4333 case 0:
4334 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4335 rn = "Status";
4336 break;
4337 case 1:
4338 check_insn(env, ctx, ISA_MIPS32R2);
4339 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4340 rn = "IntCtl";
4341 break;
4342 case 2:
4343 check_insn(env, ctx, ISA_MIPS32R2);
4344 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4345 rn = "SRSCtl";
4346 break;
4347 case 3:
4348 check_insn(env, ctx, ISA_MIPS32R2);
4349 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4350 rn = "SRSMap";
4351 break;
4352 default:
4353 goto die;
4355 break;
4356 case 13:
4357 switch (sel) {
4358 case 0:
4359 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4360 rn = "Cause";
4361 break;
4362 default:
4363 goto die;
4365 break;
4366 case 14:
4367 switch (sel) {
4368 case 0:
4369 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4370 rn = "EPC";
4371 break;
4372 default:
4373 goto die;
4375 break;
4376 case 15:
4377 switch (sel) {
4378 case 0:
4379 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4380 rn = "PRid";
4381 break;
4382 case 1:
4383 check_insn(env, ctx, ISA_MIPS32R2);
4384 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4385 rn = "EBase";
4386 break;
4387 default:
4388 goto die;
4390 break;
4391 case 16:
4392 switch (sel) {
4393 case 0:
4394 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4395 rn = "Config";
4396 break;
4397 case 1:
4398 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4399 rn = "Config1";
4400 break;
4401 case 2:
4402 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4403 rn = "Config2";
4404 break;
4405 case 3:
4406 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4407 rn = "Config3";
4408 break;
4409 /* 6,7 are implementation dependent */
4410 case 6:
4411 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4412 rn = "Config6";
4413 break;
4414 case 7:
4415 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4416 rn = "Config7";
4417 break;
4418 default:
4419 goto die;
4421 break;
4422 case 17:
4423 switch (sel) {
4424 case 0:
4425 gen_helper_dmfc0_lladdr(arg);
4426 rn = "LLAddr";
4427 break;
4428 default:
4429 goto die;
4431 break;
4432 case 18:
4433 switch (sel) {
4434 case 0 ... 7:
4435 gen_helper_1i(dmfc0_watchlo, arg, sel);
4436 rn = "WatchLo";
4437 break;
4438 default:
4439 goto die;
4441 break;
4442 case 19:
4443 switch (sel) {
4444 case 0 ... 7:
4445 gen_helper_1i(mfc0_watchhi, arg, sel);
4446 rn = "WatchHi";
4447 break;
4448 default:
4449 goto die;
4451 break;
4452 case 20:
4453 switch (sel) {
4454 case 0:
4455 check_insn(env, ctx, ISA_MIPS3);
4456 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4457 rn = "XContext";
4458 break;
4459 default:
4460 goto die;
4462 break;
4463 case 21:
4464 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4465 switch (sel) {
4466 case 0:
4467 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4468 rn = "Framemask";
4469 break;
4470 default:
4471 goto die;
4473 break;
4474 case 22:
4475 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4476 rn = "'Diagnostic"; /* implementation dependent */
4477 break;
4478 case 23:
4479 switch (sel) {
4480 case 0:
4481 gen_helper_mfc0_debug(arg); /* EJTAG support */
4482 rn = "Debug";
4483 break;
4484 case 1:
4485 // gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4486 rn = "TraceControl";
4487 // break;
4488 case 2:
4489 // gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4490 rn = "TraceControl2";
4491 // break;
4492 case 3:
4493 // gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4494 rn = "UserTraceData";
4495 // break;
4496 case 4:
4497 // gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4498 rn = "TraceBPC";
4499 // break;
4500 default:
4501 goto die;
4503 break;
4504 case 24:
4505 switch (sel) {
4506 case 0:
4507 /* EJTAG support */
4508 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4509 rn = "DEPC";
4510 break;
4511 default:
4512 goto die;
4514 break;
4515 case 25:
4516 switch (sel) {
4517 case 0:
4518 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4519 rn = "Performance0";
4520 break;
4521 case 1:
4522 // gen_helper_dmfc0_performance1(arg);
4523 rn = "Performance1";
4524 // break;
4525 case 2:
4526 // gen_helper_dmfc0_performance2(arg);
4527 rn = "Performance2";
4528 // break;
4529 case 3:
4530 // gen_helper_dmfc0_performance3(arg);
4531 rn = "Performance3";
4532 // break;
4533 case 4:
4534 // gen_helper_dmfc0_performance4(arg);
4535 rn = "Performance4";
4536 // break;
4537 case 5:
4538 // gen_helper_dmfc0_performance5(arg);
4539 rn = "Performance5";
4540 // break;
4541 case 6:
4542 // gen_helper_dmfc0_performance6(arg);
4543 rn = "Performance6";
4544 // break;
4545 case 7:
4546 // gen_helper_dmfc0_performance7(arg);
4547 rn = "Performance7";
4548 // break;
4549 default:
4550 goto die;
4552 break;
4553 case 26:
4554 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4555 rn = "ECC";
4556 break;
4557 case 27:
4558 switch (sel) {
4559 /* ignored */
4560 case 0 ... 3:
4561 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4562 rn = "CacheErr";
4563 break;
4564 default:
4565 goto die;
4567 break;
4568 case 28:
4569 switch (sel) {
4570 case 0:
4571 case 2:
4572 case 4:
4573 case 6:
4574 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4575 rn = "TagLo";
4576 break;
4577 case 1:
4578 case 3:
4579 case 5:
4580 case 7:
4581 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4582 rn = "DataLo";
4583 break;
4584 default:
4585 goto die;
4587 break;
4588 case 29:
4589 switch (sel) {
4590 case 0:
4591 case 2:
4592 case 4:
4593 case 6:
4594 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4595 rn = "TagHi";
4596 break;
4597 case 1:
4598 case 3:
4599 case 5:
4600 case 7:
4601 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4602 rn = "DataHi";
4603 break;
4604 default:
4605 goto die;
4607 break;
4608 case 30:
4609 switch (sel) {
4610 case 0:
4611 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4612 rn = "ErrorEPC";
4613 break;
4614 default:
4615 goto die;
4617 break;
4618 case 31:
4619 switch (sel) {
4620 case 0:
4621 /* EJTAG support */
4622 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4623 rn = "DESAVE";
4624 break;
4625 default:
4626 goto die;
4628 break;
4629 default:
4630 goto die;
4632 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4633 return;
4635 die:
4636 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4637 generate_exception(ctx, EXCP_RI);
4640 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4642 const char *rn = "invalid";
4644 if (sel != 0)
4645 check_insn(env, ctx, ISA_MIPS64);
4647 if (use_icount)
4648 gen_io_start();
4650 switch (reg) {
4651 case 0:
4652 switch (sel) {
4653 case 0:
4654 gen_helper_mtc0_index(arg);
4655 rn = "Index";
4656 break;
4657 case 1:
4658 check_insn(env, ctx, ASE_MT);
4659 gen_helper_mtc0_mvpcontrol(arg);
4660 rn = "MVPControl";
4661 break;
4662 case 2:
4663 check_insn(env, ctx, ASE_MT);
4664 /* ignored */
4665 rn = "MVPConf0";
4666 break;
4667 case 3:
4668 check_insn(env, ctx, ASE_MT);
4669 /* ignored */
4670 rn = "MVPConf1";
4671 break;
4672 default:
4673 goto die;
4675 break;
4676 case 1:
4677 switch (sel) {
4678 case 0:
4679 /* ignored */
4680 rn = "Random";
4681 break;
4682 case 1:
4683 check_insn(env, ctx, ASE_MT);
4684 gen_helper_mtc0_vpecontrol(arg);
4685 rn = "VPEControl";
4686 break;
4687 case 2:
4688 check_insn(env, ctx, ASE_MT);
4689 gen_helper_mtc0_vpeconf0(arg);
4690 rn = "VPEConf0";
4691 break;
4692 case 3:
4693 check_insn(env, ctx, ASE_MT);
4694 gen_helper_mtc0_vpeconf1(arg);
4695 rn = "VPEConf1";
4696 break;
4697 case 4:
4698 check_insn(env, ctx, ASE_MT);
4699 gen_helper_mtc0_yqmask(arg);
4700 rn = "YQMask";
4701 break;
4702 case 5:
4703 check_insn(env, ctx, ASE_MT);
4704 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4705 rn = "VPESchedule";
4706 break;
4707 case 6:
4708 check_insn(env, ctx, ASE_MT);
4709 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4710 rn = "VPEScheFBack";
4711 break;
4712 case 7:
4713 check_insn(env, ctx, ASE_MT);
4714 gen_helper_mtc0_vpeopt(arg);
4715 rn = "VPEOpt";
4716 break;
4717 default:
4718 goto die;
4720 break;
4721 case 2:
4722 switch (sel) {
4723 case 0:
4724 gen_helper_mtc0_entrylo0(arg);
4725 rn = "EntryLo0";
4726 break;
4727 case 1:
4728 check_insn(env, ctx, ASE_MT);
4729 gen_helper_mtc0_tcstatus(arg);
4730 rn = "TCStatus";
4731 break;
4732 case 2:
4733 check_insn(env, ctx, ASE_MT);
4734 gen_helper_mtc0_tcbind(arg);
4735 rn = "TCBind";
4736 break;
4737 case 3:
4738 check_insn(env, ctx, ASE_MT);
4739 gen_helper_mtc0_tcrestart(arg);
4740 rn = "TCRestart";
4741 break;
4742 case 4:
4743 check_insn(env, ctx, ASE_MT);
4744 gen_helper_mtc0_tchalt(arg);
4745 rn = "TCHalt";
4746 break;
4747 case 5:
4748 check_insn(env, ctx, ASE_MT);
4749 gen_helper_mtc0_tccontext(arg);
4750 rn = "TCContext";
4751 break;
4752 case 6:
4753 check_insn(env, ctx, ASE_MT);
4754 gen_helper_mtc0_tcschedule(arg);
4755 rn = "TCSchedule";
4756 break;
4757 case 7:
4758 check_insn(env, ctx, ASE_MT);
4759 gen_helper_mtc0_tcschefback(arg);
4760 rn = "TCScheFBack";
4761 break;
4762 default:
4763 goto die;
4765 break;
4766 case 3:
4767 switch (sel) {
4768 case 0:
4769 gen_helper_mtc0_entrylo1(arg);
4770 rn = "EntryLo1";
4771 break;
4772 default:
4773 goto die;
4775 break;
4776 case 4:
4777 switch (sel) {
4778 case 0:
4779 gen_helper_mtc0_context(arg);
4780 rn = "Context";
4781 break;
4782 case 1:
4783 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
4784 rn = "ContextConfig";
4785 // break;
4786 default:
4787 goto die;
4789 break;
4790 case 5:
4791 switch (sel) {
4792 case 0:
4793 gen_helper_mtc0_pagemask(arg);
4794 rn = "PageMask";
4795 break;
4796 case 1:
4797 check_insn(env, ctx, ISA_MIPS32R2);
4798 gen_helper_mtc0_pagegrain(arg);
4799 rn = "PageGrain";
4800 break;
4801 default:
4802 goto die;
4804 break;
4805 case 6:
4806 switch (sel) {
4807 case 0:
4808 gen_helper_mtc0_wired(arg);
4809 rn = "Wired";
4810 break;
4811 case 1:
4812 check_insn(env, ctx, ISA_MIPS32R2);
4813 gen_helper_mtc0_srsconf0(arg);
4814 rn = "SRSConf0";
4815 break;
4816 case 2:
4817 check_insn(env, ctx, ISA_MIPS32R2);
4818 gen_helper_mtc0_srsconf1(arg);
4819 rn = "SRSConf1";
4820 break;
4821 case 3:
4822 check_insn(env, ctx, ISA_MIPS32R2);
4823 gen_helper_mtc0_srsconf2(arg);
4824 rn = "SRSConf2";
4825 break;
4826 case 4:
4827 check_insn(env, ctx, ISA_MIPS32R2);
4828 gen_helper_mtc0_srsconf3(arg);
4829 rn = "SRSConf3";
4830 break;
4831 case 5:
4832 check_insn(env, ctx, ISA_MIPS32R2);
4833 gen_helper_mtc0_srsconf4(arg);
4834 rn = "SRSConf4";
4835 break;
4836 default:
4837 goto die;
4839 break;
4840 case 7:
4841 switch (sel) {
4842 case 0:
4843 check_insn(env, ctx, ISA_MIPS32R2);
4844 gen_helper_mtc0_hwrena(arg);
4845 rn = "HWREna";
4846 break;
4847 default:
4848 goto die;
4850 break;
4851 case 8:
4852 /* ignored */
4853 rn = "BadVAddr";
4854 break;
4855 case 9:
4856 switch (sel) {
4857 case 0:
4858 gen_helper_mtc0_count(arg);
4859 rn = "Count";
4860 break;
4861 /* 6,7 are implementation dependent */
4862 default:
4863 goto die;
4865 /* Stop translation as we may have switched the execution mode */
4866 ctx->bstate = BS_STOP;
4867 break;
4868 case 10:
4869 switch (sel) {
4870 case 0:
4871 gen_helper_mtc0_entryhi(arg);
4872 rn = "EntryHi";
4873 break;
4874 default:
4875 goto die;
4877 break;
4878 case 11:
4879 switch (sel) {
4880 case 0:
4881 gen_helper_mtc0_compare(arg);
4882 rn = "Compare";
4883 break;
4884 /* 6,7 are implementation dependent */
4885 default:
4886 goto die;
4888 /* Stop translation as we may have switched the execution mode */
4889 ctx->bstate = BS_STOP;
4890 break;
4891 case 12:
4892 switch (sel) {
4893 case 0:
4894 save_cpu_state(ctx, 1);
4895 gen_helper_mtc0_status(arg);
4896 /* BS_STOP isn't good enough here, hflags may have changed. */
4897 gen_save_pc(ctx->pc + 4);
4898 ctx->bstate = BS_EXCP;
4899 rn = "Status";
4900 break;
4901 case 1:
4902 check_insn(env, ctx, ISA_MIPS32R2);
4903 gen_helper_mtc0_intctl(arg);
4904 /* Stop translation as we may have switched the execution mode */
4905 ctx->bstate = BS_STOP;
4906 rn = "IntCtl";
4907 break;
4908 case 2:
4909 check_insn(env, ctx, ISA_MIPS32R2);
4910 gen_helper_mtc0_srsctl(arg);
4911 /* Stop translation as we may have switched the execution mode */
4912 ctx->bstate = BS_STOP;
4913 rn = "SRSCtl";
4914 break;
4915 case 3:
4916 check_insn(env, ctx, ISA_MIPS32R2);
4917 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4918 /* Stop translation as we may have switched the execution mode */
4919 ctx->bstate = BS_STOP;
4920 rn = "SRSMap";
4921 break;
4922 default:
4923 goto die;
4925 break;
4926 case 13:
4927 switch (sel) {
4928 case 0:
4929 save_cpu_state(ctx, 1);
4930 gen_helper_mtc0_cause(arg);
4931 rn = "Cause";
4932 break;
4933 default:
4934 goto die;
4936 break;
4937 case 14:
4938 switch (sel) {
4939 case 0:
4940 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4941 rn = "EPC";
4942 break;
4943 default:
4944 goto die;
4946 break;
4947 case 15:
4948 switch (sel) {
4949 case 0:
4950 /* ignored */
4951 rn = "PRid";
4952 break;
4953 case 1:
4954 check_insn(env, ctx, ISA_MIPS32R2);
4955 gen_helper_mtc0_ebase(arg);
4956 rn = "EBase";
4957 break;
4958 default:
4959 goto die;
4961 break;
4962 case 16:
4963 switch (sel) {
4964 case 0:
4965 gen_helper_mtc0_config0(arg);
4966 rn = "Config";
4967 /* Stop translation as we may have switched the execution mode */
4968 ctx->bstate = BS_STOP;
4969 break;
4970 case 1:
4971 /* ignored, read only */
4972 rn = "Config1";
4973 break;
4974 case 2:
4975 gen_helper_mtc0_config2(arg);
4976 rn = "Config2";
4977 /* Stop translation as we may have switched the execution mode */
4978 ctx->bstate = BS_STOP;
4979 break;
4980 case 3:
4981 /* ignored */
4982 rn = "Config3";
4983 break;
4984 /* 6,7 are implementation dependent */
4985 default:
4986 rn = "Invalid config selector";
4987 goto die;
4989 break;
4990 case 17:
4991 switch (sel) {
4992 case 0:
4993 gen_helper_mtc0_lladdr(arg);
4994 rn = "LLAddr";
4995 break;
4996 default:
4997 goto die;
4999 break;
5000 case 18:
5001 switch (sel) {
5002 case 0 ... 7:
5003 gen_helper_1i(mtc0_watchlo, arg, sel);
5004 rn = "WatchLo";
5005 break;
5006 default:
5007 goto die;
5009 break;
5010 case 19:
5011 switch (sel) {
5012 case 0 ... 7:
5013 gen_helper_1i(mtc0_watchhi, arg, sel);
5014 rn = "WatchHi";
5015 break;
5016 default:
5017 goto die;
5019 break;
5020 case 20:
5021 switch (sel) {
5022 case 0:
5023 check_insn(env, ctx, ISA_MIPS3);
5024 gen_helper_mtc0_xcontext(arg);
5025 rn = "XContext";
5026 break;
5027 default:
5028 goto die;
5030 break;
5031 case 21:
5032 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5033 switch (sel) {
5034 case 0:
5035 gen_helper_mtc0_framemask(arg);
5036 rn = "Framemask";
5037 break;
5038 default:
5039 goto die;
5041 break;
5042 case 22:
5043 /* ignored */
5044 rn = "Diagnostic"; /* implementation dependent */
5045 break;
5046 case 23:
5047 switch (sel) {
5048 case 0:
5049 gen_helper_mtc0_debug(arg); /* EJTAG support */
5050 /* BS_STOP isn't good enough here, hflags may have changed. */
5051 gen_save_pc(ctx->pc + 4);
5052 ctx->bstate = BS_EXCP;
5053 rn = "Debug";
5054 break;
5055 case 1:
5056 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5057 /* Stop translation as we may have switched the execution mode */
5058 ctx->bstate = BS_STOP;
5059 rn = "TraceControl";
5060 // break;
5061 case 2:
5062 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5063 /* Stop translation as we may have switched the execution mode */
5064 ctx->bstate = BS_STOP;
5065 rn = "TraceControl2";
5066 // break;
5067 case 3:
5068 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5069 /* Stop translation as we may have switched the execution mode */
5070 ctx->bstate = BS_STOP;
5071 rn = "UserTraceData";
5072 // break;
5073 case 4:
5074 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5075 /* Stop translation as we may have switched the execution mode */
5076 ctx->bstate = BS_STOP;
5077 rn = "TraceBPC";
5078 // break;
5079 default:
5080 goto die;
5082 break;
5083 case 24:
5084 switch (sel) {
5085 case 0:
5086 /* EJTAG support */
5087 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5088 rn = "DEPC";
5089 break;
5090 default:
5091 goto die;
5093 break;
5094 case 25:
5095 switch (sel) {
5096 case 0:
5097 gen_helper_mtc0_performance0(arg);
5098 rn = "Performance0";
5099 break;
5100 case 1:
5101 // gen_helper_mtc0_performance1(arg);
5102 rn = "Performance1";
5103 // break;
5104 case 2:
5105 // gen_helper_mtc0_performance2(arg);
5106 rn = "Performance2";
5107 // break;
5108 case 3:
5109 // gen_helper_mtc0_performance3(arg);
5110 rn = "Performance3";
5111 // break;
5112 case 4:
5113 // gen_helper_mtc0_performance4(arg);
5114 rn = "Performance4";
5115 // break;
5116 case 5:
5117 // gen_helper_mtc0_performance5(arg);
5118 rn = "Performance5";
5119 // break;
5120 case 6:
5121 // gen_helper_mtc0_performance6(arg);
5122 rn = "Performance6";
5123 // break;
5124 case 7:
5125 // gen_helper_mtc0_performance7(arg);
5126 rn = "Performance7";
5127 // break;
5128 default:
5129 goto die;
5131 break;
5132 case 26:
5133 /* ignored */
5134 rn = "ECC";
5135 break;
5136 case 27:
5137 switch (sel) {
5138 case 0 ... 3:
5139 /* ignored */
5140 rn = "CacheErr";
5141 break;
5142 default:
5143 goto die;
5145 break;
5146 case 28:
5147 switch (sel) {
5148 case 0:
5149 case 2:
5150 case 4:
5151 case 6:
5152 gen_helper_mtc0_taglo(arg);
5153 rn = "TagLo";
5154 break;
5155 case 1:
5156 case 3:
5157 case 5:
5158 case 7:
5159 gen_helper_mtc0_datalo(arg);
5160 rn = "DataLo";
5161 break;
5162 default:
5163 goto die;
5165 break;
5166 case 29:
5167 switch (sel) {
5168 case 0:
5169 case 2:
5170 case 4:
5171 case 6:
5172 gen_helper_mtc0_taghi(arg);
5173 rn = "TagHi";
5174 break;
5175 case 1:
5176 case 3:
5177 case 5:
5178 case 7:
5179 gen_helper_mtc0_datahi(arg);
5180 rn = "DataHi";
5181 break;
5182 default:
5183 rn = "invalid sel";
5184 goto die;
5186 break;
5187 case 30:
5188 switch (sel) {
5189 case 0:
5190 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5191 rn = "ErrorEPC";
5192 break;
5193 default:
5194 goto die;
5196 break;
5197 case 31:
5198 switch (sel) {
5199 case 0:
5200 /* EJTAG support */
5201 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5202 rn = "DESAVE";
5203 break;
5204 default:
5205 goto die;
5207 /* Stop translation as we may have switched the execution mode */
5208 ctx->bstate = BS_STOP;
5209 break;
5210 default:
5211 goto die;
5213 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5214 /* For simplicity assume that all writes can cause interrupts. */
5215 if (use_icount) {
5216 gen_io_end();
5217 ctx->bstate = BS_STOP;
5219 return;
5221 die:
5222 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5223 generate_exception(ctx, EXCP_RI);
5225 #endif /* TARGET_MIPS64 */
5227 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5228 int u, int sel, int h)
5230 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5231 TCGv t0 = tcg_temp_local_new();
5233 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5234 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5235 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5236 tcg_gen_movi_tl(t0, -1);
5237 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5238 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5239 tcg_gen_movi_tl(t0, -1);
5240 else if (u == 0) {
5241 switch (rt) {
5242 case 2:
5243 switch (sel) {
5244 case 1:
5245 gen_helper_mftc0_tcstatus(t0);
5246 break;
5247 case 2:
5248 gen_helper_mftc0_tcbind(t0);
5249 break;
5250 case 3:
5251 gen_helper_mftc0_tcrestart(t0);
5252 break;
5253 case 4:
5254 gen_helper_mftc0_tchalt(t0);
5255 break;
5256 case 5:
5257 gen_helper_mftc0_tccontext(t0);
5258 break;
5259 case 6:
5260 gen_helper_mftc0_tcschedule(t0);
5261 break;
5262 case 7:
5263 gen_helper_mftc0_tcschefback(t0);
5264 break;
5265 default:
5266 gen_mfc0(env, ctx, t0, rt, sel);
5267 break;
5269 break;
5270 case 10:
5271 switch (sel) {
5272 case 0:
5273 gen_helper_mftc0_entryhi(t0);
5274 break;
5275 default:
5276 gen_mfc0(env, ctx, t0, rt, sel);
5277 break;
5279 case 12:
5280 switch (sel) {
5281 case 0:
5282 gen_helper_mftc0_status(t0);
5283 break;
5284 default:
5285 gen_mfc0(env, ctx, t0, rt, sel);
5286 break;
5288 case 23:
5289 switch (sel) {
5290 case 0:
5291 gen_helper_mftc0_debug(t0);
5292 break;
5293 default:
5294 gen_mfc0(env, ctx, t0, rt, sel);
5295 break;
5297 break;
5298 default:
5299 gen_mfc0(env, ctx, t0, rt, sel);
5301 } else switch (sel) {
5302 /* GPR registers. */
5303 case 0:
5304 gen_helper_1i(mftgpr, t0, rt);
5305 break;
5306 /* Auxiliary CPU registers */
5307 case 1:
5308 switch (rt) {
5309 case 0:
5310 gen_helper_1i(mftlo, t0, 0);
5311 break;
5312 case 1:
5313 gen_helper_1i(mfthi, t0, 0);
5314 break;
5315 case 2:
5316 gen_helper_1i(mftacx, t0, 0);
5317 break;
5318 case 4:
5319 gen_helper_1i(mftlo, t0, 1);
5320 break;
5321 case 5:
5322 gen_helper_1i(mfthi, t0, 1);
5323 break;
5324 case 6:
5325 gen_helper_1i(mftacx, t0, 1);
5326 break;
5327 case 8:
5328 gen_helper_1i(mftlo, t0, 2);
5329 break;
5330 case 9:
5331 gen_helper_1i(mfthi, t0, 2);
5332 break;
5333 case 10:
5334 gen_helper_1i(mftacx, t0, 2);
5335 break;
5336 case 12:
5337 gen_helper_1i(mftlo, t0, 3);
5338 break;
5339 case 13:
5340 gen_helper_1i(mfthi, t0, 3);
5341 break;
5342 case 14:
5343 gen_helper_1i(mftacx, t0, 3);
5344 break;
5345 case 16:
5346 gen_helper_mftdsp(t0);
5347 break;
5348 default:
5349 goto die;
5351 break;
5352 /* Floating point (COP1). */
5353 case 2:
5354 /* XXX: For now we support only a single FPU context. */
5355 if (h == 0) {
5356 TCGv_i32 fp0 = tcg_temp_new_i32();
5358 gen_load_fpr32(fp0, rt);
5359 tcg_gen_ext_i32_tl(t0, fp0);
5360 tcg_temp_free_i32(fp0);
5361 } else {
5362 TCGv_i32 fp0 = tcg_temp_new_i32();
5364 gen_load_fpr32h(fp0, rt);
5365 tcg_gen_ext_i32_tl(t0, fp0);
5366 tcg_temp_free_i32(fp0);
5368 break;
5369 case 3:
5370 /* XXX: For now we support only a single FPU context. */
5371 gen_helper_1i(cfc1, t0, rt);
5372 break;
5373 /* COP2: Not implemented. */
5374 case 4:
5375 case 5:
5376 /* fall through */
5377 default:
5378 goto die;
5380 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5381 gen_store_gpr(t0, rd);
5382 tcg_temp_free(t0);
5383 return;
5385 die:
5386 tcg_temp_free(t0);
5387 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5388 generate_exception(ctx, EXCP_RI);
5391 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5392 int u, int sel, int h)
5394 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5395 TCGv t0 = tcg_temp_local_new();
5397 gen_load_gpr(t0, rt);
5398 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5399 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5400 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5401 /* NOP */ ;
5402 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5403 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5404 /* NOP */ ;
5405 else if (u == 0) {
5406 switch (rd) {
5407 case 2:
5408 switch (sel) {
5409 case 1:
5410 gen_helper_mttc0_tcstatus(t0);
5411 break;
5412 case 2:
5413 gen_helper_mttc0_tcbind(t0);
5414 break;
5415 case 3:
5416 gen_helper_mttc0_tcrestart(t0);
5417 break;
5418 case 4:
5419 gen_helper_mttc0_tchalt(t0);
5420 break;
5421 case 5:
5422 gen_helper_mttc0_tccontext(t0);
5423 break;
5424 case 6:
5425 gen_helper_mttc0_tcschedule(t0);
5426 break;
5427 case 7:
5428 gen_helper_mttc0_tcschefback(t0);
5429 break;
5430 default:
5431 gen_mtc0(env, ctx, t0, rd, sel);
5432 break;
5434 break;
5435 case 10:
5436 switch (sel) {
5437 case 0:
5438 gen_helper_mttc0_entryhi(t0);
5439 break;
5440 default:
5441 gen_mtc0(env, ctx, t0, rd, sel);
5442 break;
5444 case 12:
5445 switch (sel) {
5446 case 0:
5447 gen_helper_mttc0_status(t0);
5448 break;
5449 default:
5450 gen_mtc0(env, ctx, t0, rd, sel);
5451 break;
5453 case 23:
5454 switch (sel) {
5455 case 0:
5456 gen_helper_mttc0_debug(t0);
5457 break;
5458 default:
5459 gen_mtc0(env, ctx, t0, rd, sel);
5460 break;
5462 break;
5463 default:
5464 gen_mtc0(env, ctx, t0, rd, sel);
5466 } else switch (sel) {
5467 /* GPR registers. */
5468 case 0:
5469 gen_helper_1i(mttgpr, t0, rd);
5470 break;
5471 /* Auxiliary CPU registers */
5472 case 1:
5473 switch (rd) {
5474 case 0:
5475 gen_helper_1i(mttlo, t0, 0);
5476 break;
5477 case 1:
5478 gen_helper_1i(mtthi, t0, 0);
5479 break;
5480 case 2:
5481 gen_helper_1i(mttacx, t0, 0);
5482 break;
5483 case 4:
5484 gen_helper_1i(mttlo, t0, 1);
5485 break;
5486 case 5:
5487 gen_helper_1i(mtthi, t0, 1);
5488 break;
5489 case 6:
5490 gen_helper_1i(mttacx, t0, 1);
5491 break;
5492 case 8:
5493 gen_helper_1i(mttlo, t0, 2);
5494 break;
5495 case 9:
5496 gen_helper_1i(mtthi, t0, 2);
5497 break;
5498 case 10:
5499 gen_helper_1i(mttacx, t0, 2);
5500 break;
5501 case 12:
5502 gen_helper_1i(mttlo, t0, 3);
5503 break;
5504 case 13:
5505 gen_helper_1i(mtthi, t0, 3);
5506 break;
5507 case 14:
5508 gen_helper_1i(mttacx, t0, 3);
5509 break;
5510 case 16:
5511 gen_helper_mttdsp(t0);
5512 break;
5513 default:
5514 goto die;
5516 break;
5517 /* Floating point (COP1). */
5518 case 2:
5519 /* XXX: For now we support only a single FPU context. */
5520 if (h == 0) {
5521 TCGv_i32 fp0 = tcg_temp_new_i32();
5523 tcg_gen_trunc_tl_i32(fp0, t0);
5524 gen_store_fpr32(fp0, rd);
5525 tcg_temp_free_i32(fp0);
5526 } else {
5527 TCGv_i32 fp0 = tcg_temp_new_i32();
5529 tcg_gen_trunc_tl_i32(fp0, t0);
5530 gen_store_fpr32h(fp0, rd);
5531 tcg_temp_free_i32(fp0);
5533 break;
5534 case 3:
5535 /* XXX: For now we support only a single FPU context. */
5536 gen_helper_1i(ctc1, t0, rd);
5537 break;
5538 /* COP2: Not implemented. */
5539 case 4:
5540 case 5:
5541 /* fall through */
5542 default:
5543 goto die;
5545 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5546 tcg_temp_free(t0);
5547 return;
5549 die:
5550 tcg_temp_free(t0);
5551 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5552 generate_exception(ctx, EXCP_RI);
5555 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5557 const char *opn = "ldst";
5559 switch (opc) {
5560 case OPC_MFC0:
5561 if (rt == 0) {
5562 /* Treat as NOP. */
5563 return;
5565 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5566 opn = "mfc0";
5567 break;
5568 case OPC_MTC0:
5570 TCGv t0 = tcg_temp_new();
5572 gen_load_gpr(t0, rt);
5573 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5574 tcg_temp_free(t0);
5576 opn = "mtc0";
5577 break;
5578 #if defined(TARGET_MIPS64)
5579 case OPC_DMFC0:
5580 check_insn(env, ctx, ISA_MIPS3);
5581 if (rt == 0) {
5582 /* Treat as NOP. */
5583 return;
5585 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5586 opn = "dmfc0";
5587 break;
5588 case OPC_DMTC0:
5589 check_insn(env, ctx, ISA_MIPS3);
5591 TCGv t0 = tcg_temp_new();
5593 gen_load_gpr(t0, rt);
5594 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5595 tcg_temp_free(t0);
5597 opn = "dmtc0";
5598 break;
5599 #endif
5600 case OPC_MFTR:
5601 check_insn(env, ctx, ASE_MT);
5602 if (rd == 0) {
5603 /* Treat as NOP. */
5604 return;
5606 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5607 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5608 opn = "mftr";
5609 break;
5610 case OPC_MTTR:
5611 check_insn(env, ctx, ASE_MT);
5612 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5613 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5614 opn = "mttr";
5615 break;
5616 case OPC_TLBWI:
5617 opn = "tlbwi";
5618 if (!env->tlb->helper_tlbwi)
5619 goto die;
5620 gen_helper_tlbwi();
5621 break;
5622 case OPC_TLBWR:
5623 opn = "tlbwr";
5624 if (!env->tlb->helper_tlbwr)
5625 goto die;
5626 gen_helper_tlbwr();
5627 break;
5628 case OPC_TLBP:
5629 opn = "tlbp";
5630 if (!env->tlb->helper_tlbp)
5631 goto die;
5632 gen_helper_tlbp();
5633 break;
5634 case OPC_TLBR:
5635 opn = "tlbr";
5636 if (!env->tlb->helper_tlbr)
5637 goto die;
5638 gen_helper_tlbr();
5639 break;
5640 case OPC_ERET:
5641 opn = "eret";
5642 check_insn(env, ctx, ISA_MIPS2);
5643 gen_helper_eret();
5644 ctx->bstate = BS_EXCP;
5645 break;
5646 case OPC_DERET:
5647 opn = "deret";
5648 check_insn(env, ctx, ISA_MIPS32);
5649 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5650 MIPS_INVAL(opn);
5651 generate_exception(ctx, EXCP_RI);
5652 } else {
5653 gen_helper_deret();
5654 ctx->bstate = BS_EXCP;
5656 break;
5657 case OPC_WAIT:
5658 opn = "wait";
5659 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5660 /* If we get an exception, we want to restart at next instruction */
5661 ctx->pc += 4;
5662 save_cpu_state(ctx, 1);
5663 ctx->pc -= 4;
5664 gen_helper_wait();
5665 ctx->bstate = BS_EXCP;
5666 break;
5667 default:
5668 die:
5669 MIPS_INVAL(opn);
5670 generate_exception(ctx, EXCP_RI);
5671 return;
5673 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5675 #endif /* !CONFIG_USER_ONLY */
5677 /* CP1 Branches (before delay slot) */
5678 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5679 int32_t cc, int32_t offset)
5681 target_ulong btarget;
5682 const char *opn = "cp1 cond branch";
5683 TCGv_i32 t0 = tcg_temp_new_i32();
5685 if (cc != 0)
5686 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5688 btarget = ctx->pc + 4 + offset;
5690 switch (op) {
5691 case OPC_BC1F:
5692 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5693 tcg_gen_not_i32(t0, t0);
5694 tcg_gen_andi_i32(t0, t0, 1);
5695 tcg_gen_extu_i32_tl(bcond, t0);
5696 opn = "bc1f";
5697 goto not_likely;
5698 case OPC_BC1FL:
5699 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5700 tcg_gen_not_i32(t0, t0);
5701 tcg_gen_andi_i32(t0, t0, 1);
5702 tcg_gen_extu_i32_tl(bcond, t0);
5703 opn = "bc1fl";
5704 goto likely;
5705 case OPC_BC1T:
5706 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5707 tcg_gen_andi_i32(t0, t0, 1);
5708 tcg_gen_extu_i32_tl(bcond, t0);
5709 opn = "bc1t";
5710 goto not_likely;
5711 case OPC_BC1TL:
5712 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5713 tcg_gen_andi_i32(t0, t0, 1);
5714 tcg_gen_extu_i32_tl(bcond, t0);
5715 opn = "bc1tl";
5716 likely:
5717 ctx->hflags |= MIPS_HFLAG_BL;
5718 break;
5719 case OPC_BC1FANY2:
5721 TCGv_i32 t1 = tcg_temp_new_i32();
5722 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5723 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5724 tcg_gen_nor_i32(t0, t0, t1);
5725 tcg_temp_free_i32(t1);
5726 tcg_gen_andi_i32(t0, t0, 1);
5727 tcg_gen_extu_i32_tl(bcond, t0);
5729 opn = "bc1any2f";
5730 goto not_likely;
5731 case OPC_BC1TANY2:
5733 TCGv_i32 t1 = tcg_temp_new_i32();
5734 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5735 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5736 tcg_gen_or_i32(t0, t0, t1);
5737 tcg_temp_free_i32(t1);
5738 tcg_gen_andi_i32(t0, t0, 1);
5739 tcg_gen_extu_i32_tl(bcond, t0);
5741 opn = "bc1any2t";
5742 goto not_likely;
5743 case OPC_BC1FANY4:
5745 TCGv_i32 t1 = tcg_temp_new_i32();
5746 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5747 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5748 tcg_gen_or_i32(t0, t0, t1);
5749 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5750 tcg_gen_or_i32(t0, t0, t1);
5751 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5752 tcg_gen_nor_i32(t0, t0, t1);
5753 tcg_temp_free_i32(t1);
5754 tcg_gen_andi_i32(t0, t0, 1);
5755 tcg_gen_extu_i32_tl(bcond, t0);
5757 opn = "bc1any4f";
5758 goto not_likely;
5759 case OPC_BC1TANY4:
5761 TCGv_i32 t1 = tcg_temp_new_i32();
5762 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5763 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5764 tcg_gen_or_i32(t0, t0, t1);
5765 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5766 tcg_gen_or_i32(t0, t0, t1);
5767 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5768 tcg_gen_or_i32(t0, t0, t1);
5769 tcg_temp_free_i32(t1);
5770 tcg_gen_andi_i32(t0, t0, 1);
5771 tcg_gen_extu_i32_tl(bcond, t0);
5773 opn = "bc1any4t";
5774 not_likely:
5775 ctx->hflags |= MIPS_HFLAG_BC;
5776 break;
5777 default:
5778 MIPS_INVAL(opn);
5779 generate_exception (ctx, EXCP_RI);
5780 goto out;
5782 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5783 ctx->hflags, btarget);
5784 ctx->btarget = btarget;
5786 out:
5787 tcg_temp_free_i32(t0);
5790 /* Coprocessor 1 (FPU) */
5792 #define FOP(func, fmt) (((fmt) << 21) | (func))
5794 enum fopcode {
5795 OPC_ADD_S = FOP(0, FMT_S),
5796 OPC_SUB_S = FOP(1, FMT_S),
5797 OPC_MUL_S = FOP(2, FMT_S),
5798 OPC_DIV_S = FOP(3, FMT_S),
5799 OPC_SQRT_S = FOP(4, FMT_S),
5800 OPC_ABS_S = FOP(5, FMT_S),
5801 OPC_MOV_S = FOP(6, FMT_S),
5802 OPC_NEG_S = FOP(7, FMT_S),
5803 OPC_ROUND_L_S = FOP(8, FMT_S),
5804 OPC_TRUNC_L_S = FOP(9, FMT_S),
5805 OPC_CEIL_L_S = FOP(10, FMT_S),
5806 OPC_FLOOR_L_S = FOP(11, FMT_S),
5807 OPC_ROUND_W_S = FOP(12, FMT_S),
5808 OPC_TRUNC_W_S = FOP(13, FMT_S),
5809 OPC_CEIL_W_S = FOP(14, FMT_S),
5810 OPC_FLOOR_W_S = FOP(15, FMT_S),
5811 OPC_MOVCF_S = FOP(17, FMT_S),
5812 OPC_MOVZ_S = FOP(18, FMT_S),
5813 OPC_MOVN_S = FOP(19, FMT_S),
5814 OPC_RECIP_S = FOP(21, FMT_S),
5815 OPC_RSQRT_S = FOP(22, FMT_S),
5816 OPC_RECIP2_S = FOP(28, FMT_S),
5817 OPC_RECIP1_S = FOP(29, FMT_S),
5818 OPC_RSQRT1_S = FOP(30, FMT_S),
5819 OPC_RSQRT2_S = FOP(31, FMT_S),
5820 OPC_CVT_D_S = FOP(33, FMT_S),
5821 OPC_CVT_W_S = FOP(36, FMT_S),
5822 OPC_CVT_L_S = FOP(37, FMT_S),
5823 OPC_CVT_PS_S = FOP(38, FMT_S),
5824 OPC_CMP_F_S = FOP (48, FMT_S),
5825 OPC_CMP_UN_S = FOP (49, FMT_S),
5826 OPC_CMP_EQ_S = FOP (50, FMT_S),
5827 OPC_CMP_UEQ_S = FOP (51, FMT_S),
5828 OPC_CMP_OLT_S = FOP (52, FMT_S),
5829 OPC_CMP_ULT_S = FOP (53, FMT_S),
5830 OPC_CMP_OLE_S = FOP (54, FMT_S),
5831 OPC_CMP_ULE_S = FOP (55, FMT_S),
5832 OPC_CMP_SF_S = FOP (56, FMT_S),
5833 OPC_CMP_NGLE_S = FOP (57, FMT_S),
5834 OPC_CMP_SEQ_S = FOP (58, FMT_S),
5835 OPC_CMP_NGL_S = FOP (59, FMT_S),
5836 OPC_CMP_LT_S = FOP (60, FMT_S),
5837 OPC_CMP_NGE_S = FOP (61, FMT_S),
5838 OPC_CMP_LE_S = FOP (62, FMT_S),
5839 OPC_CMP_NGT_S = FOP (63, FMT_S),
5841 OPC_ADD_D = FOP(0, FMT_D),
5842 OPC_SUB_D = FOP(1, FMT_D),
5843 OPC_MUL_D = FOP(2, FMT_D),
5844 OPC_DIV_D = FOP(3, FMT_D),
5845 OPC_SQRT_D = FOP(4, FMT_D),
5846 OPC_ABS_D = FOP(5, FMT_D),
5847 OPC_MOV_D = FOP(6, FMT_D),
5848 OPC_NEG_D = FOP(7, FMT_D),
5849 OPC_ROUND_L_D = FOP(8, FMT_D),
5850 OPC_TRUNC_L_D = FOP(9, FMT_D),
5851 OPC_CEIL_L_D = FOP(10, FMT_D),
5852 OPC_FLOOR_L_D = FOP(11, FMT_D),
5853 OPC_ROUND_W_D = FOP(12, FMT_D),
5854 OPC_TRUNC_W_D = FOP(13, FMT_D),
5855 OPC_CEIL_W_D = FOP(14, FMT_D),
5856 OPC_FLOOR_W_D = FOP(15, FMT_D),
5857 OPC_MOVCF_D = FOP(17, FMT_D),
5858 OPC_MOVZ_D = FOP(18, FMT_D),
5859 OPC_MOVN_D = FOP(19, FMT_D),
5860 OPC_RECIP_D = FOP(21, FMT_D),
5861 OPC_RSQRT_D = FOP(22, FMT_D),
5862 OPC_RECIP2_D = FOP(28, FMT_D),
5863 OPC_RECIP1_D = FOP(29, FMT_D),
5864 OPC_RSQRT1_D = FOP(30, FMT_D),
5865 OPC_RSQRT2_D = FOP(31, FMT_D),
5866 OPC_CVT_S_D = FOP(32, FMT_D),
5867 OPC_CVT_W_D = FOP(36, FMT_D),
5868 OPC_CVT_L_D = FOP(37, FMT_D),
5869 OPC_CMP_F_D = FOP (48, FMT_D),
5870 OPC_CMP_UN_D = FOP (49, FMT_D),
5871 OPC_CMP_EQ_D = FOP (50, FMT_D),
5872 OPC_CMP_UEQ_D = FOP (51, FMT_D),
5873 OPC_CMP_OLT_D = FOP (52, FMT_D),
5874 OPC_CMP_ULT_D = FOP (53, FMT_D),
5875 OPC_CMP_OLE_D = FOP (54, FMT_D),
5876 OPC_CMP_ULE_D = FOP (55, FMT_D),
5877 OPC_CMP_SF_D = FOP (56, FMT_D),
5878 OPC_CMP_NGLE_D = FOP (57, FMT_D),
5879 OPC_CMP_SEQ_D = FOP (58, FMT_D),
5880 OPC_CMP_NGL_D = FOP (59, FMT_D),
5881 OPC_CMP_LT_D = FOP (60, FMT_D),
5882 OPC_CMP_NGE_D = FOP (61, FMT_D),
5883 OPC_CMP_LE_D = FOP (62, FMT_D),
5884 OPC_CMP_NGT_D = FOP (63, FMT_D),
5886 OPC_CVT_S_W = FOP(32, FMT_W),
5887 OPC_CVT_D_W = FOP(33, FMT_W),
5888 OPC_CVT_S_L = FOP(32, FMT_L),
5889 OPC_CVT_D_L = FOP(33, FMT_L),
5890 OPC_CVT_PS_PW = FOP(38, FMT_W),
5892 OPC_ADD_PS = FOP(0, FMT_PS),
5893 OPC_SUB_PS = FOP(1, FMT_PS),
5894 OPC_MUL_PS = FOP(2, FMT_PS),
5895 OPC_DIV_PS = FOP(3, FMT_PS),
5896 OPC_ABS_PS = FOP(5, FMT_PS),
5897 OPC_MOV_PS = FOP(6, FMT_PS),
5898 OPC_NEG_PS = FOP(7, FMT_PS),
5899 OPC_MOVCF_PS = FOP(17, FMT_PS),
5900 OPC_MOVZ_PS = FOP(18, FMT_PS),
5901 OPC_MOVN_PS = FOP(19, FMT_PS),
5902 OPC_ADDR_PS = FOP(24, FMT_PS),
5903 OPC_MULR_PS = FOP(26, FMT_PS),
5904 OPC_RECIP2_PS = FOP(28, FMT_PS),
5905 OPC_RECIP1_PS = FOP(29, FMT_PS),
5906 OPC_RSQRT1_PS = FOP(30, FMT_PS),
5907 OPC_RSQRT2_PS = FOP(31, FMT_PS),
5909 OPC_CVT_S_PU = FOP(32, FMT_PS),
5910 OPC_CVT_PW_PS = FOP(36, FMT_PS),
5911 OPC_CVT_S_PL = FOP(40, FMT_PS),
5912 OPC_PLL_PS = FOP(44, FMT_PS),
5913 OPC_PLU_PS = FOP(45, FMT_PS),
5914 OPC_PUL_PS = FOP(46, FMT_PS),
5915 OPC_PUU_PS = FOP(47, FMT_PS),
5916 OPC_CMP_F_PS = FOP (48, FMT_PS),
5917 OPC_CMP_UN_PS = FOP (49, FMT_PS),
5918 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
5919 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
5920 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
5921 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
5922 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
5923 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
5924 OPC_CMP_SF_PS = FOP (56, FMT_PS),
5925 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
5926 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
5927 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
5928 OPC_CMP_LT_PS = FOP (60, FMT_PS),
5929 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
5930 OPC_CMP_LE_PS = FOP (62, FMT_PS),
5931 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
5934 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5936 const char *opn = "cp1 move";
5937 TCGv t0 = tcg_temp_new();
5939 switch (opc) {
5940 case OPC_MFC1:
5942 TCGv_i32 fp0 = tcg_temp_new_i32();
5944 gen_load_fpr32(fp0, fs);
5945 tcg_gen_ext_i32_tl(t0, fp0);
5946 tcg_temp_free_i32(fp0);
5948 gen_store_gpr(t0, rt);
5949 opn = "mfc1";
5950 break;
5951 case OPC_MTC1:
5952 gen_load_gpr(t0, rt);
5954 TCGv_i32 fp0 = tcg_temp_new_i32();
5956 tcg_gen_trunc_tl_i32(fp0, t0);
5957 gen_store_fpr32(fp0, fs);
5958 tcg_temp_free_i32(fp0);
5960 opn = "mtc1";
5961 break;
5962 case OPC_CFC1:
5963 gen_helper_1i(cfc1, t0, fs);
5964 gen_store_gpr(t0, rt);
5965 opn = "cfc1";
5966 break;
5967 case OPC_CTC1:
5968 gen_load_gpr(t0, rt);
5969 gen_helper_1i(ctc1, t0, fs);
5970 opn = "ctc1";
5971 break;
5972 #if defined(TARGET_MIPS64)
5973 case OPC_DMFC1:
5974 gen_load_fpr64(ctx, t0, fs);
5975 gen_store_gpr(t0, rt);
5976 opn = "dmfc1";
5977 break;
5978 case OPC_DMTC1:
5979 gen_load_gpr(t0, rt);
5980 gen_store_fpr64(ctx, t0, fs);
5981 opn = "dmtc1";
5982 break;
5983 #endif
5984 case OPC_MFHC1:
5986 TCGv_i32 fp0 = tcg_temp_new_i32();
5988 gen_load_fpr32h(fp0, fs);
5989 tcg_gen_ext_i32_tl(t0, fp0);
5990 tcg_temp_free_i32(fp0);
5992 gen_store_gpr(t0, rt);
5993 opn = "mfhc1";
5994 break;
5995 case OPC_MTHC1:
5996 gen_load_gpr(t0, rt);
5998 TCGv_i32 fp0 = tcg_temp_new_i32();
6000 tcg_gen_trunc_tl_i32(fp0, t0);
6001 gen_store_fpr32h(fp0, fs);
6002 tcg_temp_free_i32(fp0);
6004 opn = "mthc1";
6005 break;
6006 default:
6007 MIPS_INVAL(opn);
6008 generate_exception (ctx, EXCP_RI);
6009 goto out;
6011 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6013 out:
6014 tcg_temp_free(t0);
6017 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6019 int l1;
6020 TCGCond cond;
6021 TCGv_i32 t0;
6023 if (rd == 0) {
6024 /* Treat as NOP. */
6025 return;
6028 if (tf)
6029 cond = TCG_COND_EQ;
6030 else
6031 cond = TCG_COND_NE;
6033 l1 = gen_new_label();
6034 t0 = tcg_temp_new_i32();
6035 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6036 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6037 tcg_temp_free_i32(t0);
6038 if (rs == 0) {
6039 tcg_gen_movi_tl(cpu_gpr[rd], 0);
6040 } else {
6041 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6043 gen_set_label(l1);
6046 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6048 int cond;
6049 TCGv_i32 t0 = tcg_temp_new_i32();
6050 int l1 = gen_new_label();
6052 if (tf)
6053 cond = TCG_COND_EQ;
6054 else
6055 cond = TCG_COND_NE;
6057 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6058 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6059 gen_load_fpr32(t0, fs);
6060 gen_store_fpr32(t0, fd);
6061 gen_set_label(l1);
6062 tcg_temp_free_i32(t0);
6065 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6067 int cond;
6068 TCGv_i32 t0 = tcg_temp_new_i32();
6069 TCGv_i64 fp0;
6070 int l1 = gen_new_label();
6072 if (tf)
6073 cond = TCG_COND_EQ;
6074 else
6075 cond = TCG_COND_NE;
6077 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6078 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6079 tcg_temp_free_i32(t0);
6080 fp0 = tcg_temp_new_i64();
6081 gen_load_fpr64(ctx, fp0, fs);
6082 gen_store_fpr64(ctx, fp0, fd);
6083 tcg_temp_free_i64(fp0);
6084 gen_set_label(l1);
6087 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6089 int cond;
6090 TCGv_i32 t0 = tcg_temp_new_i32();
6091 int l1 = gen_new_label();
6092 int l2 = gen_new_label();
6094 if (tf)
6095 cond = TCG_COND_EQ;
6096 else
6097 cond = TCG_COND_NE;
6099 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6100 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6101 gen_load_fpr32(t0, fs);
6102 gen_store_fpr32(t0, fd);
6103 gen_set_label(l1);
6105 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6106 tcg_gen_brcondi_i32(cond, t0, 0, l2);
6107 gen_load_fpr32h(t0, fs);
6108 gen_store_fpr32h(t0, fd);
6109 tcg_temp_free_i32(t0);
6110 gen_set_label(l2);
6114 static void gen_farith (DisasContext *ctx, enum fopcode op1,
6115 int ft, int fs, int fd, int cc)
6117 const char *opn = "farith";
6118 const char *condnames[] = {
6119 "c.f",
6120 "c.un",
6121 "c.eq",
6122 "c.ueq",
6123 "c.olt",
6124 "c.ult",
6125 "c.ole",
6126 "c.ule",
6127 "c.sf",
6128 "c.ngle",
6129 "c.seq",
6130 "c.ngl",
6131 "c.lt",
6132 "c.nge",
6133 "c.le",
6134 "c.ngt",
6136 const char *condnames_abs[] = {
6137 "cabs.f",
6138 "cabs.un",
6139 "cabs.eq",
6140 "cabs.ueq",
6141 "cabs.olt",
6142 "cabs.ult",
6143 "cabs.ole",
6144 "cabs.ule",
6145 "cabs.sf",
6146 "cabs.ngle",
6147 "cabs.seq",
6148 "cabs.ngl",
6149 "cabs.lt",
6150 "cabs.nge",
6151 "cabs.le",
6152 "cabs.ngt",
6154 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6155 uint32_t func = ctx->opcode & 0x3f;
6157 switch (op1) {
6158 case OPC_ADD_S:
6160 TCGv_i32 fp0 = tcg_temp_new_i32();
6161 TCGv_i32 fp1 = tcg_temp_new_i32();
6163 gen_load_fpr32(fp0, fs);
6164 gen_load_fpr32(fp1, ft);
6165 gen_helper_float_add_s(fp0, fp0, fp1);
6166 tcg_temp_free_i32(fp1);
6167 gen_store_fpr32(fp0, fd);
6168 tcg_temp_free_i32(fp0);
6170 opn = "add.s";
6171 optype = BINOP;
6172 break;
6173 case OPC_SUB_S:
6175 TCGv_i32 fp0 = tcg_temp_new_i32();
6176 TCGv_i32 fp1 = tcg_temp_new_i32();
6178 gen_load_fpr32(fp0, fs);
6179 gen_load_fpr32(fp1, ft);
6180 gen_helper_float_sub_s(fp0, fp0, fp1);
6181 tcg_temp_free_i32(fp1);
6182 gen_store_fpr32(fp0, fd);
6183 tcg_temp_free_i32(fp0);
6185 opn = "sub.s";
6186 optype = BINOP;
6187 break;
6188 case OPC_MUL_S:
6190 TCGv_i32 fp0 = tcg_temp_new_i32();
6191 TCGv_i32 fp1 = tcg_temp_new_i32();
6193 gen_load_fpr32(fp0, fs);
6194 gen_load_fpr32(fp1, ft);
6195 gen_helper_float_mul_s(fp0, fp0, fp1);
6196 tcg_temp_free_i32(fp1);
6197 gen_store_fpr32(fp0, fd);
6198 tcg_temp_free_i32(fp0);
6200 opn = "mul.s";
6201 optype = BINOP;
6202 break;
6203 case OPC_DIV_S:
6205 TCGv_i32 fp0 = tcg_temp_new_i32();
6206 TCGv_i32 fp1 = tcg_temp_new_i32();
6208 gen_load_fpr32(fp0, fs);
6209 gen_load_fpr32(fp1, ft);
6210 gen_helper_float_div_s(fp0, fp0, fp1);
6211 tcg_temp_free_i32(fp1);
6212 gen_store_fpr32(fp0, fd);
6213 tcg_temp_free_i32(fp0);
6215 opn = "div.s";
6216 optype = BINOP;
6217 break;
6218 case OPC_SQRT_S:
6220 TCGv_i32 fp0 = tcg_temp_new_i32();
6222 gen_load_fpr32(fp0, fs);
6223 gen_helper_float_sqrt_s(fp0, fp0);
6224 gen_store_fpr32(fp0, fd);
6225 tcg_temp_free_i32(fp0);
6227 opn = "sqrt.s";
6228 break;
6229 case OPC_ABS_S:
6231 TCGv_i32 fp0 = tcg_temp_new_i32();
6233 gen_load_fpr32(fp0, fs);
6234 gen_helper_float_abs_s(fp0, fp0);
6235 gen_store_fpr32(fp0, fd);
6236 tcg_temp_free_i32(fp0);
6238 opn = "abs.s";
6239 break;
6240 case OPC_MOV_S:
6242 TCGv_i32 fp0 = tcg_temp_new_i32();
6244 gen_load_fpr32(fp0, fs);
6245 gen_store_fpr32(fp0, fd);
6246 tcg_temp_free_i32(fp0);
6248 opn = "mov.s";
6249 break;
6250 case OPC_NEG_S:
6252 TCGv_i32 fp0 = tcg_temp_new_i32();
6254 gen_load_fpr32(fp0, fs);
6255 gen_helper_float_chs_s(fp0, fp0);
6256 gen_store_fpr32(fp0, fd);
6257 tcg_temp_free_i32(fp0);
6259 opn = "neg.s";
6260 break;
6261 case OPC_ROUND_L_S:
6262 check_cp1_64bitmode(ctx);
6264 TCGv_i32 fp32 = tcg_temp_new_i32();
6265 TCGv_i64 fp64 = tcg_temp_new_i64();
6267 gen_load_fpr32(fp32, fs);
6268 gen_helper_float_roundl_s(fp64, fp32);
6269 tcg_temp_free_i32(fp32);
6270 gen_store_fpr64(ctx, fp64, fd);
6271 tcg_temp_free_i64(fp64);
6273 opn = "round.l.s";
6274 break;
6275 case OPC_TRUNC_L_S:
6276 check_cp1_64bitmode(ctx);
6278 TCGv_i32 fp32 = tcg_temp_new_i32();
6279 TCGv_i64 fp64 = tcg_temp_new_i64();
6281 gen_load_fpr32(fp32, fs);
6282 gen_helper_float_truncl_s(fp64, fp32);
6283 tcg_temp_free_i32(fp32);
6284 gen_store_fpr64(ctx, fp64, fd);
6285 tcg_temp_free_i64(fp64);
6287 opn = "trunc.l.s";
6288 break;
6289 case OPC_CEIL_L_S:
6290 check_cp1_64bitmode(ctx);
6292 TCGv_i32 fp32 = tcg_temp_new_i32();
6293 TCGv_i64 fp64 = tcg_temp_new_i64();
6295 gen_load_fpr32(fp32, fs);
6296 gen_helper_float_ceill_s(fp64, fp32);
6297 tcg_temp_free_i32(fp32);
6298 gen_store_fpr64(ctx, fp64, fd);
6299 tcg_temp_free_i64(fp64);
6301 opn = "ceil.l.s";
6302 break;
6303 case OPC_FLOOR_L_S:
6304 check_cp1_64bitmode(ctx);
6306 TCGv_i32 fp32 = tcg_temp_new_i32();
6307 TCGv_i64 fp64 = tcg_temp_new_i64();
6309 gen_load_fpr32(fp32, fs);
6310 gen_helper_float_floorl_s(fp64, fp32);
6311 tcg_temp_free_i32(fp32);
6312 gen_store_fpr64(ctx, fp64, fd);
6313 tcg_temp_free_i64(fp64);
6315 opn = "floor.l.s";
6316 break;
6317 case OPC_ROUND_W_S:
6319 TCGv_i32 fp0 = tcg_temp_new_i32();
6321 gen_load_fpr32(fp0, fs);
6322 gen_helper_float_roundw_s(fp0, fp0);
6323 gen_store_fpr32(fp0, fd);
6324 tcg_temp_free_i32(fp0);
6326 opn = "round.w.s";
6327 break;
6328 case OPC_TRUNC_W_S:
6330 TCGv_i32 fp0 = tcg_temp_new_i32();
6332 gen_load_fpr32(fp0, fs);
6333 gen_helper_float_truncw_s(fp0, fp0);
6334 gen_store_fpr32(fp0, fd);
6335 tcg_temp_free_i32(fp0);
6337 opn = "trunc.w.s";
6338 break;
6339 case OPC_CEIL_W_S:
6341 TCGv_i32 fp0 = tcg_temp_new_i32();
6343 gen_load_fpr32(fp0, fs);
6344 gen_helper_float_ceilw_s(fp0, fp0);
6345 gen_store_fpr32(fp0, fd);
6346 tcg_temp_free_i32(fp0);
6348 opn = "ceil.w.s";
6349 break;
6350 case OPC_FLOOR_W_S:
6352 TCGv_i32 fp0 = tcg_temp_new_i32();
6354 gen_load_fpr32(fp0, fs);
6355 gen_helper_float_floorw_s(fp0, fp0);
6356 gen_store_fpr32(fp0, fd);
6357 tcg_temp_free_i32(fp0);
6359 opn = "floor.w.s";
6360 break;
6361 case OPC_MOVCF_S:
6362 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6363 opn = "movcf.s";
6364 break;
6365 case OPC_MOVZ_S:
6367 int l1 = gen_new_label();
6368 TCGv_i32 fp0;
6370 if (ft != 0) {
6371 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6373 fp0 = tcg_temp_new_i32();
6374 gen_load_fpr32(fp0, fs);
6375 gen_store_fpr32(fp0, fd);
6376 tcg_temp_free_i32(fp0);
6377 gen_set_label(l1);
6379 opn = "movz.s";
6380 break;
6381 case OPC_MOVN_S:
6383 int l1 = gen_new_label();
6384 TCGv_i32 fp0;
6386 if (ft != 0) {
6387 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6388 fp0 = tcg_temp_new_i32();
6389 gen_load_fpr32(fp0, fs);
6390 gen_store_fpr32(fp0, fd);
6391 tcg_temp_free_i32(fp0);
6392 gen_set_label(l1);
6395 opn = "movn.s";
6396 break;
6397 case OPC_RECIP_S:
6398 check_cop1x(ctx);
6400 TCGv_i32 fp0 = tcg_temp_new_i32();
6402 gen_load_fpr32(fp0, fs);
6403 gen_helper_float_recip_s(fp0, fp0);
6404 gen_store_fpr32(fp0, fd);
6405 tcg_temp_free_i32(fp0);
6407 opn = "recip.s";
6408 break;
6409 case OPC_RSQRT_S:
6410 check_cop1x(ctx);
6412 TCGv_i32 fp0 = tcg_temp_new_i32();
6414 gen_load_fpr32(fp0, fs);
6415 gen_helper_float_rsqrt_s(fp0, fp0);
6416 gen_store_fpr32(fp0, fd);
6417 tcg_temp_free_i32(fp0);
6419 opn = "rsqrt.s";
6420 break;
6421 case OPC_RECIP2_S:
6422 check_cp1_64bitmode(ctx);
6424 TCGv_i32 fp0 = tcg_temp_new_i32();
6425 TCGv_i32 fp1 = tcg_temp_new_i32();
6427 gen_load_fpr32(fp0, fs);
6428 gen_load_fpr32(fp1, fd);
6429 gen_helper_float_recip2_s(fp0, fp0, fp1);
6430 tcg_temp_free_i32(fp1);
6431 gen_store_fpr32(fp0, fd);
6432 tcg_temp_free_i32(fp0);
6434 opn = "recip2.s";
6435 break;
6436 case OPC_RECIP1_S:
6437 check_cp1_64bitmode(ctx);
6439 TCGv_i32 fp0 = tcg_temp_new_i32();
6441 gen_load_fpr32(fp0, fs);
6442 gen_helper_float_recip1_s(fp0, fp0);
6443 gen_store_fpr32(fp0, fd);
6444 tcg_temp_free_i32(fp0);
6446 opn = "recip1.s";
6447 break;
6448 case OPC_RSQRT1_S:
6449 check_cp1_64bitmode(ctx);
6451 TCGv_i32 fp0 = tcg_temp_new_i32();
6453 gen_load_fpr32(fp0, fs);
6454 gen_helper_float_rsqrt1_s(fp0, fp0);
6455 gen_store_fpr32(fp0, fd);
6456 tcg_temp_free_i32(fp0);
6458 opn = "rsqrt1.s";
6459 break;
6460 case OPC_RSQRT2_S:
6461 check_cp1_64bitmode(ctx);
6463 TCGv_i32 fp0 = tcg_temp_new_i32();
6464 TCGv_i32 fp1 = tcg_temp_new_i32();
6466 gen_load_fpr32(fp0, fs);
6467 gen_load_fpr32(fp1, ft);
6468 gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6469 tcg_temp_free_i32(fp1);
6470 gen_store_fpr32(fp0, fd);
6471 tcg_temp_free_i32(fp0);
6473 opn = "rsqrt2.s";
6474 break;
6475 case OPC_CVT_D_S:
6476 check_cp1_registers(ctx, fd);
6478 TCGv_i32 fp32 = tcg_temp_new_i32();
6479 TCGv_i64 fp64 = tcg_temp_new_i64();
6481 gen_load_fpr32(fp32, fs);
6482 gen_helper_float_cvtd_s(fp64, fp32);
6483 tcg_temp_free_i32(fp32);
6484 gen_store_fpr64(ctx, fp64, fd);
6485 tcg_temp_free_i64(fp64);
6487 opn = "cvt.d.s";
6488 break;
6489 case OPC_CVT_W_S:
6491 TCGv_i32 fp0 = tcg_temp_new_i32();
6493 gen_load_fpr32(fp0, fs);
6494 gen_helper_float_cvtw_s(fp0, fp0);
6495 gen_store_fpr32(fp0, fd);
6496 tcg_temp_free_i32(fp0);
6498 opn = "cvt.w.s";
6499 break;
6500 case OPC_CVT_L_S:
6501 check_cp1_64bitmode(ctx);
6503 TCGv_i32 fp32 = tcg_temp_new_i32();
6504 TCGv_i64 fp64 = tcg_temp_new_i64();
6506 gen_load_fpr32(fp32, fs);
6507 gen_helper_float_cvtl_s(fp64, fp32);
6508 tcg_temp_free_i32(fp32);
6509 gen_store_fpr64(ctx, fp64, fd);
6510 tcg_temp_free_i64(fp64);
6512 opn = "cvt.l.s";
6513 break;
6514 case OPC_CVT_PS_S:
6515 check_cp1_64bitmode(ctx);
6517 TCGv_i64 fp64 = tcg_temp_new_i64();
6518 TCGv_i32 fp32_0 = tcg_temp_new_i32();
6519 TCGv_i32 fp32_1 = tcg_temp_new_i32();
6521 gen_load_fpr32(fp32_0, fs);
6522 gen_load_fpr32(fp32_1, ft);
6523 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6524 tcg_temp_free_i32(fp32_1);
6525 tcg_temp_free_i32(fp32_0);
6526 gen_store_fpr64(ctx, fp64, fd);
6527 tcg_temp_free_i64(fp64);
6529 opn = "cvt.ps.s";
6530 break;
6531 case OPC_CMP_F_S:
6532 case OPC_CMP_UN_S:
6533 case OPC_CMP_EQ_S:
6534 case OPC_CMP_UEQ_S:
6535 case OPC_CMP_OLT_S:
6536 case OPC_CMP_ULT_S:
6537 case OPC_CMP_OLE_S:
6538 case OPC_CMP_ULE_S:
6539 case OPC_CMP_SF_S:
6540 case OPC_CMP_NGLE_S:
6541 case OPC_CMP_SEQ_S:
6542 case OPC_CMP_NGL_S:
6543 case OPC_CMP_LT_S:
6544 case OPC_CMP_NGE_S:
6545 case OPC_CMP_LE_S:
6546 case OPC_CMP_NGT_S:
6547 if (ctx->opcode & (1 << 6)) {
6548 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6549 opn = condnames_abs[func-48];
6550 } else {
6551 gen_cmp_s(ctx, func-48, ft, fs, cc);
6552 opn = condnames[func-48];
6554 break;
6555 case OPC_ADD_D:
6556 check_cp1_registers(ctx, fs | ft | fd);
6558 TCGv_i64 fp0 = tcg_temp_new_i64();
6559 TCGv_i64 fp1 = tcg_temp_new_i64();
6561 gen_load_fpr64(ctx, fp0, fs);
6562 gen_load_fpr64(ctx, fp1, ft);
6563 gen_helper_float_add_d(fp0, fp0, fp1);
6564 tcg_temp_free_i64(fp1);
6565 gen_store_fpr64(ctx, fp0, fd);
6566 tcg_temp_free_i64(fp0);
6568 opn = "add.d";
6569 optype = BINOP;
6570 break;
6571 case OPC_SUB_D:
6572 check_cp1_registers(ctx, fs | ft | fd);
6574 TCGv_i64 fp0 = tcg_temp_new_i64();
6575 TCGv_i64 fp1 = tcg_temp_new_i64();
6577 gen_load_fpr64(ctx, fp0, fs);
6578 gen_load_fpr64(ctx, fp1, ft);
6579 gen_helper_float_sub_d(fp0, fp0, fp1);
6580 tcg_temp_free_i64(fp1);
6581 gen_store_fpr64(ctx, fp0, fd);
6582 tcg_temp_free_i64(fp0);
6584 opn = "sub.d";
6585 optype = BINOP;
6586 break;
6587 case OPC_MUL_D:
6588 check_cp1_registers(ctx, fs | ft | fd);
6590 TCGv_i64 fp0 = tcg_temp_new_i64();
6591 TCGv_i64 fp1 = tcg_temp_new_i64();
6593 gen_load_fpr64(ctx, fp0, fs);
6594 gen_load_fpr64(ctx, fp1, ft);
6595 gen_helper_float_mul_d(fp0, fp0, fp1);
6596 tcg_temp_free_i64(fp1);
6597 gen_store_fpr64(ctx, fp0, fd);
6598 tcg_temp_free_i64(fp0);
6600 opn = "mul.d";
6601 optype = BINOP;
6602 break;
6603 case OPC_DIV_D:
6604 check_cp1_registers(ctx, fs | ft | fd);
6606 TCGv_i64 fp0 = tcg_temp_new_i64();
6607 TCGv_i64 fp1 = tcg_temp_new_i64();
6609 gen_load_fpr64(ctx, fp0, fs);
6610 gen_load_fpr64(ctx, fp1, ft);
6611 gen_helper_float_div_d(fp0, fp0, fp1);
6612 tcg_temp_free_i64(fp1);
6613 gen_store_fpr64(ctx, fp0, fd);
6614 tcg_temp_free_i64(fp0);
6616 opn = "div.d";
6617 optype = BINOP;
6618 break;
6619 case OPC_SQRT_D:
6620 check_cp1_registers(ctx, fs | fd);
6622 TCGv_i64 fp0 = tcg_temp_new_i64();
6624 gen_load_fpr64(ctx, fp0, fs);
6625 gen_helper_float_sqrt_d(fp0, fp0);
6626 gen_store_fpr64(ctx, fp0, fd);
6627 tcg_temp_free_i64(fp0);
6629 opn = "sqrt.d";
6630 break;
6631 case OPC_ABS_D:
6632 check_cp1_registers(ctx, fs | fd);
6634 TCGv_i64 fp0 = tcg_temp_new_i64();
6636 gen_load_fpr64(ctx, fp0, fs);
6637 gen_helper_float_abs_d(fp0, fp0);
6638 gen_store_fpr64(ctx, fp0, fd);
6639 tcg_temp_free_i64(fp0);
6641 opn = "abs.d";
6642 break;
6643 case OPC_MOV_D:
6644 check_cp1_registers(ctx, fs | fd);
6646 TCGv_i64 fp0 = tcg_temp_new_i64();
6648 gen_load_fpr64(ctx, fp0, fs);
6649 gen_store_fpr64(ctx, fp0, fd);
6650 tcg_temp_free_i64(fp0);
6652 opn = "mov.d";
6653 break;
6654 case OPC_NEG_D:
6655 check_cp1_registers(ctx, fs | fd);
6657 TCGv_i64 fp0 = tcg_temp_new_i64();
6659 gen_load_fpr64(ctx, fp0, fs);
6660 gen_helper_float_chs_d(fp0, fp0);
6661 gen_store_fpr64(ctx, fp0, fd);
6662 tcg_temp_free_i64(fp0);
6664 opn = "neg.d";
6665 break;
6666 case OPC_ROUND_L_D:
6667 check_cp1_64bitmode(ctx);
6669 TCGv_i64 fp0 = tcg_temp_new_i64();
6671 gen_load_fpr64(ctx, fp0, fs);
6672 gen_helper_float_roundl_d(fp0, fp0);
6673 gen_store_fpr64(ctx, fp0, fd);
6674 tcg_temp_free_i64(fp0);
6676 opn = "round.l.d";
6677 break;
6678 case OPC_TRUNC_L_D:
6679 check_cp1_64bitmode(ctx);
6681 TCGv_i64 fp0 = tcg_temp_new_i64();
6683 gen_load_fpr64(ctx, fp0, fs);
6684 gen_helper_float_truncl_d(fp0, fp0);
6685 gen_store_fpr64(ctx, fp0, fd);
6686 tcg_temp_free_i64(fp0);
6688 opn = "trunc.l.d";
6689 break;
6690 case OPC_CEIL_L_D:
6691 check_cp1_64bitmode(ctx);
6693 TCGv_i64 fp0 = tcg_temp_new_i64();
6695 gen_load_fpr64(ctx, fp0, fs);
6696 gen_helper_float_ceill_d(fp0, fp0);
6697 gen_store_fpr64(ctx, fp0, fd);
6698 tcg_temp_free_i64(fp0);
6700 opn = "ceil.l.d";
6701 break;
6702 case OPC_FLOOR_L_D:
6703 check_cp1_64bitmode(ctx);
6705 TCGv_i64 fp0 = tcg_temp_new_i64();
6707 gen_load_fpr64(ctx, fp0, fs);
6708 gen_helper_float_floorl_d(fp0, fp0);
6709 gen_store_fpr64(ctx, fp0, fd);
6710 tcg_temp_free_i64(fp0);
6712 opn = "floor.l.d";
6713 break;
6714 case OPC_ROUND_W_D:
6715 check_cp1_registers(ctx, fs);
6717 TCGv_i32 fp32 = tcg_temp_new_i32();
6718 TCGv_i64 fp64 = tcg_temp_new_i64();
6720 gen_load_fpr64(ctx, fp64, fs);
6721 gen_helper_float_roundw_d(fp32, fp64);
6722 tcg_temp_free_i64(fp64);
6723 gen_store_fpr32(fp32, fd);
6724 tcg_temp_free_i32(fp32);
6726 opn = "round.w.d";
6727 break;
6728 case OPC_TRUNC_W_D:
6729 check_cp1_registers(ctx, fs);
6731 TCGv_i32 fp32 = tcg_temp_new_i32();
6732 TCGv_i64 fp64 = tcg_temp_new_i64();
6734 gen_load_fpr64(ctx, fp64, fs);
6735 gen_helper_float_truncw_d(fp32, fp64);
6736 tcg_temp_free_i64(fp64);
6737 gen_store_fpr32(fp32, fd);
6738 tcg_temp_free_i32(fp32);
6740 opn = "trunc.w.d";
6741 break;
6742 case OPC_CEIL_W_D:
6743 check_cp1_registers(ctx, fs);
6745 TCGv_i32 fp32 = tcg_temp_new_i32();
6746 TCGv_i64 fp64 = tcg_temp_new_i64();
6748 gen_load_fpr64(ctx, fp64, fs);
6749 gen_helper_float_ceilw_d(fp32, fp64);
6750 tcg_temp_free_i64(fp64);
6751 gen_store_fpr32(fp32, fd);
6752 tcg_temp_free_i32(fp32);
6754 opn = "ceil.w.d";
6755 break;
6756 case OPC_FLOOR_W_D:
6757 check_cp1_registers(ctx, fs);
6759 TCGv_i32 fp32 = tcg_temp_new_i32();
6760 TCGv_i64 fp64 = tcg_temp_new_i64();
6762 gen_load_fpr64(ctx, fp64, fs);
6763 gen_helper_float_floorw_d(fp32, fp64);
6764 tcg_temp_free_i64(fp64);
6765 gen_store_fpr32(fp32, fd);
6766 tcg_temp_free_i32(fp32);
6768 opn = "floor.w.d";
6769 break;
6770 case OPC_MOVCF_D:
6771 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6772 opn = "movcf.d";
6773 break;
6774 case OPC_MOVZ_D:
6776 int l1 = gen_new_label();
6777 TCGv_i64 fp0;
6779 if (ft != 0) {
6780 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6782 fp0 = tcg_temp_new_i64();
6783 gen_load_fpr64(ctx, fp0, fs);
6784 gen_store_fpr64(ctx, fp0, fd);
6785 tcg_temp_free_i64(fp0);
6786 gen_set_label(l1);
6788 opn = "movz.d";
6789 break;
6790 case OPC_MOVN_D:
6792 int l1 = gen_new_label();
6793 TCGv_i64 fp0;
6795 if (ft != 0) {
6796 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6797 fp0 = tcg_temp_new_i64();
6798 gen_load_fpr64(ctx, fp0, fs);
6799 gen_store_fpr64(ctx, fp0, fd);
6800 tcg_temp_free_i64(fp0);
6801 gen_set_label(l1);
6804 opn = "movn.d";
6805 break;
6806 case OPC_RECIP_D:
6807 check_cp1_64bitmode(ctx);
6809 TCGv_i64 fp0 = tcg_temp_new_i64();
6811 gen_load_fpr64(ctx, fp0, fs);
6812 gen_helper_float_recip_d(fp0, fp0);
6813 gen_store_fpr64(ctx, fp0, fd);
6814 tcg_temp_free_i64(fp0);
6816 opn = "recip.d";
6817 break;
6818 case OPC_RSQRT_D:
6819 check_cp1_64bitmode(ctx);
6821 TCGv_i64 fp0 = tcg_temp_new_i64();
6823 gen_load_fpr64(ctx, fp0, fs);
6824 gen_helper_float_rsqrt_d(fp0, fp0);
6825 gen_store_fpr64(ctx, fp0, fd);
6826 tcg_temp_free_i64(fp0);
6828 opn = "rsqrt.d";
6829 break;
6830 case OPC_RECIP2_D:
6831 check_cp1_64bitmode(ctx);
6833 TCGv_i64 fp0 = tcg_temp_new_i64();
6834 TCGv_i64 fp1 = tcg_temp_new_i64();
6836 gen_load_fpr64(ctx, fp0, fs);
6837 gen_load_fpr64(ctx, fp1, ft);
6838 gen_helper_float_recip2_d(fp0, fp0, fp1);
6839 tcg_temp_free_i64(fp1);
6840 gen_store_fpr64(ctx, fp0, fd);
6841 tcg_temp_free_i64(fp0);
6843 opn = "recip2.d";
6844 break;
6845 case OPC_RECIP1_D:
6846 check_cp1_64bitmode(ctx);
6848 TCGv_i64 fp0 = tcg_temp_new_i64();
6850 gen_load_fpr64(ctx, fp0, fs);
6851 gen_helper_float_recip1_d(fp0, fp0);
6852 gen_store_fpr64(ctx, fp0, fd);
6853 tcg_temp_free_i64(fp0);
6855 opn = "recip1.d";
6856 break;
6857 case OPC_RSQRT1_D:
6858 check_cp1_64bitmode(ctx);
6860 TCGv_i64 fp0 = tcg_temp_new_i64();
6862 gen_load_fpr64(ctx, fp0, fs);
6863 gen_helper_float_rsqrt1_d(fp0, fp0);
6864 gen_store_fpr64(ctx, fp0, fd);
6865 tcg_temp_free_i64(fp0);
6867 opn = "rsqrt1.d";
6868 break;
6869 case OPC_RSQRT2_D:
6870 check_cp1_64bitmode(ctx);
6872 TCGv_i64 fp0 = tcg_temp_new_i64();
6873 TCGv_i64 fp1 = tcg_temp_new_i64();
6875 gen_load_fpr64(ctx, fp0, fs);
6876 gen_load_fpr64(ctx, fp1, ft);
6877 gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6878 tcg_temp_free_i64(fp1);
6879 gen_store_fpr64(ctx, fp0, fd);
6880 tcg_temp_free_i64(fp0);
6882 opn = "rsqrt2.d";
6883 break;
6884 case OPC_CMP_F_D:
6885 case OPC_CMP_UN_D:
6886 case OPC_CMP_EQ_D:
6887 case OPC_CMP_UEQ_D:
6888 case OPC_CMP_OLT_D:
6889 case OPC_CMP_ULT_D:
6890 case OPC_CMP_OLE_D:
6891 case OPC_CMP_ULE_D:
6892 case OPC_CMP_SF_D:
6893 case OPC_CMP_NGLE_D:
6894 case OPC_CMP_SEQ_D:
6895 case OPC_CMP_NGL_D:
6896 case OPC_CMP_LT_D:
6897 case OPC_CMP_NGE_D:
6898 case OPC_CMP_LE_D:
6899 case OPC_CMP_NGT_D:
6900 if (ctx->opcode & (1 << 6)) {
6901 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
6902 opn = condnames_abs[func-48];
6903 } else {
6904 gen_cmp_d(ctx, func-48, ft, fs, cc);
6905 opn = condnames[func-48];
6907 break;
6908 case OPC_CVT_S_D:
6909 check_cp1_registers(ctx, fs);
6911 TCGv_i32 fp32 = tcg_temp_new_i32();
6912 TCGv_i64 fp64 = tcg_temp_new_i64();
6914 gen_load_fpr64(ctx, fp64, fs);
6915 gen_helper_float_cvts_d(fp32, fp64);
6916 tcg_temp_free_i64(fp64);
6917 gen_store_fpr32(fp32, fd);
6918 tcg_temp_free_i32(fp32);
6920 opn = "cvt.s.d";
6921 break;
6922 case OPC_CVT_W_D:
6923 check_cp1_registers(ctx, fs);
6925 TCGv_i32 fp32 = tcg_temp_new_i32();
6926 TCGv_i64 fp64 = tcg_temp_new_i64();
6928 gen_load_fpr64(ctx, fp64, fs);
6929 gen_helper_float_cvtw_d(fp32, fp64);
6930 tcg_temp_free_i64(fp64);
6931 gen_store_fpr32(fp32, fd);
6932 tcg_temp_free_i32(fp32);
6934 opn = "cvt.w.d";
6935 break;
6936 case OPC_CVT_L_D:
6937 check_cp1_64bitmode(ctx);
6939 TCGv_i64 fp0 = tcg_temp_new_i64();
6941 gen_load_fpr64(ctx, fp0, fs);
6942 gen_helper_float_cvtl_d(fp0, fp0);
6943 gen_store_fpr64(ctx, fp0, fd);
6944 tcg_temp_free_i64(fp0);
6946 opn = "cvt.l.d";
6947 break;
6948 case OPC_CVT_S_W:
6950 TCGv_i32 fp0 = tcg_temp_new_i32();
6952 gen_load_fpr32(fp0, fs);
6953 gen_helper_float_cvts_w(fp0, fp0);
6954 gen_store_fpr32(fp0, fd);
6955 tcg_temp_free_i32(fp0);
6957 opn = "cvt.s.w";
6958 break;
6959 case OPC_CVT_D_W:
6960 check_cp1_registers(ctx, fd);
6962 TCGv_i32 fp32 = tcg_temp_new_i32();
6963 TCGv_i64 fp64 = tcg_temp_new_i64();
6965 gen_load_fpr32(fp32, fs);
6966 gen_helper_float_cvtd_w(fp64, fp32);
6967 tcg_temp_free_i32(fp32);
6968 gen_store_fpr64(ctx, fp64, fd);
6969 tcg_temp_free_i64(fp64);
6971 opn = "cvt.d.w";
6972 break;
6973 case OPC_CVT_S_L:
6974 check_cp1_64bitmode(ctx);
6976 TCGv_i32 fp32 = tcg_temp_new_i32();
6977 TCGv_i64 fp64 = tcg_temp_new_i64();
6979 gen_load_fpr64(ctx, fp64, fs);
6980 gen_helper_float_cvts_l(fp32, fp64);
6981 tcg_temp_free_i64(fp64);
6982 gen_store_fpr32(fp32, fd);
6983 tcg_temp_free_i32(fp32);
6985 opn = "cvt.s.l";
6986 break;
6987 case OPC_CVT_D_L:
6988 check_cp1_64bitmode(ctx);
6990 TCGv_i64 fp0 = tcg_temp_new_i64();
6992 gen_load_fpr64(ctx, fp0, fs);
6993 gen_helper_float_cvtd_l(fp0, fp0);
6994 gen_store_fpr64(ctx, fp0, fd);
6995 tcg_temp_free_i64(fp0);
6997 opn = "cvt.d.l";
6998 break;
6999 case OPC_CVT_PS_PW:
7000 check_cp1_64bitmode(ctx);
7002 TCGv_i64 fp0 = tcg_temp_new_i64();
7004 gen_load_fpr64(ctx, fp0, fs);
7005 gen_helper_float_cvtps_pw(fp0, fp0);
7006 gen_store_fpr64(ctx, fp0, fd);
7007 tcg_temp_free_i64(fp0);
7009 opn = "cvt.ps.pw";
7010 break;
7011 case OPC_ADD_PS:
7012 check_cp1_64bitmode(ctx);
7014 TCGv_i64 fp0 = tcg_temp_new_i64();
7015 TCGv_i64 fp1 = tcg_temp_new_i64();
7017 gen_load_fpr64(ctx, fp0, fs);
7018 gen_load_fpr64(ctx, fp1, ft);
7019 gen_helper_float_add_ps(fp0, fp0, fp1);
7020 tcg_temp_free_i64(fp1);
7021 gen_store_fpr64(ctx, fp0, fd);
7022 tcg_temp_free_i64(fp0);
7024 opn = "add.ps";
7025 break;
7026 case OPC_SUB_PS:
7027 check_cp1_64bitmode(ctx);
7029 TCGv_i64 fp0 = tcg_temp_new_i64();
7030 TCGv_i64 fp1 = tcg_temp_new_i64();
7032 gen_load_fpr64(ctx, fp0, fs);
7033 gen_load_fpr64(ctx, fp1, ft);
7034 gen_helper_float_sub_ps(fp0, fp0, fp1);
7035 tcg_temp_free_i64(fp1);
7036 gen_store_fpr64(ctx, fp0, fd);
7037 tcg_temp_free_i64(fp0);
7039 opn = "sub.ps";
7040 break;
7041 case OPC_MUL_PS:
7042 check_cp1_64bitmode(ctx);
7044 TCGv_i64 fp0 = tcg_temp_new_i64();
7045 TCGv_i64 fp1 = tcg_temp_new_i64();
7047 gen_load_fpr64(ctx, fp0, fs);
7048 gen_load_fpr64(ctx, fp1, ft);
7049 gen_helper_float_mul_ps(fp0, fp0, fp1);
7050 tcg_temp_free_i64(fp1);
7051 gen_store_fpr64(ctx, fp0, fd);
7052 tcg_temp_free_i64(fp0);
7054 opn = "mul.ps";
7055 break;
7056 case OPC_ABS_PS:
7057 check_cp1_64bitmode(ctx);
7059 TCGv_i64 fp0 = tcg_temp_new_i64();
7061 gen_load_fpr64(ctx, fp0, fs);
7062 gen_helper_float_abs_ps(fp0, fp0);
7063 gen_store_fpr64(ctx, fp0, fd);
7064 tcg_temp_free_i64(fp0);
7066 opn = "abs.ps";
7067 break;
7068 case OPC_MOV_PS:
7069 check_cp1_64bitmode(ctx);
7071 TCGv_i64 fp0 = tcg_temp_new_i64();
7073 gen_load_fpr64(ctx, fp0, fs);
7074 gen_store_fpr64(ctx, fp0, fd);
7075 tcg_temp_free_i64(fp0);
7077 opn = "mov.ps";
7078 break;
7079 case OPC_NEG_PS:
7080 check_cp1_64bitmode(ctx);
7082 TCGv_i64 fp0 = tcg_temp_new_i64();
7084 gen_load_fpr64(ctx, fp0, fs);
7085 gen_helper_float_chs_ps(fp0, fp0);
7086 gen_store_fpr64(ctx, fp0, fd);
7087 tcg_temp_free_i64(fp0);
7089 opn = "neg.ps";
7090 break;
7091 case OPC_MOVCF_PS:
7092 check_cp1_64bitmode(ctx);
7093 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7094 opn = "movcf.ps";
7095 break;
7096 case OPC_MOVZ_PS:
7097 check_cp1_64bitmode(ctx);
7099 int l1 = gen_new_label();
7100 TCGv_i64 fp0;
7102 if (ft != 0)
7103 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7104 fp0 = tcg_temp_new_i64();
7105 gen_load_fpr64(ctx, fp0, fs);
7106 gen_store_fpr64(ctx, fp0, fd);
7107 tcg_temp_free_i64(fp0);
7108 gen_set_label(l1);
7110 opn = "movz.ps";
7111 break;
7112 case OPC_MOVN_PS:
7113 check_cp1_64bitmode(ctx);
7115 int l1 = gen_new_label();
7116 TCGv_i64 fp0;
7118 if (ft != 0) {
7119 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7120 fp0 = tcg_temp_new_i64();
7121 gen_load_fpr64(ctx, fp0, fs);
7122 gen_store_fpr64(ctx, fp0, fd);
7123 tcg_temp_free_i64(fp0);
7124 gen_set_label(l1);
7127 opn = "movn.ps";
7128 break;
7129 case OPC_ADDR_PS:
7130 check_cp1_64bitmode(ctx);
7132 TCGv_i64 fp0 = tcg_temp_new_i64();
7133 TCGv_i64 fp1 = tcg_temp_new_i64();
7135 gen_load_fpr64(ctx, fp0, ft);
7136 gen_load_fpr64(ctx, fp1, fs);
7137 gen_helper_float_addr_ps(fp0, fp0, fp1);
7138 tcg_temp_free_i64(fp1);
7139 gen_store_fpr64(ctx, fp0, fd);
7140 tcg_temp_free_i64(fp0);
7142 opn = "addr.ps";
7143 break;
7144 case OPC_MULR_PS:
7145 check_cp1_64bitmode(ctx);
7147 TCGv_i64 fp0 = tcg_temp_new_i64();
7148 TCGv_i64 fp1 = tcg_temp_new_i64();
7150 gen_load_fpr64(ctx, fp0, ft);
7151 gen_load_fpr64(ctx, fp1, fs);
7152 gen_helper_float_mulr_ps(fp0, fp0, fp1);
7153 tcg_temp_free_i64(fp1);
7154 gen_store_fpr64(ctx, fp0, fd);
7155 tcg_temp_free_i64(fp0);
7157 opn = "mulr.ps";
7158 break;
7159 case OPC_RECIP2_PS:
7160 check_cp1_64bitmode(ctx);
7162 TCGv_i64 fp0 = tcg_temp_new_i64();
7163 TCGv_i64 fp1 = tcg_temp_new_i64();
7165 gen_load_fpr64(ctx, fp0, fs);
7166 gen_load_fpr64(ctx, fp1, fd);
7167 gen_helper_float_recip2_ps(fp0, fp0, fp1);
7168 tcg_temp_free_i64(fp1);
7169 gen_store_fpr64(ctx, fp0, fd);
7170 tcg_temp_free_i64(fp0);
7172 opn = "recip2.ps";
7173 break;
7174 case OPC_RECIP1_PS:
7175 check_cp1_64bitmode(ctx);
7177 TCGv_i64 fp0 = tcg_temp_new_i64();
7179 gen_load_fpr64(ctx, fp0, fs);
7180 gen_helper_float_recip1_ps(fp0, fp0);
7181 gen_store_fpr64(ctx, fp0, fd);
7182 tcg_temp_free_i64(fp0);
7184 opn = "recip1.ps";
7185 break;
7186 case OPC_RSQRT1_PS:
7187 check_cp1_64bitmode(ctx);
7189 TCGv_i64 fp0 = tcg_temp_new_i64();
7191 gen_load_fpr64(ctx, fp0, fs);
7192 gen_helper_float_rsqrt1_ps(fp0, fp0);
7193 gen_store_fpr64(ctx, fp0, fd);
7194 tcg_temp_free_i64(fp0);
7196 opn = "rsqrt1.ps";
7197 break;
7198 case OPC_RSQRT2_PS:
7199 check_cp1_64bitmode(ctx);
7201 TCGv_i64 fp0 = tcg_temp_new_i64();
7202 TCGv_i64 fp1 = tcg_temp_new_i64();
7204 gen_load_fpr64(ctx, fp0, fs);
7205 gen_load_fpr64(ctx, fp1, ft);
7206 gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7207 tcg_temp_free_i64(fp1);
7208 gen_store_fpr64(ctx, fp0, fd);
7209 tcg_temp_free_i64(fp0);
7211 opn = "rsqrt2.ps";
7212 break;
7213 case OPC_CVT_S_PU:
7214 check_cp1_64bitmode(ctx);
7216 TCGv_i32 fp0 = tcg_temp_new_i32();
7218 gen_load_fpr32h(fp0, fs);
7219 gen_helper_float_cvts_pu(fp0, fp0);
7220 gen_store_fpr32(fp0, fd);
7221 tcg_temp_free_i32(fp0);
7223 opn = "cvt.s.pu";
7224 break;
7225 case OPC_CVT_PW_PS:
7226 check_cp1_64bitmode(ctx);
7228 TCGv_i64 fp0 = tcg_temp_new_i64();
7230 gen_load_fpr64(ctx, fp0, fs);
7231 gen_helper_float_cvtpw_ps(fp0, fp0);
7232 gen_store_fpr64(ctx, fp0, fd);
7233 tcg_temp_free_i64(fp0);
7235 opn = "cvt.pw.ps";
7236 break;
7237 case OPC_CVT_S_PL:
7238 check_cp1_64bitmode(ctx);
7240 TCGv_i32 fp0 = tcg_temp_new_i32();
7242 gen_load_fpr32(fp0, fs);
7243 gen_helper_float_cvts_pl(fp0, fp0);
7244 gen_store_fpr32(fp0, fd);
7245 tcg_temp_free_i32(fp0);
7247 opn = "cvt.s.pl";
7248 break;
7249 case OPC_PLL_PS:
7250 check_cp1_64bitmode(ctx);
7252 TCGv_i32 fp0 = tcg_temp_new_i32();
7253 TCGv_i32 fp1 = tcg_temp_new_i32();
7255 gen_load_fpr32(fp0, fs);
7256 gen_load_fpr32(fp1, ft);
7257 gen_store_fpr32h(fp0, fd);
7258 gen_store_fpr32(fp1, fd);
7259 tcg_temp_free_i32(fp0);
7260 tcg_temp_free_i32(fp1);
7262 opn = "pll.ps";
7263 break;
7264 case OPC_PLU_PS:
7265 check_cp1_64bitmode(ctx);
7267 TCGv_i32 fp0 = tcg_temp_new_i32();
7268 TCGv_i32 fp1 = tcg_temp_new_i32();
7270 gen_load_fpr32(fp0, fs);
7271 gen_load_fpr32h(fp1, ft);
7272 gen_store_fpr32(fp1, fd);
7273 gen_store_fpr32h(fp0, fd);
7274 tcg_temp_free_i32(fp0);
7275 tcg_temp_free_i32(fp1);
7277 opn = "plu.ps";
7278 break;
7279 case OPC_PUL_PS:
7280 check_cp1_64bitmode(ctx);
7282 TCGv_i32 fp0 = tcg_temp_new_i32();
7283 TCGv_i32 fp1 = tcg_temp_new_i32();
7285 gen_load_fpr32h(fp0, fs);
7286 gen_load_fpr32(fp1, ft);
7287 gen_store_fpr32(fp1, fd);
7288 gen_store_fpr32h(fp0, fd);
7289 tcg_temp_free_i32(fp0);
7290 tcg_temp_free_i32(fp1);
7292 opn = "pul.ps";
7293 break;
7294 case OPC_PUU_PS:
7295 check_cp1_64bitmode(ctx);
7297 TCGv_i32 fp0 = tcg_temp_new_i32();
7298 TCGv_i32 fp1 = tcg_temp_new_i32();
7300 gen_load_fpr32h(fp0, fs);
7301 gen_load_fpr32h(fp1, ft);
7302 gen_store_fpr32(fp1, fd);
7303 gen_store_fpr32h(fp0, fd);
7304 tcg_temp_free_i32(fp0);
7305 tcg_temp_free_i32(fp1);
7307 opn = "puu.ps";
7308 break;
7309 case OPC_CMP_F_PS:
7310 case OPC_CMP_UN_PS:
7311 case OPC_CMP_EQ_PS:
7312 case OPC_CMP_UEQ_PS:
7313 case OPC_CMP_OLT_PS:
7314 case OPC_CMP_ULT_PS:
7315 case OPC_CMP_OLE_PS:
7316 case OPC_CMP_ULE_PS:
7317 case OPC_CMP_SF_PS:
7318 case OPC_CMP_NGLE_PS:
7319 case OPC_CMP_SEQ_PS:
7320 case OPC_CMP_NGL_PS:
7321 case OPC_CMP_LT_PS:
7322 case OPC_CMP_NGE_PS:
7323 case OPC_CMP_LE_PS:
7324 case OPC_CMP_NGT_PS:
7325 if (ctx->opcode & (1 << 6)) {
7326 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7327 opn = condnames_abs[func-48];
7328 } else {
7329 gen_cmp_ps(ctx, func-48, ft, fs, cc);
7330 opn = condnames[func-48];
7332 break;
7333 default:
7334 MIPS_INVAL(opn);
7335 generate_exception (ctx, EXCP_RI);
7336 return;
7338 switch (optype) {
7339 case BINOP:
7340 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7341 break;
7342 case CMPOP:
7343 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7344 break;
7345 default:
7346 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7347 break;
7351 /* Coprocessor 3 (FPU) */
7352 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7353 int fd, int fs, int base, int index)
7355 const char *opn = "extended float load/store";
7356 int store = 0;
7357 TCGv t0 = tcg_temp_new();
7359 if (base == 0) {
7360 gen_load_gpr(t0, index);
7361 } else if (index == 0) {
7362 gen_load_gpr(t0, base);
7363 } else {
7364 gen_load_gpr(t0, index);
7365 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7367 /* Don't do NOP if destination is zero: we must perform the actual
7368 memory access. */
7369 save_cpu_state(ctx, 0);
7370 switch (opc) {
7371 case OPC_LWXC1:
7372 check_cop1x(ctx);
7374 TCGv_i32 fp0 = tcg_temp_new_i32();
7376 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7377 tcg_gen_trunc_tl_i32(fp0, t0);
7378 gen_store_fpr32(fp0, fd);
7379 tcg_temp_free_i32(fp0);
7381 opn = "lwxc1";
7382 break;
7383 case OPC_LDXC1:
7384 check_cop1x(ctx);
7385 check_cp1_registers(ctx, fd);
7387 TCGv_i64 fp0 = tcg_temp_new_i64();
7389 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7390 gen_store_fpr64(ctx, fp0, fd);
7391 tcg_temp_free_i64(fp0);
7393 opn = "ldxc1";
7394 break;
7395 case OPC_LUXC1:
7396 check_cp1_64bitmode(ctx);
7397 tcg_gen_andi_tl(t0, t0, ~0x7);
7399 TCGv_i64 fp0 = tcg_temp_new_i64();
7401 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7402 gen_store_fpr64(ctx, fp0, fd);
7403 tcg_temp_free_i64(fp0);
7405 opn = "luxc1";
7406 break;
7407 case OPC_SWXC1:
7408 check_cop1x(ctx);
7410 TCGv_i32 fp0 = tcg_temp_new_i32();
7411 TCGv t1 = tcg_temp_new();
7413 gen_load_fpr32(fp0, fs);
7414 tcg_gen_extu_i32_tl(t1, fp0);
7415 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7416 tcg_temp_free_i32(fp0);
7417 tcg_temp_free(t1);
7419 opn = "swxc1";
7420 store = 1;
7421 break;
7422 case OPC_SDXC1:
7423 check_cop1x(ctx);
7424 check_cp1_registers(ctx, fs);
7426 TCGv_i64 fp0 = tcg_temp_new_i64();
7428 gen_load_fpr64(ctx, fp0, fs);
7429 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7430 tcg_temp_free_i64(fp0);
7432 opn = "sdxc1";
7433 store = 1;
7434 break;
7435 case OPC_SUXC1:
7436 check_cp1_64bitmode(ctx);
7437 tcg_gen_andi_tl(t0, t0, ~0x7);
7439 TCGv_i64 fp0 = tcg_temp_new_i64();
7441 gen_load_fpr64(ctx, fp0, fs);
7442 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7443 tcg_temp_free_i64(fp0);
7445 opn = "suxc1";
7446 store = 1;
7447 break;
7449 tcg_temp_free(t0);
7450 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7451 regnames[index], regnames[base]);
7454 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7455 int fd, int fr, int fs, int ft)
7457 const char *opn = "flt3_arith";
7459 switch (opc) {
7460 case OPC_ALNV_PS:
7461 check_cp1_64bitmode(ctx);
7463 TCGv t0 = tcg_temp_local_new();
7464 TCGv_i32 fp = tcg_temp_new_i32();
7465 TCGv_i32 fph = tcg_temp_new_i32();
7466 int l1 = gen_new_label();
7467 int l2 = gen_new_label();
7469 gen_load_gpr(t0, fr);
7470 tcg_gen_andi_tl(t0, t0, 0x7);
7472 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7473 gen_load_fpr32(fp, fs);
7474 gen_load_fpr32h(fph, fs);
7475 gen_store_fpr32(fp, fd);
7476 gen_store_fpr32h(fph, fd);
7477 tcg_gen_br(l2);
7478 gen_set_label(l1);
7479 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7480 tcg_temp_free(t0);
7481 #ifdef TARGET_WORDS_BIGENDIAN
7482 gen_load_fpr32(fp, fs);
7483 gen_load_fpr32h(fph, ft);
7484 gen_store_fpr32h(fp, fd);
7485 gen_store_fpr32(fph, fd);
7486 #else
7487 gen_load_fpr32h(fph, fs);
7488 gen_load_fpr32(fp, ft);
7489 gen_store_fpr32(fph, fd);
7490 gen_store_fpr32h(fp, fd);
7491 #endif
7492 gen_set_label(l2);
7493 tcg_temp_free_i32(fp);
7494 tcg_temp_free_i32(fph);
7496 opn = "alnv.ps";
7497 break;
7498 case OPC_MADD_S:
7499 check_cop1x(ctx);
7501 TCGv_i32 fp0 = tcg_temp_new_i32();
7502 TCGv_i32 fp1 = tcg_temp_new_i32();
7503 TCGv_i32 fp2 = tcg_temp_new_i32();
7505 gen_load_fpr32(fp0, fs);
7506 gen_load_fpr32(fp1, ft);
7507 gen_load_fpr32(fp2, fr);
7508 gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7509 tcg_temp_free_i32(fp0);
7510 tcg_temp_free_i32(fp1);
7511 gen_store_fpr32(fp2, fd);
7512 tcg_temp_free_i32(fp2);
7514 opn = "madd.s";
7515 break;
7516 case OPC_MADD_D:
7517 check_cop1x(ctx);
7518 check_cp1_registers(ctx, fd | fs | ft | fr);
7520 TCGv_i64 fp0 = tcg_temp_new_i64();
7521 TCGv_i64 fp1 = tcg_temp_new_i64();
7522 TCGv_i64 fp2 = tcg_temp_new_i64();
7524 gen_load_fpr64(ctx, fp0, fs);
7525 gen_load_fpr64(ctx, fp1, ft);
7526 gen_load_fpr64(ctx, fp2, fr);
7527 gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7528 tcg_temp_free_i64(fp0);
7529 tcg_temp_free_i64(fp1);
7530 gen_store_fpr64(ctx, fp2, fd);
7531 tcg_temp_free_i64(fp2);
7533 opn = "madd.d";
7534 break;
7535 case OPC_MADD_PS:
7536 check_cp1_64bitmode(ctx);
7538 TCGv_i64 fp0 = tcg_temp_new_i64();
7539 TCGv_i64 fp1 = tcg_temp_new_i64();
7540 TCGv_i64 fp2 = tcg_temp_new_i64();
7542 gen_load_fpr64(ctx, fp0, fs);
7543 gen_load_fpr64(ctx, fp1, ft);
7544 gen_load_fpr64(ctx, fp2, fr);
7545 gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7546 tcg_temp_free_i64(fp0);
7547 tcg_temp_free_i64(fp1);
7548 gen_store_fpr64(ctx, fp2, fd);
7549 tcg_temp_free_i64(fp2);
7551 opn = "madd.ps";
7552 break;
7553 case OPC_MSUB_S:
7554 check_cop1x(ctx);
7556 TCGv_i32 fp0 = tcg_temp_new_i32();
7557 TCGv_i32 fp1 = tcg_temp_new_i32();
7558 TCGv_i32 fp2 = tcg_temp_new_i32();
7560 gen_load_fpr32(fp0, fs);
7561 gen_load_fpr32(fp1, ft);
7562 gen_load_fpr32(fp2, fr);
7563 gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7564 tcg_temp_free_i32(fp0);
7565 tcg_temp_free_i32(fp1);
7566 gen_store_fpr32(fp2, fd);
7567 tcg_temp_free_i32(fp2);
7569 opn = "msub.s";
7570 break;
7571 case OPC_MSUB_D:
7572 check_cop1x(ctx);
7573 check_cp1_registers(ctx, fd | fs | ft | fr);
7575 TCGv_i64 fp0 = tcg_temp_new_i64();
7576 TCGv_i64 fp1 = tcg_temp_new_i64();
7577 TCGv_i64 fp2 = tcg_temp_new_i64();
7579 gen_load_fpr64(ctx, fp0, fs);
7580 gen_load_fpr64(ctx, fp1, ft);
7581 gen_load_fpr64(ctx, fp2, fr);
7582 gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7583 tcg_temp_free_i64(fp0);
7584 tcg_temp_free_i64(fp1);
7585 gen_store_fpr64(ctx, fp2, fd);
7586 tcg_temp_free_i64(fp2);
7588 opn = "msub.d";
7589 break;
7590 case OPC_MSUB_PS:
7591 check_cp1_64bitmode(ctx);
7593 TCGv_i64 fp0 = tcg_temp_new_i64();
7594 TCGv_i64 fp1 = tcg_temp_new_i64();
7595 TCGv_i64 fp2 = tcg_temp_new_i64();
7597 gen_load_fpr64(ctx, fp0, fs);
7598 gen_load_fpr64(ctx, fp1, ft);
7599 gen_load_fpr64(ctx, fp2, fr);
7600 gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7601 tcg_temp_free_i64(fp0);
7602 tcg_temp_free_i64(fp1);
7603 gen_store_fpr64(ctx, fp2, fd);
7604 tcg_temp_free_i64(fp2);
7606 opn = "msub.ps";
7607 break;
7608 case OPC_NMADD_S:
7609 check_cop1x(ctx);
7611 TCGv_i32 fp0 = tcg_temp_new_i32();
7612 TCGv_i32 fp1 = tcg_temp_new_i32();
7613 TCGv_i32 fp2 = tcg_temp_new_i32();
7615 gen_load_fpr32(fp0, fs);
7616 gen_load_fpr32(fp1, ft);
7617 gen_load_fpr32(fp2, fr);
7618 gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7619 tcg_temp_free_i32(fp0);
7620 tcg_temp_free_i32(fp1);
7621 gen_store_fpr32(fp2, fd);
7622 tcg_temp_free_i32(fp2);
7624 opn = "nmadd.s";
7625 break;
7626 case OPC_NMADD_D:
7627 check_cop1x(ctx);
7628 check_cp1_registers(ctx, fd | fs | ft | fr);
7630 TCGv_i64 fp0 = tcg_temp_new_i64();
7631 TCGv_i64 fp1 = tcg_temp_new_i64();
7632 TCGv_i64 fp2 = tcg_temp_new_i64();
7634 gen_load_fpr64(ctx, fp0, fs);
7635 gen_load_fpr64(ctx, fp1, ft);
7636 gen_load_fpr64(ctx, fp2, fr);
7637 gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7638 tcg_temp_free_i64(fp0);
7639 tcg_temp_free_i64(fp1);
7640 gen_store_fpr64(ctx, fp2, fd);
7641 tcg_temp_free_i64(fp2);
7643 opn = "nmadd.d";
7644 break;
7645 case OPC_NMADD_PS:
7646 check_cp1_64bitmode(ctx);
7648 TCGv_i64 fp0 = tcg_temp_new_i64();
7649 TCGv_i64 fp1 = tcg_temp_new_i64();
7650 TCGv_i64 fp2 = tcg_temp_new_i64();
7652 gen_load_fpr64(ctx, fp0, fs);
7653 gen_load_fpr64(ctx, fp1, ft);
7654 gen_load_fpr64(ctx, fp2, fr);
7655 gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7656 tcg_temp_free_i64(fp0);
7657 tcg_temp_free_i64(fp1);
7658 gen_store_fpr64(ctx, fp2, fd);
7659 tcg_temp_free_i64(fp2);
7661 opn = "nmadd.ps";
7662 break;
7663 case OPC_NMSUB_S:
7664 check_cop1x(ctx);
7666 TCGv_i32 fp0 = tcg_temp_new_i32();
7667 TCGv_i32 fp1 = tcg_temp_new_i32();
7668 TCGv_i32 fp2 = tcg_temp_new_i32();
7670 gen_load_fpr32(fp0, fs);
7671 gen_load_fpr32(fp1, ft);
7672 gen_load_fpr32(fp2, fr);
7673 gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7674 tcg_temp_free_i32(fp0);
7675 tcg_temp_free_i32(fp1);
7676 gen_store_fpr32(fp2, fd);
7677 tcg_temp_free_i32(fp2);
7679 opn = "nmsub.s";
7680 break;
7681 case OPC_NMSUB_D:
7682 check_cop1x(ctx);
7683 check_cp1_registers(ctx, fd | fs | ft | fr);
7685 TCGv_i64 fp0 = tcg_temp_new_i64();
7686 TCGv_i64 fp1 = tcg_temp_new_i64();
7687 TCGv_i64 fp2 = tcg_temp_new_i64();
7689 gen_load_fpr64(ctx, fp0, fs);
7690 gen_load_fpr64(ctx, fp1, ft);
7691 gen_load_fpr64(ctx, fp2, fr);
7692 gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7693 tcg_temp_free_i64(fp0);
7694 tcg_temp_free_i64(fp1);
7695 gen_store_fpr64(ctx, fp2, fd);
7696 tcg_temp_free_i64(fp2);
7698 opn = "nmsub.d";
7699 break;
7700 case OPC_NMSUB_PS:
7701 check_cp1_64bitmode(ctx);
7703 TCGv_i64 fp0 = tcg_temp_new_i64();
7704 TCGv_i64 fp1 = tcg_temp_new_i64();
7705 TCGv_i64 fp2 = tcg_temp_new_i64();
7707 gen_load_fpr64(ctx, fp0, fs);
7708 gen_load_fpr64(ctx, fp1, ft);
7709 gen_load_fpr64(ctx, fp2, fr);
7710 gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7711 tcg_temp_free_i64(fp0);
7712 tcg_temp_free_i64(fp1);
7713 gen_store_fpr64(ctx, fp2, fd);
7714 tcg_temp_free_i64(fp2);
7716 opn = "nmsub.ps";
7717 break;
7718 default:
7719 MIPS_INVAL(opn);
7720 generate_exception (ctx, EXCP_RI);
7721 return;
7723 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7724 fregnames[fs], fregnames[ft]);
7727 static void
7728 gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
7730 TCGv t0;
7732 check_insn(env, ctx, ISA_MIPS32R2);
7733 t0 = tcg_temp_new();
7735 switch (rd) {
7736 case 0:
7737 save_cpu_state(ctx, 1);
7738 gen_helper_rdhwr_cpunum(t0);
7739 gen_store_gpr(t0, rt);
7740 break;
7741 case 1:
7742 save_cpu_state(ctx, 1);
7743 gen_helper_rdhwr_synci_step(t0);
7744 gen_store_gpr(t0, rt);
7745 break;
7746 case 2:
7747 save_cpu_state(ctx, 1);
7748 gen_helper_rdhwr_cc(t0);
7749 gen_store_gpr(t0, rt);
7750 break;
7751 case 3:
7752 save_cpu_state(ctx, 1);
7753 gen_helper_rdhwr_ccres(t0);
7754 gen_store_gpr(t0, rt);
7755 break;
7756 case 29:
7757 #if defined(CONFIG_USER_ONLY)
7758 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7759 gen_store_gpr(t0, rt);
7760 break;
7761 #else
7762 /* XXX: Some CPUs implement this in hardware.
7763 Not supported yet. */
7764 #endif
7765 default: /* Invalid */
7766 MIPS_INVAL("rdhwr");
7767 generate_exception(ctx, EXCP_RI);
7768 break;
7770 tcg_temp_free(t0);
7773 static void handle_delay_slot (CPUState *env, DisasContext *ctx,
7774 int insn_bytes)
7776 if (ctx->hflags & MIPS_HFLAG_BMASK) {
7777 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7778 /* Branches completion */
7779 ctx->hflags &= ~MIPS_HFLAG_BMASK;
7780 ctx->bstate = BS_BRANCH;
7781 save_cpu_state(ctx, 0);
7782 /* FIXME: Need to clear can_do_io. */
7783 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
7784 case MIPS_HFLAG_B:
7785 /* unconditional branch */
7786 MIPS_DEBUG("unconditional branch");
7787 if (proc_hflags & MIPS_HFLAG_BX) {
7788 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
7790 gen_goto_tb(ctx, 0, ctx->btarget);
7791 break;
7792 case MIPS_HFLAG_BL:
7793 /* blikely taken case */
7794 MIPS_DEBUG("blikely branch taken");
7795 gen_goto_tb(ctx, 0, ctx->btarget);
7796 break;
7797 case MIPS_HFLAG_BC:
7798 /* Conditional branch */
7799 MIPS_DEBUG("conditional branch");
7801 int l1 = gen_new_label();
7803 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7804 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
7805 gen_set_label(l1);
7806 gen_goto_tb(ctx, 0, ctx->btarget);
7808 break;
7809 case MIPS_HFLAG_BR:
7810 /* unconditional branch to register */
7811 MIPS_DEBUG("branch to register");
7812 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
7813 TCGv t0 = tcg_temp_new();
7814 TCGv_i32 t1 = tcg_temp_new_i32();
7816 tcg_gen_andi_tl(t0, btarget, 0x1);
7817 tcg_gen_trunc_tl_i32(t1, t0);
7818 tcg_temp_free(t0);
7819 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
7820 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
7821 tcg_gen_or_i32(hflags, hflags, t1);
7822 tcg_temp_free_i32(t1);
7824 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
7825 } else {
7826 tcg_gen_mov_tl(cpu_PC, btarget);
7828 if (ctx->singlestep_enabled) {
7829 save_cpu_state(ctx, 0);
7830 gen_helper_0i(raise_exception, EXCP_DEBUG);
7832 tcg_gen_exit_tb(0);
7833 break;
7834 default:
7835 MIPS_DEBUG("unknown branch");
7836 break;
7841 /* ISA extensions (ASEs) */
7842 /* MIPS16 extension to MIPS32 */
7844 /* MIPS16 major opcodes */
7845 enum {
7846 M16_OPC_ADDIUSP = 0x00,
7847 M16_OPC_ADDIUPC = 0x01,
7848 M16_OPC_B = 0x02,
7849 M16_OPC_JAL = 0x03,
7850 M16_OPC_BEQZ = 0x04,
7851 M16_OPC_BNEQZ = 0x05,
7852 M16_OPC_SHIFT = 0x06,
7853 M16_OPC_LD = 0x07,
7854 M16_OPC_RRIA = 0x08,
7855 M16_OPC_ADDIU8 = 0x09,
7856 M16_OPC_SLTI = 0x0a,
7857 M16_OPC_SLTIU = 0x0b,
7858 M16_OPC_I8 = 0x0c,
7859 M16_OPC_LI = 0x0d,
7860 M16_OPC_CMPI = 0x0e,
7861 M16_OPC_SD = 0x0f,
7862 M16_OPC_LB = 0x10,
7863 M16_OPC_LH = 0x11,
7864 M16_OPC_LWSP = 0x12,
7865 M16_OPC_LW = 0x13,
7866 M16_OPC_LBU = 0x14,
7867 M16_OPC_LHU = 0x15,
7868 M16_OPC_LWPC = 0x16,
7869 M16_OPC_LWU = 0x17,
7870 M16_OPC_SB = 0x18,
7871 M16_OPC_SH = 0x19,
7872 M16_OPC_SWSP = 0x1a,
7873 M16_OPC_SW = 0x1b,
7874 M16_OPC_RRR = 0x1c,
7875 M16_OPC_RR = 0x1d,
7876 M16_OPC_EXTEND = 0x1e,
7877 M16_OPC_I64 = 0x1f
7880 /* I8 funct field */
7881 enum {
7882 I8_BTEQZ = 0x0,
7883 I8_BTNEZ = 0x1,
7884 I8_SWRASP = 0x2,
7885 I8_ADJSP = 0x3,
7886 I8_SVRS = 0x4,
7887 I8_MOV32R = 0x5,
7888 I8_MOVR32 = 0x7
7891 /* RRR f field */
7892 enum {
7893 RRR_DADDU = 0x0,
7894 RRR_ADDU = 0x1,
7895 RRR_DSUBU = 0x2,
7896 RRR_SUBU = 0x3
7899 /* RR funct field */
7900 enum {
7901 RR_JR = 0x00,
7902 RR_SDBBP = 0x01,
7903 RR_SLT = 0x02,
7904 RR_SLTU = 0x03,
7905 RR_SLLV = 0x04,
7906 RR_BREAK = 0x05,
7907 RR_SRLV = 0x06,
7908 RR_SRAV = 0x07,
7909 RR_DSRL = 0x08,
7910 RR_CMP = 0x0a,
7911 RR_NEG = 0x0b,
7912 RR_AND = 0x0c,
7913 RR_OR = 0x0d,
7914 RR_XOR = 0x0e,
7915 RR_NOT = 0x0f,
7916 RR_MFHI = 0x10,
7917 RR_CNVT = 0x11,
7918 RR_MFLO = 0x12,
7919 RR_DSRA = 0x13,
7920 RR_DSLLV = 0x14,
7921 RR_DSRLV = 0x16,
7922 RR_DSRAV = 0x17,
7923 RR_MULT = 0x18,
7924 RR_MULTU = 0x19,
7925 RR_DIV = 0x1a,
7926 RR_DIVU = 0x1b,
7927 RR_DMULT = 0x1c,
7928 RR_DMULTU = 0x1d,
7929 RR_DDIV = 0x1e,
7930 RR_DDIVU = 0x1f
7933 /* I64 funct field */
7934 enum {
7935 I64_LDSP = 0x0,
7936 I64_SDSP = 0x1,
7937 I64_SDRASP = 0x2,
7938 I64_DADJSP = 0x3,
7939 I64_LDPC = 0x4,
7940 I64_DADDIU5 = 0x5,
7941 I64_DADDIUPC = 0x6,
7942 I64_DADDIUSP = 0x7
7945 /* RR ry field for CNVT */
7946 enum {
7947 RR_RY_CNVT_ZEB = 0x0,
7948 RR_RY_CNVT_ZEH = 0x1,
7949 RR_RY_CNVT_ZEW = 0x2,
7950 RR_RY_CNVT_SEB = 0x4,
7951 RR_RY_CNVT_SEH = 0x5,
7952 RR_RY_CNVT_SEW = 0x6,
7955 static int xlat (int r)
7957 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
7959 return map[r];
7962 static void gen_mips16_save (DisasContext *ctx,
7963 int xsregs, int aregs,
7964 int do_ra, int do_s0, int do_s1,
7965 int framesize)
7967 TCGv t0 = tcg_temp_new();
7968 TCGv t1 = tcg_temp_new();
7969 int args, astatic;
7971 switch (aregs) {
7972 case 0:
7973 case 1:
7974 case 2:
7975 case 3:
7976 case 11:
7977 args = 0;
7978 break;
7979 case 4:
7980 case 5:
7981 case 6:
7982 case 7:
7983 args = 1;
7984 break;
7985 case 8:
7986 case 9:
7987 case 10:
7988 args = 2;
7989 break;
7990 case 12:
7991 case 13:
7992 args = 3;
7993 break;
7994 case 14:
7995 args = 4;
7996 break;
7997 default:
7998 generate_exception(ctx, EXCP_RI);
7999 return;
8002 switch (args) {
8003 case 4:
8004 gen_base_offset_addr(ctx, t0, 29, 12);
8005 gen_load_gpr(t1, 7);
8006 op_ldst_sw(t1, t0, ctx);
8007 /* Fall through */
8008 case 3:
8009 gen_base_offset_addr(ctx, t0, 29, 8);
8010 gen_load_gpr(t1, 6);
8011 op_ldst_sw(t1, t0, ctx);
8012 /* Fall through */
8013 case 2:
8014 gen_base_offset_addr(ctx, t0, 29, 4);
8015 gen_load_gpr(t1, 5);
8016 op_ldst_sw(t1, t0, ctx);
8017 /* Fall through */
8018 case 1:
8019 gen_base_offset_addr(ctx, t0, 29, 0);
8020 gen_load_gpr(t1, 4);
8021 op_ldst_sw(t1, t0, ctx);
8024 gen_load_gpr(t0, 29);
8026 #define DECR_AND_STORE(reg) do { \
8027 tcg_gen_subi_tl(t0, t0, 4); \
8028 gen_load_gpr(t1, reg); \
8029 op_ldst_sw(t1, t0, ctx); \
8030 } while (0)
8032 if (do_ra) {
8033 DECR_AND_STORE(31);
8036 switch (xsregs) {
8037 case 7:
8038 DECR_AND_STORE(30);
8039 /* Fall through */
8040 case 6:
8041 DECR_AND_STORE(23);
8042 /* Fall through */
8043 case 5:
8044 DECR_AND_STORE(22);
8045 /* Fall through */
8046 case 4:
8047 DECR_AND_STORE(21);
8048 /* Fall through */
8049 case 3:
8050 DECR_AND_STORE(20);
8051 /* Fall through */
8052 case 2:
8053 DECR_AND_STORE(19);
8054 /* Fall through */
8055 case 1:
8056 DECR_AND_STORE(18);
8059 if (do_s1) {
8060 DECR_AND_STORE(17);
8062 if (do_s0) {
8063 DECR_AND_STORE(16);
8066 switch (aregs) {
8067 case 0:
8068 case 4:
8069 case 8:
8070 case 12:
8071 case 14:
8072 astatic = 0;
8073 break;
8074 case 1:
8075 case 5:
8076 case 9:
8077 case 13:
8078 astatic = 1;
8079 break;
8080 case 2:
8081 case 6:
8082 case 10:
8083 astatic = 2;
8084 break;
8085 case 3:
8086 case 7:
8087 astatic = 3;
8088 break;
8089 case 11:
8090 astatic = 4;
8091 break;
8092 default:
8093 generate_exception(ctx, EXCP_RI);
8094 return;
8097 if (astatic > 0) {
8098 DECR_AND_STORE(7);
8099 if (astatic > 1) {
8100 DECR_AND_STORE(6);
8101 if (astatic > 2) {
8102 DECR_AND_STORE(5);
8103 if (astatic > 3) {
8104 DECR_AND_STORE(4);
8109 #undef DECR_AND_STORE
8111 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8112 tcg_temp_free(t0);
8113 tcg_temp_free(t1);
8116 static void gen_mips16_restore (DisasContext *ctx,
8117 int xsregs, int aregs,
8118 int do_ra, int do_s0, int do_s1,
8119 int framesize)
8121 int astatic;
8122 TCGv t0 = tcg_temp_new();
8123 TCGv t1 = tcg_temp_new();
8125 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8127 #define DECR_AND_LOAD(reg) do { \
8128 tcg_gen_subi_tl(t0, t0, 4); \
8129 op_ldst_lw(t1, t0, ctx); \
8130 gen_store_gpr(t1, reg); \
8131 } while (0)
8133 if (do_ra) {
8134 DECR_AND_LOAD(31);
8137 switch (xsregs) {
8138 case 7:
8139 DECR_AND_LOAD(30);
8140 /* Fall through */
8141 case 6:
8142 DECR_AND_LOAD(23);
8143 /* Fall through */
8144 case 5:
8145 DECR_AND_LOAD(22);
8146 /* Fall through */
8147 case 4:
8148 DECR_AND_LOAD(21);
8149 /* Fall through */
8150 case 3:
8151 DECR_AND_LOAD(20);
8152 /* Fall through */
8153 case 2:
8154 DECR_AND_LOAD(19);
8155 /* Fall through */
8156 case 1:
8157 DECR_AND_LOAD(18);
8160 if (do_s1) {
8161 DECR_AND_LOAD(17);
8163 if (do_s0) {
8164 DECR_AND_LOAD(16);
8167 switch (aregs) {
8168 case 0:
8169 case 4:
8170 case 8:
8171 case 12:
8172 case 14:
8173 astatic = 0;
8174 break;
8175 case 1:
8176 case 5:
8177 case 9:
8178 case 13:
8179 astatic = 1;
8180 break;
8181 case 2:
8182 case 6:
8183 case 10:
8184 astatic = 2;
8185 break;
8186 case 3:
8187 case 7:
8188 astatic = 3;
8189 break;
8190 case 11:
8191 astatic = 4;
8192 break;
8193 default:
8194 generate_exception(ctx, EXCP_RI);
8195 return;
8198 if (astatic > 0) {
8199 DECR_AND_LOAD(7);
8200 if (astatic > 1) {
8201 DECR_AND_LOAD(6);
8202 if (astatic > 2) {
8203 DECR_AND_LOAD(5);
8204 if (astatic > 3) {
8205 DECR_AND_LOAD(4);
8210 #undef DECR_AND_LOAD
8212 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8213 tcg_temp_free(t0);
8214 tcg_temp_free(t1);
8217 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8218 int is_64_bit, int extended)
8220 TCGv t0;
8222 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8223 generate_exception(ctx, EXCP_RI);
8224 return;
8227 t0 = tcg_temp_new();
8229 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8230 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8231 if (!is_64_bit) {
8232 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8235 tcg_temp_free(t0);
8238 #if defined(TARGET_MIPS64)
8239 static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8240 int ry, int funct, int16_t offset,
8241 int extended)
8243 switch (funct) {
8244 case I64_LDSP:
8245 check_mips_64(ctx);
8246 offset = extended ? offset : offset << 3;
8247 gen_ldst(ctx, OPC_LD, ry, 29, offset);
8248 break;
8249 case I64_SDSP:
8250 check_mips_64(ctx);
8251 offset = extended ? offset : offset << 3;
8252 gen_ldst(ctx, OPC_SD, ry, 29, offset);
8253 break;
8254 case I64_SDRASP:
8255 check_mips_64(ctx);
8256 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8257 gen_ldst(ctx, OPC_SD, 31, 29, offset);
8258 break;
8259 case I64_DADJSP:
8260 check_mips_64(ctx);
8261 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8262 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8263 break;
8264 case I64_LDPC:
8265 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8266 generate_exception(ctx, EXCP_RI);
8267 } else {
8268 offset = extended ? offset : offset << 3;
8269 gen_ldst(ctx, OPC_LDPC, ry, 0, offset);
8271 break;
8272 case I64_DADDIU5:
8273 check_mips_64(ctx);
8274 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8275 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8276 break;
8277 case I64_DADDIUPC:
8278 check_mips_64(ctx);
8279 offset = extended ? offset : offset << 2;
8280 gen_addiupc(ctx, ry, offset, 1, extended);
8281 break;
8282 case I64_DADDIUSP:
8283 check_mips_64(ctx);
8284 offset = extended ? offset : offset << 2;
8285 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8286 break;
8289 #endif
8291 static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8292 int *is_branch)
8294 int extend = lduw_code(ctx->pc + 2);
8295 int op, rx, ry, funct, sa;
8296 int16_t imm, offset;
8298 ctx->opcode = (ctx->opcode << 16) | extend;
8299 op = (ctx->opcode >> 11) & 0x1f;
8300 sa = (ctx->opcode >> 22) & 0x1f;
8301 funct = (ctx->opcode >> 8) & 0x7;
8302 rx = xlat((ctx->opcode >> 8) & 0x7);
8303 ry = xlat((ctx->opcode >> 5) & 0x7);
8304 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8305 | ((ctx->opcode >> 21) & 0x3f) << 5
8306 | (ctx->opcode & 0x1f));
8308 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8309 counterparts. */
8310 switch (op) {
8311 case M16_OPC_ADDIUSP:
8312 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8313 break;
8314 case M16_OPC_ADDIUPC:
8315 gen_addiupc(ctx, rx, imm, 0, 1);
8316 break;
8317 case M16_OPC_B:
8318 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8319 /* No delay slot, so just process as a normal instruction */
8320 break;
8321 case M16_OPC_BEQZ:
8322 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8323 /* No delay slot, so just process as a normal instruction */
8324 break;
8325 case M16_OPC_BNEQZ:
8326 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8327 /* No delay slot, so just process as a normal instruction */
8328 break;
8329 case M16_OPC_SHIFT:
8330 switch (ctx->opcode & 0x3) {
8331 case 0x0:
8332 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8333 break;
8334 case 0x1:
8335 #if defined(TARGET_MIPS64)
8336 check_mips_64(ctx);
8337 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8338 #else
8339 generate_exception(ctx, EXCP_RI);
8340 #endif
8341 break;
8342 case 0x2:
8343 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8344 break;
8345 case 0x3:
8346 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8347 break;
8349 break;
8350 #if defined(TARGET_MIPS64)
8351 case M16_OPC_LD:
8352 check_mips_64(ctx);
8353 gen_ldst(ctx, OPC_LD, ry, rx, offset);
8354 break;
8355 #endif
8356 case M16_OPC_RRIA:
8357 imm = ctx->opcode & 0xf;
8358 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8359 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8360 imm = (int16_t) (imm << 1) >> 1;
8361 if ((ctx->opcode >> 4) & 0x1) {
8362 #if defined(TARGET_MIPS64)
8363 check_mips_64(ctx);
8364 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8365 #else
8366 generate_exception(ctx, EXCP_RI);
8367 #endif
8368 } else {
8369 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8371 break;
8372 case M16_OPC_ADDIU8:
8373 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8374 break;
8375 case M16_OPC_SLTI:
8376 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8377 break;
8378 case M16_OPC_SLTIU:
8379 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8380 break;
8381 case M16_OPC_I8:
8382 switch (funct) {
8383 case I8_BTEQZ:
8384 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8385 break;
8386 case I8_BTNEZ:
8387 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8388 break;
8389 case I8_SWRASP:
8390 gen_ldst(ctx, OPC_SW, 31, 29, imm);
8391 break;
8392 case I8_ADJSP:
8393 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8394 break;
8395 case I8_SVRS:
8397 int xsregs = (ctx->opcode >> 24) & 0x7;
8398 int aregs = (ctx->opcode >> 16) & 0xf;
8399 int do_ra = (ctx->opcode >> 6) & 0x1;
8400 int do_s0 = (ctx->opcode >> 5) & 0x1;
8401 int do_s1 = (ctx->opcode >> 4) & 0x1;
8402 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8403 | (ctx->opcode & 0xf)) << 3;
8405 if (ctx->opcode & (1 << 7)) {
8406 gen_mips16_save(ctx, xsregs, aregs,
8407 do_ra, do_s0, do_s1,
8408 framesize);
8409 } else {
8410 gen_mips16_restore(ctx, xsregs, aregs,
8411 do_ra, do_s0, do_s1,
8412 framesize);
8415 break;
8416 default:
8417 generate_exception(ctx, EXCP_RI);
8418 break;
8420 break;
8421 case M16_OPC_LI:
8422 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8423 break;
8424 case M16_OPC_CMPI:
8425 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8426 break;
8427 #if defined(TARGET_MIPS64)
8428 case M16_OPC_SD:
8429 gen_ldst(ctx, OPC_SD, ry, rx, offset);
8430 break;
8431 #endif
8432 case M16_OPC_LB:
8433 gen_ldst(ctx, OPC_LB, ry, rx, offset);
8434 break;
8435 case M16_OPC_LH:
8436 gen_ldst(ctx, OPC_LH, ry, rx, offset);
8437 break;
8438 case M16_OPC_LWSP:
8439 gen_ldst(ctx, OPC_LW, rx, 29, offset);
8440 break;
8441 case M16_OPC_LW:
8442 gen_ldst(ctx, OPC_LW, ry, rx, offset);
8443 break;
8444 case M16_OPC_LBU:
8445 gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8446 break;
8447 case M16_OPC_LHU:
8448 gen_ldst(ctx, OPC_LHU, ry, rx, offset);
8449 break;
8450 case M16_OPC_LWPC:
8451 gen_ldst(ctx, OPC_LWPC, rx, 0, offset);
8452 break;
8453 #if defined(TARGET_MIPS64)
8454 case M16_OPC_LWU:
8455 gen_ldst(ctx, OPC_LWU, ry, rx, offset);
8456 break;
8457 #endif
8458 case M16_OPC_SB:
8459 gen_ldst(ctx, OPC_SB, ry, rx, offset);
8460 break;
8461 case M16_OPC_SH:
8462 gen_ldst(ctx, OPC_SH, ry, rx, offset);
8463 break;
8464 case M16_OPC_SWSP:
8465 gen_ldst(ctx, OPC_SW, rx, 29, offset);
8466 break;
8467 case M16_OPC_SW:
8468 gen_ldst(ctx, OPC_SW, ry, rx, offset);
8469 break;
8470 #if defined(TARGET_MIPS64)
8471 case M16_OPC_I64:
8472 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8473 break;
8474 #endif
8475 default:
8476 generate_exception(ctx, EXCP_RI);
8477 break;
8480 return 4;
8483 static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8484 int *is_branch)
8486 int rx, ry;
8487 int sa;
8488 int op, cnvt_op, op1, offset;
8489 int funct;
8490 int n_bytes;
8492 op = (ctx->opcode >> 11) & 0x1f;
8493 sa = (ctx->opcode >> 2) & 0x7;
8494 sa = sa == 0 ? 8 : sa;
8495 rx = xlat((ctx->opcode >> 8) & 0x7);
8496 cnvt_op = (ctx->opcode >> 5) & 0x7;
8497 ry = xlat((ctx->opcode >> 5) & 0x7);
8498 op1 = offset = ctx->opcode & 0x1f;
8500 n_bytes = 2;
8502 switch (op) {
8503 case M16_OPC_ADDIUSP:
8505 int16_t imm = ((uint8_t) ctx->opcode) << 2;
8507 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8509 break;
8510 case M16_OPC_ADDIUPC:
8511 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8512 break;
8513 case M16_OPC_B:
8514 offset = (ctx->opcode & 0x7ff) << 1;
8515 offset = (int16_t)(offset << 4) >> 4;
8516 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8517 /* No delay slot, so just process as a normal instruction */
8518 break;
8519 case M16_OPC_JAL:
8520 offset = lduw_code(ctx->pc + 2);
8521 offset = (((ctx->opcode & 0x1f) << 21)
8522 | ((ctx->opcode >> 5) & 0x1f) << 16
8523 | offset) << 2;
8524 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8525 gen_compute_branch(ctx, op, 4, rx, ry, offset);
8526 n_bytes = 4;
8527 *is_branch = 1;
8528 break;
8529 case M16_OPC_BEQZ:
8530 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8531 /* No delay slot, so just process as a normal instruction */
8532 break;
8533 case M16_OPC_BNEQZ:
8534 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8535 /* No delay slot, so just process as a normal instruction */
8536 break;
8537 case M16_OPC_SHIFT:
8538 switch (ctx->opcode & 0x3) {
8539 case 0x0:
8540 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8541 break;
8542 case 0x1:
8543 #if defined(TARGET_MIPS64)
8544 check_mips_64(ctx);
8545 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8546 #else
8547 generate_exception(ctx, EXCP_RI);
8548 #endif
8549 break;
8550 case 0x2:
8551 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8552 break;
8553 case 0x3:
8554 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8555 break;
8557 break;
8558 #if defined(TARGET_MIPS64)
8559 case M16_OPC_LD:
8560 check_mips_64(ctx);
8561 gen_ldst(ctx, OPC_LD, ry, rx, offset << 3);
8562 break;
8563 #endif
8564 case M16_OPC_RRIA:
8566 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8568 if ((ctx->opcode >> 4) & 1) {
8569 #if defined(TARGET_MIPS64)
8570 check_mips_64(ctx);
8571 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8572 #else
8573 generate_exception(ctx, EXCP_RI);
8574 #endif
8575 } else {
8576 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8579 break;
8580 case M16_OPC_ADDIU8:
8582 int16_t imm = (int8_t) ctx->opcode;
8584 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8586 break;
8587 case M16_OPC_SLTI:
8589 int16_t imm = (uint8_t) ctx->opcode;
8591 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8593 break;
8594 case M16_OPC_SLTIU:
8596 int16_t imm = (uint8_t) ctx->opcode;
8598 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8600 break;
8601 case M16_OPC_I8:
8603 int reg32;
8605 funct = (ctx->opcode >> 8) & 0x7;
8606 switch (funct) {
8607 case I8_BTEQZ:
8608 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8609 ((int8_t)ctx->opcode) << 1);
8610 break;
8611 case I8_BTNEZ:
8612 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
8613 ((int8_t)ctx->opcode) << 1);
8614 break;
8615 case I8_SWRASP:
8616 gen_ldst(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
8617 break;
8618 case I8_ADJSP:
8619 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
8620 ((int8_t)ctx->opcode) << 3);
8621 break;
8622 case I8_SVRS:
8624 int do_ra = ctx->opcode & (1 << 6);
8625 int do_s0 = ctx->opcode & (1 << 5);
8626 int do_s1 = ctx->opcode & (1 << 4);
8627 int framesize = ctx->opcode & 0xf;
8629 if (framesize == 0) {
8630 framesize = 128;
8631 } else {
8632 framesize = framesize << 3;
8635 if (ctx->opcode & (1 << 7)) {
8636 gen_mips16_save(ctx, 0, 0,
8637 do_ra, do_s0, do_s1, framesize);
8638 } else {
8639 gen_mips16_restore(ctx, 0, 0,
8640 do_ra, do_s0, do_s1, framesize);
8643 break;
8644 case I8_MOV32R:
8646 int rz = xlat(ctx->opcode & 0x7);
8648 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
8649 ((ctx->opcode >> 5) & 0x7);
8650 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
8652 break;
8653 case I8_MOVR32:
8654 reg32 = ctx->opcode & 0x1f;
8655 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
8656 break;
8657 default:
8658 generate_exception(ctx, EXCP_RI);
8659 break;
8662 break;
8663 case M16_OPC_LI:
8665 int16_t imm = (uint8_t) ctx->opcode;
8667 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
8669 break;
8670 case M16_OPC_CMPI:
8672 int16_t imm = (uint8_t) ctx->opcode;
8674 gen_logic_imm(env, OPC_XORI, 24, rx, imm);
8676 break;
8677 #if defined(TARGET_MIPS64)
8678 case M16_OPC_SD:
8679 check_mips_64(ctx);
8680 gen_ldst(ctx, OPC_SD, ry, rx, offset << 3);
8681 break;
8682 #endif
8683 case M16_OPC_LB:
8684 gen_ldst(ctx, OPC_LB, ry, rx, offset);
8685 break;
8686 case M16_OPC_LH:
8687 gen_ldst(ctx, OPC_LH, ry, rx, offset << 1);
8688 break;
8689 case M16_OPC_LWSP:
8690 gen_ldst(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8691 break;
8692 case M16_OPC_LW:
8693 gen_ldst(ctx, OPC_LW, ry, rx, offset << 2);
8694 break;
8695 case M16_OPC_LBU:
8696 gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8697 break;
8698 case M16_OPC_LHU:
8699 gen_ldst(ctx, OPC_LHU, ry, rx, offset << 1);
8700 break;
8701 case M16_OPC_LWPC:
8702 gen_ldst(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
8703 break;
8704 #if defined (TARGET_MIPS64)
8705 case M16_OPC_LWU:
8706 check_mips_64(ctx);
8707 gen_ldst(ctx, OPC_LWU, ry, rx, offset << 2);
8708 break;
8709 #endif
8710 case M16_OPC_SB:
8711 gen_ldst(ctx, OPC_SB, ry, rx, offset);
8712 break;
8713 case M16_OPC_SH:
8714 gen_ldst(ctx, OPC_SH, ry, rx, offset << 1);
8715 break;
8716 case M16_OPC_SWSP:
8717 gen_ldst(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8718 break;
8719 case M16_OPC_SW:
8720 gen_ldst(ctx, OPC_SW, ry, rx, offset << 2);
8721 break;
8722 case M16_OPC_RRR:
8724 int rz = xlat((ctx->opcode >> 2) & 0x7);
8725 int mips32_op;
8727 switch (ctx->opcode & 0x3) {
8728 case RRR_ADDU:
8729 mips32_op = OPC_ADDU;
8730 break;
8731 case RRR_SUBU:
8732 mips32_op = OPC_SUBU;
8733 break;
8734 #if defined(TARGET_MIPS64)
8735 case RRR_DADDU:
8736 mips32_op = OPC_DADDU;
8737 check_mips_64(ctx);
8738 break;
8739 case RRR_DSUBU:
8740 mips32_op = OPC_DSUBU;
8741 check_mips_64(ctx);
8742 break;
8743 #endif
8744 default:
8745 generate_exception(ctx, EXCP_RI);
8746 goto done;
8749 gen_arith(env, ctx, mips32_op, rz, rx, ry);
8750 done:
8753 break;
8754 case M16_OPC_RR:
8755 switch (op1) {
8756 case RR_JR:
8758 int nd = (ctx->opcode >> 7) & 0x1;
8759 int link = (ctx->opcode >> 6) & 0x1;
8760 int ra = (ctx->opcode >> 5) & 0x1;
8762 if (link) {
8763 op = nd ? OPC_JALRC : OPC_JALRS;
8764 } else {
8765 op = OPC_JR;
8768 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
8769 if (!nd) {
8770 *is_branch = 1;
8773 break;
8774 case RR_SDBBP:
8775 /* XXX: not clear which exception should be raised
8776 * when in debug mode...
8778 check_insn(env, ctx, ISA_MIPS32);
8779 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8780 generate_exception(ctx, EXCP_DBp);
8781 } else {
8782 generate_exception(ctx, EXCP_DBp);
8784 break;
8785 case RR_SLT:
8786 gen_slt(env, OPC_SLT, 24, rx, ry);
8787 break;
8788 case RR_SLTU:
8789 gen_slt(env, OPC_SLTU, 24, rx, ry);
8790 break;
8791 case RR_BREAK:
8792 generate_exception(ctx, EXCP_BREAK);
8793 break;
8794 case RR_SLLV:
8795 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
8796 break;
8797 case RR_SRLV:
8798 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
8799 break;
8800 case RR_SRAV:
8801 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
8802 break;
8803 #if defined (TARGET_MIPS64)
8804 case RR_DSRL:
8805 check_mips_64(ctx);
8806 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
8807 break;
8808 #endif
8809 case RR_CMP:
8810 gen_logic(env, OPC_XOR, 24, rx, ry);
8811 break;
8812 case RR_NEG:
8813 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
8814 break;
8815 case RR_AND:
8816 gen_logic(env, OPC_AND, rx, rx, ry);
8817 break;
8818 case RR_OR:
8819 gen_logic(env, OPC_OR, rx, rx, ry);
8820 break;
8821 case RR_XOR:
8822 gen_logic(env, OPC_XOR, rx, rx, ry);
8823 break;
8824 case RR_NOT:
8825 gen_logic(env, OPC_NOR, rx, ry, 0);
8826 break;
8827 case RR_MFHI:
8828 gen_HILO(ctx, OPC_MFHI, rx);
8829 break;
8830 case RR_CNVT:
8831 switch (cnvt_op) {
8832 case RR_RY_CNVT_ZEB:
8833 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8834 break;
8835 case RR_RY_CNVT_ZEH:
8836 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8837 break;
8838 case RR_RY_CNVT_SEB:
8839 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8840 break;
8841 case RR_RY_CNVT_SEH:
8842 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8843 break;
8844 #if defined (TARGET_MIPS64)
8845 case RR_RY_CNVT_ZEW:
8846 check_mips_64(ctx);
8847 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8848 break;
8849 case RR_RY_CNVT_SEW:
8850 check_mips_64(ctx);
8851 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8852 break;
8853 #endif
8854 default:
8855 generate_exception(ctx, EXCP_RI);
8856 break;
8858 break;
8859 case RR_MFLO:
8860 gen_HILO(ctx, OPC_MFLO, rx);
8861 break;
8862 #if defined (TARGET_MIPS64)
8863 case RR_DSRA:
8864 check_mips_64(ctx);
8865 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
8866 break;
8867 case RR_DSLLV:
8868 check_mips_64(ctx);
8869 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
8870 break;
8871 case RR_DSRLV:
8872 check_mips_64(ctx);
8873 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
8874 break;
8875 case RR_DSRAV:
8876 check_mips_64(ctx);
8877 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
8878 break;
8879 #endif
8880 case RR_MULT:
8881 gen_muldiv(ctx, OPC_MULT, rx, ry);
8882 break;
8883 case RR_MULTU:
8884 gen_muldiv(ctx, OPC_MULTU, rx, ry);
8885 break;
8886 case RR_DIV:
8887 gen_muldiv(ctx, OPC_DIV, rx, ry);
8888 break;
8889 case RR_DIVU:
8890 gen_muldiv(ctx, OPC_DIVU, rx, ry);
8891 break;
8892 #if defined (TARGET_MIPS64)
8893 case RR_DMULT:
8894 check_mips_64(ctx);
8895 gen_muldiv(ctx, OPC_DMULT, rx, ry);
8896 break;
8897 case RR_DMULTU:
8898 check_mips_64(ctx);
8899 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
8900 break;
8901 case RR_DDIV:
8902 check_mips_64(ctx);
8903 gen_muldiv(ctx, OPC_DDIV, rx, ry);
8904 break;
8905 case RR_DDIVU:
8906 check_mips_64(ctx);
8907 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
8908 break;
8909 #endif
8910 default:
8911 generate_exception(ctx, EXCP_RI);
8912 break;
8914 break;
8915 case M16_OPC_EXTEND:
8916 decode_extended_mips16_opc(env, ctx, is_branch);
8917 n_bytes = 4;
8918 break;
8919 #if defined(TARGET_MIPS64)
8920 case M16_OPC_I64:
8921 funct = (ctx->opcode >> 8) & 0x7;
8922 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
8923 break;
8924 #endif
8925 default:
8926 generate_exception(ctx, EXCP_RI);
8927 break;
8930 return n_bytes;
8933 /* microMIPS extension to MIPS32 */
8935 /* microMIPS32 major opcodes */
8937 enum {
8938 POOL32A = 0x00,
8939 POOL16A = 0x01,
8940 LBU16 = 0x02,
8941 MOVE16 = 0x03,
8942 ADDI32 = 0x04,
8943 LBU32 = 0x05,
8944 SB32 = 0x06,
8945 LB32 = 0x07,
8947 POOL32B = 0x08,
8948 POOL16B = 0x09,
8949 LHU16 = 0x0a,
8950 ANDI16 = 0x0b,
8951 ADDIU32 = 0x0c,
8952 LHU32 = 0x0d,
8953 SH32 = 0x0e,
8954 LH32 = 0x0f,
8956 POOL32I = 0x10,
8957 POOL16C = 0x11,
8958 LWSP16 = 0x12,
8959 POOL16D = 0x13,
8960 ORI32 = 0x14,
8961 POOL32F = 0x15,
8962 POOL32S = 0x16,
8963 DADDIU32 = 0x17,
8965 POOL32C = 0x18,
8966 LWGP16 = 0x19,
8967 LW16 = 0x1a,
8968 POOL16E = 0x1b,
8969 XORI32 = 0x1c,
8970 JALS32 = 0x1d,
8971 ADDIUPC = 0x1e,
8972 POOL48A = 0x1f,
8974 /* 0x20 is reserved */
8975 RES_20 = 0x20,
8976 POOL16F = 0x21,
8977 SB16 = 0x22,
8978 BEQZ16 = 0x23,
8979 SLTI32 = 0x24,
8980 BEQ32 = 0x25,
8981 SWC132 = 0x26,
8982 LWC132 = 0x27,
8984 /* 0x28 and 0x29 are reserved */
8985 RES_28 = 0x28,
8986 RES_29 = 0x29,
8987 SH16 = 0x2a,
8988 BNEZ16 = 0x2b,
8989 SLTIU32 = 0x2c,
8990 BNE32 = 0x2d,
8991 SDC132 = 0x2e,
8992 LDC132 = 0x2f,
8994 /* 0x30 and 0x31 are reserved */
8995 RES_30 = 0x30,
8996 RES_31 = 0x31,
8997 SWSP16 = 0x32,
8998 B16 = 0x33,
8999 ANDI32 = 0x34,
9000 J32 = 0x35,
9001 SD32 = 0x36,
9002 LD32 = 0x37,
9004 /* 0x38 and 0x39 are reserved */
9005 RES_38 = 0x38,
9006 RES_39 = 0x39,
9007 SW16 = 0x3a,
9008 LI16 = 0x3b,
9009 JALX32 = 0x3c,
9010 JAL32 = 0x3d,
9011 SW32 = 0x3e,
9012 LW32 = 0x3f
9015 /* POOL32A encoding of minor opcode field */
9017 enum {
9018 /* These opcodes are distinguished only by bits 9..6; those bits are
9019 * what are recorded below. */
9020 SLL32 = 0x0,
9021 SRL32 = 0x1,
9022 SRA = 0x2,
9023 ROTR = 0x3,
9025 SLLV = 0x0,
9026 SRLV = 0x1,
9027 SRAV = 0x2,
9028 ROTRV = 0x3,
9029 ADD = 0x4,
9030 ADDU32 = 0x5,
9031 SUB = 0x6,
9032 SUBU32 = 0x7,
9033 MUL = 0x8,
9034 AND = 0x9,
9035 OR32 = 0xa,
9036 NOR = 0xb,
9037 XOR32 = 0xc,
9038 SLT = 0xd,
9039 SLTU = 0xe,
9041 MOVN = 0x0,
9042 MOVZ = 0x1,
9043 LWXS = 0x4,
9045 /* The following can be distinguished by their lower 6 bits. */
9046 INS = 0x0c,
9047 EXT = 0x2c,
9048 POOL32AXF = 0x3c
9051 /* POOL32AXF encoding of minor opcode field extension */
9053 enum {
9054 /* bits 11..6 */
9055 TEQ = 0x00,
9056 TGE = 0x08,
9057 TGEU = 0x10,
9058 TLT = 0x20,
9059 TLTU = 0x28,
9060 TNE = 0x30,
9062 MFC0 = 0x03,
9063 MTC0 = 0x0b,
9065 /* bits 13..12 for 0x01 */
9066 MFHI_ACC = 0x0,
9067 MFLO_ACC = 0x1,
9068 MTHI_ACC = 0x2,
9069 MTLO_ACC = 0x3,
9071 /* bits 13..12 for 0x2a */
9072 MADD_ACC = 0x0,
9073 MADDU_ACC = 0x1,
9074 MSUB_ACC = 0x2,
9075 MSUBU_ACC = 0x3,
9077 /* bits 13..12 for 0x32 */
9078 MULT_ACC = 0x0,
9079 MULTU_ACC = 0x0,
9081 /* bits 15..12 for 0x2c */
9082 SEB = 0x2,
9083 SEH = 0x3,
9084 CLO = 0x4,
9085 CLZ = 0x5,
9086 RDHWR = 0x6,
9087 WSBH = 0x7,
9088 MULT = 0x8,
9089 MULTU = 0x9,
9090 DIV = 0xa,
9091 DIVU = 0xb,
9092 MADD = 0xc,
9093 MADDU = 0xd,
9094 MSUB = 0xe,
9095 MSUBU = 0xf,
9097 /* bits 15..12 for 0x34 */
9098 MFC2 = 0x4,
9099 MTC2 = 0x5,
9100 MFHC2 = 0x8,
9101 MTHC2 = 0x9,
9102 CFC2 = 0xc,
9103 CTC2 = 0xd,
9105 /* bits 15..12 for 0x3c */
9106 JALR = 0x0,
9107 JR = 0x0, /* alias */
9108 JALR_HB = 0x1,
9109 JALRS = 0x4,
9110 JALRS_HB = 0x5,
9112 /* bits 15..12 for 0x05 */
9113 RDPGPR = 0xe,
9114 WRPGPR = 0xf,
9116 /* bits 15..12 for 0x0d */
9117 TLBP = 0x0,
9118 TLBR = 0x1,
9119 TLBWI = 0x2,
9120 TLBWR = 0x3,
9121 WAIT = 0x9,
9122 IRET = 0xd,
9123 DERET = 0xe,
9124 ERET = 0xf,
9126 /* bits 15..12 for 0x15 */
9127 DMT = 0x0,
9128 DVPE = 0x1,
9129 EMT = 0x2,
9130 EVPE = 0x3,
9132 /* bits 15..12 for 0x1d */
9133 DI = 0x4,
9134 EI = 0x5,
9136 /* bits 15..12 for 0x2d */
9137 SYNC = 0x6,
9138 SYSCALL = 0x8,
9139 SDBBP = 0xd,
9141 /* bits 15..12 for 0x35 */
9142 MFHI32 = 0x0,
9143 MFLO32 = 0x1,
9144 MTHI32 = 0x2,
9145 MTLO32 = 0x3,
9148 /* POOL32B encoding of minor opcode field (bits 15..12) */
9150 enum {
9151 LWC2 = 0x0,
9152 LWP = 0x1,
9153 LDP = 0x4,
9154 LWM32 = 0x5,
9155 CACHE = 0x6,
9156 LDM = 0x7,
9157 SWC2 = 0x8,
9158 SWP = 0x9,
9159 SDP = 0xc,
9160 SWM32 = 0xd,
9161 SDM = 0xf
9164 /* POOL32C encoding of minor opcode field (bits 15..12) */
9166 enum {
9167 LWL = 0x0,
9168 SWL = 0x8,
9169 LWR = 0x1,
9170 SWR = 0x9,
9171 PREF = 0x2,
9172 /* 0xa is reserved */
9173 LL = 0x3,
9174 SC = 0xb,
9175 LDL = 0x4,
9176 SDL = 0xc,
9177 LDR = 0x5,
9178 SDR = 0xd,
9179 /* 0x6 is reserved */
9180 LWU = 0xe,
9181 LLD = 0x7,
9182 SCD = 0xf
9185 /* POOL32F encoding of minor opcode field (bits 5..0) */
9187 enum {
9188 /* These are the bit 7..6 values */
9189 ADD_FMT = 0x0,
9190 MOVN_FMT = 0x0,
9192 SUB_FMT = 0x1,
9193 MOVZ_FMT = 0x1,
9195 MUL_FMT = 0x2,
9197 DIV_FMT = 0x3,
9199 /* These are the bit 8..6 values */
9200 RSQRT2_FMT = 0x0,
9201 MOVF_FMT = 0x0,
9203 LWXC1 = 0x1,
9204 MOVT_FMT = 0x1,
9206 PLL_PS = 0x2,
9207 SWXC1 = 0x2,
9209 PLU_PS = 0x3,
9210 LDXC1 = 0x3,
9212 PUL_PS = 0x4,
9213 SDXC1 = 0x4,
9214 RECIP2_FMT = 0x4,
9216 PUU_PS = 0x5,
9217 LUXC1 = 0x5,
9219 CVT_PS_S = 0x6,
9220 SUXC1 = 0x6,
9221 ADDR_PS = 0x6,
9222 PREFX = 0x6,
9224 MULR_PS = 0x7,
9226 MADD_S = 0x01,
9227 MADD_D = 0x09,
9228 MADD_PS = 0x11,
9229 ALNV_PS = 0x19,
9230 MSUB_S = 0x21,
9231 MSUB_D = 0x29,
9232 MSUB_PS = 0x31,
9234 NMADD_S = 0x02,
9235 NMADD_D = 0x0a,
9236 NMADD_PS = 0x12,
9237 NMSUB_S = 0x22,
9238 NMSUB_D = 0x2a,
9239 NMSUB_PS = 0x32,
9241 POOL32FXF = 0x3b,
9243 CABS_COND_FMT = 0x1c, /* MIPS3D */
9244 C_COND_FMT = 0x3c
9247 /* POOL32Fxf encoding of minor opcode extension field */
9249 enum {
9250 CVT_L = 0x04,
9251 RSQRT_FMT = 0x08,
9252 FLOOR_L = 0x0c,
9253 CVT_PW_PS = 0x1c,
9254 CVT_W = 0x24,
9255 SQRT_FMT = 0x28,
9256 FLOOR_W = 0x2c,
9257 CVT_PS_PW = 0x3c,
9258 CFC1 = 0x40,
9259 RECIP_FMT = 0x48,
9260 CEIL_L = 0x4c,
9261 CTC1 = 0x60,
9262 CEIL_W = 0x6c,
9263 MFC1 = 0x80,
9264 CVT_S_PL = 0x84,
9265 TRUNC_L = 0x8c,
9266 MTC1 = 0xa0,
9267 CVT_S_PU = 0xa4,
9268 TRUNC_W = 0xac,
9269 MFHC1 = 0xc0,
9270 ROUND_L = 0xcc,
9271 MTHC1 = 0xe0,
9272 ROUND_W = 0xec,
9274 MOV_FMT = 0x01,
9275 MOVF = 0x05,
9276 ABS_FMT = 0x0d,
9277 RSQRT1_FMT = 0x1d,
9278 MOVT = 0x25,
9279 NEG_FMT = 0x2d,
9280 CVT_D = 0x4d,
9281 RECIP1_FMT = 0x5d,
9282 CVT_S = 0x6d
9285 /* POOL32I encoding of minor opcode field (bits 25..21) */
9287 enum {
9288 BLTZ = 0x00,
9289 BLTZAL = 0x01,
9290 BGEZ = 0x02,
9291 BGEZAL = 0x03,
9292 BLEZ = 0x04,
9293 BNEZC = 0x05,
9294 BGTZ = 0x06,
9295 BEQZC = 0x07,
9296 TLTI = 0x08,
9297 TGEI = 0x09,
9298 TLTIU = 0x0a,
9299 TGEIU = 0x0b,
9300 TNEI = 0x0c,
9301 LUI = 0x0d,
9302 TEQI = 0x0e,
9303 SYNCI = 0x10,
9304 BLTZALS = 0x11,
9305 BGEZALS = 0x13,
9306 BC2F = 0x14,
9307 BC2T = 0x15,
9308 BPOSGE64 = 0x1a,
9309 BPOSGE32 = 0x1b,
9310 /* These overlap and are distinguished by bit16 of the instruction */
9311 BC1F = 0x1c,
9312 BC1T = 0x1d,
9313 BC1ANY2F = 0x1c,
9314 BC1ANY2T = 0x1d,
9315 BC1ANY4F = 0x1e,
9316 BC1ANY4T = 0x1f
9319 /* POOL16A encoding of minor opcode field */
9321 enum {
9322 ADDU16 = 0x0,
9323 SUBU16 = 0x1
9326 /* POOL16B encoding of minor opcode field */
9328 enum {
9329 SLL16 = 0x0,
9330 SRL16 = 0x1
9333 /* POOL16C encoding of minor opcode field */
9335 enum {
9336 NOT16 = 0x00,
9337 XOR16 = 0x04,
9338 AND16 = 0x08,
9339 OR16 = 0x0c,
9340 LWM16 = 0x10,
9341 SWM16 = 0x14,
9342 JR16 = 0x18,
9343 JRC16 = 0x1a,
9344 JALR16 = 0x1c,
9345 JALR16S = 0x1e,
9346 MFHI16 = 0x20,
9347 MFLO16 = 0x24,
9348 BREAK16 = 0x28,
9349 SDBBP16 = 0x2c,
9350 JRADDIUSP = 0x30
9353 /* POOL16D encoding of minor opcode field */
9355 enum {
9356 ADDIUS5 = 0x0,
9357 ADDIUSP = 0x1
9360 /* POOL16E encoding of minor opcode field */
9362 enum {
9363 ADDIUR2 = 0x0,
9364 ADDIUR1SP = 0x1
9367 static int mmreg (int r)
9369 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9371 return map[r];
9374 /* Used for 16-bit store instructions. */
9375 static int mmreg2 (int r)
9377 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9379 return map[r];
9382 #define uMIPS_RD(op) ((op >> 7) & 0x7)
9383 #define uMIPS_RS(op) ((op >> 4) & 0x7)
9384 #define uMIPS_RS2(op) uMIPS_RS(op)
9385 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
9386 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9387 #define uMIPS_RS5(op) (op & 0x1f)
9389 /* Signed immediate */
9390 #define SIMM(op, start, width) \
9391 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
9392 << (32-width)) \
9393 >> (32-width))
9394 /* Zero-extended immediate */
9395 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9397 static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
9399 int rd = mmreg(uMIPS_RD(ctx->opcode));
9401 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9404 static void gen_addiur2 (CPUState *env, DisasContext *ctx)
9406 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9407 int rd = mmreg(uMIPS_RD(ctx->opcode));
9408 int rs = mmreg(uMIPS_RS(ctx->opcode));
9410 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9413 static void gen_addiusp (CPUState *env, DisasContext *ctx)
9415 int encoded = ZIMM(ctx->opcode, 1, 9);
9416 int decoded;
9418 if (encoded <= 1) {
9419 decoded = 256 + encoded;
9420 } else if (encoded <= 255) {
9421 decoded = encoded;
9422 } else if (encoded <= 509) {
9423 decoded = encoded - 512;
9424 } else {
9425 decoded = encoded - 768;
9428 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9431 static void gen_addius5 (CPUState *env, DisasContext *ctx)
9433 int imm = SIMM(ctx->opcode, 1, 4);
9434 int rd = (ctx->opcode >> 5) & 0x1f;
9436 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9439 static void gen_andi16 (CPUState *env, DisasContext *ctx)
9441 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9442 31, 32, 63, 64, 255, 32768, 65535 };
9443 int rd = mmreg(uMIPS_RD(ctx->opcode));
9444 int rs = mmreg(uMIPS_RS(ctx->opcode));
9445 int encoded = ZIMM(ctx->opcode, 0, 4);
9447 gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9450 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9451 int base, int16_t offset)
9453 TCGv t0, t1;
9454 TCGv_i32 t2;
9456 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9457 generate_exception(ctx, EXCP_RI);
9458 return;
9461 t0 = tcg_temp_new();
9463 gen_base_offset_addr(ctx, t0, base, offset);
9465 t1 = tcg_const_tl(reglist);
9466 t2 = tcg_const_i32(ctx->mem_idx);
9468 save_cpu_state(ctx, 1);
9469 switch (opc) {
9470 case LWM32:
9471 gen_helper_lwm(t0, t1, t2);
9472 break;
9473 case SWM32:
9474 gen_helper_swm(t0, t1, t2);
9475 break;
9476 #ifdef TARGET_MIPS64
9477 case LDM:
9478 gen_helper_ldm(t0, t1, t2);
9479 break;
9480 case SDM:
9481 gen_helper_sdm(t0, t1, t2);
9482 break;
9483 #endif
9485 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9486 tcg_temp_free(t0);
9487 tcg_temp_free(t1);
9488 tcg_temp_free_i32(t2);
9492 static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
9494 int rd = mmreg((ctx->opcode >> 3) & 0x7);
9495 int rs = mmreg(ctx->opcode & 0x7);
9496 int opc;
9498 switch (((ctx->opcode) >> 4) & 0x3f) {
9499 case NOT16 + 0:
9500 case NOT16 + 1:
9501 case NOT16 + 2:
9502 case NOT16 + 3:
9503 gen_logic(env, OPC_NOR, rd, rs, 0);
9504 break;
9505 case XOR16 + 0:
9506 case XOR16 + 1:
9507 case XOR16 + 2:
9508 case XOR16 + 3:
9509 gen_logic(env, OPC_XOR, rd, rd, rs);
9510 break;
9511 case AND16 + 0:
9512 case AND16 + 1:
9513 case AND16 + 2:
9514 case AND16 + 3:
9515 gen_logic(env, OPC_AND, rd, rd, rs);
9516 break;
9517 case OR16 + 0:
9518 case OR16 + 1:
9519 case OR16 + 2:
9520 case OR16 + 3:
9521 gen_logic(env, OPC_OR, rd, rd, rs);
9522 break;
9523 case LWM16 + 0:
9524 case LWM16 + 1:
9525 case LWM16 + 2:
9526 case LWM16 + 3:
9528 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9529 int offset = ZIMM(ctx->opcode, 0, 4);
9531 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9532 29, offset << 2);
9534 break;
9535 case SWM16 + 0:
9536 case SWM16 + 1:
9537 case SWM16 + 2:
9538 case SWM16 + 3:
9540 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9541 int offset = ZIMM(ctx->opcode, 0, 4);
9543 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9544 29, offset << 2);
9546 break;
9547 case JR16 + 0:
9548 case JR16 + 1:
9550 int reg = ctx->opcode & 0x1f;
9552 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9554 *is_branch = 1;
9555 break;
9556 case JRC16 + 0:
9557 case JRC16 + 1:
9559 int reg = ctx->opcode & 0x1f;
9561 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9562 /* Let normal delay slot handling in our caller take us
9563 to the branch target. */
9565 break;
9566 case JALR16 + 0:
9567 case JALR16 + 1:
9568 opc = OPC_JALR;
9569 goto do_jalr;
9570 case JALR16S + 0:
9571 case JALR16S + 1:
9572 opc = OPC_JALRS;
9573 do_jalr:
9575 int reg = ctx->opcode & 0x1f;
9577 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9579 *is_branch = 1;
9580 break;
9581 case MFHI16 + 0:
9582 case MFHI16 + 1:
9583 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9584 break;
9585 case MFLO16 + 0:
9586 case MFLO16 + 1:
9587 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9588 break;
9589 case BREAK16:
9590 generate_exception(ctx, EXCP_BREAK);
9591 break;
9592 case SDBBP16:
9593 /* XXX: not clear which exception should be raised
9594 * when in debug mode...
9596 check_insn(env, ctx, ISA_MIPS32);
9597 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9598 generate_exception(ctx, EXCP_DBp);
9599 } else {
9600 generate_exception(ctx, EXCP_DBp);
9602 break;
9603 case JRADDIUSP + 0:
9604 case JRADDIUSP + 1:
9606 int imm = ZIMM(ctx->opcode, 0, 5);
9608 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9609 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
9610 /* Let normal delay slot handling in our caller take us
9611 to the branch target. */
9613 break;
9614 default:
9615 generate_exception(ctx, EXCP_RI);
9616 break;
9620 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
9622 TCGv t0 = tcg_temp_new();
9623 TCGv t1 = tcg_temp_new();
9625 gen_load_gpr(t0, base);
9627 if (index != 0) {
9628 gen_load_gpr(t1, index);
9629 tcg_gen_shli_tl(t1, t1, 2);
9630 gen_op_addr_add(ctx, t0, t1, t0);
9633 save_cpu_state(ctx, 0);
9634 op_ldst_lw(t1, t0, ctx);
9635 gen_store_gpr(t1, rd);
9637 tcg_temp_free(t0);
9638 tcg_temp_free(t1);
9641 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
9642 int base, int16_t offset)
9644 const char *opn = "ldst_pair";
9645 TCGv t0, t1;
9647 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
9648 generate_exception(ctx, EXCP_RI);
9649 return;
9652 t0 = tcg_temp_new();
9653 t1 = tcg_temp_new();
9655 gen_base_offset_addr(ctx, t0, base, offset);
9657 switch (opc) {
9658 case LWP:
9659 save_cpu_state(ctx, 0);
9660 op_ldst_lw(t1, t0, ctx);
9661 gen_store_gpr(t1, rd);
9662 tcg_gen_movi_tl(t1, 4);
9663 gen_op_addr_add(ctx, t0, t0, t1);
9664 op_ldst_lw(t1, t0, ctx);
9665 gen_store_gpr(t1, rd+1);
9666 opn = "lwp";
9667 break;
9668 case SWP:
9669 save_cpu_state(ctx, 1);
9670 gen_load_gpr(t1, rd);
9671 op_ldst_sw(t1, t0, ctx);
9672 tcg_gen_movi_tl(t1, 4);
9673 gen_op_addr_add(ctx, t0, t0, t1);
9674 gen_load_gpr(t1, rd+1);
9675 op_ldst_sw(t1, t0, ctx);
9676 opn = "swp";
9677 break;
9678 #ifdef TARGET_MIPS64
9679 case LDP:
9680 save_cpu_state(ctx, 0);
9681 op_ldst_ld(t1, t0, ctx);
9682 gen_store_gpr(t1, rd);
9683 tcg_gen_movi_tl(t1, 8);
9684 gen_op_addr_add(ctx, t0, t0, t1);
9685 op_ldst_ld(t1, t0, ctx);
9686 gen_store_gpr(t1, rd+1);
9687 opn = "ldp";
9688 break;
9689 case SDP:
9690 save_cpu_state(ctx, 1);
9691 gen_load_gpr(t1, rd);
9692 op_ldst_sd(t1, t0, ctx);
9693 tcg_gen_movi_tl(t1, 8);
9694 gen_op_addr_add(ctx, t0, t0, t1);
9695 gen_load_gpr(t1, rd+1);
9696 op_ldst_sd(t1, t0, ctx);
9697 opn = "sdp";
9698 break;
9699 #endif
9701 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
9702 tcg_temp_free(t0);
9703 tcg_temp_free(t1);
9706 static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
9707 int *is_branch)
9709 int extension = (ctx->opcode >> 6) & 0x3f;
9710 int minor = (ctx->opcode >> 12) & 0xf;
9711 uint32_t mips32_op;
9713 switch (extension) {
9714 case TEQ:
9715 mips32_op = OPC_TEQ;
9716 goto do_trap;
9717 case TGE:
9718 mips32_op = OPC_TGE;
9719 goto do_trap;
9720 case TGEU:
9721 mips32_op = OPC_TGEU;
9722 goto do_trap;
9723 case TLT:
9724 mips32_op = OPC_TLT;
9725 goto do_trap;
9726 case TLTU:
9727 mips32_op = OPC_TLTU;
9728 goto do_trap;
9729 case TNE:
9730 mips32_op = OPC_TNE;
9731 do_trap:
9732 gen_trap(ctx, mips32_op, rs, rt, -1);
9733 break;
9734 #ifndef CONFIG_USER_ONLY
9735 case MFC0:
9736 case MFC0 + 32:
9737 if (rt == 0) {
9738 /* Treat as NOP. */
9739 break;
9741 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
9742 break;
9743 case MTC0:
9744 case MTC0 + 32:
9746 TCGv t0 = tcg_temp_new();
9748 gen_load_gpr(t0, rt);
9749 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
9750 tcg_temp_free(t0);
9752 break;
9753 #endif
9754 case 0x2c:
9755 switch (minor) {
9756 case SEB:
9757 gen_bshfl(ctx, OPC_SEB, rs, rt);
9758 break;
9759 case SEH:
9760 gen_bshfl(ctx, OPC_SEH, rs, rt);
9761 break;
9762 case CLO:
9763 mips32_op = OPC_CLO;
9764 goto do_cl;
9765 case CLZ:
9766 mips32_op = OPC_CLZ;
9767 do_cl:
9768 check_insn(env, ctx, ISA_MIPS32);
9769 gen_cl(ctx, mips32_op, rt, rs);
9770 break;
9771 case RDHWR:
9772 gen_rdhwr(env, ctx, rt, rs);
9773 break;
9774 case WSBH:
9775 gen_bshfl(ctx, OPC_WSBH, rs, rt);
9776 break;
9777 case MULT:
9778 mips32_op = OPC_MULT;
9779 goto do_muldiv;
9780 case MULTU:
9781 mips32_op = OPC_MULTU;
9782 goto do_muldiv;
9783 case DIV:
9784 mips32_op = OPC_DIV;
9785 goto do_muldiv;
9786 case DIVU:
9787 mips32_op = OPC_DIVU;
9788 goto do_muldiv;
9789 case MADD:
9790 mips32_op = OPC_MADD;
9791 goto do_muldiv;
9792 case MADDU:
9793 mips32_op = OPC_MADDU;
9794 goto do_muldiv;
9795 case MSUB:
9796 mips32_op = OPC_MSUB;
9797 goto do_muldiv;
9798 case MSUBU:
9799 mips32_op = OPC_MSUBU;
9800 do_muldiv:
9801 check_insn(env, ctx, ISA_MIPS32);
9802 gen_muldiv(ctx, mips32_op, rs, rt);
9803 break;
9804 default:
9805 goto pool32axf_invalid;
9807 break;
9808 case 0x34:
9809 switch (minor) {
9810 case MFC2:
9811 case MTC2:
9812 case MFHC2:
9813 case MTHC2:
9814 case CFC2:
9815 case CTC2:
9816 generate_exception_err(ctx, EXCP_CpU, 2);
9817 break;
9818 default:
9819 goto pool32axf_invalid;
9821 break;
9822 case 0x3c:
9823 switch (minor) {
9824 case JALR:
9825 case JALR_HB:
9826 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
9827 *is_branch = 1;
9828 break;
9829 case JALRS:
9830 case JALRS_HB:
9831 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
9832 *is_branch = 1;
9833 break;
9834 default:
9835 goto pool32axf_invalid;
9837 break;
9838 case 0x05:
9839 switch (minor) {
9840 case RDPGPR:
9841 check_insn(env, ctx, ISA_MIPS32R2);
9842 gen_load_srsgpr(rt, rs);
9843 break;
9844 case WRPGPR:
9845 check_insn(env, ctx, ISA_MIPS32R2);
9846 gen_store_srsgpr(rt, rs);
9847 break;
9848 default:
9849 goto pool32axf_invalid;
9851 break;
9852 #ifndef CONFIG_USER_ONLY
9853 case 0x0d:
9854 switch (minor) {
9855 case TLBP:
9856 mips32_op = OPC_TLBP;
9857 goto do_cp0;
9858 case TLBR:
9859 mips32_op = OPC_TLBR;
9860 goto do_cp0;
9861 case TLBWI:
9862 mips32_op = OPC_TLBWI;
9863 goto do_cp0;
9864 case TLBWR:
9865 mips32_op = OPC_TLBWR;
9866 goto do_cp0;
9867 case WAIT:
9868 mips32_op = OPC_WAIT;
9869 goto do_cp0;
9870 case DERET:
9871 mips32_op = OPC_DERET;
9872 goto do_cp0;
9873 case ERET:
9874 mips32_op = OPC_ERET;
9875 do_cp0:
9876 gen_cp0(env, ctx, mips32_op, rt, rs);
9877 break;
9878 default:
9879 goto pool32axf_invalid;
9881 break;
9882 case 0x1d:
9883 switch (minor) {
9884 case DI:
9886 TCGv t0 = tcg_temp_new();
9888 save_cpu_state(ctx, 1);
9889 gen_helper_di(t0);
9890 gen_store_gpr(t0, rs);
9891 /* Stop translation as we may have switched the execution mode */
9892 ctx->bstate = BS_STOP;
9893 tcg_temp_free(t0);
9895 break;
9896 case EI:
9898 TCGv t0 = tcg_temp_new();
9900 save_cpu_state(ctx, 1);
9901 gen_helper_ei(t0);
9902 gen_store_gpr(t0, rs);
9903 /* Stop translation as we may have switched the execution mode */
9904 ctx->bstate = BS_STOP;
9905 tcg_temp_free(t0);
9907 break;
9908 default:
9909 goto pool32axf_invalid;
9911 break;
9912 #endif
9913 case 0x2d:
9914 switch (minor) {
9915 case SYNC:
9916 /* NOP */
9917 break;
9918 case SYSCALL:
9919 generate_exception(ctx, EXCP_SYSCALL);
9920 ctx->bstate = BS_STOP;
9921 break;
9922 case SDBBP:
9923 check_insn(env, ctx, ISA_MIPS32);
9924 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9925 generate_exception(ctx, EXCP_DBp);
9926 } else {
9927 generate_exception(ctx, EXCP_DBp);
9929 break;
9930 default:
9931 goto pool32axf_invalid;
9933 break;
9934 case 0x35:
9935 switch (minor) {
9936 case MFHI32:
9937 gen_HILO(ctx, OPC_MFHI, rs);
9938 break;
9939 case MFLO32:
9940 gen_HILO(ctx, OPC_MFLO, rs);
9941 break;
9942 case MTHI32:
9943 gen_HILO(ctx, OPC_MTHI, rs);
9944 break;
9945 case MTLO32:
9946 gen_HILO(ctx, OPC_MTLO, rs);
9947 break;
9948 default:
9949 goto pool32axf_invalid;
9951 break;
9952 default:
9953 pool32axf_invalid:
9954 MIPS_INVAL("pool32axf");
9955 generate_exception(ctx, EXCP_RI);
9956 break;
9960 /* Values for microMIPS fmt field. Variable-width, depending on which
9961 formats the instruction supports. */
9963 enum {
9964 FMT_SD_S = 0,
9965 FMT_SD_D = 1,
9967 FMT_SDPS_S = 0,
9968 FMT_SDPS_D = 1,
9969 FMT_SDPS_PS = 2,
9971 FMT_SWL_S = 0,
9972 FMT_SWL_W = 1,
9973 FMT_SWL_L = 2,
9975 FMT_DWL_D = 0,
9976 FMT_DWL_W = 1,
9977 FMT_DWL_L = 2
9980 static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
9982 int extension = (ctx->opcode >> 6) & 0x3ff;
9983 uint32_t mips32_op;
9985 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
9986 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
9987 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
9989 switch (extension) {
9990 case FLOAT_1BIT_FMT(CFC1, 0):
9991 mips32_op = OPC_CFC1;
9992 goto do_cp1;
9993 case FLOAT_1BIT_FMT(CTC1, 0):
9994 mips32_op = OPC_CTC1;
9995 goto do_cp1;
9996 case FLOAT_1BIT_FMT(MFC1, 0):
9997 mips32_op = OPC_MFC1;
9998 goto do_cp1;
9999 case FLOAT_1BIT_FMT(MTC1, 0):
10000 mips32_op = OPC_MTC1;
10001 goto do_cp1;
10002 case FLOAT_1BIT_FMT(MFHC1, 0):
10003 mips32_op = OPC_MFHC1;
10004 goto do_cp1;
10005 case FLOAT_1BIT_FMT(MTHC1, 0):
10006 mips32_op = OPC_MTHC1;
10007 do_cp1:
10008 gen_cp1(ctx, mips32_op, rt, rs);
10009 break;
10011 /* Reciprocal square root */
10012 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10013 mips32_op = OPC_RSQRT_S;
10014 goto do_unaryfp;
10015 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10016 mips32_op = OPC_RSQRT_D;
10017 goto do_unaryfp;
10019 /* Square root */
10020 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10021 mips32_op = OPC_SQRT_S;
10022 goto do_unaryfp;
10023 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10024 mips32_op = OPC_SQRT_D;
10025 goto do_unaryfp;
10027 /* Reciprocal */
10028 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10029 mips32_op = OPC_RECIP_S;
10030 goto do_unaryfp;
10031 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10032 mips32_op = OPC_RECIP_D;
10033 goto do_unaryfp;
10035 /* Floor */
10036 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10037 mips32_op = OPC_FLOOR_L_S;
10038 goto do_unaryfp;
10039 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10040 mips32_op = OPC_FLOOR_L_D;
10041 goto do_unaryfp;
10042 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10043 mips32_op = OPC_FLOOR_W_S;
10044 goto do_unaryfp;
10045 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10046 mips32_op = OPC_FLOOR_W_D;
10047 goto do_unaryfp;
10049 /* Ceiling */
10050 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10051 mips32_op = OPC_CEIL_L_S;
10052 goto do_unaryfp;
10053 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10054 mips32_op = OPC_CEIL_L_D;
10055 goto do_unaryfp;
10056 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10057 mips32_op = OPC_CEIL_W_S;
10058 goto do_unaryfp;
10059 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10060 mips32_op = OPC_CEIL_W_D;
10061 goto do_unaryfp;
10063 /* Truncation */
10064 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10065 mips32_op = OPC_TRUNC_L_S;
10066 goto do_unaryfp;
10067 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10068 mips32_op = OPC_TRUNC_L_D;
10069 goto do_unaryfp;
10070 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10071 mips32_op = OPC_TRUNC_W_S;
10072 goto do_unaryfp;
10073 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10074 mips32_op = OPC_TRUNC_W_D;
10075 goto do_unaryfp;
10077 /* Round */
10078 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10079 mips32_op = OPC_ROUND_L_S;
10080 goto do_unaryfp;
10081 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10082 mips32_op = OPC_ROUND_L_D;
10083 goto do_unaryfp;
10084 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10085 mips32_op = OPC_ROUND_W_S;
10086 goto do_unaryfp;
10087 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10088 mips32_op = OPC_ROUND_W_D;
10089 goto do_unaryfp;
10091 /* Integer to floating-point conversion */
10092 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10093 mips32_op = OPC_CVT_L_S;
10094 goto do_unaryfp;
10095 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10096 mips32_op = OPC_CVT_L_D;
10097 goto do_unaryfp;
10098 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10099 mips32_op = OPC_CVT_W_S;
10100 goto do_unaryfp;
10101 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10102 mips32_op = OPC_CVT_W_D;
10103 goto do_unaryfp;
10105 /* Paired-foo conversions */
10106 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10107 mips32_op = OPC_CVT_S_PL;
10108 goto do_unaryfp;
10109 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10110 mips32_op = OPC_CVT_S_PU;
10111 goto do_unaryfp;
10112 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10113 mips32_op = OPC_CVT_PW_PS;
10114 goto do_unaryfp;
10115 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10116 mips32_op = OPC_CVT_PS_PW;
10117 goto do_unaryfp;
10119 /* Floating-point moves */
10120 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10121 mips32_op = OPC_MOV_S;
10122 goto do_unaryfp;
10123 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10124 mips32_op = OPC_MOV_D;
10125 goto do_unaryfp;
10126 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10127 mips32_op = OPC_MOV_PS;
10128 goto do_unaryfp;
10130 /* Absolute value */
10131 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10132 mips32_op = OPC_ABS_S;
10133 goto do_unaryfp;
10134 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10135 mips32_op = OPC_ABS_D;
10136 goto do_unaryfp;
10137 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10138 mips32_op = OPC_ABS_PS;
10139 goto do_unaryfp;
10141 /* Negation */
10142 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10143 mips32_op = OPC_NEG_S;
10144 goto do_unaryfp;
10145 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10146 mips32_op = OPC_NEG_D;
10147 goto do_unaryfp;
10148 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10149 mips32_op = OPC_NEG_PS;
10150 goto do_unaryfp;
10152 /* Reciprocal square root step */
10153 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10154 mips32_op = OPC_RSQRT1_S;
10155 goto do_unaryfp;
10156 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10157 mips32_op = OPC_RSQRT1_D;
10158 goto do_unaryfp;
10159 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10160 mips32_op = OPC_RSQRT1_PS;
10161 goto do_unaryfp;
10163 /* Reciprocal step */
10164 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10165 mips32_op = OPC_RECIP1_S;
10166 goto do_unaryfp;
10167 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10168 mips32_op = OPC_RECIP1_S;
10169 goto do_unaryfp;
10170 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10171 mips32_op = OPC_RECIP1_PS;
10172 goto do_unaryfp;
10174 /* Conversions from double */
10175 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10176 mips32_op = OPC_CVT_D_S;
10177 goto do_unaryfp;
10178 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10179 mips32_op = OPC_CVT_D_W;
10180 goto do_unaryfp;
10181 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10182 mips32_op = OPC_CVT_D_L;
10183 goto do_unaryfp;
10185 /* Conversions from single */
10186 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10187 mips32_op = OPC_CVT_S_D;
10188 goto do_unaryfp;
10189 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10190 mips32_op = OPC_CVT_S_W;
10191 goto do_unaryfp;
10192 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10193 mips32_op = OPC_CVT_S_L;
10194 do_unaryfp:
10195 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10196 break;
10198 /* Conditional moves on floating-point codes */
10199 case COND_FLOAT_MOV(MOVT, 0):
10200 case COND_FLOAT_MOV(MOVT, 1):
10201 case COND_FLOAT_MOV(MOVT, 2):
10202 case COND_FLOAT_MOV(MOVT, 3):
10203 case COND_FLOAT_MOV(MOVT, 4):
10204 case COND_FLOAT_MOV(MOVT, 5):
10205 case COND_FLOAT_MOV(MOVT, 6):
10206 case COND_FLOAT_MOV(MOVT, 7):
10207 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10208 break;
10209 case COND_FLOAT_MOV(MOVF, 0):
10210 case COND_FLOAT_MOV(MOVF, 1):
10211 case COND_FLOAT_MOV(MOVF, 2):
10212 case COND_FLOAT_MOV(MOVF, 3):
10213 case COND_FLOAT_MOV(MOVF, 4):
10214 case COND_FLOAT_MOV(MOVF, 5):
10215 case COND_FLOAT_MOV(MOVF, 6):
10216 case COND_FLOAT_MOV(MOVF, 7):
10217 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10218 break;
10219 default:
10220 MIPS_INVAL("pool32fxf");
10221 generate_exception(ctx, EXCP_RI);
10222 break;
10226 static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
10227 uint16_t insn_hw1, int *is_branch)
10229 int32_t offset;
10230 uint16_t insn;
10231 int rt, rs, rd, rr;
10232 int16_t imm;
10233 uint32_t op, minor, mips32_op;
10234 uint32_t cond, fmt, cc;
10236 insn = lduw_code(ctx->pc + 2);
10237 ctx->opcode = (ctx->opcode << 16) | insn;
10239 rt = (ctx->opcode >> 21) & 0x1f;
10240 rs = (ctx->opcode >> 16) & 0x1f;
10241 rd = (ctx->opcode >> 11) & 0x1f;
10242 rr = (ctx->opcode >> 6) & 0x1f;
10243 imm = (int16_t) ctx->opcode;
10245 op = (ctx->opcode >> 26) & 0x3f;
10246 switch (op) {
10247 case POOL32A:
10248 minor = ctx->opcode & 0x3f;
10249 switch (minor) {
10250 case 0x00:
10251 minor = (ctx->opcode >> 6) & 0xf;
10252 switch (minor) {
10253 case SLL32:
10254 mips32_op = OPC_SLL;
10255 goto do_shifti;
10256 case SRA:
10257 mips32_op = OPC_SRA;
10258 goto do_shifti;
10259 case SRL32:
10260 mips32_op = OPC_SRL;
10261 goto do_shifti;
10262 case ROTR:
10263 mips32_op = OPC_ROTR;
10264 do_shifti:
10265 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10266 break;
10267 default:
10268 goto pool32a_invalid;
10270 break;
10271 case 0x10:
10272 minor = (ctx->opcode >> 6) & 0xf;
10273 switch (minor) {
10274 /* Arithmetic */
10275 case ADD:
10276 mips32_op = OPC_ADD;
10277 goto do_arith;
10278 case ADDU32:
10279 mips32_op = OPC_ADDU;
10280 goto do_arith;
10281 case SUB:
10282 mips32_op = OPC_SUB;
10283 goto do_arith;
10284 case SUBU32:
10285 mips32_op = OPC_SUBU;
10286 goto do_arith;
10287 case MUL:
10288 mips32_op = OPC_MUL;
10289 do_arith:
10290 gen_arith(env, ctx, mips32_op, rd, rs, rt);
10291 break;
10292 /* Shifts */
10293 case SLLV:
10294 mips32_op = OPC_SLLV;
10295 goto do_shift;
10296 case SRLV:
10297 mips32_op = OPC_SRLV;
10298 goto do_shift;
10299 case SRAV:
10300 mips32_op = OPC_SRAV;
10301 goto do_shift;
10302 case ROTRV:
10303 mips32_op = OPC_ROTRV;
10304 do_shift:
10305 gen_shift(env, ctx, mips32_op, rd, rs, rt);
10306 break;
10307 /* Logical operations */
10308 case AND:
10309 mips32_op = OPC_AND;
10310 goto do_logic;
10311 case OR32:
10312 mips32_op = OPC_OR;
10313 goto do_logic;
10314 case NOR:
10315 mips32_op = OPC_NOR;
10316 goto do_logic;
10317 case XOR32:
10318 mips32_op = OPC_XOR;
10319 do_logic:
10320 gen_logic(env, mips32_op, rd, rs, rt);
10321 break;
10322 /* Set less than */
10323 case SLT:
10324 mips32_op = OPC_SLT;
10325 goto do_slt;
10326 case SLTU:
10327 mips32_op = OPC_SLTU;
10328 do_slt:
10329 gen_slt(env, mips32_op, rd, rs, rt);
10330 break;
10331 default:
10332 goto pool32a_invalid;
10334 break;
10335 case 0x18:
10336 minor = (ctx->opcode >> 6) & 0xf;
10337 switch (minor) {
10338 /* Conditional moves */
10339 case MOVN:
10340 mips32_op = OPC_MOVN;
10341 goto do_cmov;
10342 case MOVZ:
10343 mips32_op = OPC_MOVZ;
10344 do_cmov:
10345 gen_cond_move(env, mips32_op, rd, rs, rt);
10346 break;
10347 case LWXS:
10348 gen_ldxs(ctx, rs, rt, rd);
10349 break;
10350 default:
10351 goto pool32a_invalid;
10353 break;
10354 case INS:
10355 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10356 return;
10357 case EXT:
10358 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10359 return;
10360 case POOL32AXF:
10361 gen_pool32axf(env, ctx, rt, rs, is_branch);
10362 break;
10363 case 0x07:
10364 generate_exception(ctx, EXCP_BREAK);
10365 break;
10366 default:
10367 pool32a_invalid:
10368 MIPS_INVAL("pool32a");
10369 generate_exception(ctx, EXCP_RI);
10370 break;
10372 break;
10373 case POOL32B:
10374 minor = (ctx->opcode >> 12) & 0xf;
10375 switch (minor) {
10376 case CACHE:
10377 /* Treat as no-op. */
10378 break;
10379 case LWC2:
10380 case SWC2:
10381 /* COP2: Not implemented. */
10382 generate_exception_err(ctx, EXCP_CpU, 2);
10383 break;
10384 case LWP:
10385 case SWP:
10386 #ifdef TARGET_MIPS64
10387 case LDP:
10388 case SDP:
10389 #endif
10390 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10391 break;
10392 case LWM32:
10393 case SWM32:
10394 #ifdef TARGET_MIPS64
10395 case LDM:
10396 case SDM:
10397 #endif
10398 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10399 break;
10400 default:
10401 MIPS_INVAL("pool32b");
10402 generate_exception(ctx, EXCP_RI);
10403 break;
10405 break;
10406 case POOL32F:
10407 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10408 minor = ctx->opcode & 0x3f;
10409 check_cp1_enabled(ctx);
10410 switch (minor) {
10411 case ALNV_PS:
10412 mips32_op = OPC_ALNV_PS;
10413 goto do_madd;
10414 case MADD_S:
10415 mips32_op = OPC_MADD_S;
10416 goto do_madd;
10417 case MADD_D:
10418 mips32_op = OPC_MADD_D;
10419 goto do_madd;
10420 case MADD_PS:
10421 mips32_op = OPC_MADD_PS;
10422 goto do_madd;
10423 case MSUB_S:
10424 mips32_op = OPC_MSUB_S;
10425 goto do_madd;
10426 case MSUB_D:
10427 mips32_op = OPC_MSUB_D;
10428 goto do_madd;
10429 case MSUB_PS:
10430 mips32_op = OPC_MSUB_PS;
10431 goto do_madd;
10432 case NMADD_S:
10433 mips32_op = OPC_NMADD_S;
10434 goto do_madd;
10435 case NMADD_D:
10436 mips32_op = OPC_NMADD_D;
10437 goto do_madd;
10438 case NMADD_PS:
10439 mips32_op = OPC_NMADD_PS;
10440 goto do_madd;
10441 case NMSUB_S:
10442 mips32_op = OPC_NMSUB_S;
10443 goto do_madd;
10444 case NMSUB_D:
10445 mips32_op = OPC_NMSUB_D;
10446 goto do_madd;
10447 case NMSUB_PS:
10448 mips32_op = OPC_NMSUB_PS;
10449 do_madd:
10450 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10451 break;
10452 case CABS_COND_FMT:
10453 cond = (ctx->opcode >> 6) & 0xf;
10454 cc = (ctx->opcode >> 13) & 0x7;
10455 fmt = (ctx->opcode >> 10) & 0x3;
10456 switch (fmt) {
10457 case 0x0:
10458 gen_cmpabs_s(ctx, cond, rt, rs, cc);
10459 break;
10460 case 0x1:
10461 gen_cmpabs_d(ctx, cond, rt, rs, cc);
10462 break;
10463 case 0x2:
10464 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10465 break;
10466 default:
10467 goto pool32f_invalid;
10469 break;
10470 case C_COND_FMT:
10471 cond = (ctx->opcode >> 6) & 0xf;
10472 cc = (ctx->opcode >> 13) & 0x7;
10473 fmt = (ctx->opcode >> 10) & 0x3;
10474 switch (fmt) {
10475 case 0x0:
10476 gen_cmp_s(ctx, cond, rt, rs, cc);
10477 break;
10478 case 0x1:
10479 gen_cmp_d(ctx, cond, rt, rs, cc);
10480 break;
10481 case 0x2:
10482 gen_cmp_ps(ctx, cond, rt, rs, cc);
10483 break;
10484 default:
10485 goto pool32f_invalid;
10487 break;
10488 case POOL32FXF:
10489 gen_pool32fxf(env, ctx, rt, rs);
10490 break;
10491 case 0x00:
10492 /* PLL foo */
10493 switch ((ctx->opcode >> 6) & 0x7) {
10494 case PLL_PS:
10495 mips32_op = OPC_PLL_PS;
10496 goto do_ps;
10497 case PLU_PS:
10498 mips32_op = OPC_PLU_PS;
10499 goto do_ps;
10500 case PUL_PS:
10501 mips32_op = OPC_PUL_PS;
10502 goto do_ps;
10503 case PUU_PS:
10504 mips32_op = OPC_PUU_PS;
10505 goto do_ps;
10506 case CVT_PS_S:
10507 mips32_op = OPC_CVT_PS_S;
10508 do_ps:
10509 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10510 break;
10511 default:
10512 goto pool32f_invalid;
10514 break;
10515 case 0x08:
10516 /* [LS][WDU]XC1 */
10517 switch ((ctx->opcode >> 6) & 0x7) {
10518 case LWXC1:
10519 mips32_op = OPC_LWXC1;
10520 goto do_ldst_cp1;
10521 case SWXC1:
10522 mips32_op = OPC_SWXC1;
10523 goto do_ldst_cp1;
10524 case LDXC1:
10525 mips32_op = OPC_LDXC1;
10526 goto do_ldst_cp1;
10527 case SDXC1:
10528 mips32_op = OPC_SDXC1;
10529 goto do_ldst_cp1;
10530 case LUXC1:
10531 mips32_op = OPC_LUXC1;
10532 goto do_ldst_cp1;
10533 case SUXC1:
10534 mips32_op = OPC_SUXC1;
10535 do_ldst_cp1:
10536 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10537 break;
10538 default:
10539 goto pool32f_invalid;
10541 break;
10542 case 0x18:
10543 /* 3D insns */
10544 fmt = (ctx->opcode >> 9) & 0x3;
10545 switch ((ctx->opcode >> 6) & 0x7) {
10546 case RSQRT2_FMT:
10547 switch (fmt) {
10548 case FMT_SDPS_S:
10549 mips32_op = OPC_RSQRT2_S;
10550 goto do_3d;
10551 case FMT_SDPS_D:
10552 mips32_op = OPC_RSQRT2_D;
10553 goto do_3d;
10554 case FMT_SDPS_PS:
10555 mips32_op = OPC_RSQRT2_PS;
10556 goto do_3d;
10557 default:
10558 goto pool32f_invalid;
10560 break;
10561 case RECIP2_FMT:
10562 switch (fmt) {
10563 case FMT_SDPS_S:
10564 mips32_op = OPC_RECIP2_S;
10565 goto do_3d;
10566 case FMT_SDPS_D:
10567 mips32_op = OPC_RECIP2_D;
10568 goto do_3d;
10569 case FMT_SDPS_PS:
10570 mips32_op = OPC_RECIP2_PS;
10571 goto do_3d;
10572 default:
10573 goto pool32f_invalid;
10575 break;
10576 case ADDR_PS:
10577 mips32_op = OPC_ADDR_PS;
10578 goto do_3d;
10579 case MULR_PS:
10580 mips32_op = OPC_MULR_PS;
10581 do_3d:
10582 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10583 break;
10584 default:
10585 goto pool32f_invalid;
10587 break;
10588 case 0x20:
10589 /* MOV[FT].fmt and PREFX */
10590 cc = (ctx->opcode >> 13) & 0x7;
10591 fmt = (ctx->opcode >> 9) & 0x3;
10592 switch ((ctx->opcode >> 6) & 0x7) {
10593 case MOVF_FMT:
10594 switch (fmt) {
10595 case FMT_SDPS_S:
10596 gen_movcf_s(rs, rt, cc, 0);
10597 break;
10598 case FMT_SDPS_D:
10599 gen_movcf_d(ctx, rs, rt, cc, 0);
10600 break;
10601 case FMT_SDPS_PS:
10602 gen_movcf_ps(rs, rt, cc, 0);
10603 break;
10604 default:
10605 goto pool32f_invalid;
10607 break;
10608 case MOVT_FMT:
10609 switch (fmt) {
10610 case FMT_SDPS_S:
10611 gen_movcf_s(rs, rt, cc, 1);
10612 break;
10613 case FMT_SDPS_D:
10614 gen_movcf_d(ctx, rs, rt, cc, 1);
10615 break;
10616 case FMT_SDPS_PS:
10617 gen_movcf_ps(rs, rt, cc, 1);
10618 break;
10619 default:
10620 goto pool32f_invalid;
10622 break;
10623 case PREFX:
10624 break;
10625 default:
10626 goto pool32f_invalid;
10628 break;
10629 #define FINSN_3ARG_SDPS(prfx) \
10630 switch ((ctx->opcode >> 8) & 0x3) { \
10631 case FMT_SDPS_S: \
10632 mips32_op = OPC_##prfx##_S; \
10633 goto do_fpop; \
10634 case FMT_SDPS_D: \
10635 mips32_op = OPC_##prfx##_D; \
10636 goto do_fpop; \
10637 case FMT_SDPS_PS: \
10638 mips32_op = OPC_##prfx##_PS; \
10639 goto do_fpop; \
10640 default: \
10641 goto pool32f_invalid; \
10643 case 0x30:
10644 /* regular FP ops */
10645 switch ((ctx->opcode >> 6) & 0x3) {
10646 case ADD_FMT:
10647 FINSN_3ARG_SDPS(ADD);
10648 break;
10649 case SUB_FMT:
10650 FINSN_3ARG_SDPS(SUB);
10651 break;
10652 case MUL_FMT:
10653 FINSN_3ARG_SDPS(MUL);
10654 break;
10655 case DIV_FMT:
10656 fmt = (ctx->opcode >> 8) & 0x3;
10657 if (fmt == 1) {
10658 mips32_op = OPC_DIV_D;
10659 } else if (fmt == 0) {
10660 mips32_op = OPC_DIV_S;
10661 } else {
10662 goto pool32f_invalid;
10664 goto do_fpop;
10665 default:
10666 goto pool32f_invalid;
10668 break;
10669 case 0x38:
10670 /* cmovs */
10671 switch ((ctx->opcode >> 6) & 0x3) {
10672 case MOVN_FMT:
10673 FINSN_3ARG_SDPS(MOVN);
10674 break;
10675 case MOVZ_FMT:
10676 FINSN_3ARG_SDPS(MOVZ);
10677 break;
10678 default:
10679 goto pool32f_invalid;
10681 break;
10682 do_fpop:
10683 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10684 break;
10685 default:
10686 pool32f_invalid:
10687 MIPS_INVAL("pool32f");
10688 generate_exception(ctx, EXCP_RI);
10689 break;
10691 } else {
10692 generate_exception_err(ctx, EXCP_CpU, 1);
10694 break;
10695 case POOL32I:
10696 minor = (ctx->opcode >> 21) & 0x1f;
10697 switch (minor) {
10698 case BLTZ:
10699 mips32_op = OPC_BLTZ;
10700 goto do_branch;
10701 case BLTZAL:
10702 mips32_op = OPC_BLTZAL;
10703 goto do_branch;
10704 case BLTZALS:
10705 mips32_op = OPC_BLTZALS;
10706 goto do_branch;
10707 case BGEZ:
10708 mips32_op = OPC_BGEZ;
10709 goto do_branch;
10710 case BGEZAL:
10711 mips32_op = OPC_BGEZAL;
10712 goto do_branch;
10713 case BGEZALS:
10714 mips32_op = OPC_BGEZALS;
10715 goto do_branch;
10716 case BLEZ:
10717 mips32_op = OPC_BLEZ;
10718 goto do_branch;
10719 case BGTZ:
10720 mips32_op = OPC_BGTZ;
10721 do_branch:
10722 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
10723 *is_branch = 1;
10724 break;
10726 /* Traps */
10727 case TLTI:
10728 mips32_op = OPC_TLTI;
10729 goto do_trapi;
10730 case TGEI:
10731 mips32_op = OPC_TGEI;
10732 goto do_trapi;
10733 case TLTIU:
10734 mips32_op = OPC_TLTIU;
10735 goto do_trapi;
10736 case TGEIU:
10737 mips32_op = OPC_TGEIU;
10738 goto do_trapi;
10739 case TNEI:
10740 mips32_op = OPC_TNEI;
10741 goto do_trapi;
10742 case TEQI:
10743 mips32_op = OPC_TEQI;
10744 do_trapi:
10745 gen_trap(ctx, mips32_op, rs, -1, imm);
10746 break;
10748 case BNEZC:
10749 case BEQZC:
10750 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
10751 4, rs, 0, imm << 1);
10752 /* Compact branches don't have a delay slot, so just let
10753 the normal delay slot handling take us to the branch
10754 target. */
10755 break;
10756 case LUI:
10757 gen_logic_imm(env, OPC_LUI, rs, -1, imm);
10758 break;
10759 case SYNCI:
10760 break;
10761 case BC2F:
10762 case BC2T:
10763 /* COP2: Not implemented. */
10764 generate_exception_err(ctx, EXCP_CpU, 2);
10765 break;
10766 case BC1F:
10767 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
10768 goto do_cp1branch;
10769 case BC1T:
10770 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
10771 goto do_cp1branch;
10772 case BC1ANY4F:
10773 mips32_op = OPC_BC1FANY4;
10774 goto do_cp1mips3d;
10775 case BC1ANY4T:
10776 mips32_op = OPC_BC1TANY4;
10777 do_cp1mips3d:
10778 check_cop1x(ctx);
10779 check_insn(env, ctx, ASE_MIPS3D);
10780 /* Fall through */
10781 do_cp1branch:
10782 gen_compute_branch1(env, ctx, mips32_op,
10783 (ctx->opcode >> 18) & 0x7, imm << 1);
10784 *is_branch = 1;
10785 break;
10786 case BPOSGE64:
10787 case BPOSGE32:
10788 /* MIPS DSP: not implemented */
10789 /* Fall through */
10790 default:
10791 MIPS_INVAL("pool32i");
10792 generate_exception(ctx, EXCP_RI);
10793 break;
10795 break;
10796 case POOL32C:
10797 minor = (ctx->opcode >> 12) & 0xf;
10798 switch (minor) {
10799 case LWL:
10800 mips32_op = OPC_LWL;
10801 goto do_ldst_lr;
10802 case SWL:
10803 mips32_op = OPC_SWL;
10804 goto do_ldst_lr;
10805 case LWR:
10806 mips32_op = OPC_LWR;
10807 goto do_ldst_lr;
10808 case SWR:
10809 mips32_op = OPC_SWR;
10810 goto do_ldst_lr;
10811 #if defined(TARGET_MIPS64)
10812 case LDL:
10813 mips32_op = OPC_LDL;
10814 goto do_ldst_lr;
10815 case SDL:
10816 mips32_op = OPC_SDL;
10817 goto do_ldst_lr;
10818 case LDR:
10819 mips32_op = OPC_LDR;
10820 goto do_ldst_lr;
10821 case SDR:
10822 mips32_op = OPC_SDR;
10823 goto do_ldst_lr;
10824 case LWU:
10825 mips32_op = OPC_LWU;
10826 goto do_ldst_lr;
10827 case LLD:
10828 mips32_op = OPC_LLD;
10829 goto do_ldst_lr;
10830 #endif
10831 case LL:
10832 mips32_op = OPC_LL;
10833 do_ldst_lr:
10834 gen_ldst(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
10835 break;
10836 case SC:
10837 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
10838 break;
10839 #if defined(TARGET_MIPS64)
10840 case SCD:
10841 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
10842 break;
10843 #endif
10844 case PREF:
10845 /* Treat as no-op */
10846 break;
10847 default:
10848 MIPS_INVAL("pool32c");
10849 generate_exception(ctx, EXCP_RI);
10850 break;
10852 break;
10853 case ADDI32:
10854 mips32_op = OPC_ADDI;
10855 goto do_addi;
10856 case ADDIU32:
10857 mips32_op = OPC_ADDIU;
10858 do_addi:
10859 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
10860 break;
10862 /* Logical operations */
10863 case ORI32:
10864 mips32_op = OPC_ORI;
10865 goto do_logici;
10866 case XORI32:
10867 mips32_op = OPC_XORI;
10868 goto do_logici;
10869 case ANDI32:
10870 mips32_op = OPC_ANDI;
10871 do_logici:
10872 gen_logic_imm(env, mips32_op, rt, rs, imm);
10873 break;
10875 /* Set less than immediate */
10876 case SLTI32:
10877 mips32_op = OPC_SLTI;
10878 goto do_slti;
10879 case SLTIU32:
10880 mips32_op = OPC_SLTIU;
10881 do_slti:
10882 gen_slt_imm(env, mips32_op, rt, rs, imm);
10883 break;
10884 case JALX32:
10885 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
10886 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
10887 *is_branch = 1;
10888 break;
10889 case JALS32:
10890 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
10891 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
10892 *is_branch = 1;
10893 break;
10894 case BEQ32:
10895 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
10896 *is_branch = 1;
10897 break;
10898 case BNE32:
10899 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
10900 *is_branch = 1;
10901 break;
10902 case J32:
10903 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
10904 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
10905 *is_branch = 1;
10906 break;
10907 case JAL32:
10908 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
10909 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
10910 *is_branch = 1;
10911 break;
10912 /* Floating point (COP1) */
10913 case LWC132:
10914 mips32_op = OPC_LWC1;
10915 goto do_cop1;
10916 case LDC132:
10917 mips32_op = OPC_LDC1;
10918 goto do_cop1;
10919 case SWC132:
10920 mips32_op = OPC_SWC1;
10921 goto do_cop1;
10922 case SDC132:
10923 mips32_op = OPC_SDC1;
10924 do_cop1:
10925 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
10926 break;
10927 case ADDIUPC:
10929 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
10930 int offset = SIMM(ctx->opcode, 0, 23) << 2;
10932 gen_addiupc(ctx, reg, offset, 0, 0);
10934 break;
10935 /* Loads and stores */
10936 case LB32:
10937 mips32_op = OPC_LB;
10938 goto do_ldst;
10939 case LBU32:
10940 mips32_op = OPC_LBU;
10941 goto do_ldst;
10942 case LH32:
10943 mips32_op = OPC_LH;
10944 goto do_ldst;
10945 case LHU32:
10946 mips32_op = OPC_LHU;
10947 goto do_ldst;
10948 case LW32:
10949 mips32_op = OPC_LW;
10950 goto do_ldst;
10951 #ifdef TARGET_MIPS64
10952 case LD32:
10953 mips32_op = OPC_LD;
10954 goto do_ldst;
10955 case SD32:
10956 mips32_op = OPC_SD;
10957 goto do_ldst;
10958 #endif
10959 case SB32:
10960 mips32_op = OPC_SB;
10961 goto do_ldst;
10962 case SH32:
10963 mips32_op = OPC_SH;
10964 goto do_ldst;
10965 case SW32:
10966 mips32_op = OPC_SW;
10967 do_ldst:
10968 gen_ldst(ctx, mips32_op, rt, rs, imm);
10969 break;
10970 default:
10971 generate_exception(ctx, EXCP_RI);
10972 break;
10976 static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
10978 uint32_t op;
10980 /* make sure instructions are on a halfword boundary */
10981 if (ctx->pc & 0x1) {
10982 env->CP0_BadVAddr = ctx->pc;
10983 generate_exception(ctx, EXCP_AdEL);
10984 ctx->bstate = BS_STOP;
10985 return 2;
10988 op = (ctx->opcode >> 10) & 0x3f;
10989 /* Enforce properly-sized instructions in a delay slot */
10990 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10991 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
10993 switch (op) {
10994 case POOL32A:
10995 case POOL32B:
10996 case POOL32I:
10997 case POOL32C:
10998 case ADDI32:
10999 case ADDIU32:
11000 case ORI32:
11001 case XORI32:
11002 case SLTI32:
11003 case SLTIU32:
11004 case ANDI32:
11005 case JALX32:
11006 case LBU32:
11007 case LHU32:
11008 case POOL32F:
11009 case JALS32:
11010 case BEQ32:
11011 case BNE32:
11012 case J32:
11013 case JAL32:
11014 case SB32:
11015 case SH32:
11016 case POOL32S:
11017 case ADDIUPC:
11018 case SWC132:
11019 case SDC132:
11020 case SD32:
11021 case SW32:
11022 case LB32:
11023 case LH32:
11024 case DADDIU32:
11025 case POOL48A: /* ??? */
11026 case LWC132:
11027 case LDC132:
11028 case LD32:
11029 case LW32:
11030 if (bits & MIPS_HFLAG_BDS16) {
11031 generate_exception(ctx, EXCP_RI);
11032 /* Just stop translation; the user is confused. */
11033 ctx->bstate = BS_STOP;
11034 return 2;
11036 break;
11037 case POOL16A:
11038 case POOL16B:
11039 case POOL16C:
11040 case LWGP16:
11041 case POOL16F:
11042 case LBU16:
11043 case LHU16:
11044 case LWSP16:
11045 case LW16:
11046 case SB16:
11047 case SH16:
11048 case SWSP16:
11049 case SW16:
11050 case MOVE16:
11051 case ANDI16:
11052 case POOL16D:
11053 case POOL16E:
11054 case BEQZ16:
11055 case BNEZ16:
11056 case B16:
11057 case LI16:
11058 if (bits & MIPS_HFLAG_BDS32) {
11059 generate_exception(ctx, EXCP_RI);
11060 /* Just stop translation; the user is confused. */
11061 ctx->bstate = BS_STOP;
11062 return 2;
11064 break;
11065 default:
11066 break;
11069 switch (op) {
11070 case POOL16A:
11072 int rd = mmreg(uMIPS_RD(ctx->opcode));
11073 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11074 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11075 uint32_t opc = 0;
11077 switch (ctx->opcode & 0x1) {
11078 case ADDU16:
11079 opc = OPC_ADDU;
11080 break;
11081 case SUBU16:
11082 opc = OPC_SUBU;
11083 break;
11086 gen_arith(env, ctx, opc, rd, rs1, rs2);
11088 break;
11089 case POOL16B:
11091 int rd = mmreg(uMIPS_RD(ctx->opcode));
11092 int rs = mmreg(uMIPS_RS(ctx->opcode));
11093 int amount = (ctx->opcode >> 1) & 0x7;
11094 uint32_t opc = 0;
11095 amount = amount == 0 ? 8 : amount;
11097 switch (ctx->opcode & 0x1) {
11098 case SLL16:
11099 opc = OPC_SLL;
11100 break;
11101 case SRL16:
11102 opc = OPC_SRL;
11103 break;
11106 gen_shift_imm(env, ctx, opc, rd, rs, amount);
11108 break;
11109 case POOL16C:
11110 gen_pool16c_insn(env, ctx, is_branch);
11111 break;
11112 case LWGP16:
11114 int rd = mmreg(uMIPS_RD(ctx->opcode));
11115 int rb = 28; /* GP */
11116 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11118 gen_ldst(ctx, OPC_LW, rd, rb, offset);
11120 break;
11121 case POOL16F:
11122 if (ctx->opcode & 1) {
11123 generate_exception(ctx, EXCP_RI);
11124 } else {
11125 /* MOVEP */
11126 int enc_dest = uMIPS_RD(ctx->opcode);
11127 int enc_rt = uMIPS_RS2(ctx->opcode);
11128 int enc_rs = uMIPS_RS1(ctx->opcode);
11129 int rd, rs, re, rt;
11130 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11131 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11132 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11134 rd = rd_enc[enc_dest];
11135 re = re_enc[enc_dest];
11136 rs = rs_rt_enc[enc_rs];
11137 rt = rs_rt_enc[enc_rt];
11139 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11140 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11142 break;
11143 case LBU16:
11145 int rd = mmreg(uMIPS_RD(ctx->opcode));
11146 int rb = mmreg(uMIPS_RS(ctx->opcode));
11147 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11148 offset = (offset == 0xf ? -1 : offset);
11150 gen_ldst(ctx, OPC_LBU, rd, rb, offset);
11152 break;
11153 case LHU16:
11155 int rd = mmreg(uMIPS_RD(ctx->opcode));
11156 int rb = mmreg(uMIPS_RS(ctx->opcode));
11157 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11159 gen_ldst(ctx, OPC_LHU, rd, rb, offset);
11161 break;
11162 case LWSP16:
11164 int rd = (ctx->opcode >> 5) & 0x1f;
11165 int rb = 29; /* SP */
11166 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11168 gen_ldst(ctx, OPC_LW, rd, rb, offset);
11170 break;
11171 case LW16:
11173 int rd = mmreg(uMIPS_RD(ctx->opcode));
11174 int rb = mmreg(uMIPS_RS(ctx->opcode));
11175 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11177 gen_ldst(ctx, OPC_LW, rd, rb, offset);
11179 break;
11180 case SB16:
11182 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11183 int rb = mmreg(uMIPS_RS(ctx->opcode));
11184 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11186 gen_ldst(ctx, OPC_SB, rd, rb, offset);
11188 break;
11189 case SH16:
11191 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11192 int rb = mmreg(uMIPS_RS(ctx->opcode));
11193 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11195 gen_ldst(ctx, OPC_SH, rd, rb, offset);
11197 break;
11198 case SWSP16:
11200 int rd = (ctx->opcode >> 5) & 0x1f;
11201 int rb = 29; /* SP */
11202 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11204 gen_ldst(ctx, OPC_SW, rd, rb, offset);
11206 break;
11207 case SW16:
11209 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11210 int rb = mmreg(uMIPS_RS(ctx->opcode));
11211 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11213 gen_ldst(ctx, OPC_SW, rd, rb, offset);
11215 break;
11216 case MOVE16:
11218 int rd = uMIPS_RD5(ctx->opcode);
11219 int rs = uMIPS_RS5(ctx->opcode);
11221 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11223 break;
11224 case ANDI16:
11225 gen_andi16(env, ctx);
11226 break;
11227 case POOL16D:
11228 switch (ctx->opcode & 0x1) {
11229 case ADDIUS5:
11230 gen_addius5(env, ctx);
11231 break;
11232 case ADDIUSP:
11233 gen_addiusp(env, ctx);
11234 break;
11236 break;
11237 case POOL16E:
11238 switch (ctx->opcode & 0x1) {
11239 case ADDIUR2:
11240 gen_addiur2(env, ctx);
11241 break;
11242 case ADDIUR1SP:
11243 gen_addiur1sp(env, ctx);
11244 break;
11246 break;
11247 case B16:
11248 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11249 SIMM(ctx->opcode, 0, 10) << 1);
11250 *is_branch = 1;
11251 break;
11252 case BNEZ16:
11253 case BEQZ16:
11254 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11255 mmreg(uMIPS_RD(ctx->opcode)),
11256 0, SIMM(ctx->opcode, 0, 7) << 1);
11257 *is_branch = 1;
11258 break;
11259 case LI16:
11261 int reg = mmreg(uMIPS_RD(ctx->opcode));
11262 int imm = ZIMM(ctx->opcode, 0, 7);
11264 imm = (imm == 0x7f ? -1 : imm);
11265 tcg_gen_movi_tl(cpu_gpr[reg], imm);
11267 break;
11268 case RES_20:
11269 case RES_28:
11270 case RES_29:
11271 case RES_30:
11272 case RES_31:
11273 case RES_38:
11274 case RES_39:
11275 generate_exception(ctx, EXCP_RI);
11276 break;
11277 default:
11278 decode_micromips32_opc (env, ctx, op, is_branch);
11279 return 4;
11282 return 2;
11285 /* SmartMIPS extension to MIPS32 */
11287 #if defined(TARGET_MIPS64)
11289 /* MDMX extension to MIPS64 */
11291 #endif
11293 static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11295 int32_t offset;
11296 int rs, rt, rd, sa;
11297 uint32_t op, op1, op2;
11298 int16_t imm;
11300 /* make sure instructions are on a word boundary */
11301 if (ctx->pc & 0x3) {
11302 env->CP0_BadVAddr = ctx->pc;
11303 generate_exception(ctx, EXCP_AdEL);
11304 return;
11307 /* Handle blikely not taken case */
11308 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11309 int l1 = gen_new_label();
11311 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11312 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11313 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11314 gen_goto_tb(ctx, 1, ctx->pc + 4);
11315 gen_set_label(l1);
11318 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11319 tcg_gen_debug_insn_start(ctx->pc);
11321 op = MASK_OP_MAJOR(ctx->opcode);
11322 rs = (ctx->opcode >> 21) & 0x1f;
11323 rt = (ctx->opcode >> 16) & 0x1f;
11324 rd = (ctx->opcode >> 11) & 0x1f;
11325 sa = (ctx->opcode >> 6) & 0x1f;
11326 imm = (int16_t)ctx->opcode;
11327 switch (op) {
11328 case OPC_SPECIAL:
11329 op1 = MASK_SPECIAL(ctx->opcode);
11330 switch (op1) {
11331 case OPC_SLL: /* Shift with immediate */
11332 case OPC_SRA:
11333 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11334 break;
11335 case OPC_SRL:
11336 switch ((ctx->opcode >> 21) & 0x1f) {
11337 case 1:
11338 /* rotr is decoded as srl on non-R2 CPUs */
11339 if (env->insn_flags & ISA_MIPS32R2) {
11340 op1 = OPC_ROTR;
11342 /* Fallthrough */
11343 case 0:
11344 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11345 break;
11346 default:
11347 generate_exception(ctx, EXCP_RI);
11348 break;
11350 break;
11351 case OPC_MOVN: /* Conditional move */
11352 case OPC_MOVZ:
11353 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11354 INSN_LOONGSON2E | INSN_LOONGSON2F);
11355 gen_cond_move(env, op1, rd, rs, rt);
11356 break;
11357 case OPC_ADD ... OPC_SUBU:
11358 gen_arith(env, ctx, op1, rd, rs, rt);
11359 break;
11360 case OPC_SLLV: /* Shifts */
11361 case OPC_SRAV:
11362 gen_shift(env, ctx, op1, rd, rs, rt);
11363 break;
11364 case OPC_SRLV:
11365 switch ((ctx->opcode >> 6) & 0x1f) {
11366 case 1:
11367 /* rotrv is decoded as srlv on non-R2 CPUs */
11368 if (env->insn_flags & ISA_MIPS32R2) {
11369 op1 = OPC_ROTRV;
11371 /* Fallthrough */
11372 case 0:
11373 gen_shift(env, ctx, op1, rd, rs, rt);
11374 break;
11375 default:
11376 generate_exception(ctx, EXCP_RI);
11377 break;
11379 break;
11380 case OPC_SLT: /* Set on less than */
11381 case OPC_SLTU:
11382 gen_slt(env, op1, rd, rs, rt);
11383 break;
11384 case OPC_AND: /* Logic*/
11385 case OPC_OR:
11386 case OPC_NOR:
11387 case OPC_XOR:
11388 gen_logic(env, op1, rd, rs, rt);
11389 break;
11390 case OPC_MULT ... OPC_DIVU:
11391 if (sa) {
11392 check_insn(env, ctx, INSN_VR54XX);
11393 op1 = MASK_MUL_VR54XX(ctx->opcode);
11394 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11395 } else
11396 gen_muldiv(ctx, op1, rs, rt);
11397 break;
11398 case OPC_JR ... OPC_JALR:
11399 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11400 *is_branch = 1;
11401 break;
11402 case OPC_TGE ... OPC_TEQ: /* Traps */
11403 case OPC_TNE:
11404 gen_trap(ctx, op1, rs, rt, -1);
11405 break;
11406 case OPC_MFHI: /* Move from HI/LO */
11407 case OPC_MFLO:
11408 gen_HILO(ctx, op1, rd);
11409 break;
11410 case OPC_MTHI:
11411 case OPC_MTLO: /* Move to HI/LO */
11412 gen_HILO(ctx, op1, rs);
11413 break;
11414 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
11415 #ifdef MIPS_STRICT_STANDARD
11416 MIPS_INVAL("PMON / selsl");
11417 generate_exception(ctx, EXCP_RI);
11418 #else
11419 gen_helper_0i(pmon, sa);
11420 #endif
11421 break;
11422 case OPC_SYSCALL:
11423 generate_exception(ctx, EXCP_SYSCALL);
11424 ctx->bstate = BS_STOP;
11425 break;
11426 case OPC_BREAK:
11427 generate_exception(ctx, EXCP_BREAK);
11428 break;
11429 case OPC_SPIM:
11430 #ifdef MIPS_STRICT_STANDARD
11431 MIPS_INVAL("SPIM");
11432 generate_exception(ctx, EXCP_RI);
11433 #else
11434 /* Implemented as RI exception for now. */
11435 MIPS_INVAL("spim (unofficial)");
11436 generate_exception(ctx, EXCP_RI);
11437 #endif
11438 break;
11439 case OPC_SYNC:
11440 /* Treat as NOP. */
11441 break;
11443 case OPC_MOVCI:
11444 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11445 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11446 check_cp1_enabled(ctx);
11447 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11448 (ctx->opcode >> 16) & 1);
11449 } else {
11450 generate_exception_err(ctx, EXCP_CpU, 1);
11452 break;
11454 #if defined(TARGET_MIPS64)
11455 /* MIPS64 specific opcodes */
11456 case OPC_DSLL:
11457 case OPC_DSRA:
11458 case OPC_DSLL32:
11459 case OPC_DSRA32:
11460 check_insn(env, ctx, ISA_MIPS3);
11461 check_mips_64(ctx);
11462 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11463 break;
11464 case OPC_DSRL:
11465 switch ((ctx->opcode >> 21) & 0x1f) {
11466 case 1:
11467 /* drotr is decoded as dsrl on non-R2 CPUs */
11468 if (env->insn_flags & ISA_MIPS32R2) {
11469 op1 = OPC_DROTR;
11471 /* Fallthrough */
11472 case 0:
11473 check_insn(env, ctx, ISA_MIPS3);
11474 check_mips_64(ctx);
11475 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11476 break;
11477 default:
11478 generate_exception(ctx, EXCP_RI);
11479 break;
11481 break;
11482 case OPC_DSRL32:
11483 switch ((ctx->opcode >> 21) & 0x1f) {
11484 case 1:
11485 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11486 if (env->insn_flags & ISA_MIPS32R2) {
11487 op1 = OPC_DROTR32;
11489 /* Fallthrough */
11490 case 0:
11491 check_insn(env, ctx, ISA_MIPS3);
11492 check_mips_64(ctx);
11493 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11494 break;
11495 default:
11496 generate_exception(ctx, EXCP_RI);
11497 break;
11499 break;
11500 case OPC_DADD ... OPC_DSUBU:
11501 check_insn(env, ctx, ISA_MIPS3);
11502 check_mips_64(ctx);
11503 gen_arith(env, ctx, op1, rd, rs, rt);
11504 break;
11505 case OPC_DSLLV:
11506 case OPC_DSRAV:
11507 check_insn(env, ctx, ISA_MIPS3);
11508 check_mips_64(ctx);
11509 gen_shift(env, ctx, op1, rd, rs, rt);
11510 break;
11511 case OPC_DSRLV:
11512 switch ((ctx->opcode >> 6) & 0x1f) {
11513 case 1:
11514 /* drotrv is decoded as dsrlv on non-R2 CPUs */
11515 if (env->insn_flags & ISA_MIPS32R2) {
11516 op1 = OPC_DROTRV;
11518 /* Fallthrough */
11519 case 0:
11520 check_insn(env, ctx, ISA_MIPS3);
11521 check_mips_64(ctx);
11522 gen_shift(env, ctx, op1, rd, rs, rt);
11523 break;
11524 default:
11525 generate_exception(ctx, EXCP_RI);
11526 break;
11528 break;
11529 case OPC_DMULT ... OPC_DDIVU:
11530 check_insn(env, ctx, ISA_MIPS3);
11531 check_mips_64(ctx);
11532 gen_muldiv(ctx, op1, rs, rt);
11533 break;
11534 #endif
11535 default: /* Invalid */
11536 MIPS_INVAL("special");
11537 generate_exception(ctx, EXCP_RI);
11538 break;
11540 break;
11541 case OPC_SPECIAL2:
11542 op1 = MASK_SPECIAL2(ctx->opcode);
11543 switch (op1) {
11544 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11545 case OPC_MSUB ... OPC_MSUBU:
11546 check_insn(env, ctx, ISA_MIPS32);
11547 gen_muldiv(ctx, op1, rs, rt);
11548 break;
11549 case OPC_MUL:
11550 gen_arith(env, ctx, op1, rd, rs, rt);
11551 break;
11552 case OPC_CLO:
11553 case OPC_CLZ:
11554 check_insn(env, ctx, ISA_MIPS32);
11555 gen_cl(ctx, op1, rd, rs);
11556 break;
11557 case OPC_SDBBP:
11558 /* XXX: not clear which exception should be raised
11559 * when in debug mode...
11561 check_insn(env, ctx, ISA_MIPS32);
11562 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11563 generate_exception(ctx, EXCP_DBp);
11564 } else {
11565 generate_exception(ctx, EXCP_DBp);
11567 /* Treat as NOP. */
11568 break;
11569 #if defined(TARGET_MIPS64)
11570 case OPC_DCLO:
11571 case OPC_DCLZ:
11572 check_insn(env, ctx, ISA_MIPS64);
11573 check_mips_64(ctx);
11574 gen_cl(ctx, op1, rd, rs);
11575 break;
11576 #endif
11577 default: /* Invalid */
11578 MIPS_INVAL("special2");
11579 generate_exception(ctx, EXCP_RI);
11580 break;
11582 break;
11583 case OPC_SPECIAL3:
11584 op1 = MASK_SPECIAL3(ctx->opcode);
11585 switch (op1) {
11586 case OPC_EXT:
11587 case OPC_INS:
11588 check_insn(env, ctx, ISA_MIPS32R2);
11589 gen_bitops(ctx, op1, rt, rs, sa, rd);
11590 break;
11591 case OPC_BSHFL:
11592 check_insn(env, ctx, ISA_MIPS32R2);
11593 op2 = MASK_BSHFL(ctx->opcode);
11594 gen_bshfl(ctx, op2, rt, rd);
11595 break;
11596 case OPC_RDHWR:
11597 gen_rdhwr(env, ctx, rt, rd);
11598 break;
11599 case OPC_FORK:
11600 check_insn(env, ctx, ASE_MT);
11602 TCGv t0 = tcg_temp_new();
11603 TCGv t1 = tcg_temp_new();
11605 gen_load_gpr(t0, rt);
11606 gen_load_gpr(t1, rs);
11607 gen_helper_fork(t0, t1);
11608 tcg_temp_free(t0);
11609 tcg_temp_free(t1);
11611 break;
11612 case OPC_YIELD:
11613 check_insn(env, ctx, ASE_MT);
11615 TCGv t0 = tcg_temp_new();
11617 save_cpu_state(ctx, 1);
11618 gen_load_gpr(t0, rs);
11619 gen_helper_yield(t0, t0);
11620 gen_store_gpr(t0, rd);
11621 tcg_temp_free(t0);
11623 break;
11624 #if defined(TARGET_MIPS64)
11625 case OPC_DEXTM ... OPC_DEXT:
11626 case OPC_DINSM ... OPC_DINS:
11627 check_insn(env, ctx, ISA_MIPS64R2);
11628 check_mips_64(ctx);
11629 gen_bitops(ctx, op1, rt, rs, sa, rd);
11630 break;
11631 case OPC_DBSHFL:
11632 check_insn(env, ctx, ISA_MIPS64R2);
11633 check_mips_64(ctx);
11634 op2 = MASK_DBSHFL(ctx->opcode);
11635 gen_bshfl(ctx, op2, rt, rd);
11636 break;
11637 #endif
11638 default: /* Invalid */
11639 MIPS_INVAL("special3");
11640 generate_exception(ctx, EXCP_RI);
11641 break;
11643 break;
11644 case OPC_REGIMM:
11645 op1 = MASK_REGIMM(ctx->opcode);
11646 switch (op1) {
11647 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
11648 case OPC_BLTZAL ... OPC_BGEZALL:
11649 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
11650 *is_branch = 1;
11651 break;
11652 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
11653 case OPC_TNEI:
11654 gen_trap(ctx, op1, rs, -1, imm);
11655 break;
11656 case OPC_SYNCI:
11657 check_insn(env, ctx, ISA_MIPS32R2);
11658 /* Treat as NOP. */
11659 break;
11660 default: /* Invalid */
11661 MIPS_INVAL("regimm");
11662 generate_exception(ctx, EXCP_RI);
11663 break;
11665 break;
11666 case OPC_CP0:
11667 check_cp0_enabled(ctx);
11668 op1 = MASK_CP0(ctx->opcode);
11669 switch (op1) {
11670 case OPC_MFC0:
11671 case OPC_MTC0:
11672 case OPC_MFTR:
11673 case OPC_MTTR:
11674 #if defined(TARGET_MIPS64)
11675 case OPC_DMFC0:
11676 case OPC_DMTC0:
11677 #endif
11678 #ifndef CONFIG_USER_ONLY
11679 gen_cp0(env, ctx, op1, rt, rd);
11680 #endif /* !CONFIG_USER_ONLY */
11681 break;
11682 case OPC_C0_FIRST ... OPC_C0_LAST:
11683 #ifndef CONFIG_USER_ONLY
11684 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
11685 #endif /* !CONFIG_USER_ONLY */
11686 break;
11687 case OPC_MFMC0:
11688 #ifndef CONFIG_USER_ONLY
11690 TCGv t0 = tcg_temp_new();
11692 op2 = MASK_MFMC0(ctx->opcode);
11693 switch (op2) {
11694 case OPC_DMT:
11695 check_insn(env, ctx, ASE_MT);
11696 gen_helper_dmt(t0, t0);
11697 gen_store_gpr(t0, rt);
11698 break;
11699 case OPC_EMT:
11700 check_insn(env, ctx, ASE_MT);
11701 gen_helper_emt(t0, t0);
11702 gen_store_gpr(t0, rt);
11703 break;
11704 case OPC_DVPE:
11705 check_insn(env, ctx, ASE_MT);
11706 gen_helper_dvpe(t0, t0);
11707 gen_store_gpr(t0, rt);
11708 break;
11709 case OPC_EVPE:
11710 check_insn(env, ctx, ASE_MT);
11711 gen_helper_evpe(t0, t0);
11712 gen_store_gpr(t0, rt);
11713 break;
11714 case OPC_DI:
11715 check_insn(env, ctx, ISA_MIPS32R2);
11716 save_cpu_state(ctx, 1);
11717 gen_helper_di(t0);
11718 gen_store_gpr(t0, rt);
11719 /* Stop translation as we may have switched the execution mode */
11720 ctx->bstate = BS_STOP;
11721 break;
11722 case OPC_EI:
11723 check_insn(env, ctx, ISA_MIPS32R2);
11724 save_cpu_state(ctx, 1);
11725 gen_helper_ei(t0);
11726 gen_store_gpr(t0, rt);
11727 /* Stop translation as we may have switched the execution mode */
11728 ctx->bstate = BS_STOP;
11729 break;
11730 default: /* Invalid */
11731 MIPS_INVAL("mfmc0");
11732 generate_exception(ctx, EXCP_RI);
11733 break;
11735 tcg_temp_free(t0);
11737 #endif /* !CONFIG_USER_ONLY */
11738 break;
11739 case OPC_RDPGPR:
11740 check_insn(env, ctx, ISA_MIPS32R2);
11741 gen_load_srsgpr(rt, rd);
11742 break;
11743 case OPC_WRPGPR:
11744 check_insn(env, ctx, ISA_MIPS32R2);
11745 gen_store_srsgpr(rt, rd);
11746 break;
11747 default:
11748 MIPS_INVAL("cp0");
11749 generate_exception(ctx, EXCP_RI);
11750 break;
11752 break;
11753 case OPC_ADDI: /* Arithmetic with immediate opcode */
11754 case OPC_ADDIU:
11755 gen_arith_imm(env, ctx, op, rt, rs, imm);
11756 break;
11757 case OPC_SLTI: /* Set on less than with immediate opcode */
11758 case OPC_SLTIU:
11759 gen_slt_imm(env, op, rt, rs, imm);
11760 break;
11761 case OPC_ANDI: /* Arithmetic with immediate opcode */
11762 case OPC_LUI:
11763 case OPC_ORI:
11764 case OPC_XORI:
11765 gen_logic_imm(env, op, rt, rs, imm);
11766 break;
11767 case OPC_J ... OPC_JAL: /* Jump */
11768 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11769 gen_compute_branch(ctx, op, 4, rs, rt, offset);
11770 *is_branch = 1;
11771 break;
11772 case OPC_BEQ ... OPC_BGTZ: /* Branch */
11773 case OPC_BEQL ... OPC_BGTZL:
11774 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
11775 *is_branch = 1;
11776 break;
11777 case OPC_LB ... OPC_LWR: /* Load and stores */
11778 case OPC_SB ... OPC_SW:
11779 case OPC_SWR:
11780 case OPC_LL:
11781 gen_ldst(ctx, op, rt, rs, imm);
11782 break;
11783 case OPC_SC:
11784 gen_st_cond(ctx, op, rt, rs, imm);
11785 break;
11786 case OPC_CACHE:
11787 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
11788 /* Treat as NOP. */
11789 break;
11790 case OPC_PREF:
11791 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11792 /* Treat as NOP. */
11793 break;
11795 /* Floating point (COP1). */
11796 case OPC_LWC1:
11797 case OPC_LDC1:
11798 case OPC_SWC1:
11799 case OPC_SDC1:
11800 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
11801 break;
11803 case OPC_CP1:
11804 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11805 check_cp1_enabled(ctx);
11806 op1 = MASK_CP1(ctx->opcode);
11807 switch (op1) {
11808 case OPC_MFHC1:
11809 case OPC_MTHC1:
11810 check_insn(env, ctx, ISA_MIPS32R2);
11811 case OPC_MFC1:
11812 case OPC_CFC1:
11813 case OPC_MTC1:
11814 case OPC_CTC1:
11815 gen_cp1(ctx, op1, rt, rd);
11816 break;
11817 #if defined(TARGET_MIPS64)
11818 case OPC_DMFC1:
11819 case OPC_DMTC1:
11820 check_insn(env, ctx, ISA_MIPS3);
11821 gen_cp1(ctx, op1, rt, rd);
11822 break;
11823 #endif
11824 case OPC_BC1ANY2:
11825 case OPC_BC1ANY4:
11826 check_cop1x(ctx);
11827 check_insn(env, ctx, ASE_MIPS3D);
11828 /* fall through */
11829 case OPC_BC1:
11830 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
11831 (rt >> 2) & 0x7, imm << 2);
11832 *is_branch = 1;
11833 break;
11834 case OPC_S_FMT:
11835 case OPC_D_FMT:
11836 case OPC_W_FMT:
11837 case OPC_L_FMT:
11838 case OPC_PS_FMT:
11839 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
11840 (imm >> 8) & 0x7);
11841 break;
11842 default:
11843 MIPS_INVAL("cp1");
11844 generate_exception (ctx, EXCP_RI);
11845 break;
11847 } else {
11848 generate_exception_err(ctx, EXCP_CpU, 1);
11850 break;
11852 /* COP2. */
11853 case OPC_LWC2:
11854 case OPC_LDC2:
11855 case OPC_SWC2:
11856 case OPC_SDC2:
11857 case OPC_CP2:
11858 /* COP2: Not implemented. */
11859 generate_exception_err(ctx, EXCP_CpU, 2);
11860 break;
11862 case OPC_CP3:
11863 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11864 check_cp1_enabled(ctx);
11865 op1 = MASK_CP3(ctx->opcode);
11866 switch (op1) {
11867 case OPC_LWXC1:
11868 case OPC_LDXC1:
11869 case OPC_LUXC1:
11870 case OPC_SWXC1:
11871 case OPC_SDXC1:
11872 case OPC_SUXC1:
11873 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
11874 break;
11875 case OPC_PREFX:
11876 /* Treat as NOP. */
11877 break;
11878 case OPC_ALNV_PS:
11879 case OPC_MADD_S:
11880 case OPC_MADD_D:
11881 case OPC_MADD_PS:
11882 case OPC_MSUB_S:
11883 case OPC_MSUB_D:
11884 case OPC_MSUB_PS:
11885 case OPC_NMADD_S:
11886 case OPC_NMADD_D:
11887 case OPC_NMADD_PS:
11888 case OPC_NMSUB_S:
11889 case OPC_NMSUB_D:
11890 case OPC_NMSUB_PS:
11891 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
11892 break;
11893 default:
11894 MIPS_INVAL("cp3");
11895 generate_exception (ctx, EXCP_RI);
11896 break;
11898 } else {
11899 generate_exception_err(ctx, EXCP_CpU, 1);
11901 break;
11903 #if defined(TARGET_MIPS64)
11904 /* MIPS64 opcodes */
11905 case OPC_LWU:
11906 case OPC_LDL ... OPC_LDR:
11907 case OPC_SDL ... OPC_SDR:
11908 case OPC_LLD:
11909 case OPC_LD:
11910 case OPC_SD:
11911 check_insn(env, ctx, ISA_MIPS3);
11912 check_mips_64(ctx);
11913 gen_ldst(ctx, op, rt, rs, imm);
11914 break;
11915 case OPC_SCD:
11916 check_insn(env, ctx, ISA_MIPS3);
11917 check_mips_64(ctx);
11918 gen_st_cond(ctx, op, rt, rs, imm);
11919 break;
11920 case OPC_DADDI:
11921 case OPC_DADDIU:
11922 check_insn(env, ctx, ISA_MIPS3);
11923 check_mips_64(ctx);
11924 gen_arith_imm(env, ctx, op, rt, rs, imm);
11925 break;
11926 #endif
11927 case OPC_JALX:
11928 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
11929 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11930 gen_compute_branch(ctx, op, 4, rs, rt, offset);
11931 *is_branch = 1;
11932 break;
11933 case OPC_MDMX:
11934 check_insn(env, ctx, ASE_MDMX);
11935 /* MDMX: Not implemented. */
11936 default: /* Invalid */
11937 MIPS_INVAL("major opcode");
11938 generate_exception(ctx, EXCP_RI);
11939 break;
11943 static inline void
11944 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
11945 int search_pc)
11947 DisasContext ctx;
11948 target_ulong pc_start;
11949 uint16_t *gen_opc_end;
11950 CPUBreakpoint *bp;
11951 int j, lj = -1;
11952 int num_insns;
11953 int max_insns;
11954 int insn_bytes;
11955 int is_branch;
11957 if (search_pc)
11958 qemu_log("search pc %d\n", search_pc);
11960 pc_start = tb->pc;
11961 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
11962 ctx.pc = pc_start;
11963 ctx.saved_pc = -1;
11964 ctx.singlestep_enabled = env->singlestep_enabled;
11965 ctx.tb = tb;
11966 ctx.bstate = BS_NONE;
11967 /* Restore delay slot state from the tb context. */
11968 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
11969 restore_cpu_state(env, &ctx);
11970 #ifdef CONFIG_USER_ONLY
11971 ctx.mem_idx = MIPS_HFLAG_UM;
11972 #else
11973 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
11974 #endif
11975 num_insns = 0;
11976 max_insns = tb->cflags & CF_COUNT_MASK;
11977 if (max_insns == 0)
11978 max_insns = CF_COUNT_MASK;
11979 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
11980 gen_icount_start();
11981 while (ctx.bstate == BS_NONE) {
11982 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
11983 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
11984 if (bp->pc == ctx.pc) {
11985 save_cpu_state(&ctx, 1);
11986 ctx.bstate = BS_BRANCH;
11987 gen_helper_0i(raise_exception, EXCP_DEBUG);
11988 /* Include the breakpoint location or the tb won't
11989 * be flushed when it must be. */
11990 ctx.pc += 4;
11991 goto done_generating;
11996 if (search_pc) {
11997 j = gen_opc_ptr - gen_opc_buf;
11998 if (lj < j) {
11999 lj++;
12000 while (lj < j)
12001 gen_opc_instr_start[lj++] = 0;
12003 gen_opc_pc[lj] = ctx.pc;
12004 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12005 gen_opc_instr_start[lj] = 1;
12006 gen_opc_icount[lj] = num_insns;
12008 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12009 gen_io_start();
12011 is_branch = 0;
12012 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12013 ctx.opcode = ldl_code(ctx.pc);
12014 insn_bytes = 4;
12015 decode_opc(env, &ctx, &is_branch);
12016 } else if (env->insn_flags & ASE_MICROMIPS) {
12017 ctx.opcode = lduw_code(ctx.pc);
12018 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12019 } else if (env->insn_flags & ASE_MIPS16) {
12020 ctx.opcode = lduw_code(ctx.pc);
12021 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12022 } else {
12023 generate_exception(&ctx, EXCP_RI);
12024 ctx.bstate = BS_STOP;
12025 break;
12027 if (!is_branch) {
12028 handle_delay_slot(env, &ctx, insn_bytes);
12030 ctx.pc += insn_bytes;
12032 num_insns++;
12034 /* Execute a branch and its delay slot as a single instruction.
12035 This is what GDB expects and is consistent with what the
12036 hardware does (e.g. if a delay slot instruction faults, the
12037 reported PC is the PC of the branch). */
12038 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12039 break;
12041 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12042 break;
12044 if (gen_opc_ptr >= gen_opc_end)
12045 break;
12047 if (num_insns >= max_insns)
12048 break;
12050 if (singlestep)
12051 break;
12053 if (tb->cflags & CF_LAST_IO)
12054 gen_io_end();
12055 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12056 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12057 gen_helper_0i(raise_exception, EXCP_DEBUG);
12058 } else {
12059 switch (ctx.bstate) {
12060 case BS_STOP:
12061 gen_helper_interrupt_restart();
12062 gen_goto_tb(&ctx, 0, ctx.pc);
12063 break;
12064 case BS_NONE:
12065 save_cpu_state(&ctx, 0);
12066 gen_goto_tb(&ctx, 0, ctx.pc);
12067 break;
12068 case BS_EXCP:
12069 gen_helper_interrupt_restart();
12070 tcg_gen_exit_tb(0);
12071 break;
12072 case BS_BRANCH:
12073 default:
12074 break;
12077 done_generating:
12078 gen_icount_end(tb, num_insns);
12079 *gen_opc_ptr = INDEX_op_end;
12080 if (search_pc) {
12081 j = gen_opc_ptr - gen_opc_buf;
12082 lj++;
12083 while (lj <= j)
12084 gen_opc_instr_start[lj++] = 0;
12085 } else {
12086 tb->size = ctx.pc - pc_start;
12087 tb->icount = num_insns;
12089 #ifdef DEBUG_DISAS
12090 LOG_DISAS("\n");
12091 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12092 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12093 log_target_disas(pc_start, ctx.pc - pc_start, 0);
12094 qemu_log("\n");
12096 #endif
12099 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
12101 gen_intermediate_code_internal(env, tb, 0);
12104 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
12106 gen_intermediate_code_internal(env, tb, 1);
12109 static void fpu_dump_state(CPUState *env, FILE *f,
12110 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
12111 int flags)
12113 int i;
12114 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12116 #define printfpr(fp) \
12117 do { \
12118 if (is_fpu64) \
12119 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12120 " fd:%13g fs:%13g psu: %13g\n", \
12121 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
12122 (double)(fp)->fd, \
12123 (double)(fp)->fs[FP_ENDIAN_IDX], \
12124 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
12125 else { \
12126 fpr_t tmp; \
12127 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
12128 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
12129 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12130 " fd:%13g fs:%13g psu:%13g\n", \
12131 tmp.w[FP_ENDIAN_IDX], tmp.d, \
12132 (double)tmp.fd, \
12133 (double)tmp.fs[FP_ENDIAN_IDX], \
12134 (double)tmp.fs[!FP_ENDIAN_IDX]); \
12136 } while(0)
12139 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
12140 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
12141 get_float_exception_flags(&env->active_fpu.fp_status));
12142 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12143 fpu_fprintf(f, "%3s: ", fregnames[i]);
12144 printfpr(&env->active_fpu.fpr[i]);
12147 #undef printfpr
12150 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12151 /* Debug help: The architecture requires 32bit code to maintain proper
12152 sign-extended values on 64bit machines. */
12154 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12156 static void
12157 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
12158 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
12159 int flags)
12161 int i;
12163 if (!SIGN_EXT_P(env->active_tc.PC))
12164 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12165 if (!SIGN_EXT_P(env->active_tc.HI[0]))
12166 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12167 if (!SIGN_EXT_P(env->active_tc.LO[0]))
12168 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12169 if (!SIGN_EXT_P(env->btarget))
12170 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12172 for (i = 0; i < 32; i++) {
12173 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12174 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12177 if (!SIGN_EXT_P(env->CP0_EPC))
12178 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12179 if (!SIGN_EXT_P(env->lladdr))
12180 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12182 #endif
12184 void cpu_dump_state (CPUState *env, FILE *f,
12185 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
12186 int flags)
12188 int i;
12190 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12191 " LO=0x" TARGET_FMT_lx " ds %04x "
12192 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12193 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12194 env->hflags, env->btarget, env->bcond);
12195 for (i = 0; i < 32; i++) {
12196 if ((i & 3) == 0)
12197 cpu_fprintf(f, "GPR%02d:", i);
12198 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12199 if ((i & 3) == 3)
12200 cpu_fprintf(f, "\n");
12203 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
12204 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12205 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12206 env->CP0_Config0, env->CP0_Config1, env->lladdr);
12207 if (env->hflags & MIPS_HFLAG_FPU)
12208 fpu_dump_state(env, f, cpu_fprintf, flags);
12209 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12210 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12211 #endif
12214 static void mips_tcg_init(void)
12216 int i;
12217 static int inited;
12219 /* Initialize various static tables. */
12220 if (inited)
12221 return;
12223 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12224 TCGV_UNUSED(cpu_gpr[0]);
12225 for (i = 1; i < 32; i++)
12226 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12227 offsetof(CPUState, active_tc.gpr[i]),
12228 regnames[i]);
12229 cpu_PC = tcg_global_mem_new(TCG_AREG0,
12230 offsetof(CPUState, active_tc.PC), "PC");
12231 for (i = 0; i < MIPS_DSP_ACC; i++) {
12232 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12233 offsetof(CPUState, active_tc.HI[i]),
12234 regnames_HI[i]);
12235 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12236 offsetof(CPUState, active_tc.LO[i]),
12237 regnames_LO[i]);
12238 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12239 offsetof(CPUState, active_tc.ACX[i]),
12240 regnames_ACX[i]);
12242 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12243 offsetof(CPUState, active_tc.DSPControl),
12244 "DSPControl");
12245 bcond = tcg_global_mem_new(TCG_AREG0,
12246 offsetof(CPUState, bcond), "bcond");
12247 btarget = tcg_global_mem_new(TCG_AREG0,
12248 offsetof(CPUState, btarget), "btarget");
12249 hflags = tcg_global_mem_new_i32(TCG_AREG0,
12250 offsetof(CPUState, hflags), "hflags");
12252 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12253 offsetof(CPUState, active_fpu.fcr0),
12254 "fcr0");
12255 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12256 offsetof(CPUState, active_fpu.fcr31),
12257 "fcr31");
12259 /* register helpers */
12260 #define GEN_HELPER 2
12261 #include "helper.h"
12263 inited = 1;
12266 #include "translate_init.c"
12268 CPUMIPSState *cpu_mips_init (const char *cpu_model)
12270 CPUMIPSState *env;
12271 const mips_def_t *def;
12273 def = cpu_mips_find_by_name(cpu_model);
12274 if (!def)
12275 return NULL;
12276 env = qemu_mallocz(sizeof(CPUMIPSState));
12277 env->cpu_model = def;
12278 env->cpu_model_str = cpu_model;
12280 cpu_exec_init(env);
12281 #ifndef CONFIG_USER_ONLY
12282 mmu_init(env, def);
12283 #endif
12284 fpu_init(env, def);
12285 mvp_init(env, def);
12286 mips_tcg_init();
12287 cpu_reset(env);
12288 qemu_init_vcpu(env);
12289 return env;
12292 void cpu_reset (CPUMIPSState *env)
12294 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12295 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12296 log_cpu_state(env, 0);
12299 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12300 tlb_flush(env, 1);
12302 /* Reset registers to their default values */
12303 env->CP0_PRid = env->cpu_model->CP0_PRid;
12304 env->CP0_Config0 = env->cpu_model->CP0_Config0;
12305 #ifdef TARGET_WORDS_BIGENDIAN
12306 env->CP0_Config0 |= (1 << CP0C0_BE);
12307 #endif
12308 env->CP0_Config1 = env->cpu_model->CP0_Config1;
12309 env->CP0_Config2 = env->cpu_model->CP0_Config2;
12310 env->CP0_Config3 = env->cpu_model->CP0_Config3;
12311 env->CP0_Config6 = env->cpu_model->CP0_Config6;
12312 env->CP0_Config7 = env->cpu_model->CP0_Config7;
12313 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12314 << env->cpu_model->CP0_LLAddr_shift;
12315 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12316 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12317 env->CCRes = env->cpu_model->CCRes;
12318 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12319 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12320 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12321 env->current_tc = 0;
12322 env->SEGBITS = env->cpu_model->SEGBITS;
12323 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12324 #if defined(TARGET_MIPS64)
12325 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12326 env->SEGMask |= 3ULL << 62;
12328 #endif
12329 env->PABITS = env->cpu_model->PABITS;
12330 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12331 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12332 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12333 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12334 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12335 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12336 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12337 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12338 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12339 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12340 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12341 env->insn_flags = env->cpu_model->insn_flags;
12343 #if defined(CONFIG_USER_ONLY)
12344 env->hflags = MIPS_HFLAG_UM;
12345 /* Enable access to the SYNCI_Step register. */
12346 env->CP0_HWREna |= (1 << 1);
12347 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12348 env->hflags |= MIPS_HFLAG_FPU;
12350 #ifdef TARGET_MIPS64
12351 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12352 env->hflags |= MIPS_HFLAG_F64;
12354 #endif
12355 #else
12356 if (env->hflags & MIPS_HFLAG_BMASK) {
12357 /* If the exception was raised from a delay slot,
12358 come back to the jump. */
12359 env->CP0_ErrorEPC = env->active_tc.PC - 4;
12360 } else {
12361 env->CP0_ErrorEPC = env->active_tc.PC;
12363 env->active_tc.PC = (int32_t)0xBFC00000;
12364 env->CP0_Random = env->tlb->nb_tlb - 1;
12365 env->tlb->tlb_in_use = env->tlb->nb_tlb;
12366 env->CP0_Wired = 0;
12367 /* SMP not implemented */
12368 env->CP0_EBase = 0x80000000;
12369 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12370 /* vectored interrupts not implemented, timer on int 7,
12371 no performance counters. */
12372 env->CP0_IntCtl = 0xe0000000;
12374 int i;
12376 for (i = 0; i < 7; i++) {
12377 env->CP0_WatchLo[i] = 0;
12378 env->CP0_WatchHi[i] = 0x80000000;
12380 env->CP0_WatchLo[7] = 0;
12381 env->CP0_WatchHi[7] = 0;
12383 /* Count register increments in debug mode, EJTAG version 1 */
12384 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12385 env->hflags = MIPS_HFLAG_CP0;
12386 #endif
12387 #if defined(TARGET_MIPS64)
12388 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12389 env->hflags |= MIPS_HFLAG_64;
12391 #endif
12392 env->exception_index = EXCP_NONE;
12395 void gen_pc_load(CPUState *env, TranslationBlock *tb,
12396 unsigned long searched_pc, int pc_pos, void *puc)
12398 env->active_tc.PC = gen_opc_pc[pc_pos];
12399 env->hflags &= ~MIPS_HFLAG_BMASK;
12400 env->hflags |= gen_opc_hflags[pc_pos];