virtio-net: Introduce a new bottom half packet TX
[qemu/mdroth.git] / target-mips / translate.c
blob20b66a8a51bd0ac97146d8758bbb46873b55e086
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 /* Loongson 2F */
271 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
272 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
273 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
274 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
275 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
276 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
277 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
278 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
279 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
280 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
281 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
282 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
283 /* Misc */
284 OPC_CLZ = 0x20 | OPC_SPECIAL2,
285 OPC_CLO = 0x21 | OPC_SPECIAL2,
286 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
287 OPC_DCLO = 0x25 | OPC_SPECIAL2,
288 /* Special */
289 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
292 /* Special3 opcodes */
293 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
295 enum {
296 OPC_EXT = 0x00 | OPC_SPECIAL3,
297 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
298 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
299 OPC_DEXT = 0x03 | OPC_SPECIAL3,
300 OPC_INS = 0x04 | OPC_SPECIAL3,
301 OPC_DINSM = 0x05 | OPC_SPECIAL3,
302 OPC_DINSU = 0x06 | OPC_SPECIAL3,
303 OPC_DINS = 0x07 | OPC_SPECIAL3,
304 OPC_FORK = 0x08 | OPC_SPECIAL3,
305 OPC_YIELD = 0x09 | OPC_SPECIAL3,
306 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
307 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
308 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
310 /* Loongson 2E */
311 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
312 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
313 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
314 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
315 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
316 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
317 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
318 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
319 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
320 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
321 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
322 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
325 /* BSHFL opcodes */
326 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
328 enum {
329 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
330 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
331 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
334 /* DBSHFL opcodes */
335 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
337 enum {
338 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
339 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
342 /* Coprocessor 0 (rs field) */
343 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
345 enum {
346 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
347 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
348 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
349 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
350 OPC_MFTR = (0x08 << 21) | OPC_CP0,
351 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
352 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
353 OPC_MTTR = (0x0C << 21) | OPC_CP0,
354 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
355 OPC_C0 = (0x10 << 21) | OPC_CP0,
356 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
357 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
360 /* MFMC0 opcodes */
361 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
363 enum {
364 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
365 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
366 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
367 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
368 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
369 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
372 /* Coprocessor 0 (with rs == C0) */
373 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
375 enum {
376 OPC_TLBR = 0x01 | OPC_C0,
377 OPC_TLBWI = 0x02 | OPC_C0,
378 OPC_TLBWR = 0x06 | OPC_C0,
379 OPC_TLBP = 0x08 | OPC_C0,
380 OPC_RFE = 0x10 | OPC_C0,
381 OPC_ERET = 0x18 | OPC_C0,
382 OPC_DERET = 0x1F | OPC_C0,
383 OPC_WAIT = 0x20 | OPC_C0,
386 /* Coprocessor 1 (rs field) */
387 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
389 /* Values for the fmt field in FP instructions */
390 enum {
391 /* 0 - 15 are reserved */
392 FMT_S = 16, /* single fp */
393 FMT_D = 17, /* double fp */
394 FMT_E = 18, /* extended fp */
395 FMT_Q = 19, /* quad fp */
396 FMT_W = 20, /* 32-bit fixed */
397 FMT_L = 21, /* 64-bit fixed */
398 FMT_PS = 22, /* paired single fp */
399 /* 23 - 31 are reserved */
402 enum {
403 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
404 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
405 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
406 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
407 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
408 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
409 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
410 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
411 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
412 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
413 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
414 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
415 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
416 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
417 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
418 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
419 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
420 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
423 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
424 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
426 enum {
427 OPC_BC1F = (0x00 << 16) | OPC_BC1,
428 OPC_BC1T = (0x01 << 16) | OPC_BC1,
429 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
430 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
433 enum {
434 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
435 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
438 enum {
439 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
440 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
443 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
445 enum {
446 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
447 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
448 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
449 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
450 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
451 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
452 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
453 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
454 OPC_BC2 = (0x08 << 21) | OPC_CP2,
457 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
459 enum {
460 OPC_LWXC1 = 0x00 | OPC_CP3,
461 OPC_LDXC1 = 0x01 | OPC_CP3,
462 OPC_LUXC1 = 0x05 | OPC_CP3,
463 OPC_SWXC1 = 0x08 | OPC_CP3,
464 OPC_SDXC1 = 0x09 | OPC_CP3,
465 OPC_SUXC1 = 0x0D | OPC_CP3,
466 OPC_PREFX = 0x0F | OPC_CP3,
467 OPC_ALNV_PS = 0x1E | OPC_CP3,
468 OPC_MADD_S = 0x20 | OPC_CP3,
469 OPC_MADD_D = 0x21 | OPC_CP3,
470 OPC_MADD_PS = 0x26 | OPC_CP3,
471 OPC_MSUB_S = 0x28 | OPC_CP3,
472 OPC_MSUB_D = 0x29 | OPC_CP3,
473 OPC_MSUB_PS = 0x2E | OPC_CP3,
474 OPC_NMADD_S = 0x30 | OPC_CP3,
475 OPC_NMADD_D = 0x31 | OPC_CP3,
476 OPC_NMADD_PS= 0x36 | OPC_CP3,
477 OPC_NMSUB_S = 0x38 | OPC_CP3,
478 OPC_NMSUB_D = 0x39 | OPC_CP3,
479 OPC_NMSUB_PS= 0x3E | OPC_CP3,
482 /* global register indices */
483 static TCGv_ptr cpu_env;
484 static TCGv cpu_gpr[32], cpu_PC;
485 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
486 static TCGv cpu_dspctrl, btarget, bcond;
487 static TCGv_i32 hflags;
488 static TCGv_i32 fpu_fcr0, fpu_fcr31;
490 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
492 #include "gen-icount.h"
494 #define gen_helper_0i(name, arg) do { \
495 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
496 gen_helper_##name(helper_tmp); \
497 tcg_temp_free_i32(helper_tmp); \
498 } while(0)
500 #define gen_helper_1i(name, arg1, arg2) do { \
501 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
502 gen_helper_##name(arg1, helper_tmp); \
503 tcg_temp_free_i32(helper_tmp); \
504 } while(0)
506 #define gen_helper_2i(name, arg1, arg2, arg3) do { \
507 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
508 gen_helper_##name(arg1, arg2, helper_tmp); \
509 tcg_temp_free_i32(helper_tmp); \
510 } while(0)
512 #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do { \
513 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
514 gen_helper_##name(arg1, arg2, arg3, helper_tmp); \
515 tcg_temp_free_i32(helper_tmp); \
516 } while(0)
518 typedef struct DisasContext {
519 struct TranslationBlock *tb;
520 target_ulong pc, saved_pc;
521 uint32_t opcode;
522 int singlestep_enabled;
523 /* Routine used to access memory */
524 int mem_idx;
525 uint32_t hflags, saved_hflags;
526 int bstate;
527 target_ulong btarget;
528 } DisasContext;
530 enum {
531 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
532 * exception condition */
533 BS_STOP = 1, /* We want to stop translation for any reason */
534 BS_BRANCH = 2, /* We reached a branch condition */
535 BS_EXCP = 3, /* We reached an exception condition */
538 static const char *regnames[] =
539 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
540 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
541 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
542 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
544 static const char *regnames_HI[] =
545 { "HI0", "HI1", "HI2", "HI3", };
547 static const char *regnames_LO[] =
548 { "LO0", "LO1", "LO2", "LO3", };
550 static const char *regnames_ACX[] =
551 { "ACX0", "ACX1", "ACX2", "ACX3", };
553 static const char *fregnames[] =
554 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
555 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
556 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
557 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
559 #ifdef MIPS_DEBUG_DISAS
560 #define MIPS_DEBUG(fmt, ...) \
561 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
562 TARGET_FMT_lx ": %08x " fmt "\n", \
563 ctx->pc, ctx->opcode , ## __VA_ARGS__)
564 #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
565 #else
566 #define MIPS_DEBUG(fmt, ...) do { } while(0)
567 #define LOG_DISAS(...) do { } while (0)
568 #endif
570 #define MIPS_INVAL(op) \
571 do { \
572 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
573 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
574 } while (0)
576 /* General purpose registers moves. */
577 static inline void gen_load_gpr (TCGv t, int reg)
579 if (reg == 0)
580 tcg_gen_movi_tl(t, 0);
581 else
582 tcg_gen_mov_tl(t, cpu_gpr[reg]);
585 static inline void gen_store_gpr (TCGv t, int reg)
587 if (reg != 0)
588 tcg_gen_mov_tl(cpu_gpr[reg], t);
591 /* Moves to/from ACX register. */
592 static inline void gen_load_ACX (TCGv t, int reg)
594 tcg_gen_mov_tl(t, cpu_ACX[reg]);
597 static inline void gen_store_ACX (TCGv t, int reg)
599 tcg_gen_mov_tl(cpu_ACX[reg], t);
602 /* Moves to/from shadow registers. */
603 static inline void gen_load_srsgpr (int from, int to)
605 TCGv t0 = tcg_temp_new();
607 if (from == 0)
608 tcg_gen_movi_tl(t0, 0);
609 else {
610 TCGv_i32 t2 = tcg_temp_new_i32();
611 TCGv_ptr addr = tcg_temp_new_ptr();
613 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
614 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
615 tcg_gen_andi_i32(t2, t2, 0xf);
616 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
617 tcg_gen_ext_i32_ptr(addr, t2);
618 tcg_gen_add_ptr(addr, cpu_env, addr);
620 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
621 tcg_temp_free_ptr(addr);
622 tcg_temp_free_i32(t2);
624 gen_store_gpr(t0, to);
625 tcg_temp_free(t0);
628 static inline void gen_store_srsgpr (int from, int to)
630 if (to != 0) {
631 TCGv t0 = tcg_temp_new();
632 TCGv_i32 t2 = tcg_temp_new_i32();
633 TCGv_ptr addr = tcg_temp_new_ptr();
635 gen_load_gpr(t0, from);
636 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
637 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
638 tcg_gen_andi_i32(t2, t2, 0xf);
639 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
640 tcg_gen_ext_i32_ptr(addr, t2);
641 tcg_gen_add_ptr(addr, cpu_env, addr);
643 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
644 tcg_temp_free_ptr(addr);
645 tcg_temp_free_i32(t2);
646 tcg_temp_free(t0);
650 /* Floating point register moves. */
651 static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
653 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
656 static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
658 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
661 static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
663 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
666 static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
668 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
671 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
673 if (ctx->hflags & MIPS_HFLAG_F64) {
674 tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
675 } else {
676 TCGv_i32 t0 = tcg_temp_new_i32();
677 TCGv_i32 t1 = tcg_temp_new_i32();
678 gen_load_fpr32(t0, reg & ~1);
679 gen_load_fpr32(t1, reg | 1);
680 tcg_gen_concat_i32_i64(t, t0, t1);
681 tcg_temp_free_i32(t0);
682 tcg_temp_free_i32(t1);
686 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
688 if (ctx->hflags & MIPS_HFLAG_F64) {
689 tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
690 } else {
691 TCGv_i64 t0 = tcg_temp_new_i64();
692 TCGv_i32 t1 = tcg_temp_new_i32();
693 tcg_gen_trunc_i64_i32(t1, t);
694 gen_store_fpr32(t1, reg & ~1);
695 tcg_gen_shri_i64(t0, t, 32);
696 tcg_gen_trunc_i64_i32(t1, t0);
697 gen_store_fpr32(t1, reg | 1);
698 tcg_temp_free_i32(t1);
699 tcg_temp_free_i64(t0);
703 static inline int get_fp_bit (int cc)
705 if (cc)
706 return 24 + cc;
707 else
708 return 23;
711 /* Tests */
712 static inline void gen_save_pc(target_ulong pc)
714 tcg_gen_movi_tl(cpu_PC, pc);
717 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
719 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
720 if (do_save_pc && ctx->pc != ctx->saved_pc) {
721 gen_save_pc(ctx->pc);
722 ctx->saved_pc = ctx->pc;
724 if (ctx->hflags != ctx->saved_hflags) {
725 tcg_gen_movi_i32(hflags, ctx->hflags);
726 ctx->saved_hflags = ctx->hflags;
727 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
728 case MIPS_HFLAG_BR:
729 break;
730 case MIPS_HFLAG_BC:
731 case MIPS_HFLAG_BL:
732 case MIPS_HFLAG_B:
733 tcg_gen_movi_tl(btarget, ctx->btarget);
734 break;
739 static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
741 ctx->saved_hflags = ctx->hflags;
742 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
743 case MIPS_HFLAG_BR:
744 break;
745 case MIPS_HFLAG_BC:
746 case MIPS_HFLAG_BL:
747 case MIPS_HFLAG_B:
748 ctx->btarget = env->btarget;
749 break;
753 static inline void
754 generate_exception_err (DisasContext *ctx, int excp, int err)
756 TCGv_i32 texcp = tcg_const_i32(excp);
757 TCGv_i32 terr = tcg_const_i32(err);
758 save_cpu_state(ctx, 1);
759 gen_helper_raise_exception_err(texcp, terr);
760 tcg_temp_free_i32(terr);
761 tcg_temp_free_i32(texcp);
764 static inline void
765 generate_exception (DisasContext *ctx, int excp)
767 save_cpu_state(ctx, 1);
768 gen_helper_0i(raise_exception, excp);
771 /* Addresses computation */
772 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
774 tcg_gen_add_tl(ret, arg0, arg1);
776 #if defined(TARGET_MIPS64)
777 /* For compatibility with 32-bit code, data reference in user mode
778 with Status_UX = 0 should be casted to 32-bit and sign extended.
779 See the MIPS64 PRA manual, section 4.10. */
780 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
781 !(ctx->hflags & MIPS_HFLAG_UX)) {
782 tcg_gen_ext32s_i64(ret, ret);
784 #endif
787 static inline void check_cp0_enabled(DisasContext *ctx)
789 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
790 generate_exception_err(ctx, EXCP_CpU, 0);
793 static inline void check_cp1_enabled(DisasContext *ctx)
795 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
796 generate_exception_err(ctx, EXCP_CpU, 1);
799 /* Verify that the processor is running with COP1X instructions enabled.
800 This is associated with the nabla symbol in the MIPS32 and MIPS64
801 opcode tables. */
803 static inline void check_cop1x(DisasContext *ctx)
805 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
806 generate_exception(ctx, EXCP_RI);
809 /* Verify that the processor is running with 64-bit floating-point
810 operations enabled. */
812 static inline void check_cp1_64bitmode(DisasContext *ctx)
814 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
815 generate_exception(ctx, EXCP_RI);
819 * Verify if floating point register is valid; an operation is not defined
820 * if bit 0 of any register specification is set and the FR bit in the
821 * Status register equals zero, since the register numbers specify an
822 * even-odd pair of adjacent coprocessor general registers. When the FR bit
823 * in the Status register equals one, both even and odd register numbers
824 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
826 * Multiple 64 bit wide registers can be checked by calling
827 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
829 static inline void check_cp1_registers(DisasContext *ctx, int regs)
831 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
832 generate_exception(ctx, EXCP_RI);
835 /* This code generates a "reserved instruction" exception if the
836 CPU does not support the instruction set corresponding to flags. */
837 static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
839 if (unlikely(!(env->insn_flags & flags)))
840 generate_exception(ctx, EXCP_RI);
843 /* This code generates a "reserved instruction" exception if 64-bit
844 instructions are not enabled. */
845 static inline void check_mips_64(DisasContext *ctx)
847 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
848 generate_exception(ctx, EXCP_RI);
851 /* Define small wrappers for gen_load_fpr* so that we have a uniform
852 calling interface for 32 and 64-bit FPRs. No sense in changing
853 all callers for gen_load_fpr32 when we need the CTX parameter for
854 this one use. */
855 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
856 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
857 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
858 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
859 int ft, int fs, int cc) \
861 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
862 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
863 switch (ifmt) { \
864 case FMT_PS: \
865 check_cp1_64bitmode(ctx); \
866 break; \
867 case FMT_D: \
868 if (abs) { \
869 check_cop1x(ctx); \
871 check_cp1_registers(ctx, fs | ft); \
872 break; \
873 case FMT_S: \
874 if (abs) { \
875 check_cop1x(ctx); \
877 break; \
879 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
880 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
881 switch (n) { \
882 case 0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
883 case 1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
884 case 2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
885 case 3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
886 case 4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
887 case 5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
888 case 6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
889 case 7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
890 case 8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
891 case 9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
892 case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
893 case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
894 case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
895 case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
896 case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
897 case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
898 default: abort(); \
900 tcg_temp_free_i##bits (fp0); \
901 tcg_temp_free_i##bits (fp1); \
904 FOP_CONDS(, 0, d, FMT_D, 64)
905 FOP_CONDS(abs, 1, d, FMT_D, 64)
906 FOP_CONDS(, 0, s, FMT_S, 32)
907 FOP_CONDS(abs, 1, s, FMT_S, 32)
908 FOP_CONDS(, 0, ps, FMT_PS, 64)
909 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
910 #undef FOP_CONDS
911 #undef gen_ldcmp_fpr32
912 #undef gen_ldcmp_fpr64
914 /* load/store instructions. */
915 #define OP_LD(insn,fname) \
916 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
918 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
920 OP_LD(lb,ld8s);
921 OP_LD(lbu,ld8u);
922 OP_LD(lh,ld16s);
923 OP_LD(lhu,ld16u);
924 OP_LD(lw,ld32s);
925 #if defined(TARGET_MIPS64)
926 OP_LD(lwu,ld32u);
927 OP_LD(ld,ld64);
928 #endif
929 #undef OP_LD
931 #define OP_ST(insn,fname) \
932 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
934 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
936 OP_ST(sb,st8);
937 OP_ST(sh,st16);
938 OP_ST(sw,st32);
939 #if defined(TARGET_MIPS64)
940 OP_ST(sd,st64);
941 #endif
942 #undef OP_ST
944 #ifdef CONFIG_USER_ONLY
945 #define OP_LD_ATOMIC(insn,fname) \
946 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
948 TCGv t0 = tcg_temp_new(); \
949 tcg_gen_mov_tl(t0, arg1); \
950 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
951 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
952 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval)); \
953 tcg_temp_free(t0); \
955 #else
956 #define OP_LD_ATOMIC(insn,fname) \
957 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
959 gen_helper_2i(insn, ret, arg1, ctx->mem_idx); \
961 #endif
962 OP_LD_ATOMIC(ll,ld32s);
963 #if defined(TARGET_MIPS64)
964 OP_LD_ATOMIC(lld,ld64);
965 #endif
966 #undef OP_LD_ATOMIC
968 #ifdef CONFIG_USER_ONLY
969 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
970 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
972 TCGv t0 = tcg_temp_new(); \
973 int l1 = gen_new_label(); \
974 int l2 = gen_new_label(); \
976 tcg_gen_andi_tl(t0, arg2, almask); \
977 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
978 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
979 generate_exception(ctx, EXCP_AdES); \
980 gen_set_label(l1); \
981 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
982 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
983 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
984 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg)); \
985 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval)); \
986 gen_helper_0i(raise_exception, EXCP_SC); \
987 gen_set_label(l2); \
988 tcg_gen_movi_tl(t0, 0); \
989 gen_store_gpr(t0, rt); \
990 tcg_temp_free(t0); \
992 #else
993 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
994 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
996 TCGv t0 = tcg_temp_new(); \
997 gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx); \
998 gen_store_gpr(t0, rt); \
999 tcg_temp_free(t0); \
1001 #endif
1002 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1003 #if defined(TARGET_MIPS64)
1004 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1005 #endif
1006 #undef OP_ST_ATOMIC
1008 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1009 int base, int16_t offset)
1011 if (base == 0) {
1012 tcg_gen_movi_tl(addr, offset);
1013 } else if (offset == 0) {
1014 gen_load_gpr(addr, base);
1015 } else {
1016 tcg_gen_movi_tl(addr, offset);
1017 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1021 static target_ulong pc_relative_pc (DisasContext *ctx)
1023 target_ulong pc = ctx->pc;
1025 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1026 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1028 pc -= branch_bytes;
1031 pc &= ~(target_ulong)3;
1032 return pc;
1035 /* Load */
1036 static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
1037 int rt, int base, int16_t offset)
1039 const char *opn = "ld";
1040 TCGv t0, t1;
1042 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1043 /* Loongson CPU uses a load to zero register for prefetch.
1044 We emulate it as a NOP. On other CPU we must perform the
1045 actual memory access. */
1046 MIPS_DEBUG("NOP");
1047 return;
1050 t0 = tcg_temp_new();
1051 t1 = tcg_temp_new();
1052 gen_base_offset_addr(ctx, t0, base, offset);
1054 switch (opc) {
1055 #if defined(TARGET_MIPS64)
1056 case OPC_LWU:
1057 save_cpu_state(ctx, 0);
1058 op_ld_lwu(t0, t0, ctx);
1059 gen_store_gpr(t0, rt);
1060 opn = "lwu";
1061 break;
1062 case OPC_LD:
1063 save_cpu_state(ctx, 0);
1064 op_ld_ld(t0, t0, ctx);
1065 gen_store_gpr(t0, rt);
1066 opn = "ld";
1067 break;
1068 case OPC_LLD:
1069 save_cpu_state(ctx, 0);
1070 op_ld_lld(t0, t0, ctx);
1071 gen_store_gpr(t0, rt);
1072 opn = "lld";
1073 break;
1074 case OPC_LDL:
1075 save_cpu_state(ctx, 1);
1076 gen_load_gpr(t1, rt);
1077 gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1078 gen_store_gpr(t1, rt);
1079 opn = "ldl";
1080 break;
1081 case OPC_LDR:
1082 save_cpu_state(ctx, 1);
1083 gen_load_gpr(t1, rt);
1084 gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1085 gen_store_gpr(t1, rt);
1086 opn = "ldr";
1087 break;
1088 case OPC_LDPC:
1089 save_cpu_state(ctx, 1);
1090 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1091 gen_op_addr_add(ctx, t0, t0, t1);
1092 op_ld_ld(t0, t0, ctx);
1093 gen_store_gpr(t0, rt);
1094 opn = "ldpc";
1095 break;
1096 #endif
1097 case OPC_LWPC:
1098 save_cpu_state(ctx, 1);
1099 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1100 gen_op_addr_add(ctx, t0, t0, t1);
1101 op_ld_lw(t0, t0, ctx);
1102 gen_store_gpr(t0, rt);
1103 opn = "lwpc";
1104 break;
1105 case OPC_LW:
1106 save_cpu_state(ctx, 0);
1107 op_ld_lw(t0, t0, ctx);
1108 gen_store_gpr(t0, rt);
1109 opn = "lw";
1110 break;
1111 case OPC_LH:
1112 save_cpu_state(ctx, 0);
1113 op_ld_lh(t0, t0, ctx);
1114 gen_store_gpr(t0, rt);
1115 opn = "lh";
1116 break;
1117 case OPC_LHU:
1118 save_cpu_state(ctx, 0);
1119 op_ld_lhu(t0, t0, ctx);
1120 gen_store_gpr(t0, rt);
1121 opn = "lhu";
1122 break;
1123 case OPC_LB:
1124 save_cpu_state(ctx, 0);
1125 op_ld_lb(t0, t0, ctx);
1126 gen_store_gpr(t0, rt);
1127 opn = "lb";
1128 break;
1129 case OPC_LBU:
1130 save_cpu_state(ctx, 0);
1131 op_ld_lbu(t0, t0, ctx);
1132 gen_store_gpr(t0, rt);
1133 opn = "lbu";
1134 break;
1135 case OPC_LWL:
1136 save_cpu_state(ctx, 1);
1137 gen_load_gpr(t1, rt);
1138 gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1139 gen_store_gpr(t1, rt);
1140 opn = "lwl";
1141 break;
1142 case OPC_LWR:
1143 save_cpu_state(ctx, 1);
1144 gen_load_gpr(t1, rt);
1145 gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1146 gen_store_gpr(t1, rt);
1147 opn = "lwr";
1148 break;
1149 case OPC_LL:
1150 save_cpu_state(ctx, 1);
1151 op_ld_ll(t0, t0, ctx);
1152 gen_store_gpr(t0, rt);
1153 opn = "ll";
1154 break;
1156 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1157 tcg_temp_free(t0);
1158 tcg_temp_free(t1);
1161 /* Store */
1162 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1163 int base, int16_t offset)
1165 const char *opn = "st";
1166 TCGv t0 = tcg_temp_new();
1167 TCGv t1 = tcg_temp_new();
1169 gen_base_offset_addr(ctx, t0, base, offset);
1170 gen_load_gpr(t1, rt);
1171 switch (opc) {
1172 #if defined(TARGET_MIPS64)
1173 case OPC_SD:
1174 save_cpu_state(ctx, 0);
1175 op_st_sd(t1, t0, ctx);
1176 opn = "sd";
1177 break;
1178 case OPC_SDL:
1179 save_cpu_state(ctx, 1);
1180 gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1181 opn = "sdl";
1182 break;
1183 case OPC_SDR:
1184 save_cpu_state(ctx, 1);
1185 gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1186 opn = "sdr";
1187 break;
1188 #endif
1189 case OPC_SW:
1190 save_cpu_state(ctx, 0);
1191 op_st_sw(t1, t0, ctx);
1192 opn = "sw";
1193 break;
1194 case OPC_SH:
1195 save_cpu_state(ctx, 0);
1196 op_st_sh(t1, t0, ctx);
1197 opn = "sh";
1198 break;
1199 case OPC_SB:
1200 save_cpu_state(ctx, 0);
1201 op_st_sb(t1, t0, ctx);
1202 opn = "sb";
1203 break;
1204 case OPC_SWL:
1205 save_cpu_state(ctx, 1);
1206 gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1207 opn = "swl";
1208 break;
1209 case OPC_SWR:
1210 save_cpu_state(ctx, 1);
1211 gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1212 opn = "swr";
1213 break;
1215 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1216 tcg_temp_free(t0);
1217 tcg_temp_free(t1);
1221 /* Store conditional */
1222 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1223 int base, int16_t offset)
1225 const char *opn = "st_cond";
1226 TCGv t0, t1;
1228 t0 = tcg_temp_local_new();
1230 gen_base_offset_addr(ctx, t0, base, offset);
1231 /* Don't do NOP if destination is zero: we must perform the actual
1232 memory access. */
1234 t1 = tcg_temp_local_new();
1235 gen_load_gpr(t1, rt);
1236 switch (opc) {
1237 #if defined(TARGET_MIPS64)
1238 case OPC_SCD:
1239 save_cpu_state(ctx, 0);
1240 op_st_scd(t1, t0, rt, ctx);
1241 opn = "scd";
1242 break;
1243 #endif
1244 case OPC_SC:
1245 save_cpu_state(ctx, 1);
1246 op_st_sc(t1, t0, rt, ctx);
1247 opn = "sc";
1248 break;
1250 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1251 tcg_temp_free(t1);
1252 tcg_temp_free(t0);
1255 /* Load and store */
1256 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1257 int base, int16_t offset)
1259 const char *opn = "flt_ldst";
1260 TCGv t0 = tcg_temp_new();
1262 gen_base_offset_addr(ctx, t0, base, offset);
1263 /* Don't do NOP if destination is zero: we must perform the actual
1264 memory access. */
1265 switch (opc) {
1266 case OPC_LWC1:
1268 TCGv_i32 fp0 = tcg_temp_new_i32();
1270 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1271 tcg_gen_trunc_tl_i32(fp0, t0);
1272 gen_store_fpr32(fp0, ft);
1273 tcg_temp_free_i32(fp0);
1275 opn = "lwc1";
1276 break;
1277 case OPC_SWC1:
1279 TCGv_i32 fp0 = tcg_temp_new_i32();
1280 TCGv t1 = tcg_temp_new();
1282 gen_load_fpr32(fp0, ft);
1283 tcg_gen_extu_i32_tl(t1, fp0);
1284 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1285 tcg_temp_free(t1);
1286 tcg_temp_free_i32(fp0);
1288 opn = "swc1";
1289 break;
1290 case OPC_LDC1:
1292 TCGv_i64 fp0 = tcg_temp_new_i64();
1294 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1295 gen_store_fpr64(ctx, fp0, ft);
1296 tcg_temp_free_i64(fp0);
1298 opn = "ldc1";
1299 break;
1300 case OPC_SDC1:
1302 TCGv_i64 fp0 = tcg_temp_new_i64();
1304 gen_load_fpr64(ctx, fp0, ft);
1305 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1306 tcg_temp_free_i64(fp0);
1308 opn = "sdc1";
1309 break;
1310 default:
1311 MIPS_INVAL(opn);
1312 generate_exception(ctx, EXCP_RI);
1313 goto out;
1315 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1316 out:
1317 tcg_temp_free(t0);
1320 static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1321 uint32_t op, int rt, int rs, int16_t imm)
1323 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1324 check_cp1_enabled(ctx);
1325 gen_flt_ldst(ctx, op, rt, rs, imm);
1326 } else {
1327 generate_exception_err(ctx, EXCP_CpU, 1);
1331 /* Arithmetic with immediate operand */
1332 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1333 int rt, int rs, int16_t imm)
1335 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1336 const char *opn = "imm arith";
1338 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1339 /* If no destination, treat it as a NOP.
1340 For addi, we must generate the overflow exception when needed. */
1341 MIPS_DEBUG("NOP");
1342 return;
1344 switch (opc) {
1345 case OPC_ADDI:
1347 TCGv t0 = tcg_temp_local_new();
1348 TCGv t1 = tcg_temp_new();
1349 TCGv t2 = tcg_temp_new();
1350 int l1 = gen_new_label();
1352 gen_load_gpr(t1, rs);
1353 tcg_gen_addi_tl(t0, t1, uimm);
1354 tcg_gen_ext32s_tl(t0, t0);
1356 tcg_gen_xori_tl(t1, t1, ~uimm);
1357 tcg_gen_xori_tl(t2, t0, uimm);
1358 tcg_gen_and_tl(t1, t1, t2);
1359 tcg_temp_free(t2);
1360 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1361 tcg_temp_free(t1);
1362 /* operands of same sign, result different sign */
1363 generate_exception(ctx, EXCP_OVERFLOW);
1364 gen_set_label(l1);
1365 tcg_gen_ext32s_tl(t0, t0);
1366 gen_store_gpr(t0, rt);
1367 tcg_temp_free(t0);
1369 opn = "addi";
1370 break;
1371 case OPC_ADDIU:
1372 if (rs != 0) {
1373 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1374 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1375 } else {
1376 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1378 opn = "addiu";
1379 break;
1380 #if defined(TARGET_MIPS64)
1381 case OPC_DADDI:
1383 TCGv t0 = tcg_temp_local_new();
1384 TCGv t1 = tcg_temp_new();
1385 TCGv t2 = tcg_temp_new();
1386 int l1 = gen_new_label();
1388 gen_load_gpr(t1, rs);
1389 tcg_gen_addi_tl(t0, t1, uimm);
1391 tcg_gen_xori_tl(t1, t1, ~uimm);
1392 tcg_gen_xori_tl(t2, t0, uimm);
1393 tcg_gen_and_tl(t1, t1, t2);
1394 tcg_temp_free(t2);
1395 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1396 tcg_temp_free(t1);
1397 /* operands of same sign, result different sign */
1398 generate_exception(ctx, EXCP_OVERFLOW);
1399 gen_set_label(l1);
1400 gen_store_gpr(t0, rt);
1401 tcg_temp_free(t0);
1403 opn = "daddi";
1404 break;
1405 case OPC_DADDIU:
1406 if (rs != 0) {
1407 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1408 } else {
1409 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1411 opn = "daddiu";
1412 break;
1413 #endif
1415 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1418 /* Logic with immediate operand */
1419 static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1421 target_ulong uimm;
1422 const char *opn = "imm logic";
1424 if (rt == 0) {
1425 /* If no destination, treat it as a NOP. */
1426 MIPS_DEBUG("NOP");
1427 return;
1429 uimm = (uint16_t)imm;
1430 switch (opc) {
1431 case OPC_ANDI:
1432 if (likely(rs != 0))
1433 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1434 else
1435 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1436 opn = "andi";
1437 break;
1438 case OPC_ORI:
1439 if (rs != 0)
1440 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1441 else
1442 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1443 opn = "ori";
1444 break;
1445 case OPC_XORI:
1446 if (likely(rs != 0))
1447 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1448 else
1449 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1450 opn = "xori";
1451 break;
1452 case OPC_LUI:
1453 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1454 opn = "lui";
1455 break;
1457 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1460 /* Set on less than with immediate operand */
1461 static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1463 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1464 const char *opn = "imm arith";
1465 TCGv t0;
1467 if (rt == 0) {
1468 /* If no destination, treat it as a NOP. */
1469 MIPS_DEBUG("NOP");
1470 return;
1472 t0 = tcg_temp_new();
1473 gen_load_gpr(t0, rs);
1474 switch (opc) {
1475 case OPC_SLTI:
1476 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1477 opn = "slti";
1478 break;
1479 case OPC_SLTIU:
1480 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1481 opn = "sltiu";
1482 break;
1484 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1485 tcg_temp_free(t0);
1488 /* Shifts with immediate operand */
1489 static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1490 int rt, int rs, int16_t imm)
1492 target_ulong uimm = ((uint16_t)imm) & 0x1f;
1493 const char *opn = "imm shift";
1494 TCGv t0;
1496 if (rt == 0) {
1497 /* If no destination, treat it as a NOP. */
1498 MIPS_DEBUG("NOP");
1499 return;
1502 t0 = tcg_temp_new();
1503 gen_load_gpr(t0, rs);
1504 switch (opc) {
1505 case OPC_SLL:
1506 tcg_gen_shli_tl(t0, t0, uimm);
1507 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1508 opn = "sll";
1509 break;
1510 case OPC_SRA:
1511 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1512 opn = "sra";
1513 break;
1514 case OPC_SRL:
1515 if (uimm != 0) {
1516 tcg_gen_ext32u_tl(t0, t0);
1517 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1518 } else {
1519 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1521 opn = "srl";
1522 break;
1523 case OPC_ROTR:
1524 if (uimm != 0) {
1525 TCGv_i32 t1 = tcg_temp_new_i32();
1527 tcg_gen_trunc_tl_i32(t1, t0);
1528 tcg_gen_rotri_i32(t1, t1, uimm);
1529 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1530 tcg_temp_free_i32(t1);
1531 } else {
1532 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1534 opn = "rotr";
1535 break;
1536 #if defined(TARGET_MIPS64)
1537 case OPC_DSLL:
1538 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1539 opn = "dsll";
1540 break;
1541 case OPC_DSRA:
1542 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1543 opn = "dsra";
1544 break;
1545 case OPC_DSRL:
1546 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1547 opn = "dsrl";
1548 break;
1549 case OPC_DROTR:
1550 if (uimm != 0) {
1551 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1552 } else {
1553 tcg_gen_mov_tl(cpu_gpr[rt], t0);
1555 opn = "drotr";
1556 break;
1557 case OPC_DSLL32:
1558 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1559 opn = "dsll32";
1560 break;
1561 case OPC_DSRA32:
1562 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1563 opn = "dsra32";
1564 break;
1565 case OPC_DSRL32:
1566 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1567 opn = "dsrl32";
1568 break;
1569 case OPC_DROTR32:
1570 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1571 opn = "drotr32";
1572 break;
1573 #endif
1575 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1576 tcg_temp_free(t0);
1579 /* Arithmetic */
1580 static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1581 int rd, int rs, int rt)
1583 const char *opn = "arith";
1585 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1586 && opc != OPC_DADD && opc != OPC_DSUB) {
1587 /* If no destination, treat it as a NOP.
1588 For add & sub, we must generate the overflow exception when needed. */
1589 MIPS_DEBUG("NOP");
1590 return;
1593 switch (opc) {
1594 case OPC_ADD:
1596 TCGv t0 = tcg_temp_local_new();
1597 TCGv t1 = tcg_temp_new();
1598 TCGv t2 = tcg_temp_new();
1599 int l1 = gen_new_label();
1601 gen_load_gpr(t1, rs);
1602 gen_load_gpr(t2, rt);
1603 tcg_gen_add_tl(t0, t1, t2);
1604 tcg_gen_ext32s_tl(t0, t0);
1605 tcg_gen_xor_tl(t1, t1, t2);
1606 tcg_gen_xor_tl(t2, t0, t2);
1607 tcg_gen_andc_tl(t1, t2, t1);
1608 tcg_temp_free(t2);
1609 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1610 tcg_temp_free(t1);
1611 /* operands of same sign, result different sign */
1612 generate_exception(ctx, EXCP_OVERFLOW);
1613 gen_set_label(l1);
1614 gen_store_gpr(t0, rd);
1615 tcg_temp_free(t0);
1617 opn = "add";
1618 break;
1619 case OPC_ADDU:
1620 if (rs != 0 && rt != 0) {
1621 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1622 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1623 } else if (rs == 0 && rt != 0) {
1624 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1625 } else if (rs != 0 && rt == 0) {
1626 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1627 } else {
1628 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1630 opn = "addu";
1631 break;
1632 case OPC_SUB:
1634 TCGv t0 = tcg_temp_local_new();
1635 TCGv t1 = tcg_temp_new();
1636 TCGv t2 = tcg_temp_new();
1637 int l1 = gen_new_label();
1639 gen_load_gpr(t1, rs);
1640 gen_load_gpr(t2, rt);
1641 tcg_gen_sub_tl(t0, t1, t2);
1642 tcg_gen_ext32s_tl(t0, t0);
1643 tcg_gen_xor_tl(t2, t1, t2);
1644 tcg_gen_xor_tl(t1, t0, t1);
1645 tcg_gen_and_tl(t1, t1, t2);
1646 tcg_temp_free(t2);
1647 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1648 tcg_temp_free(t1);
1649 /* operands of different sign, first operand and result different sign */
1650 generate_exception(ctx, EXCP_OVERFLOW);
1651 gen_set_label(l1);
1652 gen_store_gpr(t0, rd);
1653 tcg_temp_free(t0);
1655 opn = "sub";
1656 break;
1657 case OPC_SUBU:
1658 if (rs != 0 && rt != 0) {
1659 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1660 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1661 } else if (rs == 0 && rt != 0) {
1662 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1663 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1664 } else if (rs != 0 && rt == 0) {
1665 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1666 } else {
1667 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1669 opn = "subu";
1670 break;
1671 #if defined(TARGET_MIPS64)
1672 case OPC_DADD:
1674 TCGv t0 = tcg_temp_local_new();
1675 TCGv t1 = tcg_temp_new();
1676 TCGv t2 = tcg_temp_new();
1677 int l1 = gen_new_label();
1679 gen_load_gpr(t1, rs);
1680 gen_load_gpr(t2, rt);
1681 tcg_gen_add_tl(t0, t1, t2);
1682 tcg_gen_xor_tl(t1, t1, t2);
1683 tcg_gen_xor_tl(t2, t0, t2);
1684 tcg_gen_andc_tl(t1, t2, t1);
1685 tcg_temp_free(t2);
1686 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1687 tcg_temp_free(t1);
1688 /* operands of same sign, result different sign */
1689 generate_exception(ctx, EXCP_OVERFLOW);
1690 gen_set_label(l1);
1691 gen_store_gpr(t0, rd);
1692 tcg_temp_free(t0);
1694 opn = "dadd";
1695 break;
1696 case OPC_DADDU:
1697 if (rs != 0 && rt != 0) {
1698 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1699 } else if (rs == 0 && rt != 0) {
1700 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1701 } else if (rs != 0 && rt == 0) {
1702 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1703 } else {
1704 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1706 opn = "daddu";
1707 break;
1708 case OPC_DSUB:
1710 TCGv t0 = tcg_temp_local_new();
1711 TCGv t1 = tcg_temp_new();
1712 TCGv t2 = tcg_temp_new();
1713 int l1 = gen_new_label();
1715 gen_load_gpr(t1, rs);
1716 gen_load_gpr(t2, rt);
1717 tcg_gen_sub_tl(t0, t1, t2);
1718 tcg_gen_xor_tl(t2, t1, t2);
1719 tcg_gen_xor_tl(t1, t0, t1);
1720 tcg_gen_and_tl(t1, t1, t2);
1721 tcg_temp_free(t2);
1722 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1723 tcg_temp_free(t1);
1724 /* operands of different sign, first operand and result different sign */
1725 generate_exception(ctx, EXCP_OVERFLOW);
1726 gen_set_label(l1);
1727 gen_store_gpr(t0, rd);
1728 tcg_temp_free(t0);
1730 opn = "dsub";
1731 break;
1732 case OPC_DSUBU:
1733 if (rs != 0 && rt != 0) {
1734 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1735 } else if (rs == 0 && rt != 0) {
1736 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1737 } else if (rs != 0 && rt == 0) {
1738 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1739 } else {
1740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1742 opn = "dsubu";
1743 break;
1744 #endif
1745 case OPC_MUL:
1746 if (likely(rs != 0 && rt != 0)) {
1747 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1748 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1749 } else {
1750 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1752 opn = "mul";
1753 break;
1755 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1758 /* Conditional move */
1759 static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1761 const char *opn = "cond move";
1762 int l1;
1764 if (rd == 0) {
1765 /* If no destination, treat it as a NOP.
1766 For add & sub, we must generate the overflow exception when needed. */
1767 MIPS_DEBUG("NOP");
1768 return;
1771 l1 = gen_new_label();
1772 switch (opc) {
1773 case OPC_MOVN:
1774 if (likely(rt != 0))
1775 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1776 else
1777 tcg_gen_br(l1);
1778 opn = "movn";
1779 break;
1780 case OPC_MOVZ:
1781 if (likely(rt != 0))
1782 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1783 opn = "movz";
1784 break;
1786 if (rs != 0)
1787 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1788 else
1789 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1790 gen_set_label(l1);
1792 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1795 /* Logic */
1796 static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1798 const char *opn = "logic";
1800 if (rd == 0) {
1801 /* If no destination, treat it as a NOP. */
1802 MIPS_DEBUG("NOP");
1803 return;
1806 switch (opc) {
1807 case OPC_AND:
1808 if (likely(rs != 0 && rt != 0)) {
1809 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1810 } else {
1811 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1813 opn = "and";
1814 break;
1815 case OPC_NOR:
1816 if (rs != 0 && rt != 0) {
1817 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1818 } else if (rs == 0 && rt != 0) {
1819 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1820 } else if (rs != 0 && rt == 0) {
1821 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1822 } else {
1823 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1825 opn = "nor";
1826 break;
1827 case OPC_OR:
1828 if (likely(rs != 0 && rt != 0)) {
1829 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1830 } else if (rs == 0 && rt != 0) {
1831 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1832 } else if (rs != 0 && rt == 0) {
1833 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1834 } else {
1835 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1837 opn = "or";
1838 break;
1839 case OPC_XOR:
1840 if (likely(rs != 0 && rt != 0)) {
1841 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1842 } else if (rs == 0 && rt != 0) {
1843 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1844 } else if (rs != 0 && rt == 0) {
1845 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1846 } else {
1847 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1849 opn = "xor";
1850 break;
1852 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1855 /* Set on lower than */
1856 static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1858 const char *opn = "slt";
1859 TCGv t0, t1;
1861 if (rd == 0) {
1862 /* If no destination, treat it as a NOP. */
1863 MIPS_DEBUG("NOP");
1864 return;
1867 t0 = tcg_temp_new();
1868 t1 = tcg_temp_new();
1869 gen_load_gpr(t0, rs);
1870 gen_load_gpr(t1, rt);
1871 switch (opc) {
1872 case OPC_SLT:
1873 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1874 opn = "slt";
1875 break;
1876 case OPC_SLTU:
1877 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1878 opn = "sltu";
1879 break;
1881 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1882 tcg_temp_free(t0);
1883 tcg_temp_free(t1);
1886 /* Shifts */
1887 static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1888 int rd, int rs, int rt)
1890 const char *opn = "shifts";
1891 TCGv t0, t1;
1893 if (rd == 0) {
1894 /* If no destination, treat it as a NOP.
1895 For add & sub, we must generate the overflow exception when needed. */
1896 MIPS_DEBUG("NOP");
1897 return;
1900 t0 = tcg_temp_new();
1901 t1 = tcg_temp_new();
1902 gen_load_gpr(t0, rs);
1903 gen_load_gpr(t1, rt);
1904 switch (opc) {
1905 case OPC_SLLV:
1906 tcg_gen_andi_tl(t0, t0, 0x1f);
1907 tcg_gen_shl_tl(t0, t1, t0);
1908 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1909 opn = "sllv";
1910 break;
1911 case OPC_SRAV:
1912 tcg_gen_andi_tl(t0, t0, 0x1f);
1913 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1914 opn = "srav";
1915 break;
1916 case OPC_SRLV:
1917 tcg_gen_ext32u_tl(t1, t1);
1918 tcg_gen_andi_tl(t0, t0, 0x1f);
1919 tcg_gen_shr_tl(t0, t1, t0);
1920 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1921 opn = "srlv";
1922 break;
1923 case OPC_ROTRV:
1925 TCGv_i32 t2 = tcg_temp_new_i32();
1926 TCGv_i32 t3 = tcg_temp_new_i32();
1928 tcg_gen_trunc_tl_i32(t2, t0);
1929 tcg_gen_trunc_tl_i32(t3, t1);
1930 tcg_gen_andi_i32(t2, t2, 0x1f);
1931 tcg_gen_rotr_i32(t2, t3, t2);
1932 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1933 tcg_temp_free_i32(t2);
1934 tcg_temp_free_i32(t3);
1935 opn = "rotrv";
1937 break;
1938 #if defined(TARGET_MIPS64)
1939 case OPC_DSLLV:
1940 tcg_gen_andi_tl(t0, t0, 0x3f);
1941 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1942 opn = "dsllv";
1943 break;
1944 case OPC_DSRAV:
1945 tcg_gen_andi_tl(t0, t0, 0x3f);
1946 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1947 opn = "dsrav";
1948 break;
1949 case OPC_DSRLV:
1950 tcg_gen_andi_tl(t0, t0, 0x3f);
1951 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1952 opn = "dsrlv";
1953 break;
1954 case OPC_DROTRV:
1955 tcg_gen_andi_tl(t0, t0, 0x3f);
1956 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1957 opn = "drotrv";
1958 break;
1959 #endif
1961 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1962 tcg_temp_free(t0);
1963 tcg_temp_free(t1);
1966 /* Arithmetic on HI/LO registers */
1967 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1969 const char *opn = "hilo";
1971 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1972 /* Treat as NOP. */
1973 MIPS_DEBUG("NOP");
1974 return;
1976 switch (opc) {
1977 case OPC_MFHI:
1978 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1979 opn = "mfhi";
1980 break;
1981 case OPC_MFLO:
1982 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1983 opn = "mflo";
1984 break;
1985 case OPC_MTHI:
1986 if (reg != 0)
1987 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1988 else
1989 tcg_gen_movi_tl(cpu_HI[0], 0);
1990 opn = "mthi";
1991 break;
1992 case OPC_MTLO:
1993 if (reg != 0)
1994 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1995 else
1996 tcg_gen_movi_tl(cpu_LO[0], 0);
1997 opn = "mtlo";
1998 break;
2000 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2003 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2004 int rs, int rt)
2006 const char *opn = "mul/div";
2007 TCGv t0, t1;
2009 switch (opc) {
2010 case OPC_DIV:
2011 case OPC_DIVU:
2012 #if defined(TARGET_MIPS64)
2013 case OPC_DDIV:
2014 case OPC_DDIVU:
2015 #endif
2016 t0 = tcg_temp_local_new();
2017 t1 = tcg_temp_local_new();
2018 break;
2019 default:
2020 t0 = tcg_temp_new();
2021 t1 = tcg_temp_new();
2022 break;
2025 gen_load_gpr(t0, rs);
2026 gen_load_gpr(t1, rt);
2027 switch (opc) {
2028 case OPC_DIV:
2030 int l1 = gen_new_label();
2031 int l2 = gen_new_label();
2033 tcg_gen_ext32s_tl(t0, t0);
2034 tcg_gen_ext32s_tl(t1, t1);
2035 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2036 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2037 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2039 tcg_gen_mov_tl(cpu_LO[0], t0);
2040 tcg_gen_movi_tl(cpu_HI[0], 0);
2041 tcg_gen_br(l1);
2042 gen_set_label(l2);
2043 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2044 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2045 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2046 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2047 gen_set_label(l1);
2049 opn = "div";
2050 break;
2051 case OPC_DIVU:
2053 int l1 = gen_new_label();
2055 tcg_gen_ext32u_tl(t0, t0);
2056 tcg_gen_ext32u_tl(t1, t1);
2057 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2058 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2059 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2060 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2061 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2062 gen_set_label(l1);
2064 opn = "divu";
2065 break;
2066 case OPC_MULT:
2068 TCGv_i64 t2 = tcg_temp_new_i64();
2069 TCGv_i64 t3 = tcg_temp_new_i64();
2071 tcg_gen_ext_tl_i64(t2, t0);
2072 tcg_gen_ext_tl_i64(t3, t1);
2073 tcg_gen_mul_i64(t2, t2, t3);
2074 tcg_temp_free_i64(t3);
2075 tcg_gen_trunc_i64_tl(t0, t2);
2076 tcg_gen_shri_i64(t2, t2, 32);
2077 tcg_gen_trunc_i64_tl(t1, t2);
2078 tcg_temp_free_i64(t2);
2079 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2080 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2082 opn = "mult";
2083 break;
2084 case OPC_MULTU:
2086 TCGv_i64 t2 = tcg_temp_new_i64();
2087 TCGv_i64 t3 = tcg_temp_new_i64();
2089 tcg_gen_ext32u_tl(t0, t0);
2090 tcg_gen_ext32u_tl(t1, t1);
2091 tcg_gen_extu_tl_i64(t2, t0);
2092 tcg_gen_extu_tl_i64(t3, t1);
2093 tcg_gen_mul_i64(t2, t2, t3);
2094 tcg_temp_free_i64(t3);
2095 tcg_gen_trunc_i64_tl(t0, t2);
2096 tcg_gen_shri_i64(t2, t2, 32);
2097 tcg_gen_trunc_i64_tl(t1, t2);
2098 tcg_temp_free_i64(t2);
2099 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2100 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2102 opn = "multu";
2103 break;
2104 #if defined(TARGET_MIPS64)
2105 case OPC_DDIV:
2107 int l1 = gen_new_label();
2108 int l2 = gen_new_label();
2110 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2111 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2112 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2113 tcg_gen_mov_tl(cpu_LO[0], t0);
2114 tcg_gen_movi_tl(cpu_HI[0], 0);
2115 tcg_gen_br(l1);
2116 gen_set_label(l2);
2117 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2118 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2119 gen_set_label(l1);
2121 opn = "ddiv";
2122 break;
2123 case OPC_DDIVU:
2125 int l1 = gen_new_label();
2127 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2128 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2129 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2130 gen_set_label(l1);
2132 opn = "ddivu";
2133 break;
2134 case OPC_DMULT:
2135 gen_helper_dmult(t0, t1);
2136 opn = "dmult";
2137 break;
2138 case OPC_DMULTU:
2139 gen_helper_dmultu(t0, t1);
2140 opn = "dmultu";
2141 break;
2142 #endif
2143 case OPC_MADD:
2145 TCGv_i64 t2 = tcg_temp_new_i64();
2146 TCGv_i64 t3 = tcg_temp_new_i64();
2148 tcg_gen_ext_tl_i64(t2, t0);
2149 tcg_gen_ext_tl_i64(t3, t1);
2150 tcg_gen_mul_i64(t2, t2, t3);
2151 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2152 tcg_gen_add_i64(t2, t2, t3);
2153 tcg_temp_free_i64(t3);
2154 tcg_gen_trunc_i64_tl(t0, t2);
2155 tcg_gen_shri_i64(t2, t2, 32);
2156 tcg_gen_trunc_i64_tl(t1, t2);
2157 tcg_temp_free_i64(t2);
2158 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2159 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2161 opn = "madd";
2162 break;
2163 case OPC_MADDU:
2165 TCGv_i64 t2 = tcg_temp_new_i64();
2166 TCGv_i64 t3 = tcg_temp_new_i64();
2168 tcg_gen_ext32u_tl(t0, t0);
2169 tcg_gen_ext32u_tl(t1, t1);
2170 tcg_gen_extu_tl_i64(t2, t0);
2171 tcg_gen_extu_tl_i64(t3, t1);
2172 tcg_gen_mul_i64(t2, t2, t3);
2173 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2174 tcg_gen_add_i64(t2, t2, t3);
2175 tcg_temp_free_i64(t3);
2176 tcg_gen_trunc_i64_tl(t0, t2);
2177 tcg_gen_shri_i64(t2, t2, 32);
2178 tcg_gen_trunc_i64_tl(t1, t2);
2179 tcg_temp_free_i64(t2);
2180 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2181 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2183 opn = "maddu";
2184 break;
2185 case OPC_MSUB:
2187 TCGv_i64 t2 = tcg_temp_new_i64();
2188 TCGv_i64 t3 = tcg_temp_new_i64();
2190 tcg_gen_ext_tl_i64(t2, t0);
2191 tcg_gen_ext_tl_i64(t3, t1);
2192 tcg_gen_mul_i64(t2, t2, t3);
2193 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2194 tcg_gen_sub_i64(t2, t3, t2);
2195 tcg_temp_free_i64(t3);
2196 tcg_gen_trunc_i64_tl(t0, t2);
2197 tcg_gen_shri_i64(t2, t2, 32);
2198 tcg_gen_trunc_i64_tl(t1, t2);
2199 tcg_temp_free_i64(t2);
2200 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2201 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2203 opn = "msub";
2204 break;
2205 case OPC_MSUBU:
2207 TCGv_i64 t2 = tcg_temp_new_i64();
2208 TCGv_i64 t3 = tcg_temp_new_i64();
2210 tcg_gen_ext32u_tl(t0, t0);
2211 tcg_gen_ext32u_tl(t1, t1);
2212 tcg_gen_extu_tl_i64(t2, t0);
2213 tcg_gen_extu_tl_i64(t3, t1);
2214 tcg_gen_mul_i64(t2, t2, t3);
2215 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2216 tcg_gen_sub_i64(t2, t3, t2);
2217 tcg_temp_free_i64(t3);
2218 tcg_gen_trunc_i64_tl(t0, t2);
2219 tcg_gen_shri_i64(t2, t2, 32);
2220 tcg_gen_trunc_i64_tl(t1, t2);
2221 tcg_temp_free_i64(t2);
2222 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2223 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2225 opn = "msubu";
2226 break;
2227 default:
2228 MIPS_INVAL(opn);
2229 generate_exception(ctx, EXCP_RI);
2230 goto out;
2232 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2233 out:
2234 tcg_temp_free(t0);
2235 tcg_temp_free(t1);
2238 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2239 int rd, int rs, int rt)
2241 const char *opn = "mul vr54xx";
2242 TCGv t0 = tcg_temp_new();
2243 TCGv t1 = tcg_temp_new();
2245 gen_load_gpr(t0, rs);
2246 gen_load_gpr(t1, rt);
2248 switch (opc) {
2249 case OPC_VR54XX_MULS:
2250 gen_helper_muls(t0, t0, t1);
2251 opn = "muls";
2252 break;
2253 case OPC_VR54XX_MULSU:
2254 gen_helper_mulsu(t0, t0, t1);
2255 opn = "mulsu";
2256 break;
2257 case OPC_VR54XX_MACC:
2258 gen_helper_macc(t0, t0, t1);
2259 opn = "macc";
2260 break;
2261 case OPC_VR54XX_MACCU:
2262 gen_helper_maccu(t0, t0, t1);
2263 opn = "maccu";
2264 break;
2265 case OPC_VR54XX_MSAC:
2266 gen_helper_msac(t0, t0, t1);
2267 opn = "msac";
2268 break;
2269 case OPC_VR54XX_MSACU:
2270 gen_helper_msacu(t0, t0, t1);
2271 opn = "msacu";
2272 break;
2273 case OPC_VR54XX_MULHI:
2274 gen_helper_mulhi(t0, t0, t1);
2275 opn = "mulhi";
2276 break;
2277 case OPC_VR54XX_MULHIU:
2278 gen_helper_mulhiu(t0, t0, t1);
2279 opn = "mulhiu";
2280 break;
2281 case OPC_VR54XX_MULSHI:
2282 gen_helper_mulshi(t0, t0, t1);
2283 opn = "mulshi";
2284 break;
2285 case OPC_VR54XX_MULSHIU:
2286 gen_helper_mulshiu(t0, t0, t1);
2287 opn = "mulshiu";
2288 break;
2289 case OPC_VR54XX_MACCHI:
2290 gen_helper_macchi(t0, t0, t1);
2291 opn = "macchi";
2292 break;
2293 case OPC_VR54XX_MACCHIU:
2294 gen_helper_macchiu(t0, t0, t1);
2295 opn = "macchiu";
2296 break;
2297 case OPC_VR54XX_MSACHI:
2298 gen_helper_msachi(t0, t0, t1);
2299 opn = "msachi";
2300 break;
2301 case OPC_VR54XX_MSACHIU:
2302 gen_helper_msachiu(t0, t0, t1);
2303 opn = "msachiu";
2304 break;
2305 default:
2306 MIPS_INVAL("mul vr54xx");
2307 generate_exception(ctx, EXCP_RI);
2308 goto out;
2310 gen_store_gpr(t0, rd);
2311 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2313 out:
2314 tcg_temp_free(t0);
2315 tcg_temp_free(t1);
2318 static void gen_cl (DisasContext *ctx, uint32_t opc,
2319 int rd, int rs)
2321 const char *opn = "CLx";
2322 TCGv t0;
2324 if (rd == 0) {
2325 /* Treat as NOP. */
2326 MIPS_DEBUG("NOP");
2327 return;
2329 t0 = tcg_temp_new();
2330 gen_load_gpr(t0, rs);
2331 switch (opc) {
2332 case OPC_CLO:
2333 gen_helper_clo(cpu_gpr[rd], t0);
2334 opn = "clo";
2335 break;
2336 case OPC_CLZ:
2337 gen_helper_clz(cpu_gpr[rd], t0);
2338 opn = "clz";
2339 break;
2340 #if defined(TARGET_MIPS64)
2341 case OPC_DCLO:
2342 gen_helper_dclo(cpu_gpr[rd], t0);
2343 opn = "dclo";
2344 break;
2345 case OPC_DCLZ:
2346 gen_helper_dclz(cpu_gpr[rd], t0);
2347 opn = "dclz";
2348 break;
2349 #endif
2351 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2352 tcg_temp_free(t0);
2355 /* Godson integer instructions */
2356 static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2357 int rd, int rs, int rt)
2359 const char *opn = "loongson";
2360 TCGv t0, t1;
2362 if (rd == 0) {
2363 /* Treat as NOP. */
2364 MIPS_DEBUG("NOP");
2365 return;
2368 switch (opc) {
2369 case OPC_MULT_G_2E:
2370 case OPC_MULT_G_2F:
2371 case OPC_MULTU_G_2E:
2372 case OPC_MULTU_G_2F:
2373 #if defined(TARGET_MIPS64)
2374 case OPC_DMULT_G_2E:
2375 case OPC_DMULT_G_2F:
2376 case OPC_DMULTU_G_2E:
2377 case OPC_DMULTU_G_2F:
2378 #endif
2379 t0 = tcg_temp_new();
2380 t1 = tcg_temp_new();
2381 break;
2382 default:
2383 t0 = tcg_temp_local_new();
2384 t1 = tcg_temp_local_new();
2385 break;
2388 gen_load_gpr(t0, rs);
2389 gen_load_gpr(t1, rt);
2391 switch (opc) {
2392 case OPC_MULT_G_2E:
2393 case OPC_MULT_G_2F:
2394 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2395 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2396 opn = "mult.g";
2397 break;
2398 case OPC_MULTU_G_2E:
2399 case OPC_MULTU_G_2F:
2400 tcg_gen_ext32u_tl(t0, t0);
2401 tcg_gen_ext32u_tl(t1, t1);
2402 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2403 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2404 opn = "multu.g";
2405 break;
2406 case OPC_DIV_G_2E:
2407 case OPC_DIV_G_2F:
2409 int l1 = gen_new_label();
2410 int l2 = gen_new_label();
2411 int l3 = gen_new_label();
2412 tcg_gen_ext32s_tl(t0, t0);
2413 tcg_gen_ext32s_tl(t1, t1);
2414 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2415 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2416 tcg_gen_br(l3);
2417 gen_set_label(l1);
2418 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2419 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2420 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2421 tcg_gen_br(l3);
2422 gen_set_label(l2);
2423 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2424 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2425 gen_set_label(l3);
2427 opn = "div.g";
2428 break;
2429 case OPC_DIVU_G_2E:
2430 case OPC_DIVU_G_2F:
2432 int l1 = gen_new_label();
2433 int l2 = gen_new_label();
2434 tcg_gen_ext32u_tl(t0, t0);
2435 tcg_gen_ext32u_tl(t1, t1);
2436 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2437 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2438 tcg_gen_br(l2);
2439 gen_set_label(l1);
2440 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2441 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2442 gen_set_label(l2);
2444 opn = "divu.g";
2445 break;
2446 case OPC_MOD_G_2E:
2447 case OPC_MOD_G_2F:
2449 int l1 = gen_new_label();
2450 int l2 = gen_new_label();
2451 int l3 = gen_new_label();
2452 tcg_gen_ext32u_tl(t0, t0);
2453 tcg_gen_ext32u_tl(t1, t1);
2454 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2455 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2456 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2457 gen_set_label(l1);
2458 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2459 tcg_gen_br(l3);
2460 gen_set_label(l2);
2461 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2462 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2463 gen_set_label(l3);
2465 opn = "mod.g";
2466 break;
2467 case OPC_MODU_G_2E:
2468 case OPC_MODU_G_2F:
2470 int l1 = gen_new_label();
2471 int l2 = gen_new_label();
2472 tcg_gen_ext32u_tl(t0, t0);
2473 tcg_gen_ext32u_tl(t1, t1);
2474 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2475 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2476 tcg_gen_br(l2);
2477 gen_set_label(l1);
2478 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2479 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2480 gen_set_label(l2);
2482 opn = "modu.g";
2483 break;
2484 #if defined(TARGET_MIPS64)
2485 case OPC_DMULT_G_2E:
2486 case OPC_DMULT_G_2F:
2487 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2488 opn = "dmult.g";
2489 break;
2490 case OPC_DMULTU_G_2E:
2491 case OPC_DMULTU_G_2F:
2492 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2493 opn = "dmultu.g";
2494 break;
2495 case OPC_DDIV_G_2E:
2496 case OPC_DDIV_G_2F:
2498 int l1 = gen_new_label();
2499 int l2 = gen_new_label();
2500 int l3 = gen_new_label();
2501 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2502 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2503 tcg_gen_br(l3);
2504 gen_set_label(l1);
2505 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2506 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2507 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2508 tcg_gen_br(l3);
2509 gen_set_label(l2);
2510 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2511 gen_set_label(l3);
2513 opn = "ddiv.g";
2514 break;
2515 case OPC_DDIVU_G_2E:
2516 case OPC_DDIVU_G_2F:
2518 int l1 = gen_new_label();
2519 int l2 = gen_new_label();
2520 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2521 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2522 tcg_gen_br(l2);
2523 gen_set_label(l1);
2524 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2525 gen_set_label(l2);
2527 opn = "ddivu.g";
2528 break;
2529 case OPC_DMOD_G_2E:
2530 case OPC_DMOD_G_2F:
2532 int l1 = gen_new_label();
2533 int l2 = gen_new_label();
2534 int l3 = gen_new_label();
2535 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2536 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2537 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2538 gen_set_label(l1);
2539 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2540 tcg_gen_br(l3);
2541 gen_set_label(l2);
2542 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2543 gen_set_label(l3);
2545 opn = "dmod.g";
2546 break;
2547 case OPC_DMODU_G_2E:
2548 case OPC_DMODU_G_2F:
2550 int l1 = gen_new_label();
2551 int l2 = gen_new_label();
2552 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2553 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2554 tcg_gen_br(l2);
2555 gen_set_label(l1);
2556 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2557 gen_set_label(l2);
2559 opn = "dmodu.g";
2560 break;
2561 #endif
2564 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2565 tcg_temp_free(t0);
2566 tcg_temp_free(t1);
2569 /* Traps */
2570 static void gen_trap (DisasContext *ctx, uint32_t opc,
2571 int rs, int rt, int16_t imm)
2573 int cond;
2574 TCGv t0 = tcg_temp_new();
2575 TCGv t1 = tcg_temp_new();
2577 cond = 0;
2578 /* Load needed operands */
2579 switch (opc) {
2580 case OPC_TEQ:
2581 case OPC_TGE:
2582 case OPC_TGEU:
2583 case OPC_TLT:
2584 case OPC_TLTU:
2585 case OPC_TNE:
2586 /* Compare two registers */
2587 if (rs != rt) {
2588 gen_load_gpr(t0, rs);
2589 gen_load_gpr(t1, rt);
2590 cond = 1;
2592 break;
2593 case OPC_TEQI:
2594 case OPC_TGEI:
2595 case OPC_TGEIU:
2596 case OPC_TLTI:
2597 case OPC_TLTIU:
2598 case OPC_TNEI:
2599 /* Compare register to immediate */
2600 if (rs != 0 || imm != 0) {
2601 gen_load_gpr(t0, rs);
2602 tcg_gen_movi_tl(t1, (int32_t)imm);
2603 cond = 1;
2605 break;
2607 if (cond == 0) {
2608 switch (opc) {
2609 case OPC_TEQ: /* rs == rs */
2610 case OPC_TEQI: /* r0 == 0 */
2611 case OPC_TGE: /* rs >= rs */
2612 case OPC_TGEI: /* r0 >= 0 */
2613 case OPC_TGEU: /* rs >= rs unsigned */
2614 case OPC_TGEIU: /* r0 >= 0 unsigned */
2615 /* Always trap */
2616 generate_exception(ctx, EXCP_TRAP);
2617 break;
2618 case OPC_TLT: /* rs < rs */
2619 case OPC_TLTI: /* r0 < 0 */
2620 case OPC_TLTU: /* rs < rs unsigned */
2621 case OPC_TLTIU: /* r0 < 0 unsigned */
2622 case OPC_TNE: /* rs != rs */
2623 case OPC_TNEI: /* r0 != 0 */
2624 /* Never trap: treat as NOP. */
2625 break;
2627 } else {
2628 int l1 = gen_new_label();
2630 switch (opc) {
2631 case OPC_TEQ:
2632 case OPC_TEQI:
2633 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2634 break;
2635 case OPC_TGE:
2636 case OPC_TGEI:
2637 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2638 break;
2639 case OPC_TGEU:
2640 case OPC_TGEIU:
2641 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2642 break;
2643 case OPC_TLT:
2644 case OPC_TLTI:
2645 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2646 break;
2647 case OPC_TLTU:
2648 case OPC_TLTIU:
2649 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2650 break;
2651 case OPC_TNE:
2652 case OPC_TNEI:
2653 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2654 break;
2656 generate_exception(ctx, EXCP_TRAP);
2657 gen_set_label(l1);
2659 tcg_temp_free(t0);
2660 tcg_temp_free(t1);
2663 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2665 TranslationBlock *tb;
2666 tb = ctx->tb;
2667 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2668 likely(!ctx->singlestep_enabled)) {
2669 tcg_gen_goto_tb(n);
2670 gen_save_pc(dest);
2671 tcg_gen_exit_tb((long)tb + n);
2672 } else {
2673 gen_save_pc(dest);
2674 if (ctx->singlestep_enabled) {
2675 save_cpu_state(ctx, 0);
2676 gen_helper_0i(raise_exception, EXCP_DEBUG);
2678 tcg_gen_exit_tb(0);
2682 /* Branches (before delay slot) */
2683 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2684 int insn_bytes,
2685 int rs, int rt, int32_t offset)
2687 target_ulong btgt = -1;
2688 int blink = 0;
2689 int bcond_compute = 0;
2690 TCGv t0 = tcg_temp_new();
2691 TCGv t1 = tcg_temp_new();
2693 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2694 #ifdef MIPS_DEBUG_DISAS
2695 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2696 #endif
2697 generate_exception(ctx, EXCP_RI);
2698 goto out;
2701 /* Load needed operands */
2702 switch (opc) {
2703 case OPC_BEQ:
2704 case OPC_BEQL:
2705 case OPC_BNE:
2706 case OPC_BNEL:
2707 /* Compare two registers */
2708 if (rs != rt) {
2709 gen_load_gpr(t0, rs);
2710 gen_load_gpr(t1, rt);
2711 bcond_compute = 1;
2713 btgt = ctx->pc + insn_bytes + offset;
2714 break;
2715 case OPC_BGEZ:
2716 case OPC_BGEZAL:
2717 case OPC_BGEZALS:
2718 case OPC_BGEZALL:
2719 case OPC_BGEZL:
2720 case OPC_BGTZ:
2721 case OPC_BGTZL:
2722 case OPC_BLEZ:
2723 case OPC_BLEZL:
2724 case OPC_BLTZ:
2725 case OPC_BLTZAL:
2726 case OPC_BLTZALS:
2727 case OPC_BLTZALL:
2728 case OPC_BLTZL:
2729 /* Compare to zero */
2730 if (rs != 0) {
2731 gen_load_gpr(t0, rs);
2732 bcond_compute = 1;
2734 btgt = ctx->pc + insn_bytes + offset;
2735 break;
2736 case OPC_J:
2737 case OPC_JAL:
2738 case OPC_JALX:
2739 case OPC_JALS:
2740 case OPC_JALXS:
2741 /* Jump to immediate */
2742 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2743 break;
2744 case OPC_JR:
2745 case OPC_JALR:
2746 case OPC_JALRC:
2747 case OPC_JALRS:
2748 /* Jump to register */
2749 if (offset != 0 && offset != 16) {
2750 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2751 others are reserved. */
2752 MIPS_INVAL("jump hint");
2753 generate_exception(ctx, EXCP_RI);
2754 goto out;
2756 gen_load_gpr(btarget, rs);
2757 break;
2758 default:
2759 MIPS_INVAL("branch/jump");
2760 generate_exception(ctx, EXCP_RI);
2761 goto out;
2763 if (bcond_compute == 0) {
2764 /* No condition to be computed */
2765 switch (opc) {
2766 case OPC_BEQ: /* rx == rx */
2767 case OPC_BEQL: /* rx == rx likely */
2768 case OPC_BGEZ: /* 0 >= 0 */
2769 case OPC_BGEZL: /* 0 >= 0 likely */
2770 case OPC_BLEZ: /* 0 <= 0 */
2771 case OPC_BLEZL: /* 0 <= 0 likely */
2772 /* Always take */
2773 ctx->hflags |= MIPS_HFLAG_B;
2774 MIPS_DEBUG("balways");
2775 break;
2776 case OPC_BGEZALS:
2777 case OPC_BGEZAL: /* 0 >= 0 */
2778 case OPC_BGEZALL: /* 0 >= 0 likely */
2779 ctx->hflags |= (opc == OPC_BGEZALS
2780 ? MIPS_HFLAG_BDS16
2781 : MIPS_HFLAG_BDS32);
2782 /* Always take and link */
2783 blink = 31;
2784 ctx->hflags |= MIPS_HFLAG_B;
2785 MIPS_DEBUG("balways and link");
2786 break;
2787 case OPC_BNE: /* rx != rx */
2788 case OPC_BGTZ: /* 0 > 0 */
2789 case OPC_BLTZ: /* 0 < 0 */
2790 /* Treat as NOP. */
2791 MIPS_DEBUG("bnever (NOP)");
2792 goto out;
2793 case OPC_BLTZALS:
2794 case OPC_BLTZAL: /* 0 < 0 */
2795 ctx->hflags |= (opc == OPC_BLTZALS
2796 ? MIPS_HFLAG_BDS16
2797 : MIPS_HFLAG_BDS32);
2798 /* Handle as an unconditional branch to get correct delay
2799 slot checking. */
2800 blink = 31;
2801 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2802 ctx->hflags |= MIPS_HFLAG_B;
2803 MIPS_DEBUG("bnever and link");
2804 break;
2805 case OPC_BLTZALL: /* 0 < 0 likely */
2806 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2807 /* Skip the instruction in the delay slot */
2808 MIPS_DEBUG("bnever, link and skip");
2809 ctx->pc += 4;
2810 goto out;
2811 case OPC_BNEL: /* rx != rx likely */
2812 case OPC_BGTZL: /* 0 > 0 likely */
2813 case OPC_BLTZL: /* 0 < 0 likely */
2814 /* Skip the instruction in the delay slot */
2815 MIPS_DEBUG("bnever and skip");
2816 ctx->pc += 4;
2817 goto out;
2818 case OPC_J:
2819 ctx->hflags |= MIPS_HFLAG_B;
2820 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2821 break;
2822 case OPC_JALXS:
2823 case OPC_JALX:
2824 ctx->hflags |= MIPS_HFLAG_BX;
2825 /* Fallthrough */
2826 case OPC_JALS:
2827 case OPC_JAL:
2828 blink = 31;
2829 ctx->hflags |= MIPS_HFLAG_B;
2830 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2831 ? MIPS_HFLAG_BDS16
2832 : MIPS_HFLAG_BDS32);
2833 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2834 break;
2835 case OPC_JR:
2836 ctx->hflags |= MIPS_HFLAG_BR;
2837 if (insn_bytes == 4)
2838 ctx->hflags |= MIPS_HFLAG_BDS32;
2839 MIPS_DEBUG("jr %s", regnames[rs]);
2840 break;
2841 case OPC_JALRS:
2842 case OPC_JALR:
2843 case OPC_JALRC:
2844 blink = rt;
2845 ctx->hflags |= MIPS_HFLAG_BR;
2846 ctx->hflags |= (opc == OPC_JALRS
2847 ? MIPS_HFLAG_BDS16
2848 : MIPS_HFLAG_BDS32);
2849 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2850 break;
2851 default:
2852 MIPS_INVAL("branch/jump");
2853 generate_exception(ctx, EXCP_RI);
2854 goto out;
2856 } else {
2857 switch (opc) {
2858 case OPC_BEQ:
2859 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2860 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2861 regnames[rs], regnames[rt], btgt);
2862 goto not_likely;
2863 case OPC_BEQL:
2864 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2865 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2866 regnames[rs], regnames[rt], btgt);
2867 goto likely;
2868 case OPC_BNE:
2869 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2870 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2871 regnames[rs], regnames[rt], btgt);
2872 goto not_likely;
2873 case OPC_BNEL:
2874 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2875 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2876 regnames[rs], regnames[rt], btgt);
2877 goto likely;
2878 case OPC_BGEZ:
2879 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2880 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2881 goto not_likely;
2882 case OPC_BGEZL:
2883 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2884 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2885 goto likely;
2886 case OPC_BGEZALS:
2887 case OPC_BGEZAL:
2888 ctx->hflags |= (opc == OPC_BGEZALS
2889 ? MIPS_HFLAG_BDS16
2890 : MIPS_HFLAG_BDS32);
2891 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2892 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2893 blink = 31;
2894 goto not_likely;
2895 case OPC_BGEZALL:
2896 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2897 blink = 31;
2898 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2899 goto likely;
2900 case OPC_BGTZ:
2901 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2902 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2903 goto not_likely;
2904 case OPC_BGTZL:
2905 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2906 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2907 goto likely;
2908 case OPC_BLEZ:
2909 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2910 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2911 goto not_likely;
2912 case OPC_BLEZL:
2913 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2914 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2915 goto likely;
2916 case OPC_BLTZ:
2917 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2918 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2919 goto not_likely;
2920 case OPC_BLTZL:
2921 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2922 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2923 goto likely;
2924 case OPC_BLTZALS:
2925 case OPC_BLTZAL:
2926 ctx->hflags |= (opc == OPC_BLTZALS
2927 ? MIPS_HFLAG_BDS16
2928 : MIPS_HFLAG_BDS32);
2929 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2930 blink = 31;
2931 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2932 not_likely:
2933 ctx->hflags |= MIPS_HFLAG_BC;
2934 break;
2935 case OPC_BLTZALL:
2936 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2937 blink = 31;
2938 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2939 likely:
2940 ctx->hflags |= MIPS_HFLAG_BL;
2941 break;
2942 default:
2943 MIPS_INVAL("conditional branch/jump");
2944 generate_exception(ctx, EXCP_RI);
2945 goto out;
2948 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2949 blink, ctx->hflags, btgt);
2951 ctx->btarget = btgt;
2952 if (blink > 0) {
2953 int post_delay = insn_bytes;
2954 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2956 if (opc != OPC_JALRC)
2957 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2959 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2962 out:
2963 if (insn_bytes == 2)
2964 ctx->hflags |= MIPS_HFLAG_B16;
2965 tcg_temp_free(t0);
2966 tcg_temp_free(t1);
2969 /* special3 bitfield operations */
2970 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2971 int rs, int lsb, int msb)
2973 TCGv t0 = tcg_temp_new();
2974 TCGv t1 = tcg_temp_new();
2975 target_ulong mask;
2977 gen_load_gpr(t1, rs);
2978 switch (opc) {
2979 case OPC_EXT:
2980 if (lsb + msb > 31)
2981 goto fail;
2982 tcg_gen_shri_tl(t0, t1, lsb);
2983 if (msb != 31) {
2984 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2985 } else {
2986 tcg_gen_ext32s_tl(t0, t0);
2988 break;
2989 #if defined(TARGET_MIPS64)
2990 case OPC_DEXTM:
2991 tcg_gen_shri_tl(t0, t1, lsb);
2992 if (msb != 31) {
2993 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2995 break;
2996 case OPC_DEXTU:
2997 tcg_gen_shri_tl(t0, t1, lsb + 32);
2998 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2999 break;
3000 case OPC_DEXT:
3001 tcg_gen_shri_tl(t0, t1, lsb);
3002 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3003 break;
3004 #endif
3005 case OPC_INS:
3006 if (lsb > msb)
3007 goto fail;
3008 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3009 gen_load_gpr(t0, rt);
3010 tcg_gen_andi_tl(t0, t0, ~mask);
3011 tcg_gen_shli_tl(t1, t1, lsb);
3012 tcg_gen_andi_tl(t1, t1, mask);
3013 tcg_gen_or_tl(t0, t0, t1);
3014 tcg_gen_ext32s_tl(t0, t0);
3015 break;
3016 #if defined(TARGET_MIPS64)
3017 case OPC_DINSM:
3018 if (lsb > msb)
3019 goto fail;
3020 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3021 gen_load_gpr(t0, rt);
3022 tcg_gen_andi_tl(t0, t0, ~mask);
3023 tcg_gen_shli_tl(t1, t1, lsb);
3024 tcg_gen_andi_tl(t1, t1, mask);
3025 tcg_gen_or_tl(t0, t0, t1);
3026 break;
3027 case OPC_DINSU:
3028 if (lsb > msb)
3029 goto fail;
3030 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3031 gen_load_gpr(t0, rt);
3032 tcg_gen_andi_tl(t0, t0, ~mask);
3033 tcg_gen_shli_tl(t1, t1, lsb + 32);
3034 tcg_gen_andi_tl(t1, t1, mask);
3035 tcg_gen_or_tl(t0, t0, t1);
3036 break;
3037 case OPC_DINS:
3038 if (lsb > msb)
3039 goto fail;
3040 gen_load_gpr(t0, rt);
3041 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3042 gen_load_gpr(t0, rt);
3043 tcg_gen_andi_tl(t0, t0, ~mask);
3044 tcg_gen_shli_tl(t1, t1, lsb);
3045 tcg_gen_andi_tl(t1, t1, mask);
3046 tcg_gen_or_tl(t0, t0, t1);
3047 break;
3048 #endif
3049 default:
3050 fail:
3051 MIPS_INVAL("bitops");
3052 generate_exception(ctx, EXCP_RI);
3053 tcg_temp_free(t0);
3054 tcg_temp_free(t1);
3055 return;
3057 gen_store_gpr(t0, rt);
3058 tcg_temp_free(t0);
3059 tcg_temp_free(t1);
3062 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3064 TCGv t0;
3066 if (rd == 0) {
3067 /* If no destination, treat it as a NOP. */
3068 MIPS_DEBUG("NOP");
3069 return;
3072 t0 = tcg_temp_new();
3073 gen_load_gpr(t0, rt);
3074 switch (op2) {
3075 case OPC_WSBH:
3077 TCGv t1 = tcg_temp_new();
3079 tcg_gen_shri_tl(t1, t0, 8);
3080 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3081 tcg_gen_shli_tl(t0, t0, 8);
3082 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3083 tcg_gen_or_tl(t0, t0, t1);
3084 tcg_temp_free(t1);
3085 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3087 break;
3088 case OPC_SEB:
3089 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3090 break;
3091 case OPC_SEH:
3092 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3093 break;
3094 #if defined(TARGET_MIPS64)
3095 case OPC_DSBH:
3097 TCGv t1 = tcg_temp_new();
3099 tcg_gen_shri_tl(t1, t0, 8);
3100 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
3101 tcg_gen_shli_tl(t0, t0, 8);
3102 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
3103 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3104 tcg_temp_free(t1);
3106 break;
3107 case OPC_DSHD:
3109 TCGv t1 = tcg_temp_new();
3111 tcg_gen_shri_tl(t1, t0, 16);
3112 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
3113 tcg_gen_shli_tl(t0, t0, 16);
3114 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
3115 tcg_gen_or_tl(t0, t0, t1);
3116 tcg_gen_shri_tl(t1, t0, 32);
3117 tcg_gen_shli_tl(t0, t0, 32);
3118 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3119 tcg_temp_free(t1);
3121 break;
3122 #endif
3123 default:
3124 MIPS_INVAL("bsfhl");
3125 generate_exception(ctx, EXCP_RI);
3126 tcg_temp_free(t0);
3127 return;
3129 tcg_temp_free(t0);
3132 #ifndef CONFIG_USER_ONLY
3133 /* CP0 (MMU and control) */
3134 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
3136 TCGv_i32 t0 = tcg_temp_new_i32();
3138 tcg_gen_ld_i32(t0, cpu_env, off);
3139 tcg_gen_ext_i32_tl(arg, t0);
3140 tcg_temp_free_i32(t0);
3143 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
3145 tcg_gen_ld_tl(arg, cpu_env, off);
3146 tcg_gen_ext32s_tl(arg, arg);
3149 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
3151 TCGv_i32 t0 = tcg_temp_new_i32();
3153 tcg_gen_trunc_tl_i32(t0, arg);
3154 tcg_gen_st_i32(t0, cpu_env, off);
3155 tcg_temp_free_i32(t0);
3158 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
3160 tcg_gen_ext32s_tl(arg, arg);
3161 tcg_gen_st_tl(arg, cpu_env, off);
3164 static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3166 const char *rn = "invalid";
3168 if (sel != 0)
3169 check_insn(env, ctx, ISA_MIPS32);
3171 switch (reg) {
3172 case 0:
3173 switch (sel) {
3174 case 0:
3175 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
3176 rn = "Index";
3177 break;
3178 case 1:
3179 check_insn(env, ctx, ASE_MT);
3180 gen_helper_mfc0_mvpcontrol(arg);
3181 rn = "MVPControl";
3182 break;
3183 case 2:
3184 check_insn(env, ctx, ASE_MT);
3185 gen_helper_mfc0_mvpconf0(arg);
3186 rn = "MVPConf0";
3187 break;
3188 case 3:
3189 check_insn(env, ctx, ASE_MT);
3190 gen_helper_mfc0_mvpconf1(arg);
3191 rn = "MVPConf1";
3192 break;
3193 default:
3194 goto die;
3196 break;
3197 case 1:
3198 switch (sel) {
3199 case 0:
3200 gen_helper_mfc0_random(arg);
3201 rn = "Random";
3202 break;
3203 case 1:
3204 check_insn(env, ctx, ASE_MT);
3205 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
3206 rn = "VPEControl";
3207 break;
3208 case 2:
3209 check_insn(env, ctx, ASE_MT);
3210 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
3211 rn = "VPEConf0";
3212 break;
3213 case 3:
3214 check_insn(env, ctx, ASE_MT);
3215 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
3216 rn = "VPEConf1";
3217 break;
3218 case 4:
3219 check_insn(env, ctx, ASE_MT);
3220 gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
3221 rn = "YQMask";
3222 break;
3223 case 5:
3224 check_insn(env, ctx, ASE_MT);
3225 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
3226 rn = "VPESchedule";
3227 break;
3228 case 6:
3229 check_insn(env, ctx, ASE_MT);
3230 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3231 rn = "VPEScheFBack";
3232 break;
3233 case 7:
3234 check_insn(env, ctx, ASE_MT);
3235 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
3236 rn = "VPEOpt";
3237 break;
3238 default:
3239 goto die;
3241 break;
3242 case 2:
3243 switch (sel) {
3244 case 0:
3245 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
3246 tcg_gen_ext32s_tl(arg, arg);
3247 rn = "EntryLo0";
3248 break;
3249 case 1:
3250 check_insn(env, ctx, ASE_MT);
3251 gen_helper_mfc0_tcstatus(arg);
3252 rn = "TCStatus";
3253 break;
3254 case 2:
3255 check_insn(env, ctx, ASE_MT);
3256 gen_helper_mfc0_tcbind(arg);
3257 rn = "TCBind";
3258 break;
3259 case 3:
3260 check_insn(env, ctx, ASE_MT);
3261 gen_helper_mfc0_tcrestart(arg);
3262 rn = "TCRestart";
3263 break;
3264 case 4:
3265 check_insn(env, ctx, ASE_MT);
3266 gen_helper_mfc0_tchalt(arg);
3267 rn = "TCHalt";
3268 break;
3269 case 5:
3270 check_insn(env, ctx, ASE_MT);
3271 gen_helper_mfc0_tccontext(arg);
3272 rn = "TCContext";
3273 break;
3274 case 6:
3275 check_insn(env, ctx, ASE_MT);
3276 gen_helper_mfc0_tcschedule(arg);
3277 rn = "TCSchedule";
3278 break;
3279 case 7:
3280 check_insn(env, ctx, ASE_MT);
3281 gen_helper_mfc0_tcschefback(arg);
3282 rn = "TCScheFBack";
3283 break;
3284 default:
3285 goto die;
3287 break;
3288 case 3:
3289 switch (sel) {
3290 case 0:
3291 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3292 tcg_gen_ext32s_tl(arg, arg);
3293 rn = "EntryLo1";
3294 break;
3295 default:
3296 goto die;
3298 break;
3299 case 4:
3300 switch (sel) {
3301 case 0:
3302 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3303 tcg_gen_ext32s_tl(arg, arg);
3304 rn = "Context";
3305 break;
3306 case 1:
3307 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3308 rn = "ContextConfig";
3309 // break;
3310 default:
3311 goto die;
3313 break;
3314 case 5:
3315 switch (sel) {
3316 case 0:
3317 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3318 rn = "PageMask";
3319 break;
3320 case 1:
3321 check_insn(env, ctx, ISA_MIPS32R2);
3322 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3323 rn = "PageGrain";
3324 break;
3325 default:
3326 goto die;
3328 break;
3329 case 6:
3330 switch (sel) {
3331 case 0:
3332 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3333 rn = "Wired";
3334 break;
3335 case 1:
3336 check_insn(env, ctx, ISA_MIPS32R2);
3337 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3338 rn = "SRSConf0";
3339 break;
3340 case 2:
3341 check_insn(env, ctx, ISA_MIPS32R2);
3342 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3343 rn = "SRSConf1";
3344 break;
3345 case 3:
3346 check_insn(env, ctx, ISA_MIPS32R2);
3347 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3348 rn = "SRSConf2";
3349 break;
3350 case 4:
3351 check_insn(env, ctx, ISA_MIPS32R2);
3352 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3353 rn = "SRSConf3";
3354 break;
3355 case 5:
3356 check_insn(env, ctx, ISA_MIPS32R2);
3357 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3358 rn = "SRSConf4";
3359 break;
3360 default:
3361 goto die;
3363 break;
3364 case 7:
3365 switch (sel) {
3366 case 0:
3367 check_insn(env, ctx, ISA_MIPS32R2);
3368 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3369 rn = "HWREna";
3370 break;
3371 default:
3372 goto die;
3374 break;
3375 case 8:
3376 switch (sel) {
3377 case 0:
3378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3379 tcg_gen_ext32s_tl(arg, arg);
3380 rn = "BadVAddr";
3381 break;
3382 default:
3383 goto die;
3385 break;
3386 case 9:
3387 switch (sel) {
3388 case 0:
3389 /* Mark as an IO operation because we read the time. */
3390 if (use_icount)
3391 gen_io_start();
3392 gen_helper_mfc0_count(arg);
3393 if (use_icount) {
3394 gen_io_end();
3395 ctx->bstate = BS_STOP;
3397 rn = "Count";
3398 break;
3399 /* 6,7 are implementation dependent */
3400 default:
3401 goto die;
3403 break;
3404 case 10:
3405 switch (sel) {
3406 case 0:
3407 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3408 tcg_gen_ext32s_tl(arg, arg);
3409 rn = "EntryHi";
3410 break;
3411 default:
3412 goto die;
3414 break;
3415 case 11:
3416 switch (sel) {
3417 case 0:
3418 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3419 rn = "Compare";
3420 break;
3421 /* 6,7 are implementation dependent */
3422 default:
3423 goto die;
3425 break;
3426 case 12:
3427 switch (sel) {
3428 case 0:
3429 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3430 rn = "Status";
3431 break;
3432 case 1:
3433 check_insn(env, ctx, ISA_MIPS32R2);
3434 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3435 rn = "IntCtl";
3436 break;
3437 case 2:
3438 check_insn(env, ctx, ISA_MIPS32R2);
3439 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3440 rn = "SRSCtl";
3441 break;
3442 case 3:
3443 check_insn(env, ctx, ISA_MIPS32R2);
3444 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3445 rn = "SRSMap";
3446 break;
3447 default:
3448 goto die;
3450 break;
3451 case 13:
3452 switch (sel) {
3453 case 0:
3454 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3455 rn = "Cause";
3456 break;
3457 default:
3458 goto die;
3460 break;
3461 case 14:
3462 switch (sel) {
3463 case 0:
3464 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3465 tcg_gen_ext32s_tl(arg, arg);
3466 rn = "EPC";
3467 break;
3468 default:
3469 goto die;
3471 break;
3472 case 15:
3473 switch (sel) {
3474 case 0:
3475 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3476 rn = "PRid";
3477 break;
3478 case 1:
3479 check_insn(env, ctx, ISA_MIPS32R2);
3480 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3481 rn = "EBase";
3482 break;
3483 default:
3484 goto die;
3486 break;
3487 case 16:
3488 switch (sel) {
3489 case 0:
3490 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3491 rn = "Config";
3492 break;
3493 case 1:
3494 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3495 rn = "Config1";
3496 break;
3497 case 2:
3498 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3499 rn = "Config2";
3500 break;
3501 case 3:
3502 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3503 rn = "Config3";
3504 break;
3505 /* 4,5 are reserved */
3506 /* 6,7 are implementation dependent */
3507 case 6:
3508 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3509 rn = "Config6";
3510 break;
3511 case 7:
3512 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3513 rn = "Config7";
3514 break;
3515 default:
3516 goto die;
3518 break;
3519 case 17:
3520 switch (sel) {
3521 case 0:
3522 gen_helper_mfc0_lladdr(arg);
3523 rn = "LLAddr";
3524 break;
3525 default:
3526 goto die;
3528 break;
3529 case 18:
3530 switch (sel) {
3531 case 0 ... 7:
3532 gen_helper_1i(mfc0_watchlo, arg, sel);
3533 rn = "WatchLo";
3534 break;
3535 default:
3536 goto die;
3538 break;
3539 case 19:
3540 switch (sel) {
3541 case 0 ...7:
3542 gen_helper_1i(mfc0_watchhi, arg, sel);
3543 rn = "WatchHi";
3544 break;
3545 default:
3546 goto die;
3548 break;
3549 case 20:
3550 switch (sel) {
3551 case 0:
3552 #if defined(TARGET_MIPS64)
3553 check_insn(env, ctx, ISA_MIPS3);
3554 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3555 tcg_gen_ext32s_tl(arg, arg);
3556 rn = "XContext";
3557 break;
3558 #endif
3559 default:
3560 goto die;
3562 break;
3563 case 21:
3564 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3565 switch (sel) {
3566 case 0:
3567 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3568 rn = "Framemask";
3569 break;
3570 default:
3571 goto die;
3573 break;
3574 case 22:
3575 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3576 rn = "'Diagnostic"; /* implementation dependent */
3577 break;
3578 case 23:
3579 switch (sel) {
3580 case 0:
3581 gen_helper_mfc0_debug(arg); /* EJTAG support */
3582 rn = "Debug";
3583 break;
3584 case 1:
3585 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3586 rn = "TraceControl";
3587 // break;
3588 case 2:
3589 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3590 rn = "TraceControl2";
3591 // break;
3592 case 3:
3593 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3594 rn = "UserTraceData";
3595 // break;
3596 case 4:
3597 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3598 rn = "TraceBPC";
3599 // break;
3600 default:
3601 goto die;
3603 break;
3604 case 24:
3605 switch (sel) {
3606 case 0:
3607 /* EJTAG support */
3608 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3609 tcg_gen_ext32s_tl(arg, arg);
3610 rn = "DEPC";
3611 break;
3612 default:
3613 goto die;
3615 break;
3616 case 25:
3617 switch (sel) {
3618 case 0:
3619 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3620 rn = "Performance0";
3621 break;
3622 case 1:
3623 // gen_helper_mfc0_performance1(arg);
3624 rn = "Performance1";
3625 // break;
3626 case 2:
3627 // gen_helper_mfc0_performance2(arg);
3628 rn = "Performance2";
3629 // break;
3630 case 3:
3631 // gen_helper_mfc0_performance3(arg);
3632 rn = "Performance3";
3633 // break;
3634 case 4:
3635 // gen_helper_mfc0_performance4(arg);
3636 rn = "Performance4";
3637 // break;
3638 case 5:
3639 // gen_helper_mfc0_performance5(arg);
3640 rn = "Performance5";
3641 // break;
3642 case 6:
3643 // gen_helper_mfc0_performance6(arg);
3644 rn = "Performance6";
3645 // break;
3646 case 7:
3647 // gen_helper_mfc0_performance7(arg);
3648 rn = "Performance7";
3649 // break;
3650 default:
3651 goto die;
3653 break;
3654 case 26:
3655 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3656 rn = "ECC";
3657 break;
3658 case 27:
3659 switch (sel) {
3660 case 0 ... 3:
3661 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3662 rn = "CacheErr";
3663 break;
3664 default:
3665 goto die;
3667 break;
3668 case 28:
3669 switch (sel) {
3670 case 0:
3671 case 2:
3672 case 4:
3673 case 6:
3674 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3675 rn = "TagLo";
3676 break;
3677 case 1:
3678 case 3:
3679 case 5:
3680 case 7:
3681 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3682 rn = "DataLo";
3683 break;
3684 default:
3685 goto die;
3687 break;
3688 case 29:
3689 switch (sel) {
3690 case 0:
3691 case 2:
3692 case 4:
3693 case 6:
3694 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3695 rn = "TagHi";
3696 break;
3697 case 1:
3698 case 3:
3699 case 5:
3700 case 7:
3701 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3702 rn = "DataHi";
3703 break;
3704 default:
3705 goto die;
3707 break;
3708 case 30:
3709 switch (sel) {
3710 case 0:
3711 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3712 tcg_gen_ext32s_tl(arg, arg);
3713 rn = "ErrorEPC";
3714 break;
3715 default:
3716 goto die;
3718 break;
3719 case 31:
3720 switch (sel) {
3721 case 0:
3722 /* EJTAG support */
3723 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3724 rn = "DESAVE";
3725 break;
3726 default:
3727 goto die;
3729 break;
3730 default:
3731 goto die;
3733 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3734 return;
3736 die:
3737 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3738 generate_exception(ctx, EXCP_RI);
3741 static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3743 const char *rn = "invalid";
3745 if (sel != 0)
3746 check_insn(env, ctx, ISA_MIPS32);
3748 if (use_icount)
3749 gen_io_start();
3751 switch (reg) {
3752 case 0:
3753 switch (sel) {
3754 case 0:
3755 gen_helper_mtc0_index(arg);
3756 rn = "Index";
3757 break;
3758 case 1:
3759 check_insn(env, ctx, ASE_MT);
3760 gen_helper_mtc0_mvpcontrol(arg);
3761 rn = "MVPControl";
3762 break;
3763 case 2:
3764 check_insn(env, ctx, ASE_MT);
3765 /* ignored */
3766 rn = "MVPConf0";
3767 break;
3768 case 3:
3769 check_insn(env, ctx, ASE_MT);
3770 /* ignored */
3771 rn = "MVPConf1";
3772 break;
3773 default:
3774 goto die;
3776 break;
3777 case 1:
3778 switch (sel) {
3779 case 0:
3780 /* ignored */
3781 rn = "Random";
3782 break;
3783 case 1:
3784 check_insn(env, ctx, ASE_MT);
3785 gen_helper_mtc0_vpecontrol(arg);
3786 rn = "VPEControl";
3787 break;
3788 case 2:
3789 check_insn(env, ctx, ASE_MT);
3790 gen_helper_mtc0_vpeconf0(arg);
3791 rn = "VPEConf0";
3792 break;
3793 case 3:
3794 check_insn(env, ctx, ASE_MT);
3795 gen_helper_mtc0_vpeconf1(arg);
3796 rn = "VPEConf1";
3797 break;
3798 case 4:
3799 check_insn(env, ctx, ASE_MT);
3800 gen_helper_mtc0_yqmask(arg);
3801 rn = "YQMask";
3802 break;
3803 case 5:
3804 check_insn(env, ctx, ASE_MT);
3805 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3806 rn = "VPESchedule";
3807 break;
3808 case 6:
3809 check_insn(env, ctx, ASE_MT);
3810 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3811 rn = "VPEScheFBack";
3812 break;
3813 case 7:
3814 check_insn(env, ctx, ASE_MT);
3815 gen_helper_mtc0_vpeopt(arg);
3816 rn = "VPEOpt";
3817 break;
3818 default:
3819 goto die;
3821 break;
3822 case 2:
3823 switch (sel) {
3824 case 0:
3825 gen_helper_mtc0_entrylo0(arg);
3826 rn = "EntryLo0";
3827 break;
3828 case 1:
3829 check_insn(env, ctx, ASE_MT);
3830 gen_helper_mtc0_tcstatus(arg);
3831 rn = "TCStatus";
3832 break;
3833 case 2:
3834 check_insn(env, ctx, ASE_MT);
3835 gen_helper_mtc0_tcbind(arg);
3836 rn = "TCBind";
3837 break;
3838 case 3:
3839 check_insn(env, ctx, ASE_MT);
3840 gen_helper_mtc0_tcrestart(arg);
3841 rn = "TCRestart";
3842 break;
3843 case 4:
3844 check_insn(env, ctx, ASE_MT);
3845 gen_helper_mtc0_tchalt(arg);
3846 rn = "TCHalt";
3847 break;
3848 case 5:
3849 check_insn(env, ctx, ASE_MT);
3850 gen_helper_mtc0_tccontext(arg);
3851 rn = "TCContext";
3852 break;
3853 case 6:
3854 check_insn(env, ctx, ASE_MT);
3855 gen_helper_mtc0_tcschedule(arg);
3856 rn = "TCSchedule";
3857 break;
3858 case 7:
3859 check_insn(env, ctx, ASE_MT);
3860 gen_helper_mtc0_tcschefback(arg);
3861 rn = "TCScheFBack";
3862 break;
3863 default:
3864 goto die;
3866 break;
3867 case 3:
3868 switch (sel) {
3869 case 0:
3870 gen_helper_mtc0_entrylo1(arg);
3871 rn = "EntryLo1";
3872 break;
3873 default:
3874 goto die;
3876 break;
3877 case 4:
3878 switch (sel) {
3879 case 0:
3880 gen_helper_mtc0_context(arg);
3881 rn = "Context";
3882 break;
3883 case 1:
3884 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3885 rn = "ContextConfig";
3886 // break;
3887 default:
3888 goto die;
3890 break;
3891 case 5:
3892 switch (sel) {
3893 case 0:
3894 gen_helper_mtc0_pagemask(arg);
3895 rn = "PageMask";
3896 break;
3897 case 1:
3898 check_insn(env, ctx, ISA_MIPS32R2);
3899 gen_helper_mtc0_pagegrain(arg);
3900 rn = "PageGrain";
3901 break;
3902 default:
3903 goto die;
3905 break;
3906 case 6:
3907 switch (sel) {
3908 case 0:
3909 gen_helper_mtc0_wired(arg);
3910 rn = "Wired";
3911 break;
3912 case 1:
3913 check_insn(env, ctx, ISA_MIPS32R2);
3914 gen_helper_mtc0_srsconf0(arg);
3915 rn = "SRSConf0";
3916 break;
3917 case 2:
3918 check_insn(env, ctx, ISA_MIPS32R2);
3919 gen_helper_mtc0_srsconf1(arg);
3920 rn = "SRSConf1";
3921 break;
3922 case 3:
3923 check_insn(env, ctx, ISA_MIPS32R2);
3924 gen_helper_mtc0_srsconf2(arg);
3925 rn = "SRSConf2";
3926 break;
3927 case 4:
3928 check_insn(env, ctx, ISA_MIPS32R2);
3929 gen_helper_mtc0_srsconf3(arg);
3930 rn = "SRSConf3";
3931 break;
3932 case 5:
3933 check_insn(env, ctx, ISA_MIPS32R2);
3934 gen_helper_mtc0_srsconf4(arg);
3935 rn = "SRSConf4";
3936 break;
3937 default:
3938 goto die;
3940 break;
3941 case 7:
3942 switch (sel) {
3943 case 0:
3944 check_insn(env, ctx, ISA_MIPS32R2);
3945 gen_helper_mtc0_hwrena(arg);
3946 rn = "HWREna";
3947 break;
3948 default:
3949 goto die;
3951 break;
3952 case 8:
3953 /* ignored */
3954 rn = "BadVAddr";
3955 break;
3956 case 9:
3957 switch (sel) {
3958 case 0:
3959 gen_helper_mtc0_count(arg);
3960 rn = "Count";
3961 break;
3962 /* 6,7 are implementation dependent */
3963 default:
3964 goto die;
3966 break;
3967 case 10:
3968 switch (sel) {
3969 case 0:
3970 gen_helper_mtc0_entryhi(arg);
3971 rn = "EntryHi";
3972 break;
3973 default:
3974 goto die;
3976 break;
3977 case 11:
3978 switch (sel) {
3979 case 0:
3980 gen_helper_mtc0_compare(arg);
3981 rn = "Compare";
3982 break;
3983 /* 6,7 are implementation dependent */
3984 default:
3985 goto die;
3987 break;
3988 case 12:
3989 switch (sel) {
3990 case 0:
3991 save_cpu_state(ctx, 1);
3992 gen_helper_mtc0_status(arg);
3993 /* BS_STOP isn't good enough here, hflags may have changed. */
3994 gen_save_pc(ctx->pc + 4);
3995 ctx->bstate = BS_EXCP;
3996 rn = "Status";
3997 break;
3998 case 1:
3999 check_insn(env, ctx, ISA_MIPS32R2);
4000 gen_helper_mtc0_intctl(arg);
4001 /* Stop translation as we may have switched the execution mode */
4002 ctx->bstate = BS_STOP;
4003 rn = "IntCtl";
4004 break;
4005 case 2:
4006 check_insn(env, ctx, ISA_MIPS32R2);
4007 gen_helper_mtc0_srsctl(arg);
4008 /* Stop translation as we may have switched the execution mode */
4009 ctx->bstate = BS_STOP;
4010 rn = "SRSCtl";
4011 break;
4012 case 3:
4013 check_insn(env, ctx, ISA_MIPS32R2);
4014 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4015 /* Stop translation as we may have switched the execution mode */
4016 ctx->bstate = BS_STOP;
4017 rn = "SRSMap";
4018 break;
4019 default:
4020 goto die;
4022 break;
4023 case 13:
4024 switch (sel) {
4025 case 0:
4026 save_cpu_state(ctx, 1);
4027 gen_helper_mtc0_cause(arg);
4028 rn = "Cause";
4029 break;
4030 default:
4031 goto die;
4033 break;
4034 case 14:
4035 switch (sel) {
4036 case 0:
4037 gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
4038 rn = "EPC";
4039 break;
4040 default:
4041 goto die;
4043 break;
4044 case 15:
4045 switch (sel) {
4046 case 0:
4047 /* ignored */
4048 rn = "PRid";
4049 break;
4050 case 1:
4051 check_insn(env, ctx, ISA_MIPS32R2);
4052 gen_helper_mtc0_ebase(arg);
4053 rn = "EBase";
4054 break;
4055 default:
4056 goto die;
4058 break;
4059 case 16:
4060 switch (sel) {
4061 case 0:
4062 gen_helper_mtc0_config0(arg);
4063 rn = "Config";
4064 /* Stop translation as we may have switched the execution mode */
4065 ctx->bstate = BS_STOP;
4066 break;
4067 case 1:
4068 /* ignored, read only */
4069 rn = "Config1";
4070 break;
4071 case 2:
4072 gen_helper_mtc0_config2(arg);
4073 rn = "Config2";
4074 /* Stop translation as we may have switched the execution mode */
4075 ctx->bstate = BS_STOP;
4076 break;
4077 case 3:
4078 /* ignored, read only */
4079 rn = "Config3";
4080 break;
4081 /* 4,5 are reserved */
4082 /* 6,7 are implementation dependent */
4083 case 6:
4084 /* ignored */
4085 rn = "Config6";
4086 break;
4087 case 7:
4088 /* ignored */
4089 rn = "Config7";
4090 break;
4091 default:
4092 rn = "Invalid config selector";
4093 goto die;
4095 break;
4096 case 17:
4097 switch (sel) {
4098 case 0:
4099 gen_helper_mtc0_lladdr(arg);
4100 rn = "LLAddr";
4101 break;
4102 default:
4103 goto die;
4105 break;
4106 case 18:
4107 switch (sel) {
4108 case 0 ... 7:
4109 gen_helper_1i(mtc0_watchlo, arg, sel);
4110 rn = "WatchLo";
4111 break;
4112 default:
4113 goto die;
4115 break;
4116 case 19:
4117 switch (sel) {
4118 case 0 ... 7:
4119 gen_helper_1i(mtc0_watchhi, arg, sel);
4120 rn = "WatchHi";
4121 break;
4122 default:
4123 goto die;
4125 break;
4126 case 20:
4127 switch (sel) {
4128 case 0:
4129 #if defined(TARGET_MIPS64)
4130 check_insn(env, ctx, ISA_MIPS3);
4131 gen_helper_mtc0_xcontext(arg);
4132 rn = "XContext";
4133 break;
4134 #endif
4135 default:
4136 goto die;
4138 break;
4139 case 21:
4140 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4141 switch (sel) {
4142 case 0:
4143 gen_helper_mtc0_framemask(arg);
4144 rn = "Framemask";
4145 break;
4146 default:
4147 goto die;
4149 break;
4150 case 22:
4151 /* ignored */
4152 rn = "Diagnostic"; /* implementation dependent */
4153 break;
4154 case 23:
4155 switch (sel) {
4156 case 0:
4157 gen_helper_mtc0_debug(arg); /* EJTAG support */
4158 /* BS_STOP isn't good enough here, hflags may have changed. */
4159 gen_save_pc(ctx->pc + 4);
4160 ctx->bstate = BS_EXCP;
4161 rn = "Debug";
4162 break;
4163 case 1:
4164 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
4165 rn = "TraceControl";
4166 /* Stop translation as we may have switched the execution mode */
4167 ctx->bstate = BS_STOP;
4168 // break;
4169 case 2:
4170 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
4171 rn = "TraceControl2";
4172 /* Stop translation as we may have switched the execution mode */
4173 ctx->bstate = BS_STOP;
4174 // break;
4175 case 3:
4176 /* Stop translation as we may have switched the execution mode */
4177 ctx->bstate = BS_STOP;
4178 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
4179 rn = "UserTraceData";
4180 /* Stop translation as we may have switched the execution mode */
4181 ctx->bstate = BS_STOP;
4182 // break;
4183 case 4:
4184 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
4185 /* Stop translation as we may have switched the execution mode */
4186 ctx->bstate = BS_STOP;
4187 rn = "TraceBPC";
4188 // break;
4189 default:
4190 goto die;
4192 break;
4193 case 24:
4194 switch (sel) {
4195 case 0:
4196 /* EJTAG support */
4197 gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
4198 rn = "DEPC";
4199 break;
4200 default:
4201 goto die;
4203 break;
4204 case 25:
4205 switch (sel) {
4206 case 0:
4207 gen_helper_mtc0_performance0(arg);
4208 rn = "Performance0";
4209 break;
4210 case 1:
4211 // gen_helper_mtc0_performance1(arg);
4212 rn = "Performance1";
4213 // break;
4214 case 2:
4215 // gen_helper_mtc0_performance2(arg);
4216 rn = "Performance2";
4217 // break;
4218 case 3:
4219 // gen_helper_mtc0_performance3(arg);
4220 rn = "Performance3";
4221 // break;
4222 case 4:
4223 // gen_helper_mtc0_performance4(arg);
4224 rn = "Performance4";
4225 // break;
4226 case 5:
4227 // gen_helper_mtc0_performance5(arg);
4228 rn = "Performance5";
4229 // break;
4230 case 6:
4231 // gen_helper_mtc0_performance6(arg);
4232 rn = "Performance6";
4233 // break;
4234 case 7:
4235 // gen_helper_mtc0_performance7(arg);
4236 rn = "Performance7";
4237 // break;
4238 default:
4239 goto die;
4241 break;
4242 case 26:
4243 /* ignored */
4244 rn = "ECC";
4245 break;
4246 case 27:
4247 switch (sel) {
4248 case 0 ... 3:
4249 /* ignored */
4250 rn = "CacheErr";
4251 break;
4252 default:
4253 goto die;
4255 break;
4256 case 28:
4257 switch (sel) {
4258 case 0:
4259 case 2:
4260 case 4:
4261 case 6:
4262 gen_helper_mtc0_taglo(arg);
4263 rn = "TagLo";
4264 break;
4265 case 1:
4266 case 3:
4267 case 5:
4268 case 7:
4269 gen_helper_mtc0_datalo(arg);
4270 rn = "DataLo";
4271 break;
4272 default:
4273 goto die;
4275 break;
4276 case 29:
4277 switch (sel) {
4278 case 0:
4279 case 2:
4280 case 4:
4281 case 6:
4282 gen_helper_mtc0_taghi(arg);
4283 rn = "TagHi";
4284 break;
4285 case 1:
4286 case 3:
4287 case 5:
4288 case 7:
4289 gen_helper_mtc0_datahi(arg);
4290 rn = "DataHi";
4291 break;
4292 default:
4293 rn = "invalid sel";
4294 goto die;
4296 break;
4297 case 30:
4298 switch (sel) {
4299 case 0:
4300 gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4301 rn = "ErrorEPC";
4302 break;
4303 default:
4304 goto die;
4306 break;
4307 case 31:
4308 switch (sel) {
4309 case 0:
4310 /* EJTAG support */
4311 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4312 rn = "DESAVE";
4313 break;
4314 default:
4315 goto die;
4317 /* Stop translation as we may have switched the execution mode */
4318 ctx->bstate = BS_STOP;
4319 break;
4320 default:
4321 goto die;
4323 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4324 /* For simplicity assume that all writes can cause interrupts. */
4325 if (use_icount) {
4326 gen_io_end();
4327 ctx->bstate = BS_STOP;
4329 return;
4331 die:
4332 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4333 generate_exception(ctx, EXCP_RI);
4336 #if defined(TARGET_MIPS64)
4337 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4339 const char *rn = "invalid";
4341 if (sel != 0)
4342 check_insn(env, ctx, ISA_MIPS64);
4344 switch (reg) {
4345 case 0:
4346 switch (sel) {
4347 case 0:
4348 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4349 rn = "Index";
4350 break;
4351 case 1:
4352 check_insn(env, ctx, ASE_MT);
4353 gen_helper_mfc0_mvpcontrol(arg);
4354 rn = "MVPControl";
4355 break;
4356 case 2:
4357 check_insn(env, ctx, ASE_MT);
4358 gen_helper_mfc0_mvpconf0(arg);
4359 rn = "MVPConf0";
4360 break;
4361 case 3:
4362 check_insn(env, ctx, ASE_MT);
4363 gen_helper_mfc0_mvpconf1(arg);
4364 rn = "MVPConf1";
4365 break;
4366 default:
4367 goto die;
4369 break;
4370 case 1:
4371 switch (sel) {
4372 case 0:
4373 gen_helper_mfc0_random(arg);
4374 rn = "Random";
4375 break;
4376 case 1:
4377 check_insn(env, ctx, ASE_MT);
4378 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4379 rn = "VPEControl";
4380 break;
4381 case 2:
4382 check_insn(env, ctx, ASE_MT);
4383 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4384 rn = "VPEConf0";
4385 break;
4386 case 3:
4387 check_insn(env, ctx, ASE_MT);
4388 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4389 rn = "VPEConf1";
4390 break;
4391 case 4:
4392 check_insn(env, ctx, ASE_MT);
4393 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4394 rn = "YQMask";
4395 break;
4396 case 5:
4397 check_insn(env, ctx, ASE_MT);
4398 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4399 rn = "VPESchedule";
4400 break;
4401 case 6:
4402 check_insn(env, ctx, ASE_MT);
4403 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4404 rn = "VPEScheFBack";
4405 break;
4406 case 7:
4407 check_insn(env, ctx, ASE_MT);
4408 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4409 rn = "VPEOpt";
4410 break;
4411 default:
4412 goto die;
4414 break;
4415 case 2:
4416 switch (sel) {
4417 case 0:
4418 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4419 rn = "EntryLo0";
4420 break;
4421 case 1:
4422 check_insn(env, ctx, ASE_MT);
4423 gen_helper_mfc0_tcstatus(arg);
4424 rn = "TCStatus";
4425 break;
4426 case 2:
4427 check_insn(env, ctx, ASE_MT);
4428 gen_helper_mfc0_tcbind(arg);
4429 rn = "TCBind";
4430 break;
4431 case 3:
4432 check_insn(env, ctx, ASE_MT);
4433 gen_helper_dmfc0_tcrestart(arg);
4434 rn = "TCRestart";
4435 break;
4436 case 4:
4437 check_insn(env, ctx, ASE_MT);
4438 gen_helper_dmfc0_tchalt(arg);
4439 rn = "TCHalt";
4440 break;
4441 case 5:
4442 check_insn(env, ctx, ASE_MT);
4443 gen_helper_dmfc0_tccontext(arg);
4444 rn = "TCContext";
4445 break;
4446 case 6:
4447 check_insn(env, ctx, ASE_MT);
4448 gen_helper_dmfc0_tcschedule(arg);
4449 rn = "TCSchedule";
4450 break;
4451 case 7:
4452 check_insn(env, ctx, ASE_MT);
4453 gen_helper_dmfc0_tcschefback(arg);
4454 rn = "TCScheFBack";
4455 break;
4456 default:
4457 goto die;
4459 break;
4460 case 3:
4461 switch (sel) {
4462 case 0:
4463 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4464 rn = "EntryLo1";
4465 break;
4466 default:
4467 goto die;
4469 break;
4470 case 4:
4471 switch (sel) {
4472 case 0:
4473 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4474 rn = "Context";
4475 break;
4476 case 1:
4477 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4478 rn = "ContextConfig";
4479 // break;
4480 default:
4481 goto die;
4483 break;
4484 case 5:
4485 switch (sel) {
4486 case 0:
4487 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4488 rn = "PageMask";
4489 break;
4490 case 1:
4491 check_insn(env, ctx, ISA_MIPS32R2);
4492 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4493 rn = "PageGrain";
4494 break;
4495 default:
4496 goto die;
4498 break;
4499 case 6:
4500 switch (sel) {
4501 case 0:
4502 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4503 rn = "Wired";
4504 break;
4505 case 1:
4506 check_insn(env, ctx, ISA_MIPS32R2);
4507 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4508 rn = "SRSConf0";
4509 break;
4510 case 2:
4511 check_insn(env, ctx, ISA_MIPS32R2);
4512 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4513 rn = "SRSConf1";
4514 break;
4515 case 3:
4516 check_insn(env, ctx, ISA_MIPS32R2);
4517 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4518 rn = "SRSConf2";
4519 break;
4520 case 4:
4521 check_insn(env, ctx, ISA_MIPS32R2);
4522 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4523 rn = "SRSConf3";
4524 break;
4525 case 5:
4526 check_insn(env, ctx, ISA_MIPS32R2);
4527 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4528 rn = "SRSConf4";
4529 break;
4530 default:
4531 goto die;
4533 break;
4534 case 7:
4535 switch (sel) {
4536 case 0:
4537 check_insn(env, ctx, ISA_MIPS32R2);
4538 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4539 rn = "HWREna";
4540 break;
4541 default:
4542 goto die;
4544 break;
4545 case 8:
4546 switch (sel) {
4547 case 0:
4548 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4549 rn = "BadVAddr";
4550 break;
4551 default:
4552 goto die;
4554 break;
4555 case 9:
4556 switch (sel) {
4557 case 0:
4558 /* Mark as an IO operation because we read the time. */
4559 if (use_icount)
4560 gen_io_start();
4561 gen_helper_mfc0_count(arg);
4562 if (use_icount) {
4563 gen_io_end();
4564 ctx->bstate = BS_STOP;
4566 rn = "Count";
4567 break;
4568 /* 6,7 are implementation dependent */
4569 default:
4570 goto die;
4572 break;
4573 case 10:
4574 switch (sel) {
4575 case 0:
4576 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4577 rn = "EntryHi";
4578 break;
4579 default:
4580 goto die;
4582 break;
4583 case 11:
4584 switch (sel) {
4585 case 0:
4586 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4587 rn = "Compare";
4588 break;
4589 /* 6,7 are implementation dependent */
4590 default:
4591 goto die;
4593 break;
4594 case 12:
4595 switch (sel) {
4596 case 0:
4597 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4598 rn = "Status";
4599 break;
4600 case 1:
4601 check_insn(env, ctx, ISA_MIPS32R2);
4602 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4603 rn = "IntCtl";
4604 break;
4605 case 2:
4606 check_insn(env, ctx, ISA_MIPS32R2);
4607 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4608 rn = "SRSCtl";
4609 break;
4610 case 3:
4611 check_insn(env, ctx, ISA_MIPS32R2);
4612 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4613 rn = "SRSMap";
4614 break;
4615 default:
4616 goto die;
4618 break;
4619 case 13:
4620 switch (sel) {
4621 case 0:
4622 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4623 rn = "Cause";
4624 break;
4625 default:
4626 goto die;
4628 break;
4629 case 14:
4630 switch (sel) {
4631 case 0:
4632 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4633 rn = "EPC";
4634 break;
4635 default:
4636 goto die;
4638 break;
4639 case 15:
4640 switch (sel) {
4641 case 0:
4642 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4643 rn = "PRid";
4644 break;
4645 case 1:
4646 check_insn(env, ctx, ISA_MIPS32R2);
4647 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4648 rn = "EBase";
4649 break;
4650 default:
4651 goto die;
4653 break;
4654 case 16:
4655 switch (sel) {
4656 case 0:
4657 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4658 rn = "Config";
4659 break;
4660 case 1:
4661 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4662 rn = "Config1";
4663 break;
4664 case 2:
4665 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4666 rn = "Config2";
4667 break;
4668 case 3:
4669 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4670 rn = "Config3";
4671 break;
4672 /* 6,7 are implementation dependent */
4673 case 6:
4674 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4675 rn = "Config6";
4676 break;
4677 case 7:
4678 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4679 rn = "Config7";
4680 break;
4681 default:
4682 goto die;
4684 break;
4685 case 17:
4686 switch (sel) {
4687 case 0:
4688 gen_helper_dmfc0_lladdr(arg);
4689 rn = "LLAddr";
4690 break;
4691 default:
4692 goto die;
4694 break;
4695 case 18:
4696 switch (sel) {
4697 case 0 ... 7:
4698 gen_helper_1i(dmfc0_watchlo, arg, sel);
4699 rn = "WatchLo";
4700 break;
4701 default:
4702 goto die;
4704 break;
4705 case 19:
4706 switch (sel) {
4707 case 0 ... 7:
4708 gen_helper_1i(mfc0_watchhi, arg, sel);
4709 rn = "WatchHi";
4710 break;
4711 default:
4712 goto die;
4714 break;
4715 case 20:
4716 switch (sel) {
4717 case 0:
4718 check_insn(env, ctx, ISA_MIPS3);
4719 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4720 rn = "XContext";
4721 break;
4722 default:
4723 goto die;
4725 break;
4726 case 21:
4727 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4728 switch (sel) {
4729 case 0:
4730 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4731 rn = "Framemask";
4732 break;
4733 default:
4734 goto die;
4736 break;
4737 case 22:
4738 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4739 rn = "'Diagnostic"; /* implementation dependent */
4740 break;
4741 case 23:
4742 switch (sel) {
4743 case 0:
4744 gen_helper_mfc0_debug(arg); /* EJTAG support */
4745 rn = "Debug";
4746 break;
4747 case 1:
4748 // gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4749 rn = "TraceControl";
4750 // break;
4751 case 2:
4752 // gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4753 rn = "TraceControl2";
4754 // break;
4755 case 3:
4756 // gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4757 rn = "UserTraceData";
4758 // break;
4759 case 4:
4760 // gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4761 rn = "TraceBPC";
4762 // break;
4763 default:
4764 goto die;
4766 break;
4767 case 24:
4768 switch (sel) {
4769 case 0:
4770 /* EJTAG support */
4771 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4772 rn = "DEPC";
4773 break;
4774 default:
4775 goto die;
4777 break;
4778 case 25:
4779 switch (sel) {
4780 case 0:
4781 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4782 rn = "Performance0";
4783 break;
4784 case 1:
4785 // gen_helper_dmfc0_performance1(arg);
4786 rn = "Performance1";
4787 // break;
4788 case 2:
4789 // gen_helper_dmfc0_performance2(arg);
4790 rn = "Performance2";
4791 // break;
4792 case 3:
4793 // gen_helper_dmfc0_performance3(arg);
4794 rn = "Performance3";
4795 // break;
4796 case 4:
4797 // gen_helper_dmfc0_performance4(arg);
4798 rn = "Performance4";
4799 // break;
4800 case 5:
4801 // gen_helper_dmfc0_performance5(arg);
4802 rn = "Performance5";
4803 // break;
4804 case 6:
4805 // gen_helper_dmfc0_performance6(arg);
4806 rn = "Performance6";
4807 // break;
4808 case 7:
4809 // gen_helper_dmfc0_performance7(arg);
4810 rn = "Performance7";
4811 // break;
4812 default:
4813 goto die;
4815 break;
4816 case 26:
4817 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4818 rn = "ECC";
4819 break;
4820 case 27:
4821 switch (sel) {
4822 /* ignored */
4823 case 0 ... 3:
4824 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4825 rn = "CacheErr";
4826 break;
4827 default:
4828 goto die;
4830 break;
4831 case 28:
4832 switch (sel) {
4833 case 0:
4834 case 2:
4835 case 4:
4836 case 6:
4837 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4838 rn = "TagLo";
4839 break;
4840 case 1:
4841 case 3:
4842 case 5:
4843 case 7:
4844 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4845 rn = "DataLo";
4846 break;
4847 default:
4848 goto die;
4850 break;
4851 case 29:
4852 switch (sel) {
4853 case 0:
4854 case 2:
4855 case 4:
4856 case 6:
4857 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4858 rn = "TagHi";
4859 break;
4860 case 1:
4861 case 3:
4862 case 5:
4863 case 7:
4864 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4865 rn = "DataHi";
4866 break;
4867 default:
4868 goto die;
4870 break;
4871 case 30:
4872 switch (sel) {
4873 case 0:
4874 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4875 rn = "ErrorEPC";
4876 break;
4877 default:
4878 goto die;
4880 break;
4881 case 31:
4882 switch (sel) {
4883 case 0:
4884 /* EJTAG support */
4885 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4886 rn = "DESAVE";
4887 break;
4888 default:
4889 goto die;
4891 break;
4892 default:
4893 goto die;
4895 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4896 return;
4898 die:
4899 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4900 generate_exception(ctx, EXCP_RI);
4903 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4905 const char *rn = "invalid";
4907 if (sel != 0)
4908 check_insn(env, ctx, ISA_MIPS64);
4910 if (use_icount)
4911 gen_io_start();
4913 switch (reg) {
4914 case 0:
4915 switch (sel) {
4916 case 0:
4917 gen_helper_mtc0_index(arg);
4918 rn = "Index";
4919 break;
4920 case 1:
4921 check_insn(env, ctx, ASE_MT);
4922 gen_helper_mtc0_mvpcontrol(arg);
4923 rn = "MVPControl";
4924 break;
4925 case 2:
4926 check_insn(env, ctx, ASE_MT);
4927 /* ignored */
4928 rn = "MVPConf0";
4929 break;
4930 case 3:
4931 check_insn(env, ctx, ASE_MT);
4932 /* ignored */
4933 rn = "MVPConf1";
4934 break;
4935 default:
4936 goto die;
4938 break;
4939 case 1:
4940 switch (sel) {
4941 case 0:
4942 /* ignored */
4943 rn = "Random";
4944 break;
4945 case 1:
4946 check_insn(env, ctx, ASE_MT);
4947 gen_helper_mtc0_vpecontrol(arg);
4948 rn = "VPEControl";
4949 break;
4950 case 2:
4951 check_insn(env, ctx, ASE_MT);
4952 gen_helper_mtc0_vpeconf0(arg);
4953 rn = "VPEConf0";
4954 break;
4955 case 3:
4956 check_insn(env, ctx, ASE_MT);
4957 gen_helper_mtc0_vpeconf1(arg);
4958 rn = "VPEConf1";
4959 break;
4960 case 4:
4961 check_insn(env, ctx, ASE_MT);
4962 gen_helper_mtc0_yqmask(arg);
4963 rn = "YQMask";
4964 break;
4965 case 5:
4966 check_insn(env, ctx, ASE_MT);
4967 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4968 rn = "VPESchedule";
4969 break;
4970 case 6:
4971 check_insn(env, ctx, ASE_MT);
4972 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4973 rn = "VPEScheFBack";
4974 break;
4975 case 7:
4976 check_insn(env, ctx, ASE_MT);
4977 gen_helper_mtc0_vpeopt(arg);
4978 rn = "VPEOpt";
4979 break;
4980 default:
4981 goto die;
4983 break;
4984 case 2:
4985 switch (sel) {
4986 case 0:
4987 gen_helper_mtc0_entrylo0(arg);
4988 rn = "EntryLo0";
4989 break;
4990 case 1:
4991 check_insn(env, ctx, ASE_MT);
4992 gen_helper_mtc0_tcstatus(arg);
4993 rn = "TCStatus";
4994 break;
4995 case 2:
4996 check_insn(env, ctx, ASE_MT);
4997 gen_helper_mtc0_tcbind(arg);
4998 rn = "TCBind";
4999 break;
5000 case 3:
5001 check_insn(env, ctx, ASE_MT);
5002 gen_helper_mtc0_tcrestart(arg);
5003 rn = "TCRestart";
5004 break;
5005 case 4:
5006 check_insn(env, ctx, ASE_MT);
5007 gen_helper_mtc0_tchalt(arg);
5008 rn = "TCHalt";
5009 break;
5010 case 5:
5011 check_insn(env, ctx, ASE_MT);
5012 gen_helper_mtc0_tccontext(arg);
5013 rn = "TCContext";
5014 break;
5015 case 6:
5016 check_insn(env, ctx, ASE_MT);
5017 gen_helper_mtc0_tcschedule(arg);
5018 rn = "TCSchedule";
5019 break;
5020 case 7:
5021 check_insn(env, ctx, ASE_MT);
5022 gen_helper_mtc0_tcschefback(arg);
5023 rn = "TCScheFBack";
5024 break;
5025 default:
5026 goto die;
5028 break;
5029 case 3:
5030 switch (sel) {
5031 case 0:
5032 gen_helper_mtc0_entrylo1(arg);
5033 rn = "EntryLo1";
5034 break;
5035 default:
5036 goto die;
5038 break;
5039 case 4:
5040 switch (sel) {
5041 case 0:
5042 gen_helper_mtc0_context(arg);
5043 rn = "Context";
5044 break;
5045 case 1:
5046 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
5047 rn = "ContextConfig";
5048 // break;
5049 default:
5050 goto die;
5052 break;
5053 case 5:
5054 switch (sel) {
5055 case 0:
5056 gen_helper_mtc0_pagemask(arg);
5057 rn = "PageMask";
5058 break;
5059 case 1:
5060 check_insn(env, ctx, ISA_MIPS32R2);
5061 gen_helper_mtc0_pagegrain(arg);
5062 rn = "PageGrain";
5063 break;
5064 default:
5065 goto die;
5067 break;
5068 case 6:
5069 switch (sel) {
5070 case 0:
5071 gen_helper_mtc0_wired(arg);
5072 rn = "Wired";
5073 break;
5074 case 1:
5075 check_insn(env, ctx, ISA_MIPS32R2);
5076 gen_helper_mtc0_srsconf0(arg);
5077 rn = "SRSConf0";
5078 break;
5079 case 2:
5080 check_insn(env, ctx, ISA_MIPS32R2);
5081 gen_helper_mtc0_srsconf1(arg);
5082 rn = "SRSConf1";
5083 break;
5084 case 3:
5085 check_insn(env, ctx, ISA_MIPS32R2);
5086 gen_helper_mtc0_srsconf2(arg);
5087 rn = "SRSConf2";
5088 break;
5089 case 4:
5090 check_insn(env, ctx, ISA_MIPS32R2);
5091 gen_helper_mtc0_srsconf3(arg);
5092 rn = "SRSConf3";
5093 break;
5094 case 5:
5095 check_insn(env, ctx, ISA_MIPS32R2);
5096 gen_helper_mtc0_srsconf4(arg);
5097 rn = "SRSConf4";
5098 break;
5099 default:
5100 goto die;
5102 break;
5103 case 7:
5104 switch (sel) {
5105 case 0:
5106 check_insn(env, ctx, ISA_MIPS32R2);
5107 gen_helper_mtc0_hwrena(arg);
5108 rn = "HWREna";
5109 break;
5110 default:
5111 goto die;
5113 break;
5114 case 8:
5115 /* ignored */
5116 rn = "BadVAddr";
5117 break;
5118 case 9:
5119 switch (sel) {
5120 case 0:
5121 gen_helper_mtc0_count(arg);
5122 rn = "Count";
5123 break;
5124 /* 6,7 are implementation dependent */
5125 default:
5126 goto die;
5128 /* Stop translation as we may have switched the execution mode */
5129 ctx->bstate = BS_STOP;
5130 break;
5131 case 10:
5132 switch (sel) {
5133 case 0:
5134 gen_helper_mtc0_entryhi(arg);
5135 rn = "EntryHi";
5136 break;
5137 default:
5138 goto die;
5140 break;
5141 case 11:
5142 switch (sel) {
5143 case 0:
5144 gen_helper_mtc0_compare(arg);
5145 rn = "Compare";
5146 break;
5147 /* 6,7 are implementation dependent */
5148 default:
5149 goto die;
5151 /* Stop translation as we may have switched the execution mode */
5152 ctx->bstate = BS_STOP;
5153 break;
5154 case 12:
5155 switch (sel) {
5156 case 0:
5157 save_cpu_state(ctx, 1);
5158 gen_helper_mtc0_status(arg);
5159 /* BS_STOP isn't good enough here, hflags may have changed. */
5160 gen_save_pc(ctx->pc + 4);
5161 ctx->bstate = BS_EXCP;
5162 rn = "Status";
5163 break;
5164 case 1:
5165 check_insn(env, ctx, ISA_MIPS32R2);
5166 gen_helper_mtc0_intctl(arg);
5167 /* Stop translation as we may have switched the execution mode */
5168 ctx->bstate = BS_STOP;
5169 rn = "IntCtl";
5170 break;
5171 case 2:
5172 check_insn(env, ctx, ISA_MIPS32R2);
5173 gen_helper_mtc0_srsctl(arg);
5174 /* Stop translation as we may have switched the execution mode */
5175 ctx->bstate = BS_STOP;
5176 rn = "SRSCtl";
5177 break;
5178 case 3:
5179 check_insn(env, ctx, ISA_MIPS32R2);
5180 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
5181 /* Stop translation as we may have switched the execution mode */
5182 ctx->bstate = BS_STOP;
5183 rn = "SRSMap";
5184 break;
5185 default:
5186 goto die;
5188 break;
5189 case 13:
5190 switch (sel) {
5191 case 0:
5192 save_cpu_state(ctx, 1);
5193 /* Mark as an IO operation because we may trigger a software
5194 interrupt. */
5195 if (use_icount) {
5196 gen_io_start();
5198 gen_helper_mtc0_cause(arg);
5199 if (use_icount) {
5200 gen_io_end();
5202 /* Stop translation as we may have triggered an intetrupt */
5203 ctx->bstate = BS_STOP;
5204 rn = "Cause";
5205 break;
5206 default:
5207 goto die;
5209 break;
5210 case 14:
5211 switch (sel) {
5212 case 0:
5213 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
5214 rn = "EPC";
5215 break;
5216 default:
5217 goto die;
5219 break;
5220 case 15:
5221 switch (sel) {
5222 case 0:
5223 /* ignored */
5224 rn = "PRid";
5225 break;
5226 case 1:
5227 check_insn(env, ctx, ISA_MIPS32R2);
5228 gen_helper_mtc0_ebase(arg);
5229 rn = "EBase";
5230 break;
5231 default:
5232 goto die;
5234 break;
5235 case 16:
5236 switch (sel) {
5237 case 0:
5238 gen_helper_mtc0_config0(arg);
5239 rn = "Config";
5240 /* Stop translation as we may have switched the execution mode */
5241 ctx->bstate = BS_STOP;
5242 break;
5243 case 1:
5244 /* ignored, read only */
5245 rn = "Config1";
5246 break;
5247 case 2:
5248 gen_helper_mtc0_config2(arg);
5249 rn = "Config2";
5250 /* Stop translation as we may have switched the execution mode */
5251 ctx->bstate = BS_STOP;
5252 break;
5253 case 3:
5254 /* ignored */
5255 rn = "Config3";
5256 break;
5257 /* 6,7 are implementation dependent */
5258 default:
5259 rn = "Invalid config selector";
5260 goto die;
5262 break;
5263 case 17:
5264 switch (sel) {
5265 case 0:
5266 gen_helper_mtc0_lladdr(arg);
5267 rn = "LLAddr";
5268 break;
5269 default:
5270 goto die;
5272 break;
5273 case 18:
5274 switch (sel) {
5275 case 0 ... 7:
5276 gen_helper_1i(mtc0_watchlo, arg, sel);
5277 rn = "WatchLo";
5278 break;
5279 default:
5280 goto die;
5282 break;
5283 case 19:
5284 switch (sel) {
5285 case 0 ... 7:
5286 gen_helper_1i(mtc0_watchhi, arg, sel);
5287 rn = "WatchHi";
5288 break;
5289 default:
5290 goto die;
5292 break;
5293 case 20:
5294 switch (sel) {
5295 case 0:
5296 check_insn(env, ctx, ISA_MIPS3);
5297 gen_helper_mtc0_xcontext(arg);
5298 rn = "XContext";
5299 break;
5300 default:
5301 goto die;
5303 break;
5304 case 21:
5305 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5306 switch (sel) {
5307 case 0:
5308 gen_helper_mtc0_framemask(arg);
5309 rn = "Framemask";
5310 break;
5311 default:
5312 goto die;
5314 break;
5315 case 22:
5316 /* ignored */
5317 rn = "Diagnostic"; /* implementation dependent */
5318 break;
5319 case 23:
5320 switch (sel) {
5321 case 0:
5322 gen_helper_mtc0_debug(arg); /* EJTAG support */
5323 /* BS_STOP isn't good enough here, hflags may have changed. */
5324 gen_save_pc(ctx->pc + 4);
5325 ctx->bstate = BS_EXCP;
5326 rn = "Debug";
5327 break;
5328 case 1:
5329 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5330 /* Stop translation as we may have switched the execution mode */
5331 ctx->bstate = BS_STOP;
5332 rn = "TraceControl";
5333 // break;
5334 case 2:
5335 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5336 /* Stop translation as we may have switched the execution mode */
5337 ctx->bstate = BS_STOP;
5338 rn = "TraceControl2";
5339 // break;
5340 case 3:
5341 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5342 /* Stop translation as we may have switched the execution mode */
5343 ctx->bstate = BS_STOP;
5344 rn = "UserTraceData";
5345 // break;
5346 case 4:
5347 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5348 /* Stop translation as we may have switched the execution mode */
5349 ctx->bstate = BS_STOP;
5350 rn = "TraceBPC";
5351 // break;
5352 default:
5353 goto die;
5355 break;
5356 case 24:
5357 switch (sel) {
5358 case 0:
5359 /* EJTAG support */
5360 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5361 rn = "DEPC";
5362 break;
5363 default:
5364 goto die;
5366 break;
5367 case 25:
5368 switch (sel) {
5369 case 0:
5370 gen_helper_mtc0_performance0(arg);
5371 rn = "Performance0";
5372 break;
5373 case 1:
5374 // gen_helper_mtc0_performance1(arg);
5375 rn = "Performance1";
5376 // break;
5377 case 2:
5378 // gen_helper_mtc0_performance2(arg);
5379 rn = "Performance2";
5380 // break;
5381 case 3:
5382 // gen_helper_mtc0_performance3(arg);
5383 rn = "Performance3";
5384 // break;
5385 case 4:
5386 // gen_helper_mtc0_performance4(arg);
5387 rn = "Performance4";
5388 // break;
5389 case 5:
5390 // gen_helper_mtc0_performance5(arg);
5391 rn = "Performance5";
5392 // break;
5393 case 6:
5394 // gen_helper_mtc0_performance6(arg);
5395 rn = "Performance6";
5396 // break;
5397 case 7:
5398 // gen_helper_mtc0_performance7(arg);
5399 rn = "Performance7";
5400 // break;
5401 default:
5402 goto die;
5404 break;
5405 case 26:
5406 /* ignored */
5407 rn = "ECC";
5408 break;
5409 case 27:
5410 switch (sel) {
5411 case 0 ... 3:
5412 /* ignored */
5413 rn = "CacheErr";
5414 break;
5415 default:
5416 goto die;
5418 break;
5419 case 28:
5420 switch (sel) {
5421 case 0:
5422 case 2:
5423 case 4:
5424 case 6:
5425 gen_helper_mtc0_taglo(arg);
5426 rn = "TagLo";
5427 break;
5428 case 1:
5429 case 3:
5430 case 5:
5431 case 7:
5432 gen_helper_mtc0_datalo(arg);
5433 rn = "DataLo";
5434 break;
5435 default:
5436 goto die;
5438 break;
5439 case 29:
5440 switch (sel) {
5441 case 0:
5442 case 2:
5443 case 4:
5444 case 6:
5445 gen_helper_mtc0_taghi(arg);
5446 rn = "TagHi";
5447 break;
5448 case 1:
5449 case 3:
5450 case 5:
5451 case 7:
5452 gen_helper_mtc0_datahi(arg);
5453 rn = "DataHi";
5454 break;
5455 default:
5456 rn = "invalid sel";
5457 goto die;
5459 break;
5460 case 30:
5461 switch (sel) {
5462 case 0:
5463 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5464 rn = "ErrorEPC";
5465 break;
5466 default:
5467 goto die;
5469 break;
5470 case 31:
5471 switch (sel) {
5472 case 0:
5473 /* EJTAG support */
5474 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5475 rn = "DESAVE";
5476 break;
5477 default:
5478 goto die;
5480 /* Stop translation as we may have switched the execution mode */
5481 ctx->bstate = BS_STOP;
5482 break;
5483 default:
5484 goto die;
5486 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5487 /* For simplicity assume that all writes can cause interrupts. */
5488 if (use_icount) {
5489 gen_io_end();
5490 ctx->bstate = BS_STOP;
5492 return;
5494 die:
5495 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5496 generate_exception(ctx, EXCP_RI);
5498 #endif /* TARGET_MIPS64 */
5500 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5501 int u, int sel, int h)
5503 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5504 TCGv t0 = tcg_temp_local_new();
5506 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5507 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5508 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5509 tcg_gen_movi_tl(t0, -1);
5510 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5511 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5512 tcg_gen_movi_tl(t0, -1);
5513 else if (u == 0) {
5514 switch (rt) {
5515 case 2:
5516 switch (sel) {
5517 case 1:
5518 gen_helper_mftc0_tcstatus(t0);
5519 break;
5520 case 2:
5521 gen_helper_mftc0_tcbind(t0);
5522 break;
5523 case 3:
5524 gen_helper_mftc0_tcrestart(t0);
5525 break;
5526 case 4:
5527 gen_helper_mftc0_tchalt(t0);
5528 break;
5529 case 5:
5530 gen_helper_mftc0_tccontext(t0);
5531 break;
5532 case 6:
5533 gen_helper_mftc0_tcschedule(t0);
5534 break;
5535 case 7:
5536 gen_helper_mftc0_tcschefback(t0);
5537 break;
5538 default:
5539 gen_mfc0(env, ctx, t0, rt, sel);
5540 break;
5542 break;
5543 case 10:
5544 switch (sel) {
5545 case 0:
5546 gen_helper_mftc0_entryhi(t0);
5547 break;
5548 default:
5549 gen_mfc0(env, ctx, t0, rt, sel);
5550 break;
5552 case 12:
5553 switch (sel) {
5554 case 0:
5555 gen_helper_mftc0_status(t0);
5556 break;
5557 default:
5558 gen_mfc0(env, ctx, t0, rt, sel);
5559 break;
5561 case 23:
5562 switch (sel) {
5563 case 0:
5564 gen_helper_mftc0_debug(t0);
5565 break;
5566 default:
5567 gen_mfc0(env, ctx, t0, rt, sel);
5568 break;
5570 break;
5571 default:
5572 gen_mfc0(env, ctx, t0, rt, sel);
5574 } else switch (sel) {
5575 /* GPR registers. */
5576 case 0:
5577 gen_helper_1i(mftgpr, t0, rt);
5578 break;
5579 /* Auxiliary CPU registers */
5580 case 1:
5581 switch (rt) {
5582 case 0:
5583 gen_helper_1i(mftlo, t0, 0);
5584 break;
5585 case 1:
5586 gen_helper_1i(mfthi, t0, 0);
5587 break;
5588 case 2:
5589 gen_helper_1i(mftacx, t0, 0);
5590 break;
5591 case 4:
5592 gen_helper_1i(mftlo, t0, 1);
5593 break;
5594 case 5:
5595 gen_helper_1i(mfthi, t0, 1);
5596 break;
5597 case 6:
5598 gen_helper_1i(mftacx, t0, 1);
5599 break;
5600 case 8:
5601 gen_helper_1i(mftlo, t0, 2);
5602 break;
5603 case 9:
5604 gen_helper_1i(mfthi, t0, 2);
5605 break;
5606 case 10:
5607 gen_helper_1i(mftacx, t0, 2);
5608 break;
5609 case 12:
5610 gen_helper_1i(mftlo, t0, 3);
5611 break;
5612 case 13:
5613 gen_helper_1i(mfthi, t0, 3);
5614 break;
5615 case 14:
5616 gen_helper_1i(mftacx, t0, 3);
5617 break;
5618 case 16:
5619 gen_helper_mftdsp(t0);
5620 break;
5621 default:
5622 goto die;
5624 break;
5625 /* Floating point (COP1). */
5626 case 2:
5627 /* XXX: For now we support only a single FPU context. */
5628 if (h == 0) {
5629 TCGv_i32 fp0 = tcg_temp_new_i32();
5631 gen_load_fpr32(fp0, rt);
5632 tcg_gen_ext_i32_tl(t0, fp0);
5633 tcg_temp_free_i32(fp0);
5634 } else {
5635 TCGv_i32 fp0 = tcg_temp_new_i32();
5637 gen_load_fpr32h(fp0, rt);
5638 tcg_gen_ext_i32_tl(t0, fp0);
5639 tcg_temp_free_i32(fp0);
5641 break;
5642 case 3:
5643 /* XXX: For now we support only a single FPU context. */
5644 gen_helper_1i(cfc1, t0, rt);
5645 break;
5646 /* COP2: Not implemented. */
5647 case 4:
5648 case 5:
5649 /* fall through */
5650 default:
5651 goto die;
5653 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5654 gen_store_gpr(t0, rd);
5655 tcg_temp_free(t0);
5656 return;
5658 die:
5659 tcg_temp_free(t0);
5660 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5661 generate_exception(ctx, EXCP_RI);
5664 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5665 int u, int sel, int h)
5667 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5668 TCGv t0 = tcg_temp_local_new();
5670 gen_load_gpr(t0, rt);
5671 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5672 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5673 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5674 /* NOP */ ;
5675 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5676 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5677 /* NOP */ ;
5678 else if (u == 0) {
5679 switch (rd) {
5680 case 2:
5681 switch (sel) {
5682 case 1:
5683 gen_helper_mttc0_tcstatus(t0);
5684 break;
5685 case 2:
5686 gen_helper_mttc0_tcbind(t0);
5687 break;
5688 case 3:
5689 gen_helper_mttc0_tcrestart(t0);
5690 break;
5691 case 4:
5692 gen_helper_mttc0_tchalt(t0);
5693 break;
5694 case 5:
5695 gen_helper_mttc0_tccontext(t0);
5696 break;
5697 case 6:
5698 gen_helper_mttc0_tcschedule(t0);
5699 break;
5700 case 7:
5701 gen_helper_mttc0_tcschefback(t0);
5702 break;
5703 default:
5704 gen_mtc0(env, ctx, t0, rd, sel);
5705 break;
5707 break;
5708 case 10:
5709 switch (sel) {
5710 case 0:
5711 gen_helper_mttc0_entryhi(t0);
5712 break;
5713 default:
5714 gen_mtc0(env, ctx, t0, rd, sel);
5715 break;
5717 case 12:
5718 switch (sel) {
5719 case 0:
5720 gen_helper_mttc0_status(t0);
5721 break;
5722 default:
5723 gen_mtc0(env, ctx, t0, rd, sel);
5724 break;
5726 case 23:
5727 switch (sel) {
5728 case 0:
5729 gen_helper_mttc0_debug(t0);
5730 break;
5731 default:
5732 gen_mtc0(env, ctx, t0, rd, sel);
5733 break;
5735 break;
5736 default:
5737 gen_mtc0(env, ctx, t0, rd, sel);
5739 } else switch (sel) {
5740 /* GPR registers. */
5741 case 0:
5742 gen_helper_1i(mttgpr, t0, rd);
5743 break;
5744 /* Auxiliary CPU registers */
5745 case 1:
5746 switch (rd) {
5747 case 0:
5748 gen_helper_1i(mttlo, t0, 0);
5749 break;
5750 case 1:
5751 gen_helper_1i(mtthi, t0, 0);
5752 break;
5753 case 2:
5754 gen_helper_1i(mttacx, t0, 0);
5755 break;
5756 case 4:
5757 gen_helper_1i(mttlo, t0, 1);
5758 break;
5759 case 5:
5760 gen_helper_1i(mtthi, t0, 1);
5761 break;
5762 case 6:
5763 gen_helper_1i(mttacx, t0, 1);
5764 break;
5765 case 8:
5766 gen_helper_1i(mttlo, t0, 2);
5767 break;
5768 case 9:
5769 gen_helper_1i(mtthi, t0, 2);
5770 break;
5771 case 10:
5772 gen_helper_1i(mttacx, t0, 2);
5773 break;
5774 case 12:
5775 gen_helper_1i(mttlo, t0, 3);
5776 break;
5777 case 13:
5778 gen_helper_1i(mtthi, t0, 3);
5779 break;
5780 case 14:
5781 gen_helper_1i(mttacx, t0, 3);
5782 break;
5783 case 16:
5784 gen_helper_mttdsp(t0);
5785 break;
5786 default:
5787 goto die;
5789 break;
5790 /* Floating point (COP1). */
5791 case 2:
5792 /* XXX: For now we support only a single FPU context. */
5793 if (h == 0) {
5794 TCGv_i32 fp0 = tcg_temp_new_i32();
5796 tcg_gen_trunc_tl_i32(fp0, t0);
5797 gen_store_fpr32(fp0, rd);
5798 tcg_temp_free_i32(fp0);
5799 } else {
5800 TCGv_i32 fp0 = tcg_temp_new_i32();
5802 tcg_gen_trunc_tl_i32(fp0, t0);
5803 gen_store_fpr32h(fp0, rd);
5804 tcg_temp_free_i32(fp0);
5806 break;
5807 case 3:
5808 /* XXX: For now we support only a single FPU context. */
5809 gen_helper_1i(ctc1, t0, rd);
5810 break;
5811 /* COP2: Not implemented. */
5812 case 4:
5813 case 5:
5814 /* fall through */
5815 default:
5816 goto die;
5818 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5819 tcg_temp_free(t0);
5820 return;
5822 die:
5823 tcg_temp_free(t0);
5824 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5825 generate_exception(ctx, EXCP_RI);
5828 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5830 const char *opn = "ldst";
5832 switch (opc) {
5833 case OPC_MFC0:
5834 if (rt == 0) {
5835 /* Treat as NOP. */
5836 return;
5838 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5839 opn = "mfc0";
5840 break;
5841 case OPC_MTC0:
5843 TCGv t0 = tcg_temp_new();
5845 gen_load_gpr(t0, rt);
5846 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5847 tcg_temp_free(t0);
5849 opn = "mtc0";
5850 break;
5851 #if defined(TARGET_MIPS64)
5852 case OPC_DMFC0:
5853 check_insn(env, ctx, ISA_MIPS3);
5854 if (rt == 0) {
5855 /* Treat as NOP. */
5856 return;
5858 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5859 opn = "dmfc0";
5860 break;
5861 case OPC_DMTC0:
5862 check_insn(env, ctx, ISA_MIPS3);
5864 TCGv t0 = tcg_temp_new();
5866 gen_load_gpr(t0, rt);
5867 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5868 tcg_temp_free(t0);
5870 opn = "dmtc0";
5871 break;
5872 #endif
5873 case OPC_MFTR:
5874 check_insn(env, ctx, ASE_MT);
5875 if (rd == 0) {
5876 /* Treat as NOP. */
5877 return;
5879 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5880 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5881 opn = "mftr";
5882 break;
5883 case OPC_MTTR:
5884 check_insn(env, ctx, ASE_MT);
5885 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5886 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5887 opn = "mttr";
5888 break;
5889 case OPC_TLBWI:
5890 opn = "tlbwi";
5891 if (!env->tlb->helper_tlbwi)
5892 goto die;
5893 gen_helper_tlbwi();
5894 break;
5895 case OPC_TLBWR:
5896 opn = "tlbwr";
5897 if (!env->tlb->helper_tlbwr)
5898 goto die;
5899 gen_helper_tlbwr();
5900 break;
5901 case OPC_TLBP:
5902 opn = "tlbp";
5903 if (!env->tlb->helper_tlbp)
5904 goto die;
5905 gen_helper_tlbp();
5906 break;
5907 case OPC_TLBR:
5908 opn = "tlbr";
5909 if (!env->tlb->helper_tlbr)
5910 goto die;
5911 gen_helper_tlbr();
5912 break;
5913 case OPC_ERET:
5914 opn = "eret";
5915 check_insn(env, ctx, ISA_MIPS2);
5916 gen_helper_eret();
5917 ctx->bstate = BS_EXCP;
5918 break;
5919 case OPC_DERET:
5920 opn = "deret";
5921 check_insn(env, ctx, ISA_MIPS32);
5922 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5923 MIPS_INVAL(opn);
5924 generate_exception(ctx, EXCP_RI);
5925 } else {
5926 gen_helper_deret();
5927 ctx->bstate = BS_EXCP;
5929 break;
5930 case OPC_WAIT:
5931 opn = "wait";
5932 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5933 /* If we get an exception, we want to restart at next instruction */
5934 ctx->pc += 4;
5935 save_cpu_state(ctx, 1);
5936 ctx->pc -= 4;
5937 gen_helper_wait();
5938 ctx->bstate = BS_EXCP;
5939 break;
5940 default:
5941 die:
5942 MIPS_INVAL(opn);
5943 generate_exception(ctx, EXCP_RI);
5944 return;
5946 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5948 #endif /* !CONFIG_USER_ONLY */
5950 /* CP1 Branches (before delay slot) */
5951 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5952 int32_t cc, int32_t offset)
5954 target_ulong btarget;
5955 const char *opn = "cp1 cond branch";
5956 TCGv_i32 t0 = tcg_temp_new_i32();
5958 if (cc != 0)
5959 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5961 btarget = ctx->pc + 4 + offset;
5963 switch (op) {
5964 case OPC_BC1F:
5965 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5966 tcg_gen_not_i32(t0, t0);
5967 tcg_gen_andi_i32(t0, t0, 1);
5968 tcg_gen_extu_i32_tl(bcond, t0);
5969 opn = "bc1f";
5970 goto not_likely;
5971 case OPC_BC1FL:
5972 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5973 tcg_gen_not_i32(t0, t0);
5974 tcg_gen_andi_i32(t0, t0, 1);
5975 tcg_gen_extu_i32_tl(bcond, t0);
5976 opn = "bc1fl";
5977 goto likely;
5978 case OPC_BC1T:
5979 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5980 tcg_gen_andi_i32(t0, t0, 1);
5981 tcg_gen_extu_i32_tl(bcond, t0);
5982 opn = "bc1t";
5983 goto not_likely;
5984 case OPC_BC1TL:
5985 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5986 tcg_gen_andi_i32(t0, t0, 1);
5987 tcg_gen_extu_i32_tl(bcond, t0);
5988 opn = "bc1tl";
5989 likely:
5990 ctx->hflags |= MIPS_HFLAG_BL;
5991 break;
5992 case OPC_BC1FANY2:
5994 TCGv_i32 t1 = tcg_temp_new_i32();
5995 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5996 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5997 tcg_gen_nor_i32(t0, t0, t1);
5998 tcg_temp_free_i32(t1);
5999 tcg_gen_andi_i32(t0, t0, 1);
6000 tcg_gen_extu_i32_tl(bcond, t0);
6002 opn = "bc1any2f";
6003 goto not_likely;
6004 case OPC_BC1TANY2:
6006 TCGv_i32 t1 = tcg_temp_new_i32();
6007 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6008 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6009 tcg_gen_or_i32(t0, t0, t1);
6010 tcg_temp_free_i32(t1);
6011 tcg_gen_andi_i32(t0, t0, 1);
6012 tcg_gen_extu_i32_tl(bcond, t0);
6014 opn = "bc1any2t";
6015 goto not_likely;
6016 case OPC_BC1FANY4:
6018 TCGv_i32 t1 = tcg_temp_new_i32();
6019 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6020 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6021 tcg_gen_or_i32(t0, t0, t1);
6022 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6023 tcg_gen_or_i32(t0, t0, t1);
6024 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6025 tcg_gen_nor_i32(t0, t0, t1);
6026 tcg_temp_free_i32(t1);
6027 tcg_gen_andi_i32(t0, t0, 1);
6028 tcg_gen_extu_i32_tl(bcond, t0);
6030 opn = "bc1any4f";
6031 goto not_likely;
6032 case OPC_BC1TANY4:
6034 TCGv_i32 t1 = tcg_temp_new_i32();
6035 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6036 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6037 tcg_gen_or_i32(t0, t0, t1);
6038 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6039 tcg_gen_or_i32(t0, t0, t1);
6040 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6041 tcg_gen_or_i32(t0, t0, t1);
6042 tcg_temp_free_i32(t1);
6043 tcg_gen_andi_i32(t0, t0, 1);
6044 tcg_gen_extu_i32_tl(bcond, t0);
6046 opn = "bc1any4t";
6047 not_likely:
6048 ctx->hflags |= MIPS_HFLAG_BC;
6049 break;
6050 default:
6051 MIPS_INVAL(opn);
6052 generate_exception (ctx, EXCP_RI);
6053 goto out;
6055 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6056 ctx->hflags, btarget);
6057 ctx->btarget = btarget;
6059 out:
6060 tcg_temp_free_i32(t0);
6063 /* Coprocessor 1 (FPU) */
6065 #define FOP(func, fmt) (((fmt) << 21) | (func))
6067 enum fopcode {
6068 OPC_ADD_S = FOP(0, FMT_S),
6069 OPC_SUB_S = FOP(1, FMT_S),
6070 OPC_MUL_S = FOP(2, FMT_S),
6071 OPC_DIV_S = FOP(3, FMT_S),
6072 OPC_SQRT_S = FOP(4, FMT_S),
6073 OPC_ABS_S = FOP(5, FMT_S),
6074 OPC_MOV_S = FOP(6, FMT_S),
6075 OPC_NEG_S = FOP(7, FMT_S),
6076 OPC_ROUND_L_S = FOP(8, FMT_S),
6077 OPC_TRUNC_L_S = FOP(9, FMT_S),
6078 OPC_CEIL_L_S = FOP(10, FMT_S),
6079 OPC_FLOOR_L_S = FOP(11, FMT_S),
6080 OPC_ROUND_W_S = FOP(12, FMT_S),
6081 OPC_TRUNC_W_S = FOP(13, FMT_S),
6082 OPC_CEIL_W_S = FOP(14, FMT_S),
6083 OPC_FLOOR_W_S = FOP(15, FMT_S),
6084 OPC_MOVCF_S = FOP(17, FMT_S),
6085 OPC_MOVZ_S = FOP(18, FMT_S),
6086 OPC_MOVN_S = FOP(19, FMT_S),
6087 OPC_RECIP_S = FOP(21, FMT_S),
6088 OPC_RSQRT_S = FOP(22, FMT_S),
6089 OPC_RECIP2_S = FOP(28, FMT_S),
6090 OPC_RECIP1_S = FOP(29, FMT_S),
6091 OPC_RSQRT1_S = FOP(30, FMT_S),
6092 OPC_RSQRT2_S = FOP(31, FMT_S),
6093 OPC_CVT_D_S = FOP(33, FMT_S),
6094 OPC_CVT_W_S = FOP(36, FMT_S),
6095 OPC_CVT_L_S = FOP(37, FMT_S),
6096 OPC_CVT_PS_S = FOP(38, FMT_S),
6097 OPC_CMP_F_S = FOP (48, FMT_S),
6098 OPC_CMP_UN_S = FOP (49, FMT_S),
6099 OPC_CMP_EQ_S = FOP (50, FMT_S),
6100 OPC_CMP_UEQ_S = FOP (51, FMT_S),
6101 OPC_CMP_OLT_S = FOP (52, FMT_S),
6102 OPC_CMP_ULT_S = FOP (53, FMT_S),
6103 OPC_CMP_OLE_S = FOP (54, FMT_S),
6104 OPC_CMP_ULE_S = FOP (55, FMT_S),
6105 OPC_CMP_SF_S = FOP (56, FMT_S),
6106 OPC_CMP_NGLE_S = FOP (57, FMT_S),
6107 OPC_CMP_SEQ_S = FOP (58, FMT_S),
6108 OPC_CMP_NGL_S = FOP (59, FMT_S),
6109 OPC_CMP_LT_S = FOP (60, FMT_S),
6110 OPC_CMP_NGE_S = FOP (61, FMT_S),
6111 OPC_CMP_LE_S = FOP (62, FMT_S),
6112 OPC_CMP_NGT_S = FOP (63, FMT_S),
6114 OPC_ADD_D = FOP(0, FMT_D),
6115 OPC_SUB_D = FOP(1, FMT_D),
6116 OPC_MUL_D = FOP(2, FMT_D),
6117 OPC_DIV_D = FOP(3, FMT_D),
6118 OPC_SQRT_D = FOP(4, FMT_D),
6119 OPC_ABS_D = FOP(5, FMT_D),
6120 OPC_MOV_D = FOP(6, FMT_D),
6121 OPC_NEG_D = FOP(7, FMT_D),
6122 OPC_ROUND_L_D = FOP(8, FMT_D),
6123 OPC_TRUNC_L_D = FOP(9, FMT_D),
6124 OPC_CEIL_L_D = FOP(10, FMT_D),
6125 OPC_FLOOR_L_D = FOP(11, FMT_D),
6126 OPC_ROUND_W_D = FOP(12, FMT_D),
6127 OPC_TRUNC_W_D = FOP(13, FMT_D),
6128 OPC_CEIL_W_D = FOP(14, FMT_D),
6129 OPC_FLOOR_W_D = FOP(15, FMT_D),
6130 OPC_MOVCF_D = FOP(17, FMT_D),
6131 OPC_MOVZ_D = FOP(18, FMT_D),
6132 OPC_MOVN_D = FOP(19, FMT_D),
6133 OPC_RECIP_D = FOP(21, FMT_D),
6134 OPC_RSQRT_D = FOP(22, FMT_D),
6135 OPC_RECIP2_D = FOP(28, FMT_D),
6136 OPC_RECIP1_D = FOP(29, FMT_D),
6137 OPC_RSQRT1_D = FOP(30, FMT_D),
6138 OPC_RSQRT2_D = FOP(31, FMT_D),
6139 OPC_CVT_S_D = FOP(32, FMT_D),
6140 OPC_CVT_W_D = FOP(36, FMT_D),
6141 OPC_CVT_L_D = FOP(37, FMT_D),
6142 OPC_CMP_F_D = FOP (48, FMT_D),
6143 OPC_CMP_UN_D = FOP (49, FMT_D),
6144 OPC_CMP_EQ_D = FOP (50, FMT_D),
6145 OPC_CMP_UEQ_D = FOP (51, FMT_D),
6146 OPC_CMP_OLT_D = FOP (52, FMT_D),
6147 OPC_CMP_ULT_D = FOP (53, FMT_D),
6148 OPC_CMP_OLE_D = FOP (54, FMT_D),
6149 OPC_CMP_ULE_D = FOP (55, FMT_D),
6150 OPC_CMP_SF_D = FOP (56, FMT_D),
6151 OPC_CMP_NGLE_D = FOP (57, FMT_D),
6152 OPC_CMP_SEQ_D = FOP (58, FMT_D),
6153 OPC_CMP_NGL_D = FOP (59, FMT_D),
6154 OPC_CMP_LT_D = FOP (60, FMT_D),
6155 OPC_CMP_NGE_D = FOP (61, FMT_D),
6156 OPC_CMP_LE_D = FOP (62, FMT_D),
6157 OPC_CMP_NGT_D = FOP (63, FMT_D),
6159 OPC_CVT_S_W = FOP(32, FMT_W),
6160 OPC_CVT_D_W = FOP(33, FMT_W),
6161 OPC_CVT_S_L = FOP(32, FMT_L),
6162 OPC_CVT_D_L = FOP(33, FMT_L),
6163 OPC_CVT_PS_PW = FOP(38, FMT_W),
6165 OPC_ADD_PS = FOP(0, FMT_PS),
6166 OPC_SUB_PS = FOP(1, FMT_PS),
6167 OPC_MUL_PS = FOP(2, FMT_PS),
6168 OPC_DIV_PS = FOP(3, FMT_PS),
6169 OPC_ABS_PS = FOP(5, FMT_PS),
6170 OPC_MOV_PS = FOP(6, FMT_PS),
6171 OPC_NEG_PS = FOP(7, FMT_PS),
6172 OPC_MOVCF_PS = FOP(17, FMT_PS),
6173 OPC_MOVZ_PS = FOP(18, FMT_PS),
6174 OPC_MOVN_PS = FOP(19, FMT_PS),
6175 OPC_ADDR_PS = FOP(24, FMT_PS),
6176 OPC_MULR_PS = FOP(26, FMT_PS),
6177 OPC_RECIP2_PS = FOP(28, FMT_PS),
6178 OPC_RECIP1_PS = FOP(29, FMT_PS),
6179 OPC_RSQRT1_PS = FOP(30, FMT_PS),
6180 OPC_RSQRT2_PS = FOP(31, FMT_PS),
6182 OPC_CVT_S_PU = FOP(32, FMT_PS),
6183 OPC_CVT_PW_PS = FOP(36, FMT_PS),
6184 OPC_CVT_S_PL = FOP(40, FMT_PS),
6185 OPC_PLL_PS = FOP(44, FMT_PS),
6186 OPC_PLU_PS = FOP(45, FMT_PS),
6187 OPC_PUL_PS = FOP(46, FMT_PS),
6188 OPC_PUU_PS = FOP(47, FMT_PS),
6189 OPC_CMP_F_PS = FOP (48, FMT_PS),
6190 OPC_CMP_UN_PS = FOP (49, FMT_PS),
6191 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
6192 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
6193 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
6194 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
6195 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
6196 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
6197 OPC_CMP_SF_PS = FOP (56, FMT_PS),
6198 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
6199 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
6200 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
6201 OPC_CMP_LT_PS = FOP (60, FMT_PS),
6202 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
6203 OPC_CMP_LE_PS = FOP (62, FMT_PS),
6204 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
6207 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6209 const char *opn = "cp1 move";
6210 TCGv t0 = tcg_temp_new();
6212 switch (opc) {
6213 case OPC_MFC1:
6215 TCGv_i32 fp0 = tcg_temp_new_i32();
6217 gen_load_fpr32(fp0, fs);
6218 tcg_gen_ext_i32_tl(t0, fp0);
6219 tcg_temp_free_i32(fp0);
6221 gen_store_gpr(t0, rt);
6222 opn = "mfc1";
6223 break;
6224 case OPC_MTC1:
6225 gen_load_gpr(t0, rt);
6227 TCGv_i32 fp0 = tcg_temp_new_i32();
6229 tcg_gen_trunc_tl_i32(fp0, t0);
6230 gen_store_fpr32(fp0, fs);
6231 tcg_temp_free_i32(fp0);
6233 opn = "mtc1";
6234 break;
6235 case OPC_CFC1:
6236 gen_helper_1i(cfc1, t0, fs);
6237 gen_store_gpr(t0, rt);
6238 opn = "cfc1";
6239 break;
6240 case OPC_CTC1:
6241 gen_load_gpr(t0, rt);
6242 gen_helper_1i(ctc1, t0, fs);
6243 opn = "ctc1";
6244 break;
6245 #if defined(TARGET_MIPS64)
6246 case OPC_DMFC1:
6247 gen_load_fpr64(ctx, t0, fs);
6248 gen_store_gpr(t0, rt);
6249 opn = "dmfc1";
6250 break;
6251 case OPC_DMTC1:
6252 gen_load_gpr(t0, rt);
6253 gen_store_fpr64(ctx, t0, fs);
6254 opn = "dmtc1";
6255 break;
6256 #endif
6257 case OPC_MFHC1:
6259 TCGv_i32 fp0 = tcg_temp_new_i32();
6261 gen_load_fpr32h(fp0, fs);
6262 tcg_gen_ext_i32_tl(t0, fp0);
6263 tcg_temp_free_i32(fp0);
6265 gen_store_gpr(t0, rt);
6266 opn = "mfhc1";
6267 break;
6268 case OPC_MTHC1:
6269 gen_load_gpr(t0, rt);
6271 TCGv_i32 fp0 = tcg_temp_new_i32();
6273 tcg_gen_trunc_tl_i32(fp0, t0);
6274 gen_store_fpr32h(fp0, fs);
6275 tcg_temp_free_i32(fp0);
6277 opn = "mthc1";
6278 break;
6279 default:
6280 MIPS_INVAL(opn);
6281 generate_exception (ctx, EXCP_RI);
6282 goto out;
6284 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6286 out:
6287 tcg_temp_free(t0);
6290 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6292 int l1;
6293 TCGCond cond;
6294 TCGv_i32 t0;
6296 if (rd == 0) {
6297 /* Treat as NOP. */
6298 return;
6301 if (tf)
6302 cond = TCG_COND_EQ;
6303 else
6304 cond = TCG_COND_NE;
6306 l1 = gen_new_label();
6307 t0 = tcg_temp_new_i32();
6308 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6309 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6310 tcg_temp_free_i32(t0);
6311 if (rs == 0) {
6312 tcg_gen_movi_tl(cpu_gpr[rd], 0);
6313 } else {
6314 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6316 gen_set_label(l1);
6319 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6321 int cond;
6322 TCGv_i32 t0 = tcg_temp_new_i32();
6323 int l1 = gen_new_label();
6325 if (tf)
6326 cond = TCG_COND_EQ;
6327 else
6328 cond = TCG_COND_NE;
6330 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6331 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6332 gen_load_fpr32(t0, fs);
6333 gen_store_fpr32(t0, fd);
6334 gen_set_label(l1);
6335 tcg_temp_free_i32(t0);
6338 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6340 int cond;
6341 TCGv_i32 t0 = tcg_temp_new_i32();
6342 TCGv_i64 fp0;
6343 int l1 = gen_new_label();
6345 if (tf)
6346 cond = TCG_COND_EQ;
6347 else
6348 cond = TCG_COND_NE;
6350 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6351 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6352 tcg_temp_free_i32(t0);
6353 fp0 = tcg_temp_new_i64();
6354 gen_load_fpr64(ctx, fp0, fs);
6355 gen_store_fpr64(ctx, fp0, fd);
6356 tcg_temp_free_i64(fp0);
6357 gen_set_label(l1);
6360 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6362 int cond;
6363 TCGv_i32 t0 = tcg_temp_new_i32();
6364 int l1 = gen_new_label();
6365 int l2 = gen_new_label();
6367 if (tf)
6368 cond = TCG_COND_EQ;
6369 else
6370 cond = TCG_COND_NE;
6372 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6373 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6374 gen_load_fpr32(t0, fs);
6375 gen_store_fpr32(t0, fd);
6376 gen_set_label(l1);
6378 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6379 tcg_gen_brcondi_i32(cond, t0, 0, l2);
6380 gen_load_fpr32h(t0, fs);
6381 gen_store_fpr32h(t0, fd);
6382 tcg_temp_free_i32(t0);
6383 gen_set_label(l2);
6387 static void gen_farith (DisasContext *ctx, enum fopcode op1,
6388 int ft, int fs, int fd, int cc)
6390 const char *opn = "farith";
6391 const char *condnames[] = {
6392 "c.f",
6393 "c.un",
6394 "c.eq",
6395 "c.ueq",
6396 "c.olt",
6397 "c.ult",
6398 "c.ole",
6399 "c.ule",
6400 "c.sf",
6401 "c.ngle",
6402 "c.seq",
6403 "c.ngl",
6404 "c.lt",
6405 "c.nge",
6406 "c.le",
6407 "c.ngt",
6409 const char *condnames_abs[] = {
6410 "cabs.f",
6411 "cabs.un",
6412 "cabs.eq",
6413 "cabs.ueq",
6414 "cabs.olt",
6415 "cabs.ult",
6416 "cabs.ole",
6417 "cabs.ule",
6418 "cabs.sf",
6419 "cabs.ngle",
6420 "cabs.seq",
6421 "cabs.ngl",
6422 "cabs.lt",
6423 "cabs.nge",
6424 "cabs.le",
6425 "cabs.ngt",
6427 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6428 uint32_t func = ctx->opcode & 0x3f;
6430 switch (op1) {
6431 case OPC_ADD_S:
6433 TCGv_i32 fp0 = tcg_temp_new_i32();
6434 TCGv_i32 fp1 = tcg_temp_new_i32();
6436 gen_load_fpr32(fp0, fs);
6437 gen_load_fpr32(fp1, ft);
6438 gen_helper_float_add_s(fp0, fp0, fp1);
6439 tcg_temp_free_i32(fp1);
6440 gen_store_fpr32(fp0, fd);
6441 tcg_temp_free_i32(fp0);
6443 opn = "add.s";
6444 optype = BINOP;
6445 break;
6446 case OPC_SUB_S:
6448 TCGv_i32 fp0 = tcg_temp_new_i32();
6449 TCGv_i32 fp1 = tcg_temp_new_i32();
6451 gen_load_fpr32(fp0, fs);
6452 gen_load_fpr32(fp1, ft);
6453 gen_helper_float_sub_s(fp0, fp0, fp1);
6454 tcg_temp_free_i32(fp1);
6455 gen_store_fpr32(fp0, fd);
6456 tcg_temp_free_i32(fp0);
6458 opn = "sub.s";
6459 optype = BINOP;
6460 break;
6461 case OPC_MUL_S:
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_mul_s(fp0, fp0, fp1);
6469 tcg_temp_free_i32(fp1);
6470 gen_store_fpr32(fp0, fd);
6471 tcg_temp_free_i32(fp0);
6473 opn = "mul.s";
6474 optype = BINOP;
6475 break;
6476 case OPC_DIV_S:
6478 TCGv_i32 fp0 = tcg_temp_new_i32();
6479 TCGv_i32 fp1 = tcg_temp_new_i32();
6481 gen_load_fpr32(fp0, fs);
6482 gen_load_fpr32(fp1, ft);
6483 gen_helper_float_div_s(fp0, fp0, fp1);
6484 tcg_temp_free_i32(fp1);
6485 gen_store_fpr32(fp0, fd);
6486 tcg_temp_free_i32(fp0);
6488 opn = "div.s";
6489 optype = BINOP;
6490 break;
6491 case OPC_SQRT_S:
6493 TCGv_i32 fp0 = tcg_temp_new_i32();
6495 gen_load_fpr32(fp0, fs);
6496 gen_helper_float_sqrt_s(fp0, fp0);
6497 gen_store_fpr32(fp0, fd);
6498 tcg_temp_free_i32(fp0);
6500 opn = "sqrt.s";
6501 break;
6502 case OPC_ABS_S:
6504 TCGv_i32 fp0 = tcg_temp_new_i32();
6506 gen_load_fpr32(fp0, fs);
6507 gen_helper_float_abs_s(fp0, fp0);
6508 gen_store_fpr32(fp0, fd);
6509 tcg_temp_free_i32(fp0);
6511 opn = "abs.s";
6512 break;
6513 case OPC_MOV_S:
6515 TCGv_i32 fp0 = tcg_temp_new_i32();
6517 gen_load_fpr32(fp0, fs);
6518 gen_store_fpr32(fp0, fd);
6519 tcg_temp_free_i32(fp0);
6521 opn = "mov.s";
6522 break;
6523 case OPC_NEG_S:
6525 TCGv_i32 fp0 = tcg_temp_new_i32();
6527 gen_load_fpr32(fp0, fs);
6528 gen_helper_float_chs_s(fp0, fp0);
6529 gen_store_fpr32(fp0, fd);
6530 tcg_temp_free_i32(fp0);
6532 opn = "neg.s";
6533 break;
6534 case OPC_ROUND_L_S:
6535 check_cp1_64bitmode(ctx);
6537 TCGv_i32 fp32 = tcg_temp_new_i32();
6538 TCGv_i64 fp64 = tcg_temp_new_i64();
6540 gen_load_fpr32(fp32, fs);
6541 gen_helper_float_roundl_s(fp64, fp32);
6542 tcg_temp_free_i32(fp32);
6543 gen_store_fpr64(ctx, fp64, fd);
6544 tcg_temp_free_i64(fp64);
6546 opn = "round.l.s";
6547 break;
6548 case OPC_TRUNC_L_S:
6549 check_cp1_64bitmode(ctx);
6551 TCGv_i32 fp32 = tcg_temp_new_i32();
6552 TCGv_i64 fp64 = tcg_temp_new_i64();
6554 gen_load_fpr32(fp32, fs);
6555 gen_helper_float_truncl_s(fp64, fp32);
6556 tcg_temp_free_i32(fp32);
6557 gen_store_fpr64(ctx, fp64, fd);
6558 tcg_temp_free_i64(fp64);
6560 opn = "trunc.l.s";
6561 break;
6562 case OPC_CEIL_L_S:
6563 check_cp1_64bitmode(ctx);
6565 TCGv_i32 fp32 = tcg_temp_new_i32();
6566 TCGv_i64 fp64 = tcg_temp_new_i64();
6568 gen_load_fpr32(fp32, fs);
6569 gen_helper_float_ceill_s(fp64, fp32);
6570 tcg_temp_free_i32(fp32);
6571 gen_store_fpr64(ctx, fp64, fd);
6572 tcg_temp_free_i64(fp64);
6574 opn = "ceil.l.s";
6575 break;
6576 case OPC_FLOOR_L_S:
6577 check_cp1_64bitmode(ctx);
6579 TCGv_i32 fp32 = tcg_temp_new_i32();
6580 TCGv_i64 fp64 = tcg_temp_new_i64();
6582 gen_load_fpr32(fp32, fs);
6583 gen_helper_float_floorl_s(fp64, fp32);
6584 tcg_temp_free_i32(fp32);
6585 gen_store_fpr64(ctx, fp64, fd);
6586 tcg_temp_free_i64(fp64);
6588 opn = "floor.l.s";
6589 break;
6590 case OPC_ROUND_W_S:
6592 TCGv_i32 fp0 = tcg_temp_new_i32();
6594 gen_load_fpr32(fp0, fs);
6595 gen_helper_float_roundw_s(fp0, fp0);
6596 gen_store_fpr32(fp0, fd);
6597 tcg_temp_free_i32(fp0);
6599 opn = "round.w.s";
6600 break;
6601 case OPC_TRUNC_W_S:
6603 TCGv_i32 fp0 = tcg_temp_new_i32();
6605 gen_load_fpr32(fp0, fs);
6606 gen_helper_float_truncw_s(fp0, fp0);
6607 gen_store_fpr32(fp0, fd);
6608 tcg_temp_free_i32(fp0);
6610 opn = "trunc.w.s";
6611 break;
6612 case OPC_CEIL_W_S:
6614 TCGv_i32 fp0 = tcg_temp_new_i32();
6616 gen_load_fpr32(fp0, fs);
6617 gen_helper_float_ceilw_s(fp0, fp0);
6618 gen_store_fpr32(fp0, fd);
6619 tcg_temp_free_i32(fp0);
6621 opn = "ceil.w.s";
6622 break;
6623 case OPC_FLOOR_W_S:
6625 TCGv_i32 fp0 = tcg_temp_new_i32();
6627 gen_load_fpr32(fp0, fs);
6628 gen_helper_float_floorw_s(fp0, fp0);
6629 gen_store_fpr32(fp0, fd);
6630 tcg_temp_free_i32(fp0);
6632 opn = "floor.w.s";
6633 break;
6634 case OPC_MOVCF_S:
6635 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6636 opn = "movcf.s";
6637 break;
6638 case OPC_MOVZ_S:
6640 int l1 = gen_new_label();
6641 TCGv_i32 fp0;
6643 if (ft != 0) {
6644 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6646 fp0 = tcg_temp_new_i32();
6647 gen_load_fpr32(fp0, fs);
6648 gen_store_fpr32(fp0, fd);
6649 tcg_temp_free_i32(fp0);
6650 gen_set_label(l1);
6652 opn = "movz.s";
6653 break;
6654 case OPC_MOVN_S:
6656 int l1 = gen_new_label();
6657 TCGv_i32 fp0;
6659 if (ft != 0) {
6660 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6661 fp0 = tcg_temp_new_i32();
6662 gen_load_fpr32(fp0, fs);
6663 gen_store_fpr32(fp0, fd);
6664 tcg_temp_free_i32(fp0);
6665 gen_set_label(l1);
6668 opn = "movn.s";
6669 break;
6670 case OPC_RECIP_S:
6671 check_cop1x(ctx);
6673 TCGv_i32 fp0 = tcg_temp_new_i32();
6675 gen_load_fpr32(fp0, fs);
6676 gen_helper_float_recip_s(fp0, fp0);
6677 gen_store_fpr32(fp0, fd);
6678 tcg_temp_free_i32(fp0);
6680 opn = "recip.s";
6681 break;
6682 case OPC_RSQRT_S:
6683 check_cop1x(ctx);
6685 TCGv_i32 fp0 = tcg_temp_new_i32();
6687 gen_load_fpr32(fp0, fs);
6688 gen_helper_float_rsqrt_s(fp0, fp0);
6689 gen_store_fpr32(fp0, fd);
6690 tcg_temp_free_i32(fp0);
6692 opn = "rsqrt.s";
6693 break;
6694 case OPC_RECIP2_S:
6695 check_cp1_64bitmode(ctx);
6697 TCGv_i32 fp0 = tcg_temp_new_i32();
6698 TCGv_i32 fp1 = tcg_temp_new_i32();
6700 gen_load_fpr32(fp0, fs);
6701 gen_load_fpr32(fp1, fd);
6702 gen_helper_float_recip2_s(fp0, fp0, fp1);
6703 tcg_temp_free_i32(fp1);
6704 gen_store_fpr32(fp0, fd);
6705 tcg_temp_free_i32(fp0);
6707 opn = "recip2.s";
6708 break;
6709 case OPC_RECIP1_S:
6710 check_cp1_64bitmode(ctx);
6712 TCGv_i32 fp0 = tcg_temp_new_i32();
6714 gen_load_fpr32(fp0, fs);
6715 gen_helper_float_recip1_s(fp0, fp0);
6716 gen_store_fpr32(fp0, fd);
6717 tcg_temp_free_i32(fp0);
6719 opn = "recip1.s";
6720 break;
6721 case OPC_RSQRT1_S:
6722 check_cp1_64bitmode(ctx);
6724 TCGv_i32 fp0 = tcg_temp_new_i32();
6726 gen_load_fpr32(fp0, fs);
6727 gen_helper_float_rsqrt1_s(fp0, fp0);
6728 gen_store_fpr32(fp0, fd);
6729 tcg_temp_free_i32(fp0);
6731 opn = "rsqrt1.s";
6732 break;
6733 case OPC_RSQRT2_S:
6734 check_cp1_64bitmode(ctx);
6736 TCGv_i32 fp0 = tcg_temp_new_i32();
6737 TCGv_i32 fp1 = tcg_temp_new_i32();
6739 gen_load_fpr32(fp0, fs);
6740 gen_load_fpr32(fp1, ft);
6741 gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6742 tcg_temp_free_i32(fp1);
6743 gen_store_fpr32(fp0, fd);
6744 tcg_temp_free_i32(fp0);
6746 opn = "rsqrt2.s";
6747 break;
6748 case OPC_CVT_D_S:
6749 check_cp1_registers(ctx, fd);
6751 TCGv_i32 fp32 = tcg_temp_new_i32();
6752 TCGv_i64 fp64 = tcg_temp_new_i64();
6754 gen_load_fpr32(fp32, fs);
6755 gen_helper_float_cvtd_s(fp64, fp32);
6756 tcg_temp_free_i32(fp32);
6757 gen_store_fpr64(ctx, fp64, fd);
6758 tcg_temp_free_i64(fp64);
6760 opn = "cvt.d.s";
6761 break;
6762 case OPC_CVT_W_S:
6764 TCGv_i32 fp0 = tcg_temp_new_i32();
6766 gen_load_fpr32(fp0, fs);
6767 gen_helper_float_cvtw_s(fp0, fp0);
6768 gen_store_fpr32(fp0, fd);
6769 tcg_temp_free_i32(fp0);
6771 opn = "cvt.w.s";
6772 break;
6773 case OPC_CVT_L_S:
6774 check_cp1_64bitmode(ctx);
6776 TCGv_i32 fp32 = tcg_temp_new_i32();
6777 TCGv_i64 fp64 = tcg_temp_new_i64();
6779 gen_load_fpr32(fp32, fs);
6780 gen_helper_float_cvtl_s(fp64, fp32);
6781 tcg_temp_free_i32(fp32);
6782 gen_store_fpr64(ctx, fp64, fd);
6783 tcg_temp_free_i64(fp64);
6785 opn = "cvt.l.s";
6786 break;
6787 case OPC_CVT_PS_S:
6788 check_cp1_64bitmode(ctx);
6790 TCGv_i64 fp64 = tcg_temp_new_i64();
6791 TCGv_i32 fp32_0 = tcg_temp_new_i32();
6792 TCGv_i32 fp32_1 = tcg_temp_new_i32();
6794 gen_load_fpr32(fp32_0, fs);
6795 gen_load_fpr32(fp32_1, ft);
6796 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6797 tcg_temp_free_i32(fp32_1);
6798 tcg_temp_free_i32(fp32_0);
6799 gen_store_fpr64(ctx, fp64, fd);
6800 tcg_temp_free_i64(fp64);
6802 opn = "cvt.ps.s";
6803 break;
6804 case OPC_CMP_F_S:
6805 case OPC_CMP_UN_S:
6806 case OPC_CMP_EQ_S:
6807 case OPC_CMP_UEQ_S:
6808 case OPC_CMP_OLT_S:
6809 case OPC_CMP_ULT_S:
6810 case OPC_CMP_OLE_S:
6811 case OPC_CMP_ULE_S:
6812 case OPC_CMP_SF_S:
6813 case OPC_CMP_NGLE_S:
6814 case OPC_CMP_SEQ_S:
6815 case OPC_CMP_NGL_S:
6816 case OPC_CMP_LT_S:
6817 case OPC_CMP_NGE_S:
6818 case OPC_CMP_LE_S:
6819 case OPC_CMP_NGT_S:
6820 if (ctx->opcode & (1 << 6)) {
6821 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6822 opn = condnames_abs[func-48];
6823 } else {
6824 gen_cmp_s(ctx, func-48, ft, fs, cc);
6825 opn = condnames[func-48];
6827 break;
6828 case OPC_ADD_D:
6829 check_cp1_registers(ctx, fs | ft | fd);
6831 TCGv_i64 fp0 = tcg_temp_new_i64();
6832 TCGv_i64 fp1 = tcg_temp_new_i64();
6834 gen_load_fpr64(ctx, fp0, fs);
6835 gen_load_fpr64(ctx, fp1, ft);
6836 gen_helper_float_add_d(fp0, fp0, fp1);
6837 tcg_temp_free_i64(fp1);
6838 gen_store_fpr64(ctx, fp0, fd);
6839 tcg_temp_free_i64(fp0);
6841 opn = "add.d";
6842 optype = BINOP;
6843 break;
6844 case OPC_SUB_D:
6845 check_cp1_registers(ctx, fs | ft | fd);
6847 TCGv_i64 fp0 = tcg_temp_new_i64();
6848 TCGv_i64 fp1 = tcg_temp_new_i64();
6850 gen_load_fpr64(ctx, fp0, fs);
6851 gen_load_fpr64(ctx, fp1, ft);
6852 gen_helper_float_sub_d(fp0, fp0, fp1);
6853 tcg_temp_free_i64(fp1);
6854 gen_store_fpr64(ctx, fp0, fd);
6855 tcg_temp_free_i64(fp0);
6857 opn = "sub.d";
6858 optype = BINOP;
6859 break;
6860 case OPC_MUL_D:
6861 check_cp1_registers(ctx, fs | ft | fd);
6863 TCGv_i64 fp0 = tcg_temp_new_i64();
6864 TCGv_i64 fp1 = tcg_temp_new_i64();
6866 gen_load_fpr64(ctx, fp0, fs);
6867 gen_load_fpr64(ctx, fp1, ft);
6868 gen_helper_float_mul_d(fp0, fp0, fp1);
6869 tcg_temp_free_i64(fp1);
6870 gen_store_fpr64(ctx, fp0, fd);
6871 tcg_temp_free_i64(fp0);
6873 opn = "mul.d";
6874 optype = BINOP;
6875 break;
6876 case OPC_DIV_D:
6877 check_cp1_registers(ctx, fs | ft | fd);
6879 TCGv_i64 fp0 = tcg_temp_new_i64();
6880 TCGv_i64 fp1 = tcg_temp_new_i64();
6882 gen_load_fpr64(ctx, fp0, fs);
6883 gen_load_fpr64(ctx, fp1, ft);
6884 gen_helper_float_div_d(fp0, fp0, fp1);
6885 tcg_temp_free_i64(fp1);
6886 gen_store_fpr64(ctx, fp0, fd);
6887 tcg_temp_free_i64(fp0);
6889 opn = "div.d";
6890 optype = BINOP;
6891 break;
6892 case OPC_SQRT_D:
6893 check_cp1_registers(ctx, fs | fd);
6895 TCGv_i64 fp0 = tcg_temp_new_i64();
6897 gen_load_fpr64(ctx, fp0, fs);
6898 gen_helper_float_sqrt_d(fp0, fp0);
6899 gen_store_fpr64(ctx, fp0, fd);
6900 tcg_temp_free_i64(fp0);
6902 opn = "sqrt.d";
6903 break;
6904 case OPC_ABS_D:
6905 check_cp1_registers(ctx, fs | fd);
6907 TCGv_i64 fp0 = tcg_temp_new_i64();
6909 gen_load_fpr64(ctx, fp0, fs);
6910 gen_helper_float_abs_d(fp0, fp0);
6911 gen_store_fpr64(ctx, fp0, fd);
6912 tcg_temp_free_i64(fp0);
6914 opn = "abs.d";
6915 break;
6916 case OPC_MOV_D:
6917 check_cp1_registers(ctx, fs | fd);
6919 TCGv_i64 fp0 = tcg_temp_new_i64();
6921 gen_load_fpr64(ctx, fp0, fs);
6922 gen_store_fpr64(ctx, fp0, fd);
6923 tcg_temp_free_i64(fp0);
6925 opn = "mov.d";
6926 break;
6927 case OPC_NEG_D:
6928 check_cp1_registers(ctx, fs | fd);
6930 TCGv_i64 fp0 = tcg_temp_new_i64();
6932 gen_load_fpr64(ctx, fp0, fs);
6933 gen_helper_float_chs_d(fp0, fp0);
6934 gen_store_fpr64(ctx, fp0, fd);
6935 tcg_temp_free_i64(fp0);
6937 opn = "neg.d";
6938 break;
6939 case OPC_ROUND_L_D:
6940 check_cp1_64bitmode(ctx);
6942 TCGv_i64 fp0 = tcg_temp_new_i64();
6944 gen_load_fpr64(ctx, fp0, fs);
6945 gen_helper_float_roundl_d(fp0, fp0);
6946 gen_store_fpr64(ctx, fp0, fd);
6947 tcg_temp_free_i64(fp0);
6949 opn = "round.l.d";
6950 break;
6951 case OPC_TRUNC_L_D:
6952 check_cp1_64bitmode(ctx);
6954 TCGv_i64 fp0 = tcg_temp_new_i64();
6956 gen_load_fpr64(ctx, fp0, fs);
6957 gen_helper_float_truncl_d(fp0, fp0);
6958 gen_store_fpr64(ctx, fp0, fd);
6959 tcg_temp_free_i64(fp0);
6961 opn = "trunc.l.d";
6962 break;
6963 case OPC_CEIL_L_D:
6964 check_cp1_64bitmode(ctx);
6966 TCGv_i64 fp0 = tcg_temp_new_i64();
6968 gen_load_fpr64(ctx, fp0, fs);
6969 gen_helper_float_ceill_d(fp0, fp0);
6970 gen_store_fpr64(ctx, fp0, fd);
6971 tcg_temp_free_i64(fp0);
6973 opn = "ceil.l.d";
6974 break;
6975 case OPC_FLOOR_L_D:
6976 check_cp1_64bitmode(ctx);
6978 TCGv_i64 fp0 = tcg_temp_new_i64();
6980 gen_load_fpr64(ctx, fp0, fs);
6981 gen_helper_float_floorl_d(fp0, fp0);
6982 gen_store_fpr64(ctx, fp0, fd);
6983 tcg_temp_free_i64(fp0);
6985 opn = "floor.l.d";
6986 break;
6987 case OPC_ROUND_W_D:
6988 check_cp1_registers(ctx, fs);
6990 TCGv_i32 fp32 = tcg_temp_new_i32();
6991 TCGv_i64 fp64 = tcg_temp_new_i64();
6993 gen_load_fpr64(ctx, fp64, fs);
6994 gen_helper_float_roundw_d(fp32, fp64);
6995 tcg_temp_free_i64(fp64);
6996 gen_store_fpr32(fp32, fd);
6997 tcg_temp_free_i32(fp32);
6999 opn = "round.w.d";
7000 break;
7001 case OPC_TRUNC_W_D:
7002 check_cp1_registers(ctx, fs);
7004 TCGv_i32 fp32 = tcg_temp_new_i32();
7005 TCGv_i64 fp64 = tcg_temp_new_i64();
7007 gen_load_fpr64(ctx, fp64, fs);
7008 gen_helper_float_truncw_d(fp32, fp64);
7009 tcg_temp_free_i64(fp64);
7010 gen_store_fpr32(fp32, fd);
7011 tcg_temp_free_i32(fp32);
7013 opn = "trunc.w.d";
7014 break;
7015 case OPC_CEIL_W_D:
7016 check_cp1_registers(ctx, fs);
7018 TCGv_i32 fp32 = tcg_temp_new_i32();
7019 TCGv_i64 fp64 = tcg_temp_new_i64();
7021 gen_load_fpr64(ctx, fp64, fs);
7022 gen_helper_float_ceilw_d(fp32, fp64);
7023 tcg_temp_free_i64(fp64);
7024 gen_store_fpr32(fp32, fd);
7025 tcg_temp_free_i32(fp32);
7027 opn = "ceil.w.d";
7028 break;
7029 case OPC_FLOOR_W_D:
7030 check_cp1_registers(ctx, fs);
7032 TCGv_i32 fp32 = tcg_temp_new_i32();
7033 TCGv_i64 fp64 = tcg_temp_new_i64();
7035 gen_load_fpr64(ctx, fp64, fs);
7036 gen_helper_float_floorw_d(fp32, fp64);
7037 tcg_temp_free_i64(fp64);
7038 gen_store_fpr32(fp32, fd);
7039 tcg_temp_free_i32(fp32);
7041 opn = "floor.w.d";
7042 break;
7043 case OPC_MOVCF_D:
7044 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7045 opn = "movcf.d";
7046 break;
7047 case OPC_MOVZ_D:
7049 int l1 = gen_new_label();
7050 TCGv_i64 fp0;
7052 if (ft != 0) {
7053 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7055 fp0 = tcg_temp_new_i64();
7056 gen_load_fpr64(ctx, fp0, fs);
7057 gen_store_fpr64(ctx, fp0, fd);
7058 tcg_temp_free_i64(fp0);
7059 gen_set_label(l1);
7061 opn = "movz.d";
7062 break;
7063 case OPC_MOVN_D:
7065 int l1 = gen_new_label();
7066 TCGv_i64 fp0;
7068 if (ft != 0) {
7069 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7070 fp0 = tcg_temp_new_i64();
7071 gen_load_fpr64(ctx, fp0, fs);
7072 gen_store_fpr64(ctx, fp0, fd);
7073 tcg_temp_free_i64(fp0);
7074 gen_set_label(l1);
7077 opn = "movn.d";
7078 break;
7079 case OPC_RECIP_D:
7080 check_cp1_64bitmode(ctx);
7082 TCGv_i64 fp0 = tcg_temp_new_i64();
7084 gen_load_fpr64(ctx, fp0, fs);
7085 gen_helper_float_recip_d(fp0, fp0);
7086 gen_store_fpr64(ctx, fp0, fd);
7087 tcg_temp_free_i64(fp0);
7089 opn = "recip.d";
7090 break;
7091 case OPC_RSQRT_D:
7092 check_cp1_64bitmode(ctx);
7094 TCGv_i64 fp0 = tcg_temp_new_i64();
7096 gen_load_fpr64(ctx, fp0, fs);
7097 gen_helper_float_rsqrt_d(fp0, fp0);
7098 gen_store_fpr64(ctx, fp0, fd);
7099 tcg_temp_free_i64(fp0);
7101 opn = "rsqrt.d";
7102 break;
7103 case OPC_RECIP2_D:
7104 check_cp1_64bitmode(ctx);
7106 TCGv_i64 fp0 = tcg_temp_new_i64();
7107 TCGv_i64 fp1 = tcg_temp_new_i64();
7109 gen_load_fpr64(ctx, fp0, fs);
7110 gen_load_fpr64(ctx, fp1, ft);
7111 gen_helper_float_recip2_d(fp0, fp0, fp1);
7112 tcg_temp_free_i64(fp1);
7113 gen_store_fpr64(ctx, fp0, fd);
7114 tcg_temp_free_i64(fp0);
7116 opn = "recip2.d";
7117 break;
7118 case OPC_RECIP1_D:
7119 check_cp1_64bitmode(ctx);
7121 TCGv_i64 fp0 = tcg_temp_new_i64();
7123 gen_load_fpr64(ctx, fp0, fs);
7124 gen_helper_float_recip1_d(fp0, fp0);
7125 gen_store_fpr64(ctx, fp0, fd);
7126 tcg_temp_free_i64(fp0);
7128 opn = "recip1.d";
7129 break;
7130 case OPC_RSQRT1_D:
7131 check_cp1_64bitmode(ctx);
7133 TCGv_i64 fp0 = tcg_temp_new_i64();
7135 gen_load_fpr64(ctx, fp0, fs);
7136 gen_helper_float_rsqrt1_d(fp0, fp0);
7137 gen_store_fpr64(ctx, fp0, fd);
7138 tcg_temp_free_i64(fp0);
7140 opn = "rsqrt1.d";
7141 break;
7142 case OPC_RSQRT2_D:
7143 check_cp1_64bitmode(ctx);
7145 TCGv_i64 fp0 = tcg_temp_new_i64();
7146 TCGv_i64 fp1 = tcg_temp_new_i64();
7148 gen_load_fpr64(ctx, fp0, fs);
7149 gen_load_fpr64(ctx, fp1, ft);
7150 gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
7151 tcg_temp_free_i64(fp1);
7152 gen_store_fpr64(ctx, fp0, fd);
7153 tcg_temp_free_i64(fp0);
7155 opn = "rsqrt2.d";
7156 break;
7157 case OPC_CMP_F_D:
7158 case OPC_CMP_UN_D:
7159 case OPC_CMP_EQ_D:
7160 case OPC_CMP_UEQ_D:
7161 case OPC_CMP_OLT_D:
7162 case OPC_CMP_ULT_D:
7163 case OPC_CMP_OLE_D:
7164 case OPC_CMP_ULE_D:
7165 case OPC_CMP_SF_D:
7166 case OPC_CMP_NGLE_D:
7167 case OPC_CMP_SEQ_D:
7168 case OPC_CMP_NGL_D:
7169 case OPC_CMP_LT_D:
7170 case OPC_CMP_NGE_D:
7171 case OPC_CMP_LE_D:
7172 case OPC_CMP_NGT_D:
7173 if (ctx->opcode & (1 << 6)) {
7174 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7175 opn = condnames_abs[func-48];
7176 } else {
7177 gen_cmp_d(ctx, func-48, ft, fs, cc);
7178 opn = condnames[func-48];
7180 break;
7181 case OPC_CVT_S_D:
7182 check_cp1_registers(ctx, fs);
7184 TCGv_i32 fp32 = tcg_temp_new_i32();
7185 TCGv_i64 fp64 = tcg_temp_new_i64();
7187 gen_load_fpr64(ctx, fp64, fs);
7188 gen_helper_float_cvts_d(fp32, fp64);
7189 tcg_temp_free_i64(fp64);
7190 gen_store_fpr32(fp32, fd);
7191 tcg_temp_free_i32(fp32);
7193 opn = "cvt.s.d";
7194 break;
7195 case OPC_CVT_W_D:
7196 check_cp1_registers(ctx, fs);
7198 TCGv_i32 fp32 = tcg_temp_new_i32();
7199 TCGv_i64 fp64 = tcg_temp_new_i64();
7201 gen_load_fpr64(ctx, fp64, fs);
7202 gen_helper_float_cvtw_d(fp32, fp64);
7203 tcg_temp_free_i64(fp64);
7204 gen_store_fpr32(fp32, fd);
7205 tcg_temp_free_i32(fp32);
7207 opn = "cvt.w.d";
7208 break;
7209 case OPC_CVT_L_D:
7210 check_cp1_64bitmode(ctx);
7212 TCGv_i64 fp0 = tcg_temp_new_i64();
7214 gen_load_fpr64(ctx, fp0, fs);
7215 gen_helper_float_cvtl_d(fp0, fp0);
7216 gen_store_fpr64(ctx, fp0, fd);
7217 tcg_temp_free_i64(fp0);
7219 opn = "cvt.l.d";
7220 break;
7221 case OPC_CVT_S_W:
7223 TCGv_i32 fp0 = tcg_temp_new_i32();
7225 gen_load_fpr32(fp0, fs);
7226 gen_helper_float_cvts_w(fp0, fp0);
7227 gen_store_fpr32(fp0, fd);
7228 tcg_temp_free_i32(fp0);
7230 opn = "cvt.s.w";
7231 break;
7232 case OPC_CVT_D_W:
7233 check_cp1_registers(ctx, fd);
7235 TCGv_i32 fp32 = tcg_temp_new_i32();
7236 TCGv_i64 fp64 = tcg_temp_new_i64();
7238 gen_load_fpr32(fp32, fs);
7239 gen_helper_float_cvtd_w(fp64, fp32);
7240 tcg_temp_free_i32(fp32);
7241 gen_store_fpr64(ctx, fp64, fd);
7242 tcg_temp_free_i64(fp64);
7244 opn = "cvt.d.w";
7245 break;
7246 case OPC_CVT_S_L:
7247 check_cp1_64bitmode(ctx);
7249 TCGv_i32 fp32 = tcg_temp_new_i32();
7250 TCGv_i64 fp64 = tcg_temp_new_i64();
7252 gen_load_fpr64(ctx, fp64, fs);
7253 gen_helper_float_cvts_l(fp32, fp64);
7254 tcg_temp_free_i64(fp64);
7255 gen_store_fpr32(fp32, fd);
7256 tcg_temp_free_i32(fp32);
7258 opn = "cvt.s.l";
7259 break;
7260 case OPC_CVT_D_L:
7261 check_cp1_64bitmode(ctx);
7263 TCGv_i64 fp0 = tcg_temp_new_i64();
7265 gen_load_fpr64(ctx, fp0, fs);
7266 gen_helper_float_cvtd_l(fp0, fp0);
7267 gen_store_fpr64(ctx, fp0, fd);
7268 tcg_temp_free_i64(fp0);
7270 opn = "cvt.d.l";
7271 break;
7272 case OPC_CVT_PS_PW:
7273 check_cp1_64bitmode(ctx);
7275 TCGv_i64 fp0 = tcg_temp_new_i64();
7277 gen_load_fpr64(ctx, fp0, fs);
7278 gen_helper_float_cvtps_pw(fp0, fp0);
7279 gen_store_fpr64(ctx, fp0, fd);
7280 tcg_temp_free_i64(fp0);
7282 opn = "cvt.ps.pw";
7283 break;
7284 case OPC_ADD_PS:
7285 check_cp1_64bitmode(ctx);
7287 TCGv_i64 fp0 = tcg_temp_new_i64();
7288 TCGv_i64 fp1 = tcg_temp_new_i64();
7290 gen_load_fpr64(ctx, fp0, fs);
7291 gen_load_fpr64(ctx, fp1, ft);
7292 gen_helper_float_add_ps(fp0, fp0, fp1);
7293 tcg_temp_free_i64(fp1);
7294 gen_store_fpr64(ctx, fp0, fd);
7295 tcg_temp_free_i64(fp0);
7297 opn = "add.ps";
7298 break;
7299 case OPC_SUB_PS:
7300 check_cp1_64bitmode(ctx);
7302 TCGv_i64 fp0 = tcg_temp_new_i64();
7303 TCGv_i64 fp1 = tcg_temp_new_i64();
7305 gen_load_fpr64(ctx, fp0, fs);
7306 gen_load_fpr64(ctx, fp1, ft);
7307 gen_helper_float_sub_ps(fp0, fp0, fp1);
7308 tcg_temp_free_i64(fp1);
7309 gen_store_fpr64(ctx, fp0, fd);
7310 tcg_temp_free_i64(fp0);
7312 opn = "sub.ps";
7313 break;
7314 case OPC_MUL_PS:
7315 check_cp1_64bitmode(ctx);
7317 TCGv_i64 fp0 = tcg_temp_new_i64();
7318 TCGv_i64 fp1 = tcg_temp_new_i64();
7320 gen_load_fpr64(ctx, fp0, fs);
7321 gen_load_fpr64(ctx, fp1, ft);
7322 gen_helper_float_mul_ps(fp0, fp0, fp1);
7323 tcg_temp_free_i64(fp1);
7324 gen_store_fpr64(ctx, fp0, fd);
7325 tcg_temp_free_i64(fp0);
7327 opn = "mul.ps";
7328 break;
7329 case OPC_ABS_PS:
7330 check_cp1_64bitmode(ctx);
7332 TCGv_i64 fp0 = tcg_temp_new_i64();
7334 gen_load_fpr64(ctx, fp0, fs);
7335 gen_helper_float_abs_ps(fp0, fp0);
7336 gen_store_fpr64(ctx, fp0, fd);
7337 tcg_temp_free_i64(fp0);
7339 opn = "abs.ps";
7340 break;
7341 case OPC_MOV_PS:
7342 check_cp1_64bitmode(ctx);
7344 TCGv_i64 fp0 = tcg_temp_new_i64();
7346 gen_load_fpr64(ctx, fp0, fs);
7347 gen_store_fpr64(ctx, fp0, fd);
7348 tcg_temp_free_i64(fp0);
7350 opn = "mov.ps";
7351 break;
7352 case OPC_NEG_PS:
7353 check_cp1_64bitmode(ctx);
7355 TCGv_i64 fp0 = tcg_temp_new_i64();
7357 gen_load_fpr64(ctx, fp0, fs);
7358 gen_helper_float_chs_ps(fp0, fp0);
7359 gen_store_fpr64(ctx, fp0, fd);
7360 tcg_temp_free_i64(fp0);
7362 opn = "neg.ps";
7363 break;
7364 case OPC_MOVCF_PS:
7365 check_cp1_64bitmode(ctx);
7366 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7367 opn = "movcf.ps";
7368 break;
7369 case OPC_MOVZ_PS:
7370 check_cp1_64bitmode(ctx);
7372 int l1 = gen_new_label();
7373 TCGv_i64 fp0;
7375 if (ft != 0)
7376 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7377 fp0 = tcg_temp_new_i64();
7378 gen_load_fpr64(ctx, fp0, fs);
7379 gen_store_fpr64(ctx, fp0, fd);
7380 tcg_temp_free_i64(fp0);
7381 gen_set_label(l1);
7383 opn = "movz.ps";
7384 break;
7385 case OPC_MOVN_PS:
7386 check_cp1_64bitmode(ctx);
7388 int l1 = gen_new_label();
7389 TCGv_i64 fp0;
7391 if (ft != 0) {
7392 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7393 fp0 = tcg_temp_new_i64();
7394 gen_load_fpr64(ctx, fp0, fs);
7395 gen_store_fpr64(ctx, fp0, fd);
7396 tcg_temp_free_i64(fp0);
7397 gen_set_label(l1);
7400 opn = "movn.ps";
7401 break;
7402 case OPC_ADDR_PS:
7403 check_cp1_64bitmode(ctx);
7405 TCGv_i64 fp0 = tcg_temp_new_i64();
7406 TCGv_i64 fp1 = tcg_temp_new_i64();
7408 gen_load_fpr64(ctx, fp0, ft);
7409 gen_load_fpr64(ctx, fp1, fs);
7410 gen_helper_float_addr_ps(fp0, fp0, fp1);
7411 tcg_temp_free_i64(fp1);
7412 gen_store_fpr64(ctx, fp0, fd);
7413 tcg_temp_free_i64(fp0);
7415 opn = "addr.ps";
7416 break;
7417 case OPC_MULR_PS:
7418 check_cp1_64bitmode(ctx);
7420 TCGv_i64 fp0 = tcg_temp_new_i64();
7421 TCGv_i64 fp1 = tcg_temp_new_i64();
7423 gen_load_fpr64(ctx, fp0, ft);
7424 gen_load_fpr64(ctx, fp1, fs);
7425 gen_helper_float_mulr_ps(fp0, fp0, fp1);
7426 tcg_temp_free_i64(fp1);
7427 gen_store_fpr64(ctx, fp0, fd);
7428 tcg_temp_free_i64(fp0);
7430 opn = "mulr.ps";
7431 break;
7432 case OPC_RECIP2_PS:
7433 check_cp1_64bitmode(ctx);
7435 TCGv_i64 fp0 = tcg_temp_new_i64();
7436 TCGv_i64 fp1 = tcg_temp_new_i64();
7438 gen_load_fpr64(ctx, fp0, fs);
7439 gen_load_fpr64(ctx, fp1, fd);
7440 gen_helper_float_recip2_ps(fp0, fp0, fp1);
7441 tcg_temp_free_i64(fp1);
7442 gen_store_fpr64(ctx, fp0, fd);
7443 tcg_temp_free_i64(fp0);
7445 opn = "recip2.ps";
7446 break;
7447 case OPC_RECIP1_PS:
7448 check_cp1_64bitmode(ctx);
7450 TCGv_i64 fp0 = tcg_temp_new_i64();
7452 gen_load_fpr64(ctx, fp0, fs);
7453 gen_helper_float_recip1_ps(fp0, fp0);
7454 gen_store_fpr64(ctx, fp0, fd);
7455 tcg_temp_free_i64(fp0);
7457 opn = "recip1.ps";
7458 break;
7459 case OPC_RSQRT1_PS:
7460 check_cp1_64bitmode(ctx);
7462 TCGv_i64 fp0 = tcg_temp_new_i64();
7464 gen_load_fpr64(ctx, fp0, fs);
7465 gen_helper_float_rsqrt1_ps(fp0, fp0);
7466 gen_store_fpr64(ctx, fp0, fd);
7467 tcg_temp_free_i64(fp0);
7469 opn = "rsqrt1.ps";
7470 break;
7471 case OPC_RSQRT2_PS:
7472 check_cp1_64bitmode(ctx);
7474 TCGv_i64 fp0 = tcg_temp_new_i64();
7475 TCGv_i64 fp1 = tcg_temp_new_i64();
7477 gen_load_fpr64(ctx, fp0, fs);
7478 gen_load_fpr64(ctx, fp1, ft);
7479 gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7480 tcg_temp_free_i64(fp1);
7481 gen_store_fpr64(ctx, fp0, fd);
7482 tcg_temp_free_i64(fp0);
7484 opn = "rsqrt2.ps";
7485 break;
7486 case OPC_CVT_S_PU:
7487 check_cp1_64bitmode(ctx);
7489 TCGv_i32 fp0 = tcg_temp_new_i32();
7491 gen_load_fpr32h(fp0, fs);
7492 gen_helper_float_cvts_pu(fp0, fp0);
7493 gen_store_fpr32(fp0, fd);
7494 tcg_temp_free_i32(fp0);
7496 opn = "cvt.s.pu";
7497 break;
7498 case OPC_CVT_PW_PS:
7499 check_cp1_64bitmode(ctx);
7501 TCGv_i64 fp0 = tcg_temp_new_i64();
7503 gen_load_fpr64(ctx, fp0, fs);
7504 gen_helper_float_cvtpw_ps(fp0, fp0);
7505 gen_store_fpr64(ctx, fp0, fd);
7506 tcg_temp_free_i64(fp0);
7508 opn = "cvt.pw.ps";
7509 break;
7510 case OPC_CVT_S_PL:
7511 check_cp1_64bitmode(ctx);
7513 TCGv_i32 fp0 = tcg_temp_new_i32();
7515 gen_load_fpr32(fp0, fs);
7516 gen_helper_float_cvts_pl(fp0, fp0);
7517 gen_store_fpr32(fp0, fd);
7518 tcg_temp_free_i32(fp0);
7520 opn = "cvt.s.pl";
7521 break;
7522 case OPC_PLL_PS:
7523 check_cp1_64bitmode(ctx);
7525 TCGv_i32 fp0 = tcg_temp_new_i32();
7526 TCGv_i32 fp1 = tcg_temp_new_i32();
7528 gen_load_fpr32(fp0, fs);
7529 gen_load_fpr32(fp1, ft);
7530 gen_store_fpr32h(fp0, fd);
7531 gen_store_fpr32(fp1, fd);
7532 tcg_temp_free_i32(fp0);
7533 tcg_temp_free_i32(fp1);
7535 opn = "pll.ps";
7536 break;
7537 case OPC_PLU_PS:
7538 check_cp1_64bitmode(ctx);
7540 TCGv_i32 fp0 = tcg_temp_new_i32();
7541 TCGv_i32 fp1 = tcg_temp_new_i32();
7543 gen_load_fpr32(fp0, fs);
7544 gen_load_fpr32h(fp1, ft);
7545 gen_store_fpr32(fp1, fd);
7546 gen_store_fpr32h(fp0, fd);
7547 tcg_temp_free_i32(fp0);
7548 tcg_temp_free_i32(fp1);
7550 opn = "plu.ps";
7551 break;
7552 case OPC_PUL_PS:
7553 check_cp1_64bitmode(ctx);
7555 TCGv_i32 fp0 = tcg_temp_new_i32();
7556 TCGv_i32 fp1 = tcg_temp_new_i32();
7558 gen_load_fpr32h(fp0, fs);
7559 gen_load_fpr32(fp1, ft);
7560 gen_store_fpr32(fp1, fd);
7561 gen_store_fpr32h(fp0, fd);
7562 tcg_temp_free_i32(fp0);
7563 tcg_temp_free_i32(fp1);
7565 opn = "pul.ps";
7566 break;
7567 case OPC_PUU_PS:
7568 check_cp1_64bitmode(ctx);
7570 TCGv_i32 fp0 = tcg_temp_new_i32();
7571 TCGv_i32 fp1 = tcg_temp_new_i32();
7573 gen_load_fpr32h(fp0, fs);
7574 gen_load_fpr32h(fp1, ft);
7575 gen_store_fpr32(fp1, fd);
7576 gen_store_fpr32h(fp0, fd);
7577 tcg_temp_free_i32(fp0);
7578 tcg_temp_free_i32(fp1);
7580 opn = "puu.ps";
7581 break;
7582 case OPC_CMP_F_PS:
7583 case OPC_CMP_UN_PS:
7584 case OPC_CMP_EQ_PS:
7585 case OPC_CMP_UEQ_PS:
7586 case OPC_CMP_OLT_PS:
7587 case OPC_CMP_ULT_PS:
7588 case OPC_CMP_OLE_PS:
7589 case OPC_CMP_ULE_PS:
7590 case OPC_CMP_SF_PS:
7591 case OPC_CMP_NGLE_PS:
7592 case OPC_CMP_SEQ_PS:
7593 case OPC_CMP_NGL_PS:
7594 case OPC_CMP_LT_PS:
7595 case OPC_CMP_NGE_PS:
7596 case OPC_CMP_LE_PS:
7597 case OPC_CMP_NGT_PS:
7598 if (ctx->opcode & (1 << 6)) {
7599 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7600 opn = condnames_abs[func-48];
7601 } else {
7602 gen_cmp_ps(ctx, func-48, ft, fs, cc);
7603 opn = condnames[func-48];
7605 break;
7606 default:
7607 MIPS_INVAL(opn);
7608 generate_exception (ctx, EXCP_RI);
7609 return;
7611 switch (optype) {
7612 case BINOP:
7613 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7614 break;
7615 case CMPOP:
7616 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7617 break;
7618 default:
7619 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7620 break;
7624 /* Coprocessor 3 (FPU) */
7625 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7626 int fd, int fs, int base, int index)
7628 const char *opn = "extended float load/store";
7629 int store = 0;
7630 TCGv t0 = tcg_temp_new();
7632 if (base == 0) {
7633 gen_load_gpr(t0, index);
7634 } else if (index == 0) {
7635 gen_load_gpr(t0, base);
7636 } else {
7637 gen_load_gpr(t0, index);
7638 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7640 /* Don't do NOP if destination is zero: we must perform the actual
7641 memory access. */
7642 save_cpu_state(ctx, 0);
7643 switch (opc) {
7644 case OPC_LWXC1:
7645 check_cop1x(ctx);
7647 TCGv_i32 fp0 = tcg_temp_new_i32();
7649 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7650 tcg_gen_trunc_tl_i32(fp0, t0);
7651 gen_store_fpr32(fp0, fd);
7652 tcg_temp_free_i32(fp0);
7654 opn = "lwxc1";
7655 break;
7656 case OPC_LDXC1:
7657 check_cop1x(ctx);
7658 check_cp1_registers(ctx, fd);
7660 TCGv_i64 fp0 = tcg_temp_new_i64();
7662 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7663 gen_store_fpr64(ctx, fp0, fd);
7664 tcg_temp_free_i64(fp0);
7666 opn = "ldxc1";
7667 break;
7668 case OPC_LUXC1:
7669 check_cp1_64bitmode(ctx);
7670 tcg_gen_andi_tl(t0, t0, ~0x7);
7672 TCGv_i64 fp0 = tcg_temp_new_i64();
7674 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7675 gen_store_fpr64(ctx, fp0, fd);
7676 tcg_temp_free_i64(fp0);
7678 opn = "luxc1";
7679 break;
7680 case OPC_SWXC1:
7681 check_cop1x(ctx);
7683 TCGv_i32 fp0 = tcg_temp_new_i32();
7684 TCGv t1 = tcg_temp_new();
7686 gen_load_fpr32(fp0, fs);
7687 tcg_gen_extu_i32_tl(t1, fp0);
7688 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7689 tcg_temp_free_i32(fp0);
7690 tcg_temp_free(t1);
7692 opn = "swxc1";
7693 store = 1;
7694 break;
7695 case OPC_SDXC1:
7696 check_cop1x(ctx);
7697 check_cp1_registers(ctx, fs);
7699 TCGv_i64 fp0 = tcg_temp_new_i64();
7701 gen_load_fpr64(ctx, fp0, fs);
7702 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7703 tcg_temp_free_i64(fp0);
7705 opn = "sdxc1";
7706 store = 1;
7707 break;
7708 case OPC_SUXC1:
7709 check_cp1_64bitmode(ctx);
7710 tcg_gen_andi_tl(t0, t0, ~0x7);
7712 TCGv_i64 fp0 = tcg_temp_new_i64();
7714 gen_load_fpr64(ctx, fp0, fs);
7715 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7716 tcg_temp_free_i64(fp0);
7718 opn = "suxc1";
7719 store = 1;
7720 break;
7722 tcg_temp_free(t0);
7723 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7724 regnames[index], regnames[base]);
7727 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7728 int fd, int fr, int fs, int ft)
7730 const char *opn = "flt3_arith";
7732 switch (opc) {
7733 case OPC_ALNV_PS:
7734 check_cp1_64bitmode(ctx);
7736 TCGv t0 = tcg_temp_local_new();
7737 TCGv_i32 fp = tcg_temp_new_i32();
7738 TCGv_i32 fph = tcg_temp_new_i32();
7739 int l1 = gen_new_label();
7740 int l2 = gen_new_label();
7742 gen_load_gpr(t0, fr);
7743 tcg_gen_andi_tl(t0, t0, 0x7);
7745 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7746 gen_load_fpr32(fp, fs);
7747 gen_load_fpr32h(fph, fs);
7748 gen_store_fpr32(fp, fd);
7749 gen_store_fpr32h(fph, fd);
7750 tcg_gen_br(l2);
7751 gen_set_label(l1);
7752 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7753 tcg_temp_free(t0);
7754 #ifdef TARGET_WORDS_BIGENDIAN
7755 gen_load_fpr32(fp, fs);
7756 gen_load_fpr32h(fph, ft);
7757 gen_store_fpr32h(fp, fd);
7758 gen_store_fpr32(fph, fd);
7759 #else
7760 gen_load_fpr32h(fph, fs);
7761 gen_load_fpr32(fp, ft);
7762 gen_store_fpr32(fph, fd);
7763 gen_store_fpr32h(fp, fd);
7764 #endif
7765 gen_set_label(l2);
7766 tcg_temp_free_i32(fp);
7767 tcg_temp_free_i32(fph);
7769 opn = "alnv.ps";
7770 break;
7771 case OPC_MADD_S:
7772 check_cop1x(ctx);
7774 TCGv_i32 fp0 = tcg_temp_new_i32();
7775 TCGv_i32 fp1 = tcg_temp_new_i32();
7776 TCGv_i32 fp2 = tcg_temp_new_i32();
7778 gen_load_fpr32(fp0, fs);
7779 gen_load_fpr32(fp1, ft);
7780 gen_load_fpr32(fp2, fr);
7781 gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7782 tcg_temp_free_i32(fp0);
7783 tcg_temp_free_i32(fp1);
7784 gen_store_fpr32(fp2, fd);
7785 tcg_temp_free_i32(fp2);
7787 opn = "madd.s";
7788 break;
7789 case OPC_MADD_D:
7790 check_cop1x(ctx);
7791 check_cp1_registers(ctx, fd | fs | ft | fr);
7793 TCGv_i64 fp0 = tcg_temp_new_i64();
7794 TCGv_i64 fp1 = tcg_temp_new_i64();
7795 TCGv_i64 fp2 = tcg_temp_new_i64();
7797 gen_load_fpr64(ctx, fp0, fs);
7798 gen_load_fpr64(ctx, fp1, ft);
7799 gen_load_fpr64(ctx, fp2, fr);
7800 gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7801 tcg_temp_free_i64(fp0);
7802 tcg_temp_free_i64(fp1);
7803 gen_store_fpr64(ctx, fp2, fd);
7804 tcg_temp_free_i64(fp2);
7806 opn = "madd.d";
7807 break;
7808 case OPC_MADD_PS:
7809 check_cp1_64bitmode(ctx);
7811 TCGv_i64 fp0 = tcg_temp_new_i64();
7812 TCGv_i64 fp1 = tcg_temp_new_i64();
7813 TCGv_i64 fp2 = tcg_temp_new_i64();
7815 gen_load_fpr64(ctx, fp0, fs);
7816 gen_load_fpr64(ctx, fp1, ft);
7817 gen_load_fpr64(ctx, fp2, fr);
7818 gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7819 tcg_temp_free_i64(fp0);
7820 tcg_temp_free_i64(fp1);
7821 gen_store_fpr64(ctx, fp2, fd);
7822 tcg_temp_free_i64(fp2);
7824 opn = "madd.ps";
7825 break;
7826 case OPC_MSUB_S:
7827 check_cop1x(ctx);
7829 TCGv_i32 fp0 = tcg_temp_new_i32();
7830 TCGv_i32 fp1 = tcg_temp_new_i32();
7831 TCGv_i32 fp2 = tcg_temp_new_i32();
7833 gen_load_fpr32(fp0, fs);
7834 gen_load_fpr32(fp1, ft);
7835 gen_load_fpr32(fp2, fr);
7836 gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7837 tcg_temp_free_i32(fp0);
7838 tcg_temp_free_i32(fp1);
7839 gen_store_fpr32(fp2, fd);
7840 tcg_temp_free_i32(fp2);
7842 opn = "msub.s";
7843 break;
7844 case OPC_MSUB_D:
7845 check_cop1x(ctx);
7846 check_cp1_registers(ctx, fd | fs | ft | fr);
7848 TCGv_i64 fp0 = tcg_temp_new_i64();
7849 TCGv_i64 fp1 = tcg_temp_new_i64();
7850 TCGv_i64 fp2 = tcg_temp_new_i64();
7852 gen_load_fpr64(ctx, fp0, fs);
7853 gen_load_fpr64(ctx, fp1, ft);
7854 gen_load_fpr64(ctx, fp2, fr);
7855 gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7856 tcg_temp_free_i64(fp0);
7857 tcg_temp_free_i64(fp1);
7858 gen_store_fpr64(ctx, fp2, fd);
7859 tcg_temp_free_i64(fp2);
7861 opn = "msub.d";
7862 break;
7863 case OPC_MSUB_PS:
7864 check_cp1_64bitmode(ctx);
7866 TCGv_i64 fp0 = tcg_temp_new_i64();
7867 TCGv_i64 fp1 = tcg_temp_new_i64();
7868 TCGv_i64 fp2 = tcg_temp_new_i64();
7870 gen_load_fpr64(ctx, fp0, fs);
7871 gen_load_fpr64(ctx, fp1, ft);
7872 gen_load_fpr64(ctx, fp2, fr);
7873 gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7874 tcg_temp_free_i64(fp0);
7875 tcg_temp_free_i64(fp1);
7876 gen_store_fpr64(ctx, fp2, fd);
7877 tcg_temp_free_i64(fp2);
7879 opn = "msub.ps";
7880 break;
7881 case OPC_NMADD_S:
7882 check_cop1x(ctx);
7884 TCGv_i32 fp0 = tcg_temp_new_i32();
7885 TCGv_i32 fp1 = tcg_temp_new_i32();
7886 TCGv_i32 fp2 = tcg_temp_new_i32();
7888 gen_load_fpr32(fp0, fs);
7889 gen_load_fpr32(fp1, ft);
7890 gen_load_fpr32(fp2, fr);
7891 gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7892 tcg_temp_free_i32(fp0);
7893 tcg_temp_free_i32(fp1);
7894 gen_store_fpr32(fp2, fd);
7895 tcg_temp_free_i32(fp2);
7897 opn = "nmadd.s";
7898 break;
7899 case OPC_NMADD_D:
7900 check_cop1x(ctx);
7901 check_cp1_registers(ctx, fd | fs | ft | fr);
7903 TCGv_i64 fp0 = tcg_temp_new_i64();
7904 TCGv_i64 fp1 = tcg_temp_new_i64();
7905 TCGv_i64 fp2 = tcg_temp_new_i64();
7907 gen_load_fpr64(ctx, fp0, fs);
7908 gen_load_fpr64(ctx, fp1, ft);
7909 gen_load_fpr64(ctx, fp2, fr);
7910 gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7911 tcg_temp_free_i64(fp0);
7912 tcg_temp_free_i64(fp1);
7913 gen_store_fpr64(ctx, fp2, fd);
7914 tcg_temp_free_i64(fp2);
7916 opn = "nmadd.d";
7917 break;
7918 case OPC_NMADD_PS:
7919 check_cp1_64bitmode(ctx);
7921 TCGv_i64 fp0 = tcg_temp_new_i64();
7922 TCGv_i64 fp1 = tcg_temp_new_i64();
7923 TCGv_i64 fp2 = tcg_temp_new_i64();
7925 gen_load_fpr64(ctx, fp0, fs);
7926 gen_load_fpr64(ctx, fp1, ft);
7927 gen_load_fpr64(ctx, fp2, fr);
7928 gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7929 tcg_temp_free_i64(fp0);
7930 tcg_temp_free_i64(fp1);
7931 gen_store_fpr64(ctx, fp2, fd);
7932 tcg_temp_free_i64(fp2);
7934 opn = "nmadd.ps";
7935 break;
7936 case OPC_NMSUB_S:
7937 check_cop1x(ctx);
7939 TCGv_i32 fp0 = tcg_temp_new_i32();
7940 TCGv_i32 fp1 = tcg_temp_new_i32();
7941 TCGv_i32 fp2 = tcg_temp_new_i32();
7943 gen_load_fpr32(fp0, fs);
7944 gen_load_fpr32(fp1, ft);
7945 gen_load_fpr32(fp2, fr);
7946 gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7947 tcg_temp_free_i32(fp0);
7948 tcg_temp_free_i32(fp1);
7949 gen_store_fpr32(fp2, fd);
7950 tcg_temp_free_i32(fp2);
7952 opn = "nmsub.s";
7953 break;
7954 case OPC_NMSUB_D:
7955 check_cop1x(ctx);
7956 check_cp1_registers(ctx, fd | fs | ft | fr);
7958 TCGv_i64 fp0 = tcg_temp_new_i64();
7959 TCGv_i64 fp1 = tcg_temp_new_i64();
7960 TCGv_i64 fp2 = tcg_temp_new_i64();
7962 gen_load_fpr64(ctx, fp0, fs);
7963 gen_load_fpr64(ctx, fp1, ft);
7964 gen_load_fpr64(ctx, fp2, fr);
7965 gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7966 tcg_temp_free_i64(fp0);
7967 tcg_temp_free_i64(fp1);
7968 gen_store_fpr64(ctx, fp2, fd);
7969 tcg_temp_free_i64(fp2);
7971 opn = "nmsub.d";
7972 break;
7973 case OPC_NMSUB_PS:
7974 check_cp1_64bitmode(ctx);
7976 TCGv_i64 fp0 = tcg_temp_new_i64();
7977 TCGv_i64 fp1 = tcg_temp_new_i64();
7978 TCGv_i64 fp2 = tcg_temp_new_i64();
7980 gen_load_fpr64(ctx, fp0, fs);
7981 gen_load_fpr64(ctx, fp1, ft);
7982 gen_load_fpr64(ctx, fp2, fr);
7983 gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7984 tcg_temp_free_i64(fp0);
7985 tcg_temp_free_i64(fp1);
7986 gen_store_fpr64(ctx, fp2, fd);
7987 tcg_temp_free_i64(fp2);
7989 opn = "nmsub.ps";
7990 break;
7991 default:
7992 MIPS_INVAL(opn);
7993 generate_exception (ctx, EXCP_RI);
7994 return;
7996 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7997 fregnames[fs], fregnames[ft]);
8000 static void
8001 gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
8003 TCGv t0;
8005 check_insn(env, ctx, ISA_MIPS32R2);
8006 t0 = tcg_temp_new();
8008 switch (rd) {
8009 case 0:
8010 save_cpu_state(ctx, 1);
8011 gen_helper_rdhwr_cpunum(t0);
8012 gen_store_gpr(t0, rt);
8013 break;
8014 case 1:
8015 save_cpu_state(ctx, 1);
8016 gen_helper_rdhwr_synci_step(t0);
8017 gen_store_gpr(t0, rt);
8018 break;
8019 case 2:
8020 save_cpu_state(ctx, 1);
8021 gen_helper_rdhwr_cc(t0);
8022 gen_store_gpr(t0, rt);
8023 break;
8024 case 3:
8025 save_cpu_state(ctx, 1);
8026 gen_helper_rdhwr_ccres(t0);
8027 gen_store_gpr(t0, rt);
8028 break;
8029 case 29:
8030 #if defined(CONFIG_USER_ONLY)
8031 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
8032 gen_store_gpr(t0, rt);
8033 break;
8034 #else
8035 /* XXX: Some CPUs implement this in hardware.
8036 Not supported yet. */
8037 #endif
8038 default: /* Invalid */
8039 MIPS_INVAL("rdhwr");
8040 generate_exception(ctx, EXCP_RI);
8041 break;
8043 tcg_temp_free(t0);
8046 static void handle_delay_slot (CPUState *env, DisasContext *ctx,
8047 int insn_bytes)
8049 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8050 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8051 /* Branches completion */
8052 ctx->hflags &= ~MIPS_HFLAG_BMASK;
8053 ctx->bstate = BS_BRANCH;
8054 save_cpu_state(ctx, 0);
8055 /* FIXME: Need to clear can_do_io. */
8056 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
8057 case MIPS_HFLAG_B:
8058 /* unconditional branch */
8059 MIPS_DEBUG("unconditional branch");
8060 if (proc_hflags & MIPS_HFLAG_BX) {
8061 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
8063 gen_goto_tb(ctx, 0, ctx->btarget);
8064 break;
8065 case MIPS_HFLAG_BL:
8066 /* blikely taken case */
8067 MIPS_DEBUG("blikely branch taken");
8068 gen_goto_tb(ctx, 0, ctx->btarget);
8069 break;
8070 case MIPS_HFLAG_BC:
8071 /* Conditional branch */
8072 MIPS_DEBUG("conditional branch");
8074 int l1 = gen_new_label();
8076 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8077 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
8078 gen_set_label(l1);
8079 gen_goto_tb(ctx, 0, ctx->btarget);
8081 break;
8082 case MIPS_HFLAG_BR:
8083 /* unconditional branch to register */
8084 MIPS_DEBUG("branch to register");
8085 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
8086 TCGv t0 = tcg_temp_new();
8087 TCGv_i32 t1 = tcg_temp_new_i32();
8089 tcg_gen_andi_tl(t0, btarget, 0x1);
8090 tcg_gen_trunc_tl_i32(t1, t0);
8091 tcg_temp_free(t0);
8092 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
8093 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
8094 tcg_gen_or_i32(hflags, hflags, t1);
8095 tcg_temp_free_i32(t1);
8097 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
8098 } else {
8099 tcg_gen_mov_tl(cpu_PC, btarget);
8101 if (ctx->singlestep_enabled) {
8102 save_cpu_state(ctx, 0);
8103 gen_helper_0i(raise_exception, EXCP_DEBUG);
8105 tcg_gen_exit_tb(0);
8106 break;
8107 default:
8108 MIPS_DEBUG("unknown branch");
8109 break;
8114 /* ISA extensions (ASEs) */
8115 /* MIPS16 extension to MIPS32 */
8117 /* MIPS16 major opcodes */
8118 enum {
8119 M16_OPC_ADDIUSP = 0x00,
8120 M16_OPC_ADDIUPC = 0x01,
8121 M16_OPC_B = 0x02,
8122 M16_OPC_JAL = 0x03,
8123 M16_OPC_BEQZ = 0x04,
8124 M16_OPC_BNEQZ = 0x05,
8125 M16_OPC_SHIFT = 0x06,
8126 M16_OPC_LD = 0x07,
8127 M16_OPC_RRIA = 0x08,
8128 M16_OPC_ADDIU8 = 0x09,
8129 M16_OPC_SLTI = 0x0a,
8130 M16_OPC_SLTIU = 0x0b,
8131 M16_OPC_I8 = 0x0c,
8132 M16_OPC_LI = 0x0d,
8133 M16_OPC_CMPI = 0x0e,
8134 M16_OPC_SD = 0x0f,
8135 M16_OPC_LB = 0x10,
8136 M16_OPC_LH = 0x11,
8137 M16_OPC_LWSP = 0x12,
8138 M16_OPC_LW = 0x13,
8139 M16_OPC_LBU = 0x14,
8140 M16_OPC_LHU = 0x15,
8141 M16_OPC_LWPC = 0x16,
8142 M16_OPC_LWU = 0x17,
8143 M16_OPC_SB = 0x18,
8144 M16_OPC_SH = 0x19,
8145 M16_OPC_SWSP = 0x1a,
8146 M16_OPC_SW = 0x1b,
8147 M16_OPC_RRR = 0x1c,
8148 M16_OPC_RR = 0x1d,
8149 M16_OPC_EXTEND = 0x1e,
8150 M16_OPC_I64 = 0x1f
8153 /* I8 funct field */
8154 enum {
8155 I8_BTEQZ = 0x0,
8156 I8_BTNEZ = 0x1,
8157 I8_SWRASP = 0x2,
8158 I8_ADJSP = 0x3,
8159 I8_SVRS = 0x4,
8160 I8_MOV32R = 0x5,
8161 I8_MOVR32 = 0x7
8164 /* RRR f field */
8165 enum {
8166 RRR_DADDU = 0x0,
8167 RRR_ADDU = 0x1,
8168 RRR_DSUBU = 0x2,
8169 RRR_SUBU = 0x3
8172 /* RR funct field */
8173 enum {
8174 RR_JR = 0x00,
8175 RR_SDBBP = 0x01,
8176 RR_SLT = 0x02,
8177 RR_SLTU = 0x03,
8178 RR_SLLV = 0x04,
8179 RR_BREAK = 0x05,
8180 RR_SRLV = 0x06,
8181 RR_SRAV = 0x07,
8182 RR_DSRL = 0x08,
8183 RR_CMP = 0x0a,
8184 RR_NEG = 0x0b,
8185 RR_AND = 0x0c,
8186 RR_OR = 0x0d,
8187 RR_XOR = 0x0e,
8188 RR_NOT = 0x0f,
8189 RR_MFHI = 0x10,
8190 RR_CNVT = 0x11,
8191 RR_MFLO = 0x12,
8192 RR_DSRA = 0x13,
8193 RR_DSLLV = 0x14,
8194 RR_DSRLV = 0x16,
8195 RR_DSRAV = 0x17,
8196 RR_MULT = 0x18,
8197 RR_MULTU = 0x19,
8198 RR_DIV = 0x1a,
8199 RR_DIVU = 0x1b,
8200 RR_DMULT = 0x1c,
8201 RR_DMULTU = 0x1d,
8202 RR_DDIV = 0x1e,
8203 RR_DDIVU = 0x1f
8206 /* I64 funct field */
8207 enum {
8208 I64_LDSP = 0x0,
8209 I64_SDSP = 0x1,
8210 I64_SDRASP = 0x2,
8211 I64_DADJSP = 0x3,
8212 I64_LDPC = 0x4,
8213 I64_DADDIU5 = 0x5,
8214 I64_DADDIUPC = 0x6,
8215 I64_DADDIUSP = 0x7
8218 /* RR ry field for CNVT */
8219 enum {
8220 RR_RY_CNVT_ZEB = 0x0,
8221 RR_RY_CNVT_ZEH = 0x1,
8222 RR_RY_CNVT_ZEW = 0x2,
8223 RR_RY_CNVT_SEB = 0x4,
8224 RR_RY_CNVT_SEH = 0x5,
8225 RR_RY_CNVT_SEW = 0x6,
8228 static int xlat (int r)
8230 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8232 return map[r];
8235 static void gen_mips16_save (DisasContext *ctx,
8236 int xsregs, int aregs,
8237 int do_ra, int do_s0, int do_s1,
8238 int framesize)
8240 TCGv t0 = tcg_temp_new();
8241 TCGv t1 = tcg_temp_new();
8242 int args, astatic;
8244 switch (aregs) {
8245 case 0:
8246 case 1:
8247 case 2:
8248 case 3:
8249 case 11:
8250 args = 0;
8251 break;
8252 case 4:
8253 case 5:
8254 case 6:
8255 case 7:
8256 args = 1;
8257 break;
8258 case 8:
8259 case 9:
8260 case 10:
8261 args = 2;
8262 break;
8263 case 12:
8264 case 13:
8265 args = 3;
8266 break;
8267 case 14:
8268 args = 4;
8269 break;
8270 default:
8271 generate_exception(ctx, EXCP_RI);
8272 return;
8275 switch (args) {
8276 case 4:
8277 gen_base_offset_addr(ctx, t0, 29, 12);
8278 gen_load_gpr(t1, 7);
8279 op_st_sw(t1, t0, ctx);
8280 /* Fall through */
8281 case 3:
8282 gen_base_offset_addr(ctx, t0, 29, 8);
8283 gen_load_gpr(t1, 6);
8284 op_st_sw(t1, t0, ctx);
8285 /* Fall through */
8286 case 2:
8287 gen_base_offset_addr(ctx, t0, 29, 4);
8288 gen_load_gpr(t1, 5);
8289 op_st_sw(t1, t0, ctx);
8290 /* Fall through */
8291 case 1:
8292 gen_base_offset_addr(ctx, t0, 29, 0);
8293 gen_load_gpr(t1, 4);
8294 op_st_sw(t1, t0, ctx);
8297 gen_load_gpr(t0, 29);
8299 #define DECR_AND_STORE(reg) do { \
8300 tcg_gen_subi_tl(t0, t0, 4); \
8301 gen_load_gpr(t1, reg); \
8302 op_st_sw(t1, t0, ctx); \
8303 } while (0)
8305 if (do_ra) {
8306 DECR_AND_STORE(31);
8309 switch (xsregs) {
8310 case 7:
8311 DECR_AND_STORE(30);
8312 /* Fall through */
8313 case 6:
8314 DECR_AND_STORE(23);
8315 /* Fall through */
8316 case 5:
8317 DECR_AND_STORE(22);
8318 /* Fall through */
8319 case 4:
8320 DECR_AND_STORE(21);
8321 /* Fall through */
8322 case 3:
8323 DECR_AND_STORE(20);
8324 /* Fall through */
8325 case 2:
8326 DECR_AND_STORE(19);
8327 /* Fall through */
8328 case 1:
8329 DECR_AND_STORE(18);
8332 if (do_s1) {
8333 DECR_AND_STORE(17);
8335 if (do_s0) {
8336 DECR_AND_STORE(16);
8339 switch (aregs) {
8340 case 0:
8341 case 4:
8342 case 8:
8343 case 12:
8344 case 14:
8345 astatic = 0;
8346 break;
8347 case 1:
8348 case 5:
8349 case 9:
8350 case 13:
8351 astatic = 1;
8352 break;
8353 case 2:
8354 case 6:
8355 case 10:
8356 astatic = 2;
8357 break;
8358 case 3:
8359 case 7:
8360 astatic = 3;
8361 break;
8362 case 11:
8363 astatic = 4;
8364 break;
8365 default:
8366 generate_exception(ctx, EXCP_RI);
8367 return;
8370 if (astatic > 0) {
8371 DECR_AND_STORE(7);
8372 if (astatic > 1) {
8373 DECR_AND_STORE(6);
8374 if (astatic > 2) {
8375 DECR_AND_STORE(5);
8376 if (astatic > 3) {
8377 DECR_AND_STORE(4);
8382 #undef DECR_AND_STORE
8384 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8385 tcg_temp_free(t0);
8386 tcg_temp_free(t1);
8389 static void gen_mips16_restore (DisasContext *ctx,
8390 int xsregs, int aregs,
8391 int do_ra, int do_s0, int do_s1,
8392 int framesize)
8394 int astatic;
8395 TCGv t0 = tcg_temp_new();
8396 TCGv t1 = tcg_temp_new();
8398 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8400 #define DECR_AND_LOAD(reg) do { \
8401 tcg_gen_subi_tl(t0, t0, 4); \
8402 op_ld_lw(t1, t0, ctx); \
8403 gen_store_gpr(t1, reg); \
8404 } while (0)
8406 if (do_ra) {
8407 DECR_AND_LOAD(31);
8410 switch (xsregs) {
8411 case 7:
8412 DECR_AND_LOAD(30);
8413 /* Fall through */
8414 case 6:
8415 DECR_AND_LOAD(23);
8416 /* Fall through */
8417 case 5:
8418 DECR_AND_LOAD(22);
8419 /* Fall through */
8420 case 4:
8421 DECR_AND_LOAD(21);
8422 /* Fall through */
8423 case 3:
8424 DECR_AND_LOAD(20);
8425 /* Fall through */
8426 case 2:
8427 DECR_AND_LOAD(19);
8428 /* Fall through */
8429 case 1:
8430 DECR_AND_LOAD(18);
8433 if (do_s1) {
8434 DECR_AND_LOAD(17);
8436 if (do_s0) {
8437 DECR_AND_LOAD(16);
8440 switch (aregs) {
8441 case 0:
8442 case 4:
8443 case 8:
8444 case 12:
8445 case 14:
8446 astatic = 0;
8447 break;
8448 case 1:
8449 case 5:
8450 case 9:
8451 case 13:
8452 astatic = 1;
8453 break;
8454 case 2:
8455 case 6:
8456 case 10:
8457 astatic = 2;
8458 break;
8459 case 3:
8460 case 7:
8461 astatic = 3;
8462 break;
8463 case 11:
8464 astatic = 4;
8465 break;
8466 default:
8467 generate_exception(ctx, EXCP_RI);
8468 return;
8471 if (astatic > 0) {
8472 DECR_AND_LOAD(7);
8473 if (astatic > 1) {
8474 DECR_AND_LOAD(6);
8475 if (astatic > 2) {
8476 DECR_AND_LOAD(5);
8477 if (astatic > 3) {
8478 DECR_AND_LOAD(4);
8483 #undef DECR_AND_LOAD
8485 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8486 tcg_temp_free(t0);
8487 tcg_temp_free(t1);
8490 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8491 int is_64_bit, int extended)
8493 TCGv t0;
8495 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8496 generate_exception(ctx, EXCP_RI);
8497 return;
8500 t0 = tcg_temp_new();
8502 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8503 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8504 if (!is_64_bit) {
8505 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8508 tcg_temp_free(t0);
8511 #if defined(TARGET_MIPS64)
8512 static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8513 int ry, int funct, int16_t offset,
8514 int extended)
8516 switch (funct) {
8517 case I64_LDSP:
8518 check_mips_64(ctx);
8519 offset = extended ? offset : offset << 3;
8520 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
8521 break;
8522 case I64_SDSP:
8523 check_mips_64(ctx);
8524 offset = extended ? offset : offset << 3;
8525 gen_st(ctx, OPC_SD, ry, 29, offset);
8526 break;
8527 case I64_SDRASP:
8528 check_mips_64(ctx);
8529 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8530 gen_st(ctx, OPC_SD, 31, 29, offset);
8531 break;
8532 case I64_DADJSP:
8533 check_mips_64(ctx);
8534 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8535 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8536 break;
8537 case I64_LDPC:
8538 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8539 generate_exception(ctx, EXCP_RI);
8540 } else {
8541 offset = extended ? offset : offset << 3;
8542 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
8544 break;
8545 case I64_DADDIU5:
8546 check_mips_64(ctx);
8547 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8548 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8549 break;
8550 case I64_DADDIUPC:
8551 check_mips_64(ctx);
8552 offset = extended ? offset : offset << 2;
8553 gen_addiupc(ctx, ry, offset, 1, extended);
8554 break;
8555 case I64_DADDIUSP:
8556 check_mips_64(ctx);
8557 offset = extended ? offset : offset << 2;
8558 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8559 break;
8562 #endif
8564 static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8565 int *is_branch)
8567 int extend = lduw_code(ctx->pc + 2);
8568 int op, rx, ry, funct, sa;
8569 int16_t imm, offset;
8571 ctx->opcode = (ctx->opcode << 16) | extend;
8572 op = (ctx->opcode >> 11) & 0x1f;
8573 sa = (ctx->opcode >> 22) & 0x1f;
8574 funct = (ctx->opcode >> 8) & 0x7;
8575 rx = xlat((ctx->opcode >> 8) & 0x7);
8576 ry = xlat((ctx->opcode >> 5) & 0x7);
8577 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8578 | ((ctx->opcode >> 21) & 0x3f) << 5
8579 | (ctx->opcode & 0x1f));
8581 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8582 counterparts. */
8583 switch (op) {
8584 case M16_OPC_ADDIUSP:
8585 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8586 break;
8587 case M16_OPC_ADDIUPC:
8588 gen_addiupc(ctx, rx, imm, 0, 1);
8589 break;
8590 case M16_OPC_B:
8591 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8592 /* No delay slot, so just process as a normal instruction */
8593 break;
8594 case M16_OPC_BEQZ:
8595 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8596 /* No delay slot, so just process as a normal instruction */
8597 break;
8598 case M16_OPC_BNEQZ:
8599 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8600 /* No delay slot, so just process as a normal instruction */
8601 break;
8602 case M16_OPC_SHIFT:
8603 switch (ctx->opcode & 0x3) {
8604 case 0x0:
8605 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8606 break;
8607 case 0x1:
8608 #if defined(TARGET_MIPS64)
8609 check_mips_64(ctx);
8610 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8611 #else
8612 generate_exception(ctx, EXCP_RI);
8613 #endif
8614 break;
8615 case 0x2:
8616 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8617 break;
8618 case 0x3:
8619 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8620 break;
8622 break;
8623 #if defined(TARGET_MIPS64)
8624 case M16_OPC_LD:
8625 check_mips_64(ctx);
8626 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
8627 break;
8628 #endif
8629 case M16_OPC_RRIA:
8630 imm = ctx->opcode & 0xf;
8631 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8632 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8633 imm = (int16_t) (imm << 1) >> 1;
8634 if ((ctx->opcode >> 4) & 0x1) {
8635 #if defined(TARGET_MIPS64)
8636 check_mips_64(ctx);
8637 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8638 #else
8639 generate_exception(ctx, EXCP_RI);
8640 #endif
8641 } else {
8642 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8644 break;
8645 case M16_OPC_ADDIU8:
8646 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8647 break;
8648 case M16_OPC_SLTI:
8649 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8650 break;
8651 case M16_OPC_SLTIU:
8652 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8653 break;
8654 case M16_OPC_I8:
8655 switch (funct) {
8656 case I8_BTEQZ:
8657 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8658 break;
8659 case I8_BTNEZ:
8660 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8661 break;
8662 case I8_SWRASP:
8663 gen_st(ctx, OPC_SW, 31, 29, imm);
8664 break;
8665 case I8_ADJSP:
8666 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8667 break;
8668 case I8_SVRS:
8670 int xsregs = (ctx->opcode >> 24) & 0x7;
8671 int aregs = (ctx->opcode >> 16) & 0xf;
8672 int do_ra = (ctx->opcode >> 6) & 0x1;
8673 int do_s0 = (ctx->opcode >> 5) & 0x1;
8674 int do_s1 = (ctx->opcode >> 4) & 0x1;
8675 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8676 | (ctx->opcode & 0xf)) << 3;
8678 if (ctx->opcode & (1 << 7)) {
8679 gen_mips16_save(ctx, xsregs, aregs,
8680 do_ra, do_s0, do_s1,
8681 framesize);
8682 } else {
8683 gen_mips16_restore(ctx, xsregs, aregs,
8684 do_ra, do_s0, do_s1,
8685 framesize);
8688 break;
8689 default:
8690 generate_exception(ctx, EXCP_RI);
8691 break;
8693 break;
8694 case M16_OPC_LI:
8695 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8696 break;
8697 case M16_OPC_CMPI:
8698 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8699 break;
8700 #if defined(TARGET_MIPS64)
8701 case M16_OPC_SD:
8702 gen_st(ctx, OPC_SD, ry, rx, offset);
8703 break;
8704 #endif
8705 case M16_OPC_LB:
8706 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8707 break;
8708 case M16_OPC_LH:
8709 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
8710 break;
8711 case M16_OPC_LWSP:
8712 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
8713 break;
8714 case M16_OPC_LW:
8715 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
8716 break;
8717 case M16_OPC_LBU:
8718 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8719 break;
8720 case M16_OPC_LHU:
8721 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
8722 break;
8723 case M16_OPC_LWPC:
8724 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
8725 break;
8726 #if defined(TARGET_MIPS64)
8727 case M16_OPC_LWU:
8728 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
8729 break;
8730 #endif
8731 case M16_OPC_SB:
8732 gen_st(ctx, OPC_SB, ry, rx, offset);
8733 break;
8734 case M16_OPC_SH:
8735 gen_st(ctx, OPC_SH, ry, rx, offset);
8736 break;
8737 case M16_OPC_SWSP:
8738 gen_st(ctx, OPC_SW, rx, 29, offset);
8739 break;
8740 case M16_OPC_SW:
8741 gen_st(ctx, OPC_SW, ry, rx, offset);
8742 break;
8743 #if defined(TARGET_MIPS64)
8744 case M16_OPC_I64:
8745 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8746 break;
8747 #endif
8748 default:
8749 generate_exception(ctx, EXCP_RI);
8750 break;
8753 return 4;
8756 static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8757 int *is_branch)
8759 int rx, ry;
8760 int sa;
8761 int op, cnvt_op, op1, offset;
8762 int funct;
8763 int n_bytes;
8765 op = (ctx->opcode >> 11) & 0x1f;
8766 sa = (ctx->opcode >> 2) & 0x7;
8767 sa = sa == 0 ? 8 : sa;
8768 rx = xlat((ctx->opcode >> 8) & 0x7);
8769 cnvt_op = (ctx->opcode >> 5) & 0x7;
8770 ry = xlat((ctx->opcode >> 5) & 0x7);
8771 op1 = offset = ctx->opcode & 0x1f;
8773 n_bytes = 2;
8775 switch (op) {
8776 case M16_OPC_ADDIUSP:
8778 int16_t imm = ((uint8_t) ctx->opcode) << 2;
8780 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8782 break;
8783 case M16_OPC_ADDIUPC:
8784 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8785 break;
8786 case M16_OPC_B:
8787 offset = (ctx->opcode & 0x7ff) << 1;
8788 offset = (int16_t)(offset << 4) >> 4;
8789 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8790 /* No delay slot, so just process as a normal instruction */
8791 break;
8792 case M16_OPC_JAL:
8793 offset = lduw_code(ctx->pc + 2);
8794 offset = (((ctx->opcode & 0x1f) << 21)
8795 | ((ctx->opcode >> 5) & 0x1f) << 16
8796 | offset) << 2;
8797 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8798 gen_compute_branch(ctx, op, 4, rx, ry, offset);
8799 n_bytes = 4;
8800 *is_branch = 1;
8801 break;
8802 case M16_OPC_BEQZ:
8803 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8804 /* No delay slot, so just process as a normal instruction */
8805 break;
8806 case M16_OPC_BNEQZ:
8807 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8808 /* No delay slot, so just process as a normal instruction */
8809 break;
8810 case M16_OPC_SHIFT:
8811 switch (ctx->opcode & 0x3) {
8812 case 0x0:
8813 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8814 break;
8815 case 0x1:
8816 #if defined(TARGET_MIPS64)
8817 check_mips_64(ctx);
8818 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8819 #else
8820 generate_exception(ctx, EXCP_RI);
8821 #endif
8822 break;
8823 case 0x2:
8824 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8825 break;
8826 case 0x3:
8827 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8828 break;
8830 break;
8831 #if defined(TARGET_MIPS64)
8832 case M16_OPC_LD:
8833 check_mips_64(ctx);
8834 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
8835 break;
8836 #endif
8837 case M16_OPC_RRIA:
8839 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8841 if ((ctx->opcode >> 4) & 1) {
8842 #if defined(TARGET_MIPS64)
8843 check_mips_64(ctx);
8844 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8845 #else
8846 generate_exception(ctx, EXCP_RI);
8847 #endif
8848 } else {
8849 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8852 break;
8853 case M16_OPC_ADDIU8:
8855 int16_t imm = (int8_t) ctx->opcode;
8857 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8859 break;
8860 case M16_OPC_SLTI:
8862 int16_t imm = (uint8_t) ctx->opcode;
8864 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8866 break;
8867 case M16_OPC_SLTIU:
8869 int16_t imm = (uint8_t) ctx->opcode;
8871 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8873 break;
8874 case M16_OPC_I8:
8876 int reg32;
8878 funct = (ctx->opcode >> 8) & 0x7;
8879 switch (funct) {
8880 case I8_BTEQZ:
8881 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8882 ((int8_t)ctx->opcode) << 1);
8883 break;
8884 case I8_BTNEZ:
8885 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
8886 ((int8_t)ctx->opcode) << 1);
8887 break;
8888 case I8_SWRASP:
8889 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
8890 break;
8891 case I8_ADJSP:
8892 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
8893 ((int8_t)ctx->opcode) << 3);
8894 break;
8895 case I8_SVRS:
8897 int do_ra = ctx->opcode & (1 << 6);
8898 int do_s0 = ctx->opcode & (1 << 5);
8899 int do_s1 = ctx->opcode & (1 << 4);
8900 int framesize = ctx->opcode & 0xf;
8902 if (framesize == 0) {
8903 framesize = 128;
8904 } else {
8905 framesize = framesize << 3;
8908 if (ctx->opcode & (1 << 7)) {
8909 gen_mips16_save(ctx, 0, 0,
8910 do_ra, do_s0, do_s1, framesize);
8911 } else {
8912 gen_mips16_restore(ctx, 0, 0,
8913 do_ra, do_s0, do_s1, framesize);
8916 break;
8917 case I8_MOV32R:
8919 int rz = xlat(ctx->opcode & 0x7);
8921 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
8922 ((ctx->opcode >> 5) & 0x7);
8923 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
8925 break;
8926 case I8_MOVR32:
8927 reg32 = ctx->opcode & 0x1f;
8928 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
8929 break;
8930 default:
8931 generate_exception(ctx, EXCP_RI);
8932 break;
8935 break;
8936 case M16_OPC_LI:
8938 int16_t imm = (uint8_t) ctx->opcode;
8940 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
8942 break;
8943 case M16_OPC_CMPI:
8945 int16_t imm = (uint8_t) ctx->opcode;
8947 gen_logic_imm(env, OPC_XORI, 24, rx, imm);
8949 break;
8950 #if defined(TARGET_MIPS64)
8951 case M16_OPC_SD:
8952 check_mips_64(ctx);
8953 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
8954 break;
8955 #endif
8956 case M16_OPC_LB:
8957 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8958 break;
8959 case M16_OPC_LH:
8960 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
8961 break;
8962 case M16_OPC_LWSP:
8963 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8964 break;
8965 case M16_OPC_LW:
8966 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
8967 break;
8968 case M16_OPC_LBU:
8969 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8970 break;
8971 case M16_OPC_LHU:
8972 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
8973 break;
8974 case M16_OPC_LWPC:
8975 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
8976 break;
8977 #if defined (TARGET_MIPS64)
8978 case M16_OPC_LWU:
8979 check_mips_64(ctx);
8980 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
8981 break;
8982 #endif
8983 case M16_OPC_SB:
8984 gen_st(ctx, OPC_SB, ry, rx, offset);
8985 break;
8986 case M16_OPC_SH:
8987 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
8988 break;
8989 case M16_OPC_SWSP:
8990 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8991 break;
8992 case M16_OPC_SW:
8993 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
8994 break;
8995 case M16_OPC_RRR:
8997 int rz = xlat((ctx->opcode >> 2) & 0x7);
8998 int mips32_op;
9000 switch (ctx->opcode & 0x3) {
9001 case RRR_ADDU:
9002 mips32_op = OPC_ADDU;
9003 break;
9004 case RRR_SUBU:
9005 mips32_op = OPC_SUBU;
9006 break;
9007 #if defined(TARGET_MIPS64)
9008 case RRR_DADDU:
9009 mips32_op = OPC_DADDU;
9010 check_mips_64(ctx);
9011 break;
9012 case RRR_DSUBU:
9013 mips32_op = OPC_DSUBU;
9014 check_mips_64(ctx);
9015 break;
9016 #endif
9017 default:
9018 generate_exception(ctx, EXCP_RI);
9019 goto done;
9022 gen_arith(env, ctx, mips32_op, rz, rx, ry);
9023 done:
9026 break;
9027 case M16_OPC_RR:
9028 switch (op1) {
9029 case RR_JR:
9031 int nd = (ctx->opcode >> 7) & 0x1;
9032 int link = (ctx->opcode >> 6) & 0x1;
9033 int ra = (ctx->opcode >> 5) & 0x1;
9035 if (link) {
9036 op = nd ? OPC_JALRC : OPC_JALRS;
9037 } else {
9038 op = OPC_JR;
9041 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9042 if (!nd) {
9043 *is_branch = 1;
9046 break;
9047 case RR_SDBBP:
9048 /* XXX: not clear which exception should be raised
9049 * when in debug mode...
9051 check_insn(env, ctx, ISA_MIPS32);
9052 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9053 generate_exception(ctx, EXCP_DBp);
9054 } else {
9055 generate_exception(ctx, EXCP_DBp);
9057 break;
9058 case RR_SLT:
9059 gen_slt(env, OPC_SLT, 24, rx, ry);
9060 break;
9061 case RR_SLTU:
9062 gen_slt(env, OPC_SLTU, 24, rx, ry);
9063 break;
9064 case RR_BREAK:
9065 generate_exception(ctx, EXCP_BREAK);
9066 break;
9067 case RR_SLLV:
9068 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9069 break;
9070 case RR_SRLV:
9071 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9072 break;
9073 case RR_SRAV:
9074 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9075 break;
9076 #if defined (TARGET_MIPS64)
9077 case RR_DSRL:
9078 check_mips_64(ctx);
9079 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9080 break;
9081 #endif
9082 case RR_CMP:
9083 gen_logic(env, OPC_XOR, 24, rx, ry);
9084 break;
9085 case RR_NEG:
9086 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9087 break;
9088 case RR_AND:
9089 gen_logic(env, OPC_AND, rx, rx, ry);
9090 break;
9091 case RR_OR:
9092 gen_logic(env, OPC_OR, rx, rx, ry);
9093 break;
9094 case RR_XOR:
9095 gen_logic(env, OPC_XOR, rx, rx, ry);
9096 break;
9097 case RR_NOT:
9098 gen_logic(env, OPC_NOR, rx, ry, 0);
9099 break;
9100 case RR_MFHI:
9101 gen_HILO(ctx, OPC_MFHI, rx);
9102 break;
9103 case RR_CNVT:
9104 switch (cnvt_op) {
9105 case RR_RY_CNVT_ZEB:
9106 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9107 break;
9108 case RR_RY_CNVT_ZEH:
9109 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9110 break;
9111 case RR_RY_CNVT_SEB:
9112 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9113 break;
9114 case RR_RY_CNVT_SEH:
9115 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9116 break;
9117 #if defined (TARGET_MIPS64)
9118 case RR_RY_CNVT_ZEW:
9119 check_mips_64(ctx);
9120 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9121 break;
9122 case RR_RY_CNVT_SEW:
9123 check_mips_64(ctx);
9124 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9125 break;
9126 #endif
9127 default:
9128 generate_exception(ctx, EXCP_RI);
9129 break;
9131 break;
9132 case RR_MFLO:
9133 gen_HILO(ctx, OPC_MFLO, rx);
9134 break;
9135 #if defined (TARGET_MIPS64)
9136 case RR_DSRA:
9137 check_mips_64(ctx);
9138 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9139 break;
9140 case RR_DSLLV:
9141 check_mips_64(ctx);
9142 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9143 break;
9144 case RR_DSRLV:
9145 check_mips_64(ctx);
9146 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9147 break;
9148 case RR_DSRAV:
9149 check_mips_64(ctx);
9150 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9151 break;
9152 #endif
9153 case RR_MULT:
9154 gen_muldiv(ctx, OPC_MULT, rx, ry);
9155 break;
9156 case RR_MULTU:
9157 gen_muldiv(ctx, OPC_MULTU, rx, ry);
9158 break;
9159 case RR_DIV:
9160 gen_muldiv(ctx, OPC_DIV, rx, ry);
9161 break;
9162 case RR_DIVU:
9163 gen_muldiv(ctx, OPC_DIVU, rx, ry);
9164 break;
9165 #if defined (TARGET_MIPS64)
9166 case RR_DMULT:
9167 check_mips_64(ctx);
9168 gen_muldiv(ctx, OPC_DMULT, rx, ry);
9169 break;
9170 case RR_DMULTU:
9171 check_mips_64(ctx);
9172 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9173 break;
9174 case RR_DDIV:
9175 check_mips_64(ctx);
9176 gen_muldiv(ctx, OPC_DDIV, rx, ry);
9177 break;
9178 case RR_DDIVU:
9179 check_mips_64(ctx);
9180 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9181 break;
9182 #endif
9183 default:
9184 generate_exception(ctx, EXCP_RI);
9185 break;
9187 break;
9188 case M16_OPC_EXTEND:
9189 decode_extended_mips16_opc(env, ctx, is_branch);
9190 n_bytes = 4;
9191 break;
9192 #if defined(TARGET_MIPS64)
9193 case M16_OPC_I64:
9194 funct = (ctx->opcode >> 8) & 0x7;
9195 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9196 break;
9197 #endif
9198 default:
9199 generate_exception(ctx, EXCP_RI);
9200 break;
9203 return n_bytes;
9206 /* microMIPS extension to MIPS32 */
9208 /* microMIPS32 major opcodes */
9210 enum {
9211 POOL32A = 0x00,
9212 POOL16A = 0x01,
9213 LBU16 = 0x02,
9214 MOVE16 = 0x03,
9215 ADDI32 = 0x04,
9216 LBU32 = 0x05,
9217 SB32 = 0x06,
9218 LB32 = 0x07,
9220 POOL32B = 0x08,
9221 POOL16B = 0x09,
9222 LHU16 = 0x0a,
9223 ANDI16 = 0x0b,
9224 ADDIU32 = 0x0c,
9225 LHU32 = 0x0d,
9226 SH32 = 0x0e,
9227 LH32 = 0x0f,
9229 POOL32I = 0x10,
9230 POOL16C = 0x11,
9231 LWSP16 = 0x12,
9232 POOL16D = 0x13,
9233 ORI32 = 0x14,
9234 POOL32F = 0x15,
9235 POOL32S = 0x16,
9236 DADDIU32 = 0x17,
9238 POOL32C = 0x18,
9239 LWGP16 = 0x19,
9240 LW16 = 0x1a,
9241 POOL16E = 0x1b,
9242 XORI32 = 0x1c,
9243 JALS32 = 0x1d,
9244 ADDIUPC = 0x1e,
9245 POOL48A = 0x1f,
9247 /* 0x20 is reserved */
9248 RES_20 = 0x20,
9249 POOL16F = 0x21,
9250 SB16 = 0x22,
9251 BEQZ16 = 0x23,
9252 SLTI32 = 0x24,
9253 BEQ32 = 0x25,
9254 SWC132 = 0x26,
9255 LWC132 = 0x27,
9257 /* 0x28 and 0x29 are reserved */
9258 RES_28 = 0x28,
9259 RES_29 = 0x29,
9260 SH16 = 0x2a,
9261 BNEZ16 = 0x2b,
9262 SLTIU32 = 0x2c,
9263 BNE32 = 0x2d,
9264 SDC132 = 0x2e,
9265 LDC132 = 0x2f,
9267 /* 0x30 and 0x31 are reserved */
9268 RES_30 = 0x30,
9269 RES_31 = 0x31,
9270 SWSP16 = 0x32,
9271 B16 = 0x33,
9272 ANDI32 = 0x34,
9273 J32 = 0x35,
9274 SD32 = 0x36,
9275 LD32 = 0x37,
9277 /* 0x38 and 0x39 are reserved */
9278 RES_38 = 0x38,
9279 RES_39 = 0x39,
9280 SW16 = 0x3a,
9281 LI16 = 0x3b,
9282 JALX32 = 0x3c,
9283 JAL32 = 0x3d,
9284 SW32 = 0x3e,
9285 LW32 = 0x3f
9288 /* POOL32A encoding of minor opcode field */
9290 enum {
9291 /* These opcodes are distinguished only by bits 9..6; those bits are
9292 * what are recorded below. */
9293 SLL32 = 0x0,
9294 SRL32 = 0x1,
9295 SRA = 0x2,
9296 ROTR = 0x3,
9298 SLLV = 0x0,
9299 SRLV = 0x1,
9300 SRAV = 0x2,
9301 ROTRV = 0x3,
9302 ADD = 0x4,
9303 ADDU32 = 0x5,
9304 SUB = 0x6,
9305 SUBU32 = 0x7,
9306 MUL = 0x8,
9307 AND = 0x9,
9308 OR32 = 0xa,
9309 NOR = 0xb,
9310 XOR32 = 0xc,
9311 SLT = 0xd,
9312 SLTU = 0xe,
9314 MOVN = 0x0,
9315 MOVZ = 0x1,
9316 LWXS = 0x4,
9318 /* The following can be distinguished by their lower 6 bits. */
9319 INS = 0x0c,
9320 EXT = 0x2c,
9321 POOL32AXF = 0x3c
9324 /* POOL32AXF encoding of minor opcode field extension */
9326 enum {
9327 /* bits 11..6 */
9328 TEQ = 0x00,
9329 TGE = 0x08,
9330 TGEU = 0x10,
9331 TLT = 0x20,
9332 TLTU = 0x28,
9333 TNE = 0x30,
9335 MFC0 = 0x03,
9336 MTC0 = 0x0b,
9338 /* bits 13..12 for 0x01 */
9339 MFHI_ACC = 0x0,
9340 MFLO_ACC = 0x1,
9341 MTHI_ACC = 0x2,
9342 MTLO_ACC = 0x3,
9344 /* bits 13..12 for 0x2a */
9345 MADD_ACC = 0x0,
9346 MADDU_ACC = 0x1,
9347 MSUB_ACC = 0x2,
9348 MSUBU_ACC = 0x3,
9350 /* bits 13..12 for 0x32 */
9351 MULT_ACC = 0x0,
9352 MULTU_ACC = 0x0,
9354 /* bits 15..12 for 0x2c */
9355 SEB = 0x2,
9356 SEH = 0x3,
9357 CLO = 0x4,
9358 CLZ = 0x5,
9359 RDHWR = 0x6,
9360 WSBH = 0x7,
9361 MULT = 0x8,
9362 MULTU = 0x9,
9363 DIV = 0xa,
9364 DIVU = 0xb,
9365 MADD = 0xc,
9366 MADDU = 0xd,
9367 MSUB = 0xe,
9368 MSUBU = 0xf,
9370 /* bits 15..12 for 0x34 */
9371 MFC2 = 0x4,
9372 MTC2 = 0x5,
9373 MFHC2 = 0x8,
9374 MTHC2 = 0x9,
9375 CFC2 = 0xc,
9376 CTC2 = 0xd,
9378 /* bits 15..12 for 0x3c */
9379 JALR = 0x0,
9380 JR = 0x0, /* alias */
9381 JALR_HB = 0x1,
9382 JALRS = 0x4,
9383 JALRS_HB = 0x5,
9385 /* bits 15..12 for 0x05 */
9386 RDPGPR = 0xe,
9387 WRPGPR = 0xf,
9389 /* bits 15..12 for 0x0d */
9390 TLBP = 0x0,
9391 TLBR = 0x1,
9392 TLBWI = 0x2,
9393 TLBWR = 0x3,
9394 WAIT = 0x9,
9395 IRET = 0xd,
9396 DERET = 0xe,
9397 ERET = 0xf,
9399 /* bits 15..12 for 0x15 */
9400 DMT = 0x0,
9401 DVPE = 0x1,
9402 EMT = 0x2,
9403 EVPE = 0x3,
9405 /* bits 15..12 for 0x1d */
9406 DI = 0x4,
9407 EI = 0x5,
9409 /* bits 15..12 for 0x2d */
9410 SYNC = 0x6,
9411 SYSCALL = 0x8,
9412 SDBBP = 0xd,
9414 /* bits 15..12 for 0x35 */
9415 MFHI32 = 0x0,
9416 MFLO32 = 0x1,
9417 MTHI32 = 0x2,
9418 MTLO32 = 0x3,
9421 /* POOL32B encoding of minor opcode field (bits 15..12) */
9423 enum {
9424 LWC2 = 0x0,
9425 LWP = 0x1,
9426 LDP = 0x4,
9427 LWM32 = 0x5,
9428 CACHE = 0x6,
9429 LDM = 0x7,
9430 SWC2 = 0x8,
9431 SWP = 0x9,
9432 SDP = 0xc,
9433 SWM32 = 0xd,
9434 SDM = 0xf
9437 /* POOL32C encoding of minor opcode field (bits 15..12) */
9439 enum {
9440 LWL = 0x0,
9441 SWL = 0x8,
9442 LWR = 0x1,
9443 SWR = 0x9,
9444 PREF = 0x2,
9445 /* 0xa is reserved */
9446 LL = 0x3,
9447 SC = 0xb,
9448 LDL = 0x4,
9449 SDL = 0xc,
9450 LDR = 0x5,
9451 SDR = 0xd,
9452 /* 0x6 is reserved */
9453 LWU = 0xe,
9454 LLD = 0x7,
9455 SCD = 0xf
9458 /* POOL32F encoding of minor opcode field (bits 5..0) */
9460 enum {
9461 /* These are the bit 7..6 values */
9462 ADD_FMT = 0x0,
9463 MOVN_FMT = 0x0,
9465 SUB_FMT = 0x1,
9466 MOVZ_FMT = 0x1,
9468 MUL_FMT = 0x2,
9470 DIV_FMT = 0x3,
9472 /* These are the bit 8..6 values */
9473 RSQRT2_FMT = 0x0,
9474 MOVF_FMT = 0x0,
9476 LWXC1 = 0x1,
9477 MOVT_FMT = 0x1,
9479 PLL_PS = 0x2,
9480 SWXC1 = 0x2,
9482 PLU_PS = 0x3,
9483 LDXC1 = 0x3,
9485 PUL_PS = 0x4,
9486 SDXC1 = 0x4,
9487 RECIP2_FMT = 0x4,
9489 PUU_PS = 0x5,
9490 LUXC1 = 0x5,
9492 CVT_PS_S = 0x6,
9493 SUXC1 = 0x6,
9494 ADDR_PS = 0x6,
9495 PREFX = 0x6,
9497 MULR_PS = 0x7,
9499 MADD_S = 0x01,
9500 MADD_D = 0x09,
9501 MADD_PS = 0x11,
9502 ALNV_PS = 0x19,
9503 MSUB_S = 0x21,
9504 MSUB_D = 0x29,
9505 MSUB_PS = 0x31,
9507 NMADD_S = 0x02,
9508 NMADD_D = 0x0a,
9509 NMADD_PS = 0x12,
9510 NMSUB_S = 0x22,
9511 NMSUB_D = 0x2a,
9512 NMSUB_PS = 0x32,
9514 POOL32FXF = 0x3b,
9516 CABS_COND_FMT = 0x1c, /* MIPS3D */
9517 C_COND_FMT = 0x3c
9520 /* POOL32Fxf encoding of minor opcode extension field */
9522 enum {
9523 CVT_L = 0x04,
9524 RSQRT_FMT = 0x08,
9525 FLOOR_L = 0x0c,
9526 CVT_PW_PS = 0x1c,
9527 CVT_W = 0x24,
9528 SQRT_FMT = 0x28,
9529 FLOOR_W = 0x2c,
9530 CVT_PS_PW = 0x3c,
9531 CFC1 = 0x40,
9532 RECIP_FMT = 0x48,
9533 CEIL_L = 0x4c,
9534 CTC1 = 0x60,
9535 CEIL_W = 0x6c,
9536 MFC1 = 0x80,
9537 CVT_S_PL = 0x84,
9538 TRUNC_L = 0x8c,
9539 MTC1 = 0xa0,
9540 CVT_S_PU = 0xa4,
9541 TRUNC_W = 0xac,
9542 MFHC1 = 0xc0,
9543 ROUND_L = 0xcc,
9544 MTHC1 = 0xe0,
9545 ROUND_W = 0xec,
9547 MOV_FMT = 0x01,
9548 MOVF = 0x05,
9549 ABS_FMT = 0x0d,
9550 RSQRT1_FMT = 0x1d,
9551 MOVT = 0x25,
9552 NEG_FMT = 0x2d,
9553 CVT_D = 0x4d,
9554 RECIP1_FMT = 0x5d,
9555 CVT_S = 0x6d
9558 /* POOL32I encoding of minor opcode field (bits 25..21) */
9560 enum {
9561 BLTZ = 0x00,
9562 BLTZAL = 0x01,
9563 BGEZ = 0x02,
9564 BGEZAL = 0x03,
9565 BLEZ = 0x04,
9566 BNEZC = 0x05,
9567 BGTZ = 0x06,
9568 BEQZC = 0x07,
9569 TLTI = 0x08,
9570 TGEI = 0x09,
9571 TLTIU = 0x0a,
9572 TGEIU = 0x0b,
9573 TNEI = 0x0c,
9574 LUI = 0x0d,
9575 TEQI = 0x0e,
9576 SYNCI = 0x10,
9577 BLTZALS = 0x11,
9578 BGEZALS = 0x13,
9579 BC2F = 0x14,
9580 BC2T = 0x15,
9581 BPOSGE64 = 0x1a,
9582 BPOSGE32 = 0x1b,
9583 /* These overlap and are distinguished by bit16 of the instruction */
9584 BC1F = 0x1c,
9585 BC1T = 0x1d,
9586 BC1ANY2F = 0x1c,
9587 BC1ANY2T = 0x1d,
9588 BC1ANY4F = 0x1e,
9589 BC1ANY4T = 0x1f
9592 /* POOL16A encoding of minor opcode field */
9594 enum {
9595 ADDU16 = 0x0,
9596 SUBU16 = 0x1
9599 /* POOL16B encoding of minor opcode field */
9601 enum {
9602 SLL16 = 0x0,
9603 SRL16 = 0x1
9606 /* POOL16C encoding of minor opcode field */
9608 enum {
9609 NOT16 = 0x00,
9610 XOR16 = 0x04,
9611 AND16 = 0x08,
9612 OR16 = 0x0c,
9613 LWM16 = 0x10,
9614 SWM16 = 0x14,
9615 JR16 = 0x18,
9616 JRC16 = 0x1a,
9617 JALR16 = 0x1c,
9618 JALR16S = 0x1e,
9619 MFHI16 = 0x20,
9620 MFLO16 = 0x24,
9621 BREAK16 = 0x28,
9622 SDBBP16 = 0x2c,
9623 JRADDIUSP = 0x30
9626 /* POOL16D encoding of minor opcode field */
9628 enum {
9629 ADDIUS5 = 0x0,
9630 ADDIUSP = 0x1
9633 /* POOL16E encoding of minor opcode field */
9635 enum {
9636 ADDIUR2 = 0x0,
9637 ADDIUR1SP = 0x1
9640 static int mmreg (int r)
9642 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9644 return map[r];
9647 /* Used for 16-bit store instructions. */
9648 static int mmreg2 (int r)
9650 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9652 return map[r];
9655 #define uMIPS_RD(op) ((op >> 7) & 0x7)
9656 #define uMIPS_RS(op) ((op >> 4) & 0x7)
9657 #define uMIPS_RS2(op) uMIPS_RS(op)
9658 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
9659 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9660 #define uMIPS_RS5(op) (op & 0x1f)
9662 /* Signed immediate */
9663 #define SIMM(op, start, width) \
9664 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
9665 << (32-width)) \
9666 >> (32-width))
9667 /* Zero-extended immediate */
9668 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9670 static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
9672 int rd = mmreg(uMIPS_RD(ctx->opcode));
9674 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9677 static void gen_addiur2 (CPUState *env, DisasContext *ctx)
9679 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9680 int rd = mmreg(uMIPS_RD(ctx->opcode));
9681 int rs = mmreg(uMIPS_RS(ctx->opcode));
9683 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9686 static void gen_addiusp (CPUState *env, DisasContext *ctx)
9688 int encoded = ZIMM(ctx->opcode, 1, 9);
9689 int decoded;
9691 if (encoded <= 1) {
9692 decoded = 256 + encoded;
9693 } else if (encoded <= 255) {
9694 decoded = encoded;
9695 } else if (encoded <= 509) {
9696 decoded = encoded - 512;
9697 } else {
9698 decoded = encoded - 768;
9701 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9704 static void gen_addius5 (CPUState *env, DisasContext *ctx)
9706 int imm = SIMM(ctx->opcode, 1, 4);
9707 int rd = (ctx->opcode >> 5) & 0x1f;
9709 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9712 static void gen_andi16 (CPUState *env, DisasContext *ctx)
9714 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9715 31, 32, 63, 64, 255, 32768, 65535 };
9716 int rd = mmreg(uMIPS_RD(ctx->opcode));
9717 int rs = mmreg(uMIPS_RS(ctx->opcode));
9718 int encoded = ZIMM(ctx->opcode, 0, 4);
9720 gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9723 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9724 int base, int16_t offset)
9726 TCGv t0, t1;
9727 TCGv_i32 t2;
9729 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9730 generate_exception(ctx, EXCP_RI);
9731 return;
9734 t0 = tcg_temp_new();
9736 gen_base_offset_addr(ctx, t0, base, offset);
9738 t1 = tcg_const_tl(reglist);
9739 t2 = tcg_const_i32(ctx->mem_idx);
9741 save_cpu_state(ctx, 1);
9742 switch (opc) {
9743 case LWM32:
9744 gen_helper_lwm(t0, t1, t2);
9745 break;
9746 case SWM32:
9747 gen_helper_swm(t0, t1, t2);
9748 break;
9749 #ifdef TARGET_MIPS64
9750 case LDM:
9751 gen_helper_ldm(t0, t1, t2);
9752 break;
9753 case SDM:
9754 gen_helper_sdm(t0, t1, t2);
9755 break;
9756 #endif
9758 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9759 tcg_temp_free(t0);
9760 tcg_temp_free(t1);
9761 tcg_temp_free_i32(t2);
9765 static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
9767 int rd = mmreg((ctx->opcode >> 3) & 0x7);
9768 int rs = mmreg(ctx->opcode & 0x7);
9769 int opc;
9771 switch (((ctx->opcode) >> 4) & 0x3f) {
9772 case NOT16 + 0:
9773 case NOT16 + 1:
9774 case NOT16 + 2:
9775 case NOT16 + 3:
9776 gen_logic(env, OPC_NOR, rd, rs, 0);
9777 break;
9778 case XOR16 + 0:
9779 case XOR16 + 1:
9780 case XOR16 + 2:
9781 case XOR16 + 3:
9782 gen_logic(env, OPC_XOR, rd, rd, rs);
9783 break;
9784 case AND16 + 0:
9785 case AND16 + 1:
9786 case AND16 + 2:
9787 case AND16 + 3:
9788 gen_logic(env, OPC_AND, rd, rd, rs);
9789 break;
9790 case OR16 + 0:
9791 case OR16 + 1:
9792 case OR16 + 2:
9793 case OR16 + 3:
9794 gen_logic(env, OPC_OR, rd, rd, rs);
9795 break;
9796 case LWM16 + 0:
9797 case LWM16 + 1:
9798 case LWM16 + 2:
9799 case LWM16 + 3:
9801 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9802 int offset = ZIMM(ctx->opcode, 0, 4);
9804 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9805 29, offset << 2);
9807 break;
9808 case SWM16 + 0:
9809 case SWM16 + 1:
9810 case SWM16 + 2:
9811 case SWM16 + 3:
9813 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9814 int offset = ZIMM(ctx->opcode, 0, 4);
9816 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9817 29, offset << 2);
9819 break;
9820 case JR16 + 0:
9821 case JR16 + 1:
9823 int reg = ctx->opcode & 0x1f;
9825 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9827 *is_branch = 1;
9828 break;
9829 case JRC16 + 0:
9830 case JRC16 + 1:
9832 int reg = ctx->opcode & 0x1f;
9834 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9835 /* Let normal delay slot handling in our caller take us
9836 to the branch target. */
9838 break;
9839 case JALR16 + 0:
9840 case JALR16 + 1:
9841 opc = OPC_JALR;
9842 goto do_jalr;
9843 case JALR16S + 0:
9844 case JALR16S + 1:
9845 opc = OPC_JALRS;
9846 do_jalr:
9848 int reg = ctx->opcode & 0x1f;
9850 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9852 *is_branch = 1;
9853 break;
9854 case MFHI16 + 0:
9855 case MFHI16 + 1:
9856 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9857 break;
9858 case MFLO16 + 0:
9859 case MFLO16 + 1:
9860 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9861 break;
9862 case BREAK16:
9863 generate_exception(ctx, EXCP_BREAK);
9864 break;
9865 case SDBBP16:
9866 /* XXX: not clear which exception should be raised
9867 * when in debug mode...
9869 check_insn(env, ctx, ISA_MIPS32);
9870 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9871 generate_exception(ctx, EXCP_DBp);
9872 } else {
9873 generate_exception(ctx, EXCP_DBp);
9875 break;
9876 case JRADDIUSP + 0:
9877 case JRADDIUSP + 1:
9879 int imm = ZIMM(ctx->opcode, 0, 5);
9881 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9882 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
9883 /* Let normal delay slot handling in our caller take us
9884 to the branch target. */
9886 break;
9887 default:
9888 generate_exception(ctx, EXCP_RI);
9889 break;
9893 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
9895 TCGv t0 = tcg_temp_new();
9896 TCGv t1 = tcg_temp_new();
9898 gen_load_gpr(t0, base);
9900 if (index != 0) {
9901 gen_load_gpr(t1, index);
9902 tcg_gen_shli_tl(t1, t1, 2);
9903 gen_op_addr_add(ctx, t0, t1, t0);
9906 save_cpu_state(ctx, 0);
9907 op_ld_lw(t1, t0, ctx);
9908 gen_store_gpr(t1, rd);
9910 tcg_temp_free(t0);
9911 tcg_temp_free(t1);
9914 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
9915 int base, int16_t offset)
9917 const char *opn = "ldst_pair";
9918 TCGv t0, t1;
9920 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
9921 generate_exception(ctx, EXCP_RI);
9922 return;
9925 t0 = tcg_temp_new();
9926 t1 = tcg_temp_new();
9928 gen_base_offset_addr(ctx, t0, base, offset);
9930 switch (opc) {
9931 case LWP:
9932 save_cpu_state(ctx, 0);
9933 op_ld_lw(t1, t0, ctx);
9934 gen_store_gpr(t1, rd);
9935 tcg_gen_movi_tl(t1, 4);
9936 gen_op_addr_add(ctx, t0, t0, t1);
9937 op_ld_lw(t1, t0, ctx);
9938 gen_store_gpr(t1, rd+1);
9939 opn = "lwp";
9940 break;
9941 case SWP:
9942 save_cpu_state(ctx, 1);
9943 gen_load_gpr(t1, rd);
9944 op_st_sw(t1, t0, ctx);
9945 tcg_gen_movi_tl(t1, 4);
9946 gen_op_addr_add(ctx, t0, t0, t1);
9947 gen_load_gpr(t1, rd+1);
9948 op_st_sw(t1, t0, ctx);
9949 opn = "swp";
9950 break;
9951 #ifdef TARGET_MIPS64
9952 case LDP:
9953 save_cpu_state(ctx, 0);
9954 op_ld_ld(t1, t0, ctx);
9955 gen_store_gpr(t1, rd);
9956 tcg_gen_movi_tl(t1, 8);
9957 gen_op_addr_add(ctx, t0, t0, t1);
9958 op_ld_ld(t1, t0, ctx);
9959 gen_store_gpr(t1, rd+1);
9960 opn = "ldp";
9961 break;
9962 case SDP:
9963 save_cpu_state(ctx, 1);
9964 gen_load_gpr(t1, rd);
9965 op_st_sd(t1, t0, ctx);
9966 tcg_gen_movi_tl(t1, 8);
9967 gen_op_addr_add(ctx, t0, t0, t1);
9968 gen_load_gpr(t1, rd+1);
9969 op_st_sd(t1, t0, ctx);
9970 opn = "sdp";
9971 break;
9972 #endif
9974 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
9975 tcg_temp_free(t0);
9976 tcg_temp_free(t1);
9979 static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
9980 int *is_branch)
9982 int extension = (ctx->opcode >> 6) & 0x3f;
9983 int minor = (ctx->opcode >> 12) & 0xf;
9984 uint32_t mips32_op;
9986 switch (extension) {
9987 case TEQ:
9988 mips32_op = OPC_TEQ;
9989 goto do_trap;
9990 case TGE:
9991 mips32_op = OPC_TGE;
9992 goto do_trap;
9993 case TGEU:
9994 mips32_op = OPC_TGEU;
9995 goto do_trap;
9996 case TLT:
9997 mips32_op = OPC_TLT;
9998 goto do_trap;
9999 case TLTU:
10000 mips32_op = OPC_TLTU;
10001 goto do_trap;
10002 case TNE:
10003 mips32_op = OPC_TNE;
10004 do_trap:
10005 gen_trap(ctx, mips32_op, rs, rt, -1);
10006 break;
10007 #ifndef CONFIG_USER_ONLY
10008 case MFC0:
10009 case MFC0 + 32:
10010 if (rt == 0) {
10011 /* Treat as NOP. */
10012 break;
10014 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10015 break;
10016 case MTC0:
10017 case MTC0 + 32:
10019 TCGv t0 = tcg_temp_new();
10021 gen_load_gpr(t0, rt);
10022 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
10023 tcg_temp_free(t0);
10025 break;
10026 #endif
10027 case 0x2c:
10028 switch (minor) {
10029 case SEB:
10030 gen_bshfl(ctx, OPC_SEB, rs, rt);
10031 break;
10032 case SEH:
10033 gen_bshfl(ctx, OPC_SEH, rs, rt);
10034 break;
10035 case CLO:
10036 mips32_op = OPC_CLO;
10037 goto do_cl;
10038 case CLZ:
10039 mips32_op = OPC_CLZ;
10040 do_cl:
10041 check_insn(env, ctx, ISA_MIPS32);
10042 gen_cl(ctx, mips32_op, rt, rs);
10043 break;
10044 case RDHWR:
10045 gen_rdhwr(env, ctx, rt, rs);
10046 break;
10047 case WSBH:
10048 gen_bshfl(ctx, OPC_WSBH, rs, rt);
10049 break;
10050 case MULT:
10051 mips32_op = OPC_MULT;
10052 goto do_muldiv;
10053 case MULTU:
10054 mips32_op = OPC_MULTU;
10055 goto do_muldiv;
10056 case DIV:
10057 mips32_op = OPC_DIV;
10058 goto do_muldiv;
10059 case DIVU:
10060 mips32_op = OPC_DIVU;
10061 goto do_muldiv;
10062 case MADD:
10063 mips32_op = OPC_MADD;
10064 goto do_muldiv;
10065 case MADDU:
10066 mips32_op = OPC_MADDU;
10067 goto do_muldiv;
10068 case MSUB:
10069 mips32_op = OPC_MSUB;
10070 goto do_muldiv;
10071 case MSUBU:
10072 mips32_op = OPC_MSUBU;
10073 do_muldiv:
10074 check_insn(env, ctx, ISA_MIPS32);
10075 gen_muldiv(ctx, mips32_op, rs, rt);
10076 break;
10077 default:
10078 goto pool32axf_invalid;
10080 break;
10081 case 0x34:
10082 switch (minor) {
10083 case MFC2:
10084 case MTC2:
10085 case MFHC2:
10086 case MTHC2:
10087 case CFC2:
10088 case CTC2:
10089 generate_exception_err(ctx, EXCP_CpU, 2);
10090 break;
10091 default:
10092 goto pool32axf_invalid;
10094 break;
10095 case 0x3c:
10096 switch (minor) {
10097 case JALR:
10098 case JALR_HB:
10099 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10100 *is_branch = 1;
10101 break;
10102 case JALRS:
10103 case JALRS_HB:
10104 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10105 *is_branch = 1;
10106 break;
10107 default:
10108 goto pool32axf_invalid;
10110 break;
10111 case 0x05:
10112 switch (minor) {
10113 case RDPGPR:
10114 check_insn(env, ctx, ISA_MIPS32R2);
10115 gen_load_srsgpr(rt, rs);
10116 break;
10117 case WRPGPR:
10118 check_insn(env, ctx, ISA_MIPS32R2);
10119 gen_store_srsgpr(rt, rs);
10120 break;
10121 default:
10122 goto pool32axf_invalid;
10124 break;
10125 #ifndef CONFIG_USER_ONLY
10126 case 0x0d:
10127 switch (minor) {
10128 case TLBP:
10129 mips32_op = OPC_TLBP;
10130 goto do_cp0;
10131 case TLBR:
10132 mips32_op = OPC_TLBR;
10133 goto do_cp0;
10134 case TLBWI:
10135 mips32_op = OPC_TLBWI;
10136 goto do_cp0;
10137 case TLBWR:
10138 mips32_op = OPC_TLBWR;
10139 goto do_cp0;
10140 case WAIT:
10141 mips32_op = OPC_WAIT;
10142 goto do_cp0;
10143 case DERET:
10144 mips32_op = OPC_DERET;
10145 goto do_cp0;
10146 case ERET:
10147 mips32_op = OPC_ERET;
10148 do_cp0:
10149 gen_cp0(env, ctx, mips32_op, rt, rs);
10150 break;
10151 default:
10152 goto pool32axf_invalid;
10154 break;
10155 case 0x1d:
10156 switch (minor) {
10157 case DI:
10159 TCGv t0 = tcg_temp_new();
10161 save_cpu_state(ctx, 1);
10162 gen_helper_di(t0);
10163 gen_store_gpr(t0, rs);
10164 /* Stop translation as we may have switched the execution mode */
10165 ctx->bstate = BS_STOP;
10166 tcg_temp_free(t0);
10168 break;
10169 case EI:
10171 TCGv t0 = tcg_temp_new();
10173 save_cpu_state(ctx, 1);
10174 gen_helper_ei(t0);
10175 gen_store_gpr(t0, rs);
10176 /* Stop translation as we may have switched the execution mode */
10177 ctx->bstate = BS_STOP;
10178 tcg_temp_free(t0);
10180 break;
10181 default:
10182 goto pool32axf_invalid;
10184 break;
10185 #endif
10186 case 0x2d:
10187 switch (minor) {
10188 case SYNC:
10189 /* NOP */
10190 break;
10191 case SYSCALL:
10192 generate_exception(ctx, EXCP_SYSCALL);
10193 ctx->bstate = BS_STOP;
10194 break;
10195 case SDBBP:
10196 check_insn(env, ctx, ISA_MIPS32);
10197 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10198 generate_exception(ctx, EXCP_DBp);
10199 } else {
10200 generate_exception(ctx, EXCP_DBp);
10202 break;
10203 default:
10204 goto pool32axf_invalid;
10206 break;
10207 case 0x35:
10208 switch (minor) {
10209 case MFHI32:
10210 gen_HILO(ctx, OPC_MFHI, rs);
10211 break;
10212 case MFLO32:
10213 gen_HILO(ctx, OPC_MFLO, rs);
10214 break;
10215 case MTHI32:
10216 gen_HILO(ctx, OPC_MTHI, rs);
10217 break;
10218 case MTLO32:
10219 gen_HILO(ctx, OPC_MTLO, rs);
10220 break;
10221 default:
10222 goto pool32axf_invalid;
10224 break;
10225 default:
10226 pool32axf_invalid:
10227 MIPS_INVAL("pool32axf");
10228 generate_exception(ctx, EXCP_RI);
10229 break;
10233 /* Values for microMIPS fmt field. Variable-width, depending on which
10234 formats the instruction supports. */
10236 enum {
10237 FMT_SD_S = 0,
10238 FMT_SD_D = 1,
10240 FMT_SDPS_S = 0,
10241 FMT_SDPS_D = 1,
10242 FMT_SDPS_PS = 2,
10244 FMT_SWL_S = 0,
10245 FMT_SWL_W = 1,
10246 FMT_SWL_L = 2,
10248 FMT_DWL_D = 0,
10249 FMT_DWL_W = 1,
10250 FMT_DWL_L = 2
10253 static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
10255 int extension = (ctx->opcode >> 6) & 0x3ff;
10256 uint32_t mips32_op;
10258 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10259 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10260 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10262 switch (extension) {
10263 case FLOAT_1BIT_FMT(CFC1, 0):
10264 mips32_op = OPC_CFC1;
10265 goto do_cp1;
10266 case FLOAT_1BIT_FMT(CTC1, 0):
10267 mips32_op = OPC_CTC1;
10268 goto do_cp1;
10269 case FLOAT_1BIT_FMT(MFC1, 0):
10270 mips32_op = OPC_MFC1;
10271 goto do_cp1;
10272 case FLOAT_1BIT_FMT(MTC1, 0):
10273 mips32_op = OPC_MTC1;
10274 goto do_cp1;
10275 case FLOAT_1BIT_FMT(MFHC1, 0):
10276 mips32_op = OPC_MFHC1;
10277 goto do_cp1;
10278 case FLOAT_1BIT_FMT(MTHC1, 0):
10279 mips32_op = OPC_MTHC1;
10280 do_cp1:
10281 gen_cp1(ctx, mips32_op, rt, rs);
10282 break;
10284 /* Reciprocal square root */
10285 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10286 mips32_op = OPC_RSQRT_S;
10287 goto do_unaryfp;
10288 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10289 mips32_op = OPC_RSQRT_D;
10290 goto do_unaryfp;
10292 /* Square root */
10293 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10294 mips32_op = OPC_SQRT_S;
10295 goto do_unaryfp;
10296 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10297 mips32_op = OPC_SQRT_D;
10298 goto do_unaryfp;
10300 /* Reciprocal */
10301 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10302 mips32_op = OPC_RECIP_S;
10303 goto do_unaryfp;
10304 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10305 mips32_op = OPC_RECIP_D;
10306 goto do_unaryfp;
10308 /* Floor */
10309 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10310 mips32_op = OPC_FLOOR_L_S;
10311 goto do_unaryfp;
10312 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10313 mips32_op = OPC_FLOOR_L_D;
10314 goto do_unaryfp;
10315 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10316 mips32_op = OPC_FLOOR_W_S;
10317 goto do_unaryfp;
10318 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10319 mips32_op = OPC_FLOOR_W_D;
10320 goto do_unaryfp;
10322 /* Ceiling */
10323 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10324 mips32_op = OPC_CEIL_L_S;
10325 goto do_unaryfp;
10326 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10327 mips32_op = OPC_CEIL_L_D;
10328 goto do_unaryfp;
10329 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10330 mips32_op = OPC_CEIL_W_S;
10331 goto do_unaryfp;
10332 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10333 mips32_op = OPC_CEIL_W_D;
10334 goto do_unaryfp;
10336 /* Truncation */
10337 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10338 mips32_op = OPC_TRUNC_L_S;
10339 goto do_unaryfp;
10340 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10341 mips32_op = OPC_TRUNC_L_D;
10342 goto do_unaryfp;
10343 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10344 mips32_op = OPC_TRUNC_W_S;
10345 goto do_unaryfp;
10346 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10347 mips32_op = OPC_TRUNC_W_D;
10348 goto do_unaryfp;
10350 /* Round */
10351 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10352 mips32_op = OPC_ROUND_L_S;
10353 goto do_unaryfp;
10354 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10355 mips32_op = OPC_ROUND_L_D;
10356 goto do_unaryfp;
10357 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10358 mips32_op = OPC_ROUND_W_S;
10359 goto do_unaryfp;
10360 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10361 mips32_op = OPC_ROUND_W_D;
10362 goto do_unaryfp;
10364 /* Integer to floating-point conversion */
10365 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10366 mips32_op = OPC_CVT_L_S;
10367 goto do_unaryfp;
10368 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10369 mips32_op = OPC_CVT_L_D;
10370 goto do_unaryfp;
10371 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10372 mips32_op = OPC_CVT_W_S;
10373 goto do_unaryfp;
10374 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10375 mips32_op = OPC_CVT_W_D;
10376 goto do_unaryfp;
10378 /* Paired-foo conversions */
10379 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10380 mips32_op = OPC_CVT_S_PL;
10381 goto do_unaryfp;
10382 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10383 mips32_op = OPC_CVT_S_PU;
10384 goto do_unaryfp;
10385 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10386 mips32_op = OPC_CVT_PW_PS;
10387 goto do_unaryfp;
10388 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10389 mips32_op = OPC_CVT_PS_PW;
10390 goto do_unaryfp;
10392 /* Floating-point moves */
10393 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10394 mips32_op = OPC_MOV_S;
10395 goto do_unaryfp;
10396 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10397 mips32_op = OPC_MOV_D;
10398 goto do_unaryfp;
10399 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10400 mips32_op = OPC_MOV_PS;
10401 goto do_unaryfp;
10403 /* Absolute value */
10404 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10405 mips32_op = OPC_ABS_S;
10406 goto do_unaryfp;
10407 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10408 mips32_op = OPC_ABS_D;
10409 goto do_unaryfp;
10410 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10411 mips32_op = OPC_ABS_PS;
10412 goto do_unaryfp;
10414 /* Negation */
10415 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10416 mips32_op = OPC_NEG_S;
10417 goto do_unaryfp;
10418 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10419 mips32_op = OPC_NEG_D;
10420 goto do_unaryfp;
10421 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10422 mips32_op = OPC_NEG_PS;
10423 goto do_unaryfp;
10425 /* Reciprocal square root step */
10426 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10427 mips32_op = OPC_RSQRT1_S;
10428 goto do_unaryfp;
10429 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10430 mips32_op = OPC_RSQRT1_D;
10431 goto do_unaryfp;
10432 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10433 mips32_op = OPC_RSQRT1_PS;
10434 goto do_unaryfp;
10436 /* Reciprocal step */
10437 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10438 mips32_op = OPC_RECIP1_S;
10439 goto do_unaryfp;
10440 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10441 mips32_op = OPC_RECIP1_S;
10442 goto do_unaryfp;
10443 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10444 mips32_op = OPC_RECIP1_PS;
10445 goto do_unaryfp;
10447 /* Conversions from double */
10448 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10449 mips32_op = OPC_CVT_D_S;
10450 goto do_unaryfp;
10451 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10452 mips32_op = OPC_CVT_D_W;
10453 goto do_unaryfp;
10454 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10455 mips32_op = OPC_CVT_D_L;
10456 goto do_unaryfp;
10458 /* Conversions from single */
10459 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10460 mips32_op = OPC_CVT_S_D;
10461 goto do_unaryfp;
10462 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10463 mips32_op = OPC_CVT_S_W;
10464 goto do_unaryfp;
10465 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10466 mips32_op = OPC_CVT_S_L;
10467 do_unaryfp:
10468 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10469 break;
10471 /* Conditional moves on floating-point codes */
10472 case COND_FLOAT_MOV(MOVT, 0):
10473 case COND_FLOAT_MOV(MOVT, 1):
10474 case COND_FLOAT_MOV(MOVT, 2):
10475 case COND_FLOAT_MOV(MOVT, 3):
10476 case COND_FLOAT_MOV(MOVT, 4):
10477 case COND_FLOAT_MOV(MOVT, 5):
10478 case COND_FLOAT_MOV(MOVT, 6):
10479 case COND_FLOAT_MOV(MOVT, 7):
10480 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10481 break;
10482 case COND_FLOAT_MOV(MOVF, 0):
10483 case COND_FLOAT_MOV(MOVF, 1):
10484 case COND_FLOAT_MOV(MOVF, 2):
10485 case COND_FLOAT_MOV(MOVF, 3):
10486 case COND_FLOAT_MOV(MOVF, 4):
10487 case COND_FLOAT_MOV(MOVF, 5):
10488 case COND_FLOAT_MOV(MOVF, 6):
10489 case COND_FLOAT_MOV(MOVF, 7):
10490 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10491 break;
10492 default:
10493 MIPS_INVAL("pool32fxf");
10494 generate_exception(ctx, EXCP_RI);
10495 break;
10499 static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
10500 uint16_t insn_hw1, int *is_branch)
10502 int32_t offset;
10503 uint16_t insn;
10504 int rt, rs, rd, rr;
10505 int16_t imm;
10506 uint32_t op, minor, mips32_op;
10507 uint32_t cond, fmt, cc;
10509 insn = lduw_code(ctx->pc + 2);
10510 ctx->opcode = (ctx->opcode << 16) | insn;
10512 rt = (ctx->opcode >> 21) & 0x1f;
10513 rs = (ctx->opcode >> 16) & 0x1f;
10514 rd = (ctx->opcode >> 11) & 0x1f;
10515 rr = (ctx->opcode >> 6) & 0x1f;
10516 imm = (int16_t) ctx->opcode;
10518 op = (ctx->opcode >> 26) & 0x3f;
10519 switch (op) {
10520 case POOL32A:
10521 minor = ctx->opcode & 0x3f;
10522 switch (minor) {
10523 case 0x00:
10524 minor = (ctx->opcode >> 6) & 0xf;
10525 switch (minor) {
10526 case SLL32:
10527 mips32_op = OPC_SLL;
10528 goto do_shifti;
10529 case SRA:
10530 mips32_op = OPC_SRA;
10531 goto do_shifti;
10532 case SRL32:
10533 mips32_op = OPC_SRL;
10534 goto do_shifti;
10535 case ROTR:
10536 mips32_op = OPC_ROTR;
10537 do_shifti:
10538 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10539 break;
10540 default:
10541 goto pool32a_invalid;
10543 break;
10544 case 0x10:
10545 minor = (ctx->opcode >> 6) & 0xf;
10546 switch (minor) {
10547 /* Arithmetic */
10548 case ADD:
10549 mips32_op = OPC_ADD;
10550 goto do_arith;
10551 case ADDU32:
10552 mips32_op = OPC_ADDU;
10553 goto do_arith;
10554 case SUB:
10555 mips32_op = OPC_SUB;
10556 goto do_arith;
10557 case SUBU32:
10558 mips32_op = OPC_SUBU;
10559 goto do_arith;
10560 case MUL:
10561 mips32_op = OPC_MUL;
10562 do_arith:
10563 gen_arith(env, ctx, mips32_op, rd, rs, rt);
10564 break;
10565 /* Shifts */
10566 case SLLV:
10567 mips32_op = OPC_SLLV;
10568 goto do_shift;
10569 case SRLV:
10570 mips32_op = OPC_SRLV;
10571 goto do_shift;
10572 case SRAV:
10573 mips32_op = OPC_SRAV;
10574 goto do_shift;
10575 case ROTRV:
10576 mips32_op = OPC_ROTRV;
10577 do_shift:
10578 gen_shift(env, ctx, mips32_op, rd, rs, rt);
10579 break;
10580 /* Logical operations */
10581 case AND:
10582 mips32_op = OPC_AND;
10583 goto do_logic;
10584 case OR32:
10585 mips32_op = OPC_OR;
10586 goto do_logic;
10587 case NOR:
10588 mips32_op = OPC_NOR;
10589 goto do_logic;
10590 case XOR32:
10591 mips32_op = OPC_XOR;
10592 do_logic:
10593 gen_logic(env, mips32_op, rd, rs, rt);
10594 break;
10595 /* Set less than */
10596 case SLT:
10597 mips32_op = OPC_SLT;
10598 goto do_slt;
10599 case SLTU:
10600 mips32_op = OPC_SLTU;
10601 do_slt:
10602 gen_slt(env, mips32_op, rd, rs, rt);
10603 break;
10604 default:
10605 goto pool32a_invalid;
10607 break;
10608 case 0x18:
10609 minor = (ctx->opcode >> 6) & 0xf;
10610 switch (minor) {
10611 /* Conditional moves */
10612 case MOVN:
10613 mips32_op = OPC_MOVN;
10614 goto do_cmov;
10615 case MOVZ:
10616 mips32_op = OPC_MOVZ;
10617 do_cmov:
10618 gen_cond_move(env, mips32_op, rd, rs, rt);
10619 break;
10620 case LWXS:
10621 gen_ldxs(ctx, rs, rt, rd);
10622 break;
10623 default:
10624 goto pool32a_invalid;
10626 break;
10627 case INS:
10628 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10629 return;
10630 case EXT:
10631 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10632 return;
10633 case POOL32AXF:
10634 gen_pool32axf(env, ctx, rt, rs, is_branch);
10635 break;
10636 case 0x07:
10637 generate_exception(ctx, EXCP_BREAK);
10638 break;
10639 default:
10640 pool32a_invalid:
10641 MIPS_INVAL("pool32a");
10642 generate_exception(ctx, EXCP_RI);
10643 break;
10645 break;
10646 case POOL32B:
10647 minor = (ctx->opcode >> 12) & 0xf;
10648 switch (minor) {
10649 case CACHE:
10650 /* Treat as no-op. */
10651 break;
10652 case LWC2:
10653 case SWC2:
10654 /* COP2: Not implemented. */
10655 generate_exception_err(ctx, EXCP_CpU, 2);
10656 break;
10657 case LWP:
10658 case SWP:
10659 #ifdef TARGET_MIPS64
10660 case LDP:
10661 case SDP:
10662 #endif
10663 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10664 break;
10665 case LWM32:
10666 case SWM32:
10667 #ifdef TARGET_MIPS64
10668 case LDM:
10669 case SDM:
10670 #endif
10671 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10672 break;
10673 default:
10674 MIPS_INVAL("pool32b");
10675 generate_exception(ctx, EXCP_RI);
10676 break;
10678 break;
10679 case POOL32F:
10680 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10681 minor = ctx->opcode & 0x3f;
10682 check_cp1_enabled(ctx);
10683 switch (minor) {
10684 case ALNV_PS:
10685 mips32_op = OPC_ALNV_PS;
10686 goto do_madd;
10687 case MADD_S:
10688 mips32_op = OPC_MADD_S;
10689 goto do_madd;
10690 case MADD_D:
10691 mips32_op = OPC_MADD_D;
10692 goto do_madd;
10693 case MADD_PS:
10694 mips32_op = OPC_MADD_PS;
10695 goto do_madd;
10696 case MSUB_S:
10697 mips32_op = OPC_MSUB_S;
10698 goto do_madd;
10699 case MSUB_D:
10700 mips32_op = OPC_MSUB_D;
10701 goto do_madd;
10702 case MSUB_PS:
10703 mips32_op = OPC_MSUB_PS;
10704 goto do_madd;
10705 case NMADD_S:
10706 mips32_op = OPC_NMADD_S;
10707 goto do_madd;
10708 case NMADD_D:
10709 mips32_op = OPC_NMADD_D;
10710 goto do_madd;
10711 case NMADD_PS:
10712 mips32_op = OPC_NMADD_PS;
10713 goto do_madd;
10714 case NMSUB_S:
10715 mips32_op = OPC_NMSUB_S;
10716 goto do_madd;
10717 case NMSUB_D:
10718 mips32_op = OPC_NMSUB_D;
10719 goto do_madd;
10720 case NMSUB_PS:
10721 mips32_op = OPC_NMSUB_PS;
10722 do_madd:
10723 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10724 break;
10725 case CABS_COND_FMT:
10726 cond = (ctx->opcode >> 6) & 0xf;
10727 cc = (ctx->opcode >> 13) & 0x7;
10728 fmt = (ctx->opcode >> 10) & 0x3;
10729 switch (fmt) {
10730 case 0x0:
10731 gen_cmpabs_s(ctx, cond, rt, rs, cc);
10732 break;
10733 case 0x1:
10734 gen_cmpabs_d(ctx, cond, rt, rs, cc);
10735 break;
10736 case 0x2:
10737 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10738 break;
10739 default:
10740 goto pool32f_invalid;
10742 break;
10743 case C_COND_FMT:
10744 cond = (ctx->opcode >> 6) & 0xf;
10745 cc = (ctx->opcode >> 13) & 0x7;
10746 fmt = (ctx->opcode >> 10) & 0x3;
10747 switch (fmt) {
10748 case 0x0:
10749 gen_cmp_s(ctx, cond, rt, rs, cc);
10750 break;
10751 case 0x1:
10752 gen_cmp_d(ctx, cond, rt, rs, cc);
10753 break;
10754 case 0x2:
10755 gen_cmp_ps(ctx, cond, rt, rs, cc);
10756 break;
10757 default:
10758 goto pool32f_invalid;
10760 break;
10761 case POOL32FXF:
10762 gen_pool32fxf(env, ctx, rt, rs);
10763 break;
10764 case 0x00:
10765 /* PLL foo */
10766 switch ((ctx->opcode >> 6) & 0x7) {
10767 case PLL_PS:
10768 mips32_op = OPC_PLL_PS;
10769 goto do_ps;
10770 case PLU_PS:
10771 mips32_op = OPC_PLU_PS;
10772 goto do_ps;
10773 case PUL_PS:
10774 mips32_op = OPC_PUL_PS;
10775 goto do_ps;
10776 case PUU_PS:
10777 mips32_op = OPC_PUU_PS;
10778 goto do_ps;
10779 case CVT_PS_S:
10780 mips32_op = OPC_CVT_PS_S;
10781 do_ps:
10782 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10783 break;
10784 default:
10785 goto pool32f_invalid;
10787 break;
10788 case 0x08:
10789 /* [LS][WDU]XC1 */
10790 switch ((ctx->opcode >> 6) & 0x7) {
10791 case LWXC1:
10792 mips32_op = OPC_LWXC1;
10793 goto do_ldst_cp1;
10794 case SWXC1:
10795 mips32_op = OPC_SWXC1;
10796 goto do_ldst_cp1;
10797 case LDXC1:
10798 mips32_op = OPC_LDXC1;
10799 goto do_ldst_cp1;
10800 case SDXC1:
10801 mips32_op = OPC_SDXC1;
10802 goto do_ldst_cp1;
10803 case LUXC1:
10804 mips32_op = OPC_LUXC1;
10805 goto do_ldst_cp1;
10806 case SUXC1:
10807 mips32_op = OPC_SUXC1;
10808 do_ldst_cp1:
10809 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10810 break;
10811 default:
10812 goto pool32f_invalid;
10814 break;
10815 case 0x18:
10816 /* 3D insns */
10817 fmt = (ctx->opcode >> 9) & 0x3;
10818 switch ((ctx->opcode >> 6) & 0x7) {
10819 case RSQRT2_FMT:
10820 switch (fmt) {
10821 case FMT_SDPS_S:
10822 mips32_op = OPC_RSQRT2_S;
10823 goto do_3d;
10824 case FMT_SDPS_D:
10825 mips32_op = OPC_RSQRT2_D;
10826 goto do_3d;
10827 case FMT_SDPS_PS:
10828 mips32_op = OPC_RSQRT2_PS;
10829 goto do_3d;
10830 default:
10831 goto pool32f_invalid;
10833 break;
10834 case RECIP2_FMT:
10835 switch (fmt) {
10836 case FMT_SDPS_S:
10837 mips32_op = OPC_RECIP2_S;
10838 goto do_3d;
10839 case FMT_SDPS_D:
10840 mips32_op = OPC_RECIP2_D;
10841 goto do_3d;
10842 case FMT_SDPS_PS:
10843 mips32_op = OPC_RECIP2_PS;
10844 goto do_3d;
10845 default:
10846 goto pool32f_invalid;
10848 break;
10849 case ADDR_PS:
10850 mips32_op = OPC_ADDR_PS;
10851 goto do_3d;
10852 case MULR_PS:
10853 mips32_op = OPC_MULR_PS;
10854 do_3d:
10855 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10856 break;
10857 default:
10858 goto pool32f_invalid;
10860 break;
10861 case 0x20:
10862 /* MOV[FT].fmt and PREFX */
10863 cc = (ctx->opcode >> 13) & 0x7;
10864 fmt = (ctx->opcode >> 9) & 0x3;
10865 switch ((ctx->opcode >> 6) & 0x7) {
10866 case MOVF_FMT:
10867 switch (fmt) {
10868 case FMT_SDPS_S:
10869 gen_movcf_s(rs, rt, cc, 0);
10870 break;
10871 case FMT_SDPS_D:
10872 gen_movcf_d(ctx, rs, rt, cc, 0);
10873 break;
10874 case FMT_SDPS_PS:
10875 gen_movcf_ps(rs, rt, cc, 0);
10876 break;
10877 default:
10878 goto pool32f_invalid;
10880 break;
10881 case MOVT_FMT:
10882 switch (fmt) {
10883 case FMT_SDPS_S:
10884 gen_movcf_s(rs, rt, cc, 1);
10885 break;
10886 case FMT_SDPS_D:
10887 gen_movcf_d(ctx, rs, rt, cc, 1);
10888 break;
10889 case FMT_SDPS_PS:
10890 gen_movcf_ps(rs, rt, cc, 1);
10891 break;
10892 default:
10893 goto pool32f_invalid;
10895 break;
10896 case PREFX:
10897 break;
10898 default:
10899 goto pool32f_invalid;
10901 break;
10902 #define FINSN_3ARG_SDPS(prfx) \
10903 switch ((ctx->opcode >> 8) & 0x3) { \
10904 case FMT_SDPS_S: \
10905 mips32_op = OPC_##prfx##_S; \
10906 goto do_fpop; \
10907 case FMT_SDPS_D: \
10908 mips32_op = OPC_##prfx##_D; \
10909 goto do_fpop; \
10910 case FMT_SDPS_PS: \
10911 mips32_op = OPC_##prfx##_PS; \
10912 goto do_fpop; \
10913 default: \
10914 goto pool32f_invalid; \
10916 case 0x30:
10917 /* regular FP ops */
10918 switch ((ctx->opcode >> 6) & 0x3) {
10919 case ADD_FMT:
10920 FINSN_3ARG_SDPS(ADD);
10921 break;
10922 case SUB_FMT:
10923 FINSN_3ARG_SDPS(SUB);
10924 break;
10925 case MUL_FMT:
10926 FINSN_3ARG_SDPS(MUL);
10927 break;
10928 case DIV_FMT:
10929 fmt = (ctx->opcode >> 8) & 0x3;
10930 if (fmt == 1) {
10931 mips32_op = OPC_DIV_D;
10932 } else if (fmt == 0) {
10933 mips32_op = OPC_DIV_S;
10934 } else {
10935 goto pool32f_invalid;
10937 goto do_fpop;
10938 default:
10939 goto pool32f_invalid;
10941 break;
10942 case 0x38:
10943 /* cmovs */
10944 switch ((ctx->opcode >> 6) & 0x3) {
10945 case MOVN_FMT:
10946 FINSN_3ARG_SDPS(MOVN);
10947 break;
10948 case MOVZ_FMT:
10949 FINSN_3ARG_SDPS(MOVZ);
10950 break;
10951 default:
10952 goto pool32f_invalid;
10954 break;
10955 do_fpop:
10956 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10957 break;
10958 default:
10959 pool32f_invalid:
10960 MIPS_INVAL("pool32f");
10961 generate_exception(ctx, EXCP_RI);
10962 break;
10964 } else {
10965 generate_exception_err(ctx, EXCP_CpU, 1);
10967 break;
10968 case POOL32I:
10969 minor = (ctx->opcode >> 21) & 0x1f;
10970 switch (minor) {
10971 case BLTZ:
10972 mips32_op = OPC_BLTZ;
10973 goto do_branch;
10974 case BLTZAL:
10975 mips32_op = OPC_BLTZAL;
10976 goto do_branch;
10977 case BLTZALS:
10978 mips32_op = OPC_BLTZALS;
10979 goto do_branch;
10980 case BGEZ:
10981 mips32_op = OPC_BGEZ;
10982 goto do_branch;
10983 case BGEZAL:
10984 mips32_op = OPC_BGEZAL;
10985 goto do_branch;
10986 case BGEZALS:
10987 mips32_op = OPC_BGEZALS;
10988 goto do_branch;
10989 case BLEZ:
10990 mips32_op = OPC_BLEZ;
10991 goto do_branch;
10992 case BGTZ:
10993 mips32_op = OPC_BGTZ;
10994 do_branch:
10995 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
10996 *is_branch = 1;
10997 break;
10999 /* Traps */
11000 case TLTI:
11001 mips32_op = OPC_TLTI;
11002 goto do_trapi;
11003 case TGEI:
11004 mips32_op = OPC_TGEI;
11005 goto do_trapi;
11006 case TLTIU:
11007 mips32_op = OPC_TLTIU;
11008 goto do_trapi;
11009 case TGEIU:
11010 mips32_op = OPC_TGEIU;
11011 goto do_trapi;
11012 case TNEI:
11013 mips32_op = OPC_TNEI;
11014 goto do_trapi;
11015 case TEQI:
11016 mips32_op = OPC_TEQI;
11017 do_trapi:
11018 gen_trap(ctx, mips32_op, rs, -1, imm);
11019 break;
11021 case BNEZC:
11022 case BEQZC:
11023 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
11024 4, rs, 0, imm << 1);
11025 /* Compact branches don't have a delay slot, so just let
11026 the normal delay slot handling take us to the branch
11027 target. */
11028 break;
11029 case LUI:
11030 gen_logic_imm(env, OPC_LUI, rs, -1, imm);
11031 break;
11032 case SYNCI:
11033 break;
11034 case BC2F:
11035 case BC2T:
11036 /* COP2: Not implemented. */
11037 generate_exception_err(ctx, EXCP_CpU, 2);
11038 break;
11039 case BC1F:
11040 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11041 goto do_cp1branch;
11042 case BC1T:
11043 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11044 goto do_cp1branch;
11045 case BC1ANY4F:
11046 mips32_op = OPC_BC1FANY4;
11047 goto do_cp1mips3d;
11048 case BC1ANY4T:
11049 mips32_op = OPC_BC1TANY4;
11050 do_cp1mips3d:
11051 check_cop1x(ctx);
11052 check_insn(env, ctx, ASE_MIPS3D);
11053 /* Fall through */
11054 do_cp1branch:
11055 gen_compute_branch1(env, ctx, mips32_op,
11056 (ctx->opcode >> 18) & 0x7, imm << 1);
11057 *is_branch = 1;
11058 break;
11059 case BPOSGE64:
11060 case BPOSGE32:
11061 /* MIPS DSP: not implemented */
11062 /* Fall through */
11063 default:
11064 MIPS_INVAL("pool32i");
11065 generate_exception(ctx, EXCP_RI);
11066 break;
11068 break;
11069 case POOL32C:
11070 minor = (ctx->opcode >> 12) & 0xf;
11071 switch (minor) {
11072 case LWL:
11073 mips32_op = OPC_LWL;
11074 goto do_ld_lr;
11075 case SWL:
11076 mips32_op = OPC_SWL;
11077 goto do_st_lr;
11078 case LWR:
11079 mips32_op = OPC_LWR;
11080 goto do_ld_lr;
11081 case SWR:
11082 mips32_op = OPC_SWR;
11083 goto do_st_lr;
11084 #if defined(TARGET_MIPS64)
11085 case LDL:
11086 mips32_op = OPC_LDL;
11087 goto do_ld_lr;
11088 case SDL:
11089 mips32_op = OPC_SDL;
11090 goto do_st_lr;
11091 case LDR:
11092 mips32_op = OPC_LDR;
11093 goto do_ld_lr;
11094 case SDR:
11095 mips32_op = OPC_SDR;
11096 goto do_st_lr;
11097 case LWU:
11098 mips32_op = OPC_LWU;
11099 goto do_ld_lr;
11100 case LLD:
11101 mips32_op = OPC_LLD;
11102 goto do_ld_lr;
11103 #endif
11104 case LL:
11105 mips32_op = OPC_LL;
11106 goto do_ld_lr;
11107 do_ld_lr:
11108 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11109 break;
11110 do_st_lr:
11111 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11112 break;
11113 case SC:
11114 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11115 break;
11116 #if defined(TARGET_MIPS64)
11117 case SCD:
11118 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11119 break;
11120 #endif
11121 case PREF:
11122 /* Treat as no-op */
11123 break;
11124 default:
11125 MIPS_INVAL("pool32c");
11126 generate_exception(ctx, EXCP_RI);
11127 break;
11129 break;
11130 case ADDI32:
11131 mips32_op = OPC_ADDI;
11132 goto do_addi;
11133 case ADDIU32:
11134 mips32_op = OPC_ADDIU;
11135 do_addi:
11136 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11137 break;
11139 /* Logical operations */
11140 case ORI32:
11141 mips32_op = OPC_ORI;
11142 goto do_logici;
11143 case XORI32:
11144 mips32_op = OPC_XORI;
11145 goto do_logici;
11146 case ANDI32:
11147 mips32_op = OPC_ANDI;
11148 do_logici:
11149 gen_logic_imm(env, mips32_op, rt, rs, imm);
11150 break;
11152 /* Set less than immediate */
11153 case SLTI32:
11154 mips32_op = OPC_SLTI;
11155 goto do_slti;
11156 case SLTIU32:
11157 mips32_op = OPC_SLTIU;
11158 do_slti:
11159 gen_slt_imm(env, mips32_op, rt, rs, imm);
11160 break;
11161 case JALX32:
11162 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11163 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11164 *is_branch = 1;
11165 break;
11166 case JALS32:
11167 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11168 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11169 *is_branch = 1;
11170 break;
11171 case BEQ32:
11172 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11173 *is_branch = 1;
11174 break;
11175 case BNE32:
11176 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11177 *is_branch = 1;
11178 break;
11179 case J32:
11180 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11181 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11182 *is_branch = 1;
11183 break;
11184 case JAL32:
11185 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11186 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11187 *is_branch = 1;
11188 break;
11189 /* Floating point (COP1) */
11190 case LWC132:
11191 mips32_op = OPC_LWC1;
11192 goto do_cop1;
11193 case LDC132:
11194 mips32_op = OPC_LDC1;
11195 goto do_cop1;
11196 case SWC132:
11197 mips32_op = OPC_SWC1;
11198 goto do_cop1;
11199 case SDC132:
11200 mips32_op = OPC_SDC1;
11201 do_cop1:
11202 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11203 break;
11204 case ADDIUPC:
11206 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
11207 int offset = SIMM(ctx->opcode, 0, 23) << 2;
11209 gen_addiupc(ctx, reg, offset, 0, 0);
11211 break;
11212 /* Loads and stores */
11213 case LB32:
11214 mips32_op = OPC_LB;
11215 goto do_ld;
11216 case LBU32:
11217 mips32_op = OPC_LBU;
11218 goto do_ld;
11219 case LH32:
11220 mips32_op = OPC_LH;
11221 goto do_ld;
11222 case LHU32:
11223 mips32_op = OPC_LHU;
11224 goto do_ld;
11225 case LW32:
11226 mips32_op = OPC_LW;
11227 goto do_ld;
11228 #ifdef TARGET_MIPS64
11229 case LD32:
11230 mips32_op = OPC_LD;
11231 goto do_ld;
11232 case SD32:
11233 mips32_op = OPC_SD;
11234 goto do_st;
11235 #endif
11236 case SB32:
11237 mips32_op = OPC_SB;
11238 goto do_st;
11239 case SH32:
11240 mips32_op = OPC_SH;
11241 goto do_st;
11242 case SW32:
11243 mips32_op = OPC_SW;
11244 goto do_st;
11245 do_ld:
11246 gen_ld(env, ctx, mips32_op, rt, rs, imm);
11247 break;
11248 do_st:
11249 gen_st(ctx, mips32_op, rt, rs, imm);
11250 break;
11251 default:
11252 generate_exception(ctx, EXCP_RI);
11253 break;
11257 static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11259 uint32_t op;
11261 /* make sure instructions are on a halfword boundary */
11262 if (ctx->pc & 0x1) {
11263 env->CP0_BadVAddr = ctx->pc;
11264 generate_exception(ctx, EXCP_AdEL);
11265 ctx->bstate = BS_STOP;
11266 return 2;
11269 op = (ctx->opcode >> 10) & 0x3f;
11270 /* Enforce properly-sized instructions in a delay slot */
11271 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11272 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11274 switch (op) {
11275 case POOL32A:
11276 case POOL32B:
11277 case POOL32I:
11278 case POOL32C:
11279 case ADDI32:
11280 case ADDIU32:
11281 case ORI32:
11282 case XORI32:
11283 case SLTI32:
11284 case SLTIU32:
11285 case ANDI32:
11286 case JALX32:
11287 case LBU32:
11288 case LHU32:
11289 case POOL32F:
11290 case JALS32:
11291 case BEQ32:
11292 case BNE32:
11293 case J32:
11294 case JAL32:
11295 case SB32:
11296 case SH32:
11297 case POOL32S:
11298 case ADDIUPC:
11299 case SWC132:
11300 case SDC132:
11301 case SD32:
11302 case SW32:
11303 case LB32:
11304 case LH32:
11305 case DADDIU32:
11306 case POOL48A: /* ??? */
11307 case LWC132:
11308 case LDC132:
11309 case LD32:
11310 case LW32:
11311 if (bits & MIPS_HFLAG_BDS16) {
11312 generate_exception(ctx, EXCP_RI);
11313 /* Just stop translation; the user is confused. */
11314 ctx->bstate = BS_STOP;
11315 return 2;
11317 break;
11318 case POOL16A:
11319 case POOL16B:
11320 case POOL16C:
11321 case LWGP16:
11322 case POOL16F:
11323 case LBU16:
11324 case LHU16:
11325 case LWSP16:
11326 case LW16:
11327 case SB16:
11328 case SH16:
11329 case SWSP16:
11330 case SW16:
11331 case MOVE16:
11332 case ANDI16:
11333 case POOL16D:
11334 case POOL16E:
11335 case BEQZ16:
11336 case BNEZ16:
11337 case B16:
11338 case LI16:
11339 if (bits & MIPS_HFLAG_BDS32) {
11340 generate_exception(ctx, EXCP_RI);
11341 /* Just stop translation; the user is confused. */
11342 ctx->bstate = BS_STOP;
11343 return 2;
11345 break;
11346 default:
11347 break;
11350 switch (op) {
11351 case POOL16A:
11353 int rd = mmreg(uMIPS_RD(ctx->opcode));
11354 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11355 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11356 uint32_t opc = 0;
11358 switch (ctx->opcode & 0x1) {
11359 case ADDU16:
11360 opc = OPC_ADDU;
11361 break;
11362 case SUBU16:
11363 opc = OPC_SUBU;
11364 break;
11367 gen_arith(env, ctx, opc, rd, rs1, rs2);
11369 break;
11370 case POOL16B:
11372 int rd = mmreg(uMIPS_RD(ctx->opcode));
11373 int rs = mmreg(uMIPS_RS(ctx->opcode));
11374 int amount = (ctx->opcode >> 1) & 0x7;
11375 uint32_t opc = 0;
11376 amount = amount == 0 ? 8 : amount;
11378 switch (ctx->opcode & 0x1) {
11379 case SLL16:
11380 opc = OPC_SLL;
11381 break;
11382 case SRL16:
11383 opc = OPC_SRL;
11384 break;
11387 gen_shift_imm(env, ctx, opc, rd, rs, amount);
11389 break;
11390 case POOL16C:
11391 gen_pool16c_insn(env, ctx, is_branch);
11392 break;
11393 case LWGP16:
11395 int rd = mmreg(uMIPS_RD(ctx->opcode));
11396 int rb = 28; /* GP */
11397 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11399 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11401 break;
11402 case POOL16F:
11403 if (ctx->opcode & 1) {
11404 generate_exception(ctx, EXCP_RI);
11405 } else {
11406 /* MOVEP */
11407 int enc_dest = uMIPS_RD(ctx->opcode);
11408 int enc_rt = uMIPS_RS2(ctx->opcode);
11409 int enc_rs = uMIPS_RS1(ctx->opcode);
11410 int rd, rs, re, rt;
11411 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11412 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11413 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11415 rd = rd_enc[enc_dest];
11416 re = re_enc[enc_dest];
11417 rs = rs_rt_enc[enc_rs];
11418 rt = rs_rt_enc[enc_rt];
11420 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11421 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11423 break;
11424 case LBU16:
11426 int rd = mmreg(uMIPS_RD(ctx->opcode));
11427 int rb = mmreg(uMIPS_RS(ctx->opcode));
11428 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11429 offset = (offset == 0xf ? -1 : offset);
11431 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
11433 break;
11434 case LHU16:
11436 int rd = mmreg(uMIPS_RD(ctx->opcode));
11437 int rb = mmreg(uMIPS_RS(ctx->opcode));
11438 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11440 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
11442 break;
11443 case LWSP16:
11445 int rd = (ctx->opcode >> 5) & 0x1f;
11446 int rb = 29; /* SP */
11447 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11449 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11451 break;
11452 case LW16:
11454 int rd = mmreg(uMIPS_RD(ctx->opcode));
11455 int rb = mmreg(uMIPS_RS(ctx->opcode));
11456 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11458 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11460 break;
11461 case SB16:
11463 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11464 int rb = mmreg(uMIPS_RS(ctx->opcode));
11465 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11467 gen_st(ctx, OPC_SB, rd, rb, offset);
11469 break;
11470 case SH16:
11472 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11473 int rb = mmreg(uMIPS_RS(ctx->opcode));
11474 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11476 gen_st(ctx, OPC_SH, rd, rb, offset);
11478 break;
11479 case SWSP16:
11481 int rd = (ctx->opcode >> 5) & 0x1f;
11482 int rb = 29; /* SP */
11483 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11485 gen_st(ctx, OPC_SW, rd, rb, offset);
11487 break;
11488 case SW16:
11490 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11491 int rb = mmreg(uMIPS_RS(ctx->opcode));
11492 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11494 gen_st(ctx, OPC_SW, rd, rb, offset);
11496 break;
11497 case MOVE16:
11499 int rd = uMIPS_RD5(ctx->opcode);
11500 int rs = uMIPS_RS5(ctx->opcode);
11502 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11504 break;
11505 case ANDI16:
11506 gen_andi16(env, ctx);
11507 break;
11508 case POOL16D:
11509 switch (ctx->opcode & 0x1) {
11510 case ADDIUS5:
11511 gen_addius5(env, ctx);
11512 break;
11513 case ADDIUSP:
11514 gen_addiusp(env, ctx);
11515 break;
11517 break;
11518 case POOL16E:
11519 switch (ctx->opcode & 0x1) {
11520 case ADDIUR2:
11521 gen_addiur2(env, ctx);
11522 break;
11523 case ADDIUR1SP:
11524 gen_addiur1sp(env, ctx);
11525 break;
11527 break;
11528 case B16:
11529 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11530 SIMM(ctx->opcode, 0, 10) << 1);
11531 *is_branch = 1;
11532 break;
11533 case BNEZ16:
11534 case BEQZ16:
11535 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11536 mmreg(uMIPS_RD(ctx->opcode)),
11537 0, SIMM(ctx->opcode, 0, 7) << 1);
11538 *is_branch = 1;
11539 break;
11540 case LI16:
11542 int reg = mmreg(uMIPS_RD(ctx->opcode));
11543 int imm = ZIMM(ctx->opcode, 0, 7);
11545 imm = (imm == 0x7f ? -1 : imm);
11546 tcg_gen_movi_tl(cpu_gpr[reg], imm);
11548 break;
11549 case RES_20:
11550 case RES_28:
11551 case RES_29:
11552 case RES_30:
11553 case RES_31:
11554 case RES_38:
11555 case RES_39:
11556 generate_exception(ctx, EXCP_RI);
11557 break;
11558 default:
11559 decode_micromips32_opc (env, ctx, op, is_branch);
11560 return 4;
11563 return 2;
11566 /* SmartMIPS extension to MIPS32 */
11568 #if defined(TARGET_MIPS64)
11570 /* MDMX extension to MIPS64 */
11572 #endif
11574 static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11576 int32_t offset;
11577 int rs, rt, rd, sa;
11578 uint32_t op, op1, op2;
11579 int16_t imm;
11581 /* make sure instructions are on a word boundary */
11582 if (ctx->pc & 0x3) {
11583 env->CP0_BadVAddr = ctx->pc;
11584 generate_exception(ctx, EXCP_AdEL);
11585 return;
11588 /* Handle blikely not taken case */
11589 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11590 int l1 = gen_new_label();
11592 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11593 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11594 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11595 gen_goto_tb(ctx, 1, ctx->pc + 4);
11596 gen_set_label(l1);
11599 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11600 tcg_gen_debug_insn_start(ctx->pc);
11602 op = MASK_OP_MAJOR(ctx->opcode);
11603 rs = (ctx->opcode >> 21) & 0x1f;
11604 rt = (ctx->opcode >> 16) & 0x1f;
11605 rd = (ctx->opcode >> 11) & 0x1f;
11606 sa = (ctx->opcode >> 6) & 0x1f;
11607 imm = (int16_t)ctx->opcode;
11608 switch (op) {
11609 case OPC_SPECIAL:
11610 op1 = MASK_SPECIAL(ctx->opcode);
11611 switch (op1) {
11612 case OPC_SLL: /* Shift with immediate */
11613 case OPC_SRA:
11614 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11615 break;
11616 case OPC_SRL:
11617 switch ((ctx->opcode >> 21) & 0x1f) {
11618 case 1:
11619 /* rotr is decoded as srl on non-R2 CPUs */
11620 if (env->insn_flags & ISA_MIPS32R2) {
11621 op1 = OPC_ROTR;
11623 /* Fallthrough */
11624 case 0:
11625 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11626 break;
11627 default:
11628 generate_exception(ctx, EXCP_RI);
11629 break;
11631 break;
11632 case OPC_MOVN: /* Conditional move */
11633 case OPC_MOVZ:
11634 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11635 INSN_LOONGSON2E | INSN_LOONGSON2F);
11636 gen_cond_move(env, op1, rd, rs, rt);
11637 break;
11638 case OPC_ADD ... OPC_SUBU:
11639 gen_arith(env, ctx, op1, rd, rs, rt);
11640 break;
11641 case OPC_SLLV: /* Shifts */
11642 case OPC_SRAV:
11643 gen_shift(env, ctx, op1, rd, rs, rt);
11644 break;
11645 case OPC_SRLV:
11646 switch ((ctx->opcode >> 6) & 0x1f) {
11647 case 1:
11648 /* rotrv is decoded as srlv on non-R2 CPUs */
11649 if (env->insn_flags & ISA_MIPS32R2) {
11650 op1 = OPC_ROTRV;
11652 /* Fallthrough */
11653 case 0:
11654 gen_shift(env, ctx, op1, rd, rs, rt);
11655 break;
11656 default:
11657 generate_exception(ctx, EXCP_RI);
11658 break;
11660 break;
11661 case OPC_SLT: /* Set on less than */
11662 case OPC_SLTU:
11663 gen_slt(env, op1, rd, rs, rt);
11664 break;
11665 case OPC_AND: /* Logic*/
11666 case OPC_OR:
11667 case OPC_NOR:
11668 case OPC_XOR:
11669 gen_logic(env, op1, rd, rs, rt);
11670 break;
11671 case OPC_MULT ... OPC_DIVU:
11672 if (sa) {
11673 check_insn(env, ctx, INSN_VR54XX);
11674 op1 = MASK_MUL_VR54XX(ctx->opcode);
11675 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11676 } else
11677 gen_muldiv(ctx, op1, rs, rt);
11678 break;
11679 case OPC_JR ... OPC_JALR:
11680 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11681 *is_branch = 1;
11682 break;
11683 case OPC_TGE ... OPC_TEQ: /* Traps */
11684 case OPC_TNE:
11685 gen_trap(ctx, op1, rs, rt, -1);
11686 break;
11687 case OPC_MFHI: /* Move from HI/LO */
11688 case OPC_MFLO:
11689 gen_HILO(ctx, op1, rd);
11690 break;
11691 case OPC_MTHI:
11692 case OPC_MTLO: /* Move to HI/LO */
11693 gen_HILO(ctx, op1, rs);
11694 break;
11695 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
11696 #ifdef MIPS_STRICT_STANDARD
11697 MIPS_INVAL("PMON / selsl");
11698 generate_exception(ctx, EXCP_RI);
11699 #else
11700 gen_helper_0i(pmon, sa);
11701 #endif
11702 break;
11703 case OPC_SYSCALL:
11704 generate_exception(ctx, EXCP_SYSCALL);
11705 ctx->bstate = BS_STOP;
11706 break;
11707 case OPC_BREAK:
11708 generate_exception(ctx, EXCP_BREAK);
11709 break;
11710 case OPC_SPIM:
11711 #ifdef MIPS_STRICT_STANDARD
11712 MIPS_INVAL("SPIM");
11713 generate_exception(ctx, EXCP_RI);
11714 #else
11715 /* Implemented as RI exception for now. */
11716 MIPS_INVAL("spim (unofficial)");
11717 generate_exception(ctx, EXCP_RI);
11718 #endif
11719 break;
11720 case OPC_SYNC:
11721 /* Treat as NOP. */
11722 break;
11724 case OPC_MOVCI:
11725 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11726 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11727 check_cp1_enabled(ctx);
11728 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11729 (ctx->opcode >> 16) & 1);
11730 } else {
11731 generate_exception_err(ctx, EXCP_CpU, 1);
11733 break;
11735 #if defined(TARGET_MIPS64)
11736 /* MIPS64 specific opcodes */
11737 case OPC_DSLL:
11738 case OPC_DSRA:
11739 case OPC_DSLL32:
11740 case OPC_DSRA32:
11741 check_insn(env, ctx, ISA_MIPS3);
11742 check_mips_64(ctx);
11743 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11744 break;
11745 case OPC_DSRL:
11746 switch ((ctx->opcode >> 21) & 0x1f) {
11747 case 1:
11748 /* drotr is decoded as dsrl on non-R2 CPUs */
11749 if (env->insn_flags & ISA_MIPS32R2) {
11750 op1 = OPC_DROTR;
11752 /* Fallthrough */
11753 case 0:
11754 check_insn(env, ctx, ISA_MIPS3);
11755 check_mips_64(ctx);
11756 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11757 break;
11758 default:
11759 generate_exception(ctx, EXCP_RI);
11760 break;
11762 break;
11763 case OPC_DSRL32:
11764 switch ((ctx->opcode >> 21) & 0x1f) {
11765 case 1:
11766 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11767 if (env->insn_flags & ISA_MIPS32R2) {
11768 op1 = OPC_DROTR32;
11770 /* Fallthrough */
11771 case 0:
11772 check_insn(env, ctx, ISA_MIPS3);
11773 check_mips_64(ctx);
11774 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11775 break;
11776 default:
11777 generate_exception(ctx, EXCP_RI);
11778 break;
11780 break;
11781 case OPC_DADD ... OPC_DSUBU:
11782 check_insn(env, ctx, ISA_MIPS3);
11783 check_mips_64(ctx);
11784 gen_arith(env, ctx, op1, rd, rs, rt);
11785 break;
11786 case OPC_DSLLV:
11787 case OPC_DSRAV:
11788 check_insn(env, ctx, ISA_MIPS3);
11789 check_mips_64(ctx);
11790 gen_shift(env, ctx, op1, rd, rs, rt);
11791 break;
11792 case OPC_DSRLV:
11793 switch ((ctx->opcode >> 6) & 0x1f) {
11794 case 1:
11795 /* drotrv is decoded as dsrlv on non-R2 CPUs */
11796 if (env->insn_flags & ISA_MIPS32R2) {
11797 op1 = OPC_DROTRV;
11799 /* Fallthrough */
11800 case 0:
11801 check_insn(env, ctx, ISA_MIPS3);
11802 check_mips_64(ctx);
11803 gen_shift(env, ctx, op1, rd, rs, rt);
11804 break;
11805 default:
11806 generate_exception(ctx, EXCP_RI);
11807 break;
11809 break;
11810 case OPC_DMULT ... OPC_DDIVU:
11811 check_insn(env, ctx, ISA_MIPS3);
11812 check_mips_64(ctx);
11813 gen_muldiv(ctx, op1, rs, rt);
11814 break;
11815 #endif
11816 default: /* Invalid */
11817 MIPS_INVAL("special");
11818 generate_exception(ctx, EXCP_RI);
11819 break;
11821 break;
11822 case OPC_SPECIAL2:
11823 op1 = MASK_SPECIAL2(ctx->opcode);
11824 switch (op1) {
11825 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11826 case OPC_MSUB ... OPC_MSUBU:
11827 check_insn(env, ctx, ISA_MIPS32);
11828 gen_muldiv(ctx, op1, rs, rt);
11829 break;
11830 case OPC_MUL:
11831 gen_arith(env, ctx, op1, rd, rs, rt);
11832 break;
11833 case OPC_CLO:
11834 case OPC_CLZ:
11835 check_insn(env, ctx, ISA_MIPS32);
11836 gen_cl(ctx, op1, rd, rs);
11837 break;
11838 case OPC_SDBBP:
11839 /* XXX: not clear which exception should be raised
11840 * when in debug mode...
11842 check_insn(env, ctx, ISA_MIPS32);
11843 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11844 generate_exception(ctx, EXCP_DBp);
11845 } else {
11846 generate_exception(ctx, EXCP_DBp);
11848 /* Treat as NOP. */
11849 break;
11850 case OPC_DIV_G_2F:
11851 case OPC_DIVU_G_2F:
11852 case OPC_MULT_G_2F:
11853 case OPC_MULTU_G_2F:
11854 case OPC_MOD_G_2F:
11855 case OPC_MODU_G_2F:
11856 check_insn(env, ctx, INSN_LOONGSON2F);
11857 gen_loongson_integer(ctx, op1, rd, rs, rt);
11858 break;
11859 #if defined(TARGET_MIPS64)
11860 case OPC_DCLO:
11861 case OPC_DCLZ:
11862 check_insn(env, ctx, ISA_MIPS64);
11863 check_mips_64(ctx);
11864 gen_cl(ctx, op1, rd, rs);
11865 break;
11866 case OPC_DMULT_G_2F:
11867 case OPC_DMULTU_G_2F:
11868 case OPC_DDIV_G_2F:
11869 case OPC_DDIVU_G_2F:
11870 case OPC_DMOD_G_2F:
11871 case OPC_DMODU_G_2F:
11872 check_insn(env, ctx, INSN_LOONGSON2F);
11873 gen_loongson_integer(ctx, op1, rd, rs, rt);
11874 break;
11875 #endif
11876 default: /* Invalid */
11877 MIPS_INVAL("special2");
11878 generate_exception(ctx, EXCP_RI);
11879 break;
11881 break;
11882 case OPC_SPECIAL3:
11883 op1 = MASK_SPECIAL3(ctx->opcode);
11884 switch (op1) {
11885 case OPC_EXT:
11886 case OPC_INS:
11887 check_insn(env, ctx, ISA_MIPS32R2);
11888 gen_bitops(ctx, op1, rt, rs, sa, rd);
11889 break;
11890 case OPC_BSHFL:
11891 check_insn(env, ctx, ISA_MIPS32R2);
11892 op2 = MASK_BSHFL(ctx->opcode);
11893 gen_bshfl(ctx, op2, rt, rd);
11894 break;
11895 case OPC_RDHWR:
11896 gen_rdhwr(env, ctx, rt, rd);
11897 break;
11898 case OPC_FORK:
11899 check_insn(env, ctx, ASE_MT);
11901 TCGv t0 = tcg_temp_new();
11902 TCGv t1 = tcg_temp_new();
11904 gen_load_gpr(t0, rt);
11905 gen_load_gpr(t1, rs);
11906 gen_helper_fork(t0, t1);
11907 tcg_temp_free(t0);
11908 tcg_temp_free(t1);
11910 break;
11911 case OPC_YIELD:
11912 check_insn(env, ctx, ASE_MT);
11914 TCGv t0 = tcg_temp_new();
11916 save_cpu_state(ctx, 1);
11917 gen_load_gpr(t0, rs);
11918 gen_helper_yield(t0, t0);
11919 gen_store_gpr(t0, rd);
11920 tcg_temp_free(t0);
11922 break;
11923 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
11924 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
11925 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
11926 check_insn(env, ctx, INSN_LOONGSON2E);
11927 gen_loongson_integer(ctx, op1, rd, rs, rt);
11928 break;
11929 #if defined(TARGET_MIPS64)
11930 case OPC_DEXTM ... OPC_DEXT:
11931 case OPC_DINSM ... OPC_DINS:
11932 check_insn(env, ctx, ISA_MIPS64R2);
11933 check_mips_64(ctx);
11934 gen_bitops(ctx, op1, rt, rs, sa, rd);
11935 break;
11936 case OPC_DBSHFL:
11937 check_insn(env, ctx, ISA_MIPS64R2);
11938 check_mips_64(ctx);
11939 op2 = MASK_DBSHFL(ctx->opcode);
11940 gen_bshfl(ctx, op2, rt, rd);
11941 break;
11942 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
11943 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
11944 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
11945 check_insn(env, ctx, INSN_LOONGSON2E);
11946 gen_loongson_integer(ctx, op1, rd, rs, rt);
11947 break;
11948 #endif
11949 default: /* Invalid */
11950 MIPS_INVAL("special3");
11951 generate_exception(ctx, EXCP_RI);
11952 break;
11954 break;
11955 case OPC_REGIMM:
11956 op1 = MASK_REGIMM(ctx->opcode);
11957 switch (op1) {
11958 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
11959 case OPC_BLTZAL ... OPC_BGEZALL:
11960 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
11961 *is_branch = 1;
11962 break;
11963 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
11964 case OPC_TNEI:
11965 gen_trap(ctx, op1, rs, -1, imm);
11966 break;
11967 case OPC_SYNCI:
11968 check_insn(env, ctx, ISA_MIPS32R2);
11969 /* Treat as NOP. */
11970 break;
11971 default: /* Invalid */
11972 MIPS_INVAL("regimm");
11973 generate_exception(ctx, EXCP_RI);
11974 break;
11976 break;
11977 case OPC_CP0:
11978 check_cp0_enabled(ctx);
11979 op1 = MASK_CP0(ctx->opcode);
11980 switch (op1) {
11981 case OPC_MFC0:
11982 case OPC_MTC0:
11983 case OPC_MFTR:
11984 case OPC_MTTR:
11985 #if defined(TARGET_MIPS64)
11986 case OPC_DMFC0:
11987 case OPC_DMTC0:
11988 #endif
11989 #ifndef CONFIG_USER_ONLY
11990 gen_cp0(env, ctx, op1, rt, rd);
11991 #endif /* !CONFIG_USER_ONLY */
11992 break;
11993 case OPC_C0_FIRST ... OPC_C0_LAST:
11994 #ifndef CONFIG_USER_ONLY
11995 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
11996 #endif /* !CONFIG_USER_ONLY */
11997 break;
11998 case OPC_MFMC0:
11999 #ifndef CONFIG_USER_ONLY
12001 TCGv t0 = tcg_temp_new();
12003 op2 = MASK_MFMC0(ctx->opcode);
12004 switch (op2) {
12005 case OPC_DMT:
12006 check_insn(env, ctx, ASE_MT);
12007 gen_helper_dmt(t0, t0);
12008 gen_store_gpr(t0, rt);
12009 break;
12010 case OPC_EMT:
12011 check_insn(env, ctx, ASE_MT);
12012 gen_helper_emt(t0, t0);
12013 gen_store_gpr(t0, rt);
12014 break;
12015 case OPC_DVPE:
12016 check_insn(env, ctx, ASE_MT);
12017 gen_helper_dvpe(t0, t0);
12018 gen_store_gpr(t0, rt);
12019 break;
12020 case OPC_EVPE:
12021 check_insn(env, ctx, ASE_MT);
12022 gen_helper_evpe(t0, t0);
12023 gen_store_gpr(t0, rt);
12024 break;
12025 case OPC_DI:
12026 check_insn(env, ctx, ISA_MIPS32R2);
12027 save_cpu_state(ctx, 1);
12028 gen_helper_di(t0);
12029 gen_store_gpr(t0, rt);
12030 /* Stop translation as we may have switched the execution mode */
12031 ctx->bstate = BS_STOP;
12032 break;
12033 case OPC_EI:
12034 check_insn(env, ctx, ISA_MIPS32R2);
12035 save_cpu_state(ctx, 1);
12036 gen_helper_ei(t0);
12037 gen_store_gpr(t0, rt);
12038 /* Stop translation as we may have switched the execution mode */
12039 ctx->bstate = BS_STOP;
12040 break;
12041 default: /* Invalid */
12042 MIPS_INVAL("mfmc0");
12043 generate_exception(ctx, EXCP_RI);
12044 break;
12046 tcg_temp_free(t0);
12048 #endif /* !CONFIG_USER_ONLY */
12049 break;
12050 case OPC_RDPGPR:
12051 check_insn(env, ctx, ISA_MIPS32R2);
12052 gen_load_srsgpr(rt, rd);
12053 break;
12054 case OPC_WRPGPR:
12055 check_insn(env, ctx, ISA_MIPS32R2);
12056 gen_store_srsgpr(rt, rd);
12057 break;
12058 default:
12059 MIPS_INVAL("cp0");
12060 generate_exception(ctx, EXCP_RI);
12061 break;
12063 break;
12064 case OPC_ADDI: /* Arithmetic with immediate opcode */
12065 case OPC_ADDIU:
12066 gen_arith_imm(env, ctx, op, rt, rs, imm);
12067 break;
12068 case OPC_SLTI: /* Set on less than with immediate opcode */
12069 case OPC_SLTIU:
12070 gen_slt_imm(env, op, rt, rs, imm);
12071 break;
12072 case OPC_ANDI: /* Arithmetic with immediate opcode */
12073 case OPC_LUI:
12074 case OPC_ORI:
12075 case OPC_XORI:
12076 gen_logic_imm(env, op, rt, rs, imm);
12077 break;
12078 case OPC_J ... OPC_JAL: /* Jump */
12079 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12080 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12081 *is_branch = 1;
12082 break;
12083 case OPC_BEQ ... OPC_BGTZ: /* Branch */
12084 case OPC_BEQL ... OPC_BGTZL:
12085 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12086 *is_branch = 1;
12087 break;
12088 case OPC_LB ... OPC_LWR: /* Load and stores */
12089 case OPC_LL:
12090 gen_ld(env, ctx, op, rt, rs, imm);
12091 break;
12092 case OPC_SB ... OPC_SW:
12093 case OPC_SWR:
12094 gen_st(ctx, op, rt, rs, imm);
12095 break;
12096 case OPC_SC:
12097 gen_st_cond(ctx, op, rt, rs, imm);
12098 break;
12099 case OPC_CACHE:
12100 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12101 /* Treat as NOP. */
12102 break;
12103 case OPC_PREF:
12104 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12105 /* Treat as NOP. */
12106 break;
12108 /* Floating point (COP1). */
12109 case OPC_LWC1:
12110 case OPC_LDC1:
12111 case OPC_SWC1:
12112 case OPC_SDC1:
12113 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12114 break;
12116 case OPC_CP1:
12117 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12118 check_cp1_enabled(ctx);
12119 op1 = MASK_CP1(ctx->opcode);
12120 switch (op1) {
12121 case OPC_MFHC1:
12122 case OPC_MTHC1:
12123 check_insn(env, ctx, ISA_MIPS32R2);
12124 case OPC_MFC1:
12125 case OPC_CFC1:
12126 case OPC_MTC1:
12127 case OPC_CTC1:
12128 gen_cp1(ctx, op1, rt, rd);
12129 break;
12130 #if defined(TARGET_MIPS64)
12131 case OPC_DMFC1:
12132 case OPC_DMTC1:
12133 check_insn(env, ctx, ISA_MIPS3);
12134 gen_cp1(ctx, op1, rt, rd);
12135 break;
12136 #endif
12137 case OPC_BC1ANY2:
12138 case OPC_BC1ANY4:
12139 check_cop1x(ctx);
12140 check_insn(env, ctx, ASE_MIPS3D);
12141 /* fall through */
12142 case OPC_BC1:
12143 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12144 (rt >> 2) & 0x7, imm << 2);
12145 *is_branch = 1;
12146 break;
12147 case OPC_S_FMT:
12148 case OPC_D_FMT:
12149 case OPC_W_FMT:
12150 case OPC_L_FMT:
12151 case OPC_PS_FMT:
12152 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12153 (imm >> 8) & 0x7);
12154 break;
12155 default:
12156 MIPS_INVAL("cp1");
12157 generate_exception (ctx, EXCP_RI);
12158 break;
12160 } else {
12161 generate_exception_err(ctx, EXCP_CpU, 1);
12163 break;
12165 /* COP2. */
12166 case OPC_LWC2:
12167 case OPC_LDC2:
12168 case OPC_SWC2:
12169 case OPC_SDC2:
12170 case OPC_CP2:
12171 /* COP2: Not implemented. */
12172 generate_exception_err(ctx, EXCP_CpU, 2);
12173 break;
12175 case OPC_CP3:
12176 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12177 check_cp1_enabled(ctx);
12178 op1 = MASK_CP3(ctx->opcode);
12179 switch (op1) {
12180 case OPC_LWXC1:
12181 case OPC_LDXC1:
12182 case OPC_LUXC1:
12183 case OPC_SWXC1:
12184 case OPC_SDXC1:
12185 case OPC_SUXC1:
12186 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12187 break;
12188 case OPC_PREFX:
12189 /* Treat as NOP. */
12190 break;
12191 case OPC_ALNV_PS:
12192 case OPC_MADD_S:
12193 case OPC_MADD_D:
12194 case OPC_MADD_PS:
12195 case OPC_MSUB_S:
12196 case OPC_MSUB_D:
12197 case OPC_MSUB_PS:
12198 case OPC_NMADD_S:
12199 case OPC_NMADD_D:
12200 case OPC_NMADD_PS:
12201 case OPC_NMSUB_S:
12202 case OPC_NMSUB_D:
12203 case OPC_NMSUB_PS:
12204 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12205 break;
12206 default:
12207 MIPS_INVAL("cp3");
12208 generate_exception (ctx, EXCP_RI);
12209 break;
12211 } else {
12212 generate_exception_err(ctx, EXCP_CpU, 1);
12214 break;
12216 #if defined(TARGET_MIPS64)
12217 /* MIPS64 opcodes */
12218 case OPC_LWU:
12219 case OPC_LDL ... OPC_LDR:
12220 case OPC_LLD:
12221 case OPC_LD:
12222 check_insn(env, ctx, ISA_MIPS3);
12223 check_mips_64(ctx);
12224 gen_ld(env, ctx, op, rt, rs, imm);
12225 break;
12226 case OPC_SDL ... OPC_SDR:
12227 case OPC_SD:
12228 check_insn(env, ctx, ISA_MIPS3);
12229 check_mips_64(ctx);
12230 gen_st(ctx, op, rt, rs, imm);
12231 break;
12232 case OPC_SCD:
12233 check_insn(env, ctx, ISA_MIPS3);
12234 check_mips_64(ctx);
12235 gen_st_cond(ctx, op, rt, rs, imm);
12236 break;
12237 case OPC_DADDI:
12238 case OPC_DADDIU:
12239 check_insn(env, ctx, ISA_MIPS3);
12240 check_mips_64(ctx);
12241 gen_arith_imm(env, ctx, op, rt, rs, imm);
12242 break;
12243 #endif
12244 case OPC_JALX:
12245 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
12246 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12247 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12248 *is_branch = 1;
12249 break;
12250 case OPC_MDMX:
12251 check_insn(env, ctx, ASE_MDMX);
12252 /* MDMX: Not implemented. */
12253 default: /* Invalid */
12254 MIPS_INVAL("major opcode");
12255 generate_exception(ctx, EXCP_RI);
12256 break;
12260 static inline void
12261 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
12262 int search_pc)
12264 DisasContext ctx;
12265 target_ulong pc_start;
12266 uint16_t *gen_opc_end;
12267 CPUBreakpoint *bp;
12268 int j, lj = -1;
12269 int num_insns;
12270 int max_insns;
12271 int insn_bytes;
12272 int is_branch;
12274 if (search_pc)
12275 qemu_log("search pc %d\n", search_pc);
12277 pc_start = tb->pc;
12278 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12279 ctx.pc = pc_start;
12280 ctx.saved_pc = -1;
12281 ctx.singlestep_enabled = env->singlestep_enabled;
12282 ctx.tb = tb;
12283 ctx.bstate = BS_NONE;
12284 /* Restore delay slot state from the tb context. */
12285 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
12286 restore_cpu_state(env, &ctx);
12287 #ifdef CONFIG_USER_ONLY
12288 ctx.mem_idx = MIPS_HFLAG_UM;
12289 #else
12290 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12291 #endif
12292 num_insns = 0;
12293 max_insns = tb->cflags & CF_COUNT_MASK;
12294 if (max_insns == 0)
12295 max_insns = CF_COUNT_MASK;
12296 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
12297 gen_icount_start();
12298 while (ctx.bstate == BS_NONE) {
12299 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
12300 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
12301 if (bp->pc == ctx.pc) {
12302 save_cpu_state(&ctx, 1);
12303 ctx.bstate = BS_BRANCH;
12304 gen_helper_0i(raise_exception, EXCP_DEBUG);
12305 /* Include the breakpoint location or the tb won't
12306 * be flushed when it must be. */
12307 ctx.pc += 4;
12308 goto done_generating;
12313 if (search_pc) {
12314 j = gen_opc_ptr - gen_opc_buf;
12315 if (lj < j) {
12316 lj++;
12317 while (lj < j)
12318 gen_opc_instr_start[lj++] = 0;
12320 gen_opc_pc[lj] = ctx.pc;
12321 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12322 gen_opc_instr_start[lj] = 1;
12323 gen_opc_icount[lj] = num_insns;
12325 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12326 gen_io_start();
12328 is_branch = 0;
12329 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12330 ctx.opcode = ldl_code(ctx.pc);
12331 insn_bytes = 4;
12332 decode_opc(env, &ctx, &is_branch);
12333 } else if (env->insn_flags & ASE_MICROMIPS) {
12334 ctx.opcode = lduw_code(ctx.pc);
12335 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12336 } else if (env->insn_flags & ASE_MIPS16) {
12337 ctx.opcode = lduw_code(ctx.pc);
12338 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12339 } else {
12340 generate_exception(&ctx, EXCP_RI);
12341 ctx.bstate = BS_STOP;
12342 break;
12344 if (!is_branch) {
12345 handle_delay_slot(env, &ctx, insn_bytes);
12347 ctx.pc += insn_bytes;
12349 num_insns++;
12351 /* Execute a branch and its delay slot as a single instruction.
12352 This is what GDB expects and is consistent with what the
12353 hardware does (e.g. if a delay slot instruction faults, the
12354 reported PC is the PC of the branch). */
12355 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12356 break;
12358 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12359 break;
12361 if (gen_opc_ptr >= gen_opc_end)
12362 break;
12364 if (num_insns >= max_insns)
12365 break;
12367 if (singlestep)
12368 break;
12370 if (tb->cflags & CF_LAST_IO)
12371 gen_io_end();
12372 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12373 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12374 gen_helper_0i(raise_exception, EXCP_DEBUG);
12375 } else {
12376 switch (ctx.bstate) {
12377 case BS_STOP:
12378 gen_goto_tb(&ctx, 0, ctx.pc);
12379 break;
12380 case BS_NONE:
12381 save_cpu_state(&ctx, 0);
12382 gen_goto_tb(&ctx, 0, ctx.pc);
12383 break;
12384 case BS_EXCP:
12385 tcg_gen_exit_tb(0);
12386 break;
12387 case BS_BRANCH:
12388 default:
12389 break;
12392 done_generating:
12393 gen_icount_end(tb, num_insns);
12394 *gen_opc_ptr = INDEX_op_end;
12395 if (search_pc) {
12396 j = gen_opc_ptr - gen_opc_buf;
12397 lj++;
12398 while (lj <= j)
12399 gen_opc_instr_start[lj++] = 0;
12400 } else {
12401 tb->size = ctx.pc - pc_start;
12402 tb->icount = num_insns;
12404 #ifdef DEBUG_DISAS
12405 LOG_DISAS("\n");
12406 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12407 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12408 log_target_disas(pc_start, ctx.pc - pc_start, 0);
12409 qemu_log("\n");
12411 #endif
12414 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
12416 gen_intermediate_code_internal(env, tb, 0);
12419 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
12421 gen_intermediate_code_internal(env, tb, 1);
12424 static void fpu_dump_state(CPUState *env, FILE *f,
12425 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
12426 int flags)
12428 int i;
12429 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12431 #define printfpr(fp) \
12432 do { \
12433 if (is_fpu64) \
12434 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12435 " fd:%13g fs:%13g psu: %13g\n", \
12436 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
12437 (double)(fp)->fd, \
12438 (double)(fp)->fs[FP_ENDIAN_IDX], \
12439 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
12440 else { \
12441 fpr_t tmp; \
12442 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
12443 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
12444 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12445 " fd:%13g fs:%13g psu:%13g\n", \
12446 tmp.w[FP_ENDIAN_IDX], tmp.d, \
12447 (double)tmp.fd, \
12448 (double)tmp.fs[FP_ENDIAN_IDX], \
12449 (double)tmp.fs[!FP_ENDIAN_IDX]); \
12451 } while(0)
12454 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
12455 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
12456 get_float_exception_flags(&env->active_fpu.fp_status));
12457 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12458 fpu_fprintf(f, "%3s: ", fregnames[i]);
12459 printfpr(&env->active_fpu.fpr[i]);
12462 #undef printfpr
12465 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12466 /* Debug help: The architecture requires 32bit code to maintain proper
12467 sign-extended values on 64bit machines. */
12469 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12471 static void
12472 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
12473 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
12474 int flags)
12476 int i;
12478 if (!SIGN_EXT_P(env->active_tc.PC))
12479 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12480 if (!SIGN_EXT_P(env->active_tc.HI[0]))
12481 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12482 if (!SIGN_EXT_P(env->active_tc.LO[0]))
12483 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12484 if (!SIGN_EXT_P(env->btarget))
12485 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12487 for (i = 0; i < 32; i++) {
12488 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12489 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12492 if (!SIGN_EXT_P(env->CP0_EPC))
12493 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12494 if (!SIGN_EXT_P(env->lladdr))
12495 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12497 #endif
12499 void cpu_dump_state (CPUState *env, FILE *f,
12500 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
12501 int flags)
12503 int i;
12505 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12506 " LO=0x" TARGET_FMT_lx " ds %04x "
12507 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12508 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12509 env->hflags, env->btarget, env->bcond);
12510 for (i = 0; i < 32; i++) {
12511 if ((i & 3) == 0)
12512 cpu_fprintf(f, "GPR%02d:", i);
12513 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12514 if ((i & 3) == 3)
12515 cpu_fprintf(f, "\n");
12518 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
12519 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12520 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12521 env->CP0_Config0, env->CP0_Config1, env->lladdr);
12522 if (env->hflags & MIPS_HFLAG_FPU)
12523 fpu_dump_state(env, f, cpu_fprintf, flags);
12524 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12525 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12526 #endif
12529 static void mips_tcg_init(void)
12531 int i;
12532 static int inited;
12534 /* Initialize various static tables. */
12535 if (inited)
12536 return;
12538 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12539 TCGV_UNUSED(cpu_gpr[0]);
12540 for (i = 1; i < 32; i++)
12541 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12542 offsetof(CPUState, active_tc.gpr[i]),
12543 regnames[i]);
12544 cpu_PC = tcg_global_mem_new(TCG_AREG0,
12545 offsetof(CPUState, active_tc.PC), "PC");
12546 for (i = 0; i < MIPS_DSP_ACC; i++) {
12547 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12548 offsetof(CPUState, active_tc.HI[i]),
12549 regnames_HI[i]);
12550 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12551 offsetof(CPUState, active_tc.LO[i]),
12552 regnames_LO[i]);
12553 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12554 offsetof(CPUState, active_tc.ACX[i]),
12555 regnames_ACX[i]);
12557 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12558 offsetof(CPUState, active_tc.DSPControl),
12559 "DSPControl");
12560 bcond = tcg_global_mem_new(TCG_AREG0,
12561 offsetof(CPUState, bcond), "bcond");
12562 btarget = tcg_global_mem_new(TCG_AREG0,
12563 offsetof(CPUState, btarget), "btarget");
12564 hflags = tcg_global_mem_new_i32(TCG_AREG0,
12565 offsetof(CPUState, hflags), "hflags");
12567 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12568 offsetof(CPUState, active_fpu.fcr0),
12569 "fcr0");
12570 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12571 offsetof(CPUState, active_fpu.fcr31),
12572 "fcr31");
12574 /* register helpers */
12575 #define GEN_HELPER 2
12576 #include "helper.h"
12578 inited = 1;
12581 #include "translate_init.c"
12583 CPUMIPSState *cpu_mips_init (const char *cpu_model)
12585 CPUMIPSState *env;
12586 const mips_def_t *def;
12588 def = cpu_mips_find_by_name(cpu_model);
12589 if (!def)
12590 return NULL;
12591 env = qemu_mallocz(sizeof(CPUMIPSState));
12592 env->cpu_model = def;
12593 env->cpu_model_str = cpu_model;
12595 cpu_exec_init(env);
12596 #ifndef CONFIG_USER_ONLY
12597 mmu_init(env, def);
12598 #endif
12599 fpu_init(env, def);
12600 mvp_init(env, def);
12601 mips_tcg_init();
12602 cpu_reset(env);
12603 qemu_init_vcpu(env);
12604 return env;
12607 void cpu_reset (CPUMIPSState *env)
12609 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12610 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12611 log_cpu_state(env, 0);
12614 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12615 tlb_flush(env, 1);
12617 /* Reset registers to their default values */
12618 env->CP0_PRid = env->cpu_model->CP0_PRid;
12619 env->CP0_Config0 = env->cpu_model->CP0_Config0;
12620 #ifdef TARGET_WORDS_BIGENDIAN
12621 env->CP0_Config0 |= (1 << CP0C0_BE);
12622 #endif
12623 env->CP0_Config1 = env->cpu_model->CP0_Config1;
12624 env->CP0_Config2 = env->cpu_model->CP0_Config2;
12625 env->CP0_Config3 = env->cpu_model->CP0_Config3;
12626 env->CP0_Config6 = env->cpu_model->CP0_Config6;
12627 env->CP0_Config7 = env->cpu_model->CP0_Config7;
12628 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12629 << env->cpu_model->CP0_LLAddr_shift;
12630 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12631 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12632 env->CCRes = env->cpu_model->CCRes;
12633 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12634 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12635 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12636 env->current_tc = 0;
12637 env->SEGBITS = env->cpu_model->SEGBITS;
12638 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12639 #if defined(TARGET_MIPS64)
12640 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12641 env->SEGMask |= 3ULL << 62;
12643 #endif
12644 env->PABITS = env->cpu_model->PABITS;
12645 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12646 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12647 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12648 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12649 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12650 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12651 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12652 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12653 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12654 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12655 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12656 env->insn_flags = env->cpu_model->insn_flags;
12658 #if defined(CONFIG_USER_ONLY)
12659 env->hflags = MIPS_HFLAG_UM;
12660 /* Enable access to the SYNCI_Step register. */
12661 env->CP0_HWREna |= (1 << 1);
12662 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12663 env->hflags |= MIPS_HFLAG_FPU;
12665 #ifdef TARGET_MIPS64
12666 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12667 env->hflags |= MIPS_HFLAG_F64;
12669 #endif
12670 #else
12671 if (env->hflags & MIPS_HFLAG_BMASK) {
12672 /* If the exception was raised from a delay slot,
12673 come back to the jump. */
12674 env->CP0_ErrorEPC = env->active_tc.PC - 4;
12675 } else {
12676 env->CP0_ErrorEPC = env->active_tc.PC;
12678 env->active_tc.PC = (int32_t)0xBFC00000;
12679 env->CP0_Random = env->tlb->nb_tlb - 1;
12680 env->tlb->tlb_in_use = env->tlb->nb_tlb;
12681 env->CP0_Wired = 0;
12682 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
12683 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12684 /* vectored interrupts not implemented, timer on int 7,
12685 no performance counters. */
12686 env->CP0_IntCtl = 0xe0000000;
12688 int i;
12690 for (i = 0; i < 7; i++) {
12691 env->CP0_WatchLo[i] = 0;
12692 env->CP0_WatchHi[i] = 0x80000000;
12694 env->CP0_WatchLo[7] = 0;
12695 env->CP0_WatchHi[7] = 0;
12697 /* Count register increments in debug mode, EJTAG version 1 */
12698 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12699 env->hflags = MIPS_HFLAG_CP0;
12700 #endif
12701 #if defined(TARGET_MIPS64)
12702 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12703 env->hflags |= MIPS_HFLAG_64;
12705 #endif
12706 env->exception_index = EXCP_NONE;
12709 void gen_pc_load(CPUState *env, TranslationBlock *tb,
12710 unsigned long searched_pc, int pc_pos, void *puc)
12712 env->active_tc.PC = gen_opc_pc[pc_pos];
12713 env->hflags &= ~MIPS_HFLAG_BMASK;
12714 env->hflags |= gen_opc_hflags[pc_pos];