target-sh4: move intr_at_halt out of cpu_halted()
[qemu/agraf.git] / target-mips / translate.c
blob0f93e2abb10f1a331a29f059bcc25bff12ee5bca
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, 1);
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, 0);
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, 0);
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 (void)opn; /* avoid a compiler warning */
1157 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1158 tcg_temp_free(t0);
1159 tcg_temp_free(t1);
1162 /* Store */
1163 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1164 int base, int16_t offset)
1166 const char *opn = "st";
1167 TCGv t0 = tcg_temp_new();
1168 TCGv t1 = tcg_temp_new();
1170 gen_base_offset_addr(ctx, t0, base, offset);
1171 gen_load_gpr(t1, rt);
1172 switch (opc) {
1173 #if defined(TARGET_MIPS64)
1174 case OPC_SD:
1175 save_cpu_state(ctx, 0);
1176 op_st_sd(t1, t0, ctx);
1177 opn = "sd";
1178 break;
1179 case OPC_SDL:
1180 save_cpu_state(ctx, 1);
1181 gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1182 opn = "sdl";
1183 break;
1184 case OPC_SDR:
1185 save_cpu_state(ctx, 1);
1186 gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1187 opn = "sdr";
1188 break;
1189 #endif
1190 case OPC_SW:
1191 save_cpu_state(ctx, 0);
1192 op_st_sw(t1, t0, ctx);
1193 opn = "sw";
1194 break;
1195 case OPC_SH:
1196 save_cpu_state(ctx, 0);
1197 op_st_sh(t1, t0, ctx);
1198 opn = "sh";
1199 break;
1200 case OPC_SB:
1201 save_cpu_state(ctx, 0);
1202 op_st_sb(t1, t0, ctx);
1203 opn = "sb";
1204 break;
1205 case OPC_SWL:
1206 save_cpu_state(ctx, 1);
1207 gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1208 opn = "swl";
1209 break;
1210 case OPC_SWR:
1211 save_cpu_state(ctx, 1);
1212 gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1213 opn = "swr";
1214 break;
1216 (void)opn; /* avoid a compiler warning */
1217 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1218 tcg_temp_free(t0);
1219 tcg_temp_free(t1);
1223 /* Store conditional */
1224 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1225 int base, int16_t offset)
1227 const char *opn = "st_cond";
1228 TCGv t0, t1;
1230 t0 = tcg_temp_local_new();
1232 gen_base_offset_addr(ctx, t0, base, offset);
1233 /* Don't do NOP if destination is zero: we must perform the actual
1234 memory access. */
1236 t1 = tcg_temp_local_new();
1237 gen_load_gpr(t1, rt);
1238 switch (opc) {
1239 #if defined(TARGET_MIPS64)
1240 case OPC_SCD:
1241 save_cpu_state(ctx, 1);
1242 op_st_scd(t1, t0, rt, ctx);
1243 opn = "scd";
1244 break;
1245 #endif
1246 case OPC_SC:
1247 save_cpu_state(ctx, 1);
1248 op_st_sc(t1, t0, rt, ctx);
1249 opn = "sc";
1250 break;
1252 (void)opn; /* avoid a compiler warning */
1253 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1254 tcg_temp_free(t1);
1255 tcg_temp_free(t0);
1258 /* Load and store */
1259 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1260 int base, int16_t offset)
1262 const char *opn = "flt_ldst";
1263 TCGv t0 = tcg_temp_new();
1265 gen_base_offset_addr(ctx, t0, base, offset);
1266 /* Don't do NOP if destination is zero: we must perform the actual
1267 memory access. */
1268 switch (opc) {
1269 case OPC_LWC1:
1271 TCGv_i32 fp0 = tcg_temp_new_i32();
1273 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1274 tcg_gen_trunc_tl_i32(fp0, t0);
1275 gen_store_fpr32(fp0, ft);
1276 tcg_temp_free_i32(fp0);
1278 opn = "lwc1";
1279 break;
1280 case OPC_SWC1:
1282 TCGv_i32 fp0 = tcg_temp_new_i32();
1283 TCGv t1 = tcg_temp_new();
1285 gen_load_fpr32(fp0, ft);
1286 tcg_gen_extu_i32_tl(t1, fp0);
1287 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1288 tcg_temp_free(t1);
1289 tcg_temp_free_i32(fp0);
1291 opn = "swc1";
1292 break;
1293 case OPC_LDC1:
1295 TCGv_i64 fp0 = tcg_temp_new_i64();
1297 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1298 gen_store_fpr64(ctx, fp0, ft);
1299 tcg_temp_free_i64(fp0);
1301 opn = "ldc1";
1302 break;
1303 case OPC_SDC1:
1305 TCGv_i64 fp0 = tcg_temp_new_i64();
1307 gen_load_fpr64(ctx, fp0, ft);
1308 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1309 tcg_temp_free_i64(fp0);
1311 opn = "sdc1";
1312 break;
1313 default:
1314 MIPS_INVAL(opn);
1315 generate_exception(ctx, EXCP_RI);
1316 goto out;
1318 (void)opn; /* avoid a compiler warning */
1319 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1320 out:
1321 tcg_temp_free(t0);
1324 static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1325 uint32_t op, int rt, int rs, int16_t imm)
1327 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1328 check_cp1_enabled(ctx);
1329 gen_flt_ldst(ctx, op, rt, rs, imm);
1330 } else {
1331 generate_exception_err(ctx, EXCP_CpU, 1);
1335 /* Arithmetic with immediate operand */
1336 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1337 int rt, int rs, int16_t imm)
1339 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1340 const char *opn = "imm arith";
1342 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1343 /* If no destination, treat it as a NOP.
1344 For addi, we must generate the overflow exception when needed. */
1345 MIPS_DEBUG("NOP");
1346 return;
1348 switch (opc) {
1349 case OPC_ADDI:
1351 TCGv t0 = tcg_temp_local_new();
1352 TCGv t1 = tcg_temp_new();
1353 TCGv t2 = tcg_temp_new();
1354 int l1 = gen_new_label();
1356 gen_load_gpr(t1, rs);
1357 tcg_gen_addi_tl(t0, t1, uimm);
1358 tcg_gen_ext32s_tl(t0, t0);
1360 tcg_gen_xori_tl(t1, t1, ~uimm);
1361 tcg_gen_xori_tl(t2, t0, uimm);
1362 tcg_gen_and_tl(t1, t1, t2);
1363 tcg_temp_free(t2);
1364 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1365 tcg_temp_free(t1);
1366 /* operands of same sign, result different sign */
1367 generate_exception(ctx, EXCP_OVERFLOW);
1368 gen_set_label(l1);
1369 tcg_gen_ext32s_tl(t0, t0);
1370 gen_store_gpr(t0, rt);
1371 tcg_temp_free(t0);
1373 opn = "addi";
1374 break;
1375 case OPC_ADDIU:
1376 if (rs != 0) {
1377 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1378 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1379 } else {
1380 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1382 opn = "addiu";
1383 break;
1384 #if defined(TARGET_MIPS64)
1385 case OPC_DADDI:
1387 TCGv t0 = tcg_temp_local_new();
1388 TCGv t1 = tcg_temp_new();
1389 TCGv t2 = tcg_temp_new();
1390 int l1 = gen_new_label();
1392 gen_load_gpr(t1, rs);
1393 tcg_gen_addi_tl(t0, t1, uimm);
1395 tcg_gen_xori_tl(t1, t1, ~uimm);
1396 tcg_gen_xori_tl(t2, t0, uimm);
1397 tcg_gen_and_tl(t1, t1, t2);
1398 tcg_temp_free(t2);
1399 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1400 tcg_temp_free(t1);
1401 /* operands of same sign, result different sign */
1402 generate_exception(ctx, EXCP_OVERFLOW);
1403 gen_set_label(l1);
1404 gen_store_gpr(t0, rt);
1405 tcg_temp_free(t0);
1407 opn = "daddi";
1408 break;
1409 case OPC_DADDIU:
1410 if (rs != 0) {
1411 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1412 } else {
1413 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1415 opn = "daddiu";
1416 break;
1417 #endif
1419 (void)opn; /* avoid a compiler warning */
1420 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1423 /* Logic with immediate operand */
1424 static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1426 target_ulong uimm;
1427 const char *opn = "imm logic";
1429 if (rt == 0) {
1430 /* If no destination, treat it as a NOP. */
1431 MIPS_DEBUG("NOP");
1432 return;
1434 uimm = (uint16_t)imm;
1435 switch (opc) {
1436 case OPC_ANDI:
1437 if (likely(rs != 0))
1438 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1439 else
1440 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1441 opn = "andi";
1442 break;
1443 case OPC_ORI:
1444 if (rs != 0)
1445 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1446 else
1447 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1448 opn = "ori";
1449 break;
1450 case OPC_XORI:
1451 if (likely(rs != 0))
1452 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1453 else
1454 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1455 opn = "xori";
1456 break;
1457 case OPC_LUI:
1458 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1459 opn = "lui";
1460 break;
1462 (void)opn; /* avoid a compiler warning */
1463 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1466 /* Set on less than with immediate operand */
1467 static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1469 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1470 const char *opn = "imm arith";
1471 TCGv t0;
1473 if (rt == 0) {
1474 /* If no destination, treat it as a NOP. */
1475 MIPS_DEBUG("NOP");
1476 return;
1478 t0 = tcg_temp_new();
1479 gen_load_gpr(t0, rs);
1480 switch (opc) {
1481 case OPC_SLTI:
1482 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1483 opn = "slti";
1484 break;
1485 case OPC_SLTIU:
1486 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1487 opn = "sltiu";
1488 break;
1490 (void)opn; /* avoid a compiler warning */
1491 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1492 tcg_temp_free(t0);
1495 /* Shifts with immediate operand */
1496 static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1497 int rt, int rs, int16_t imm)
1499 target_ulong uimm = ((uint16_t)imm) & 0x1f;
1500 const char *opn = "imm shift";
1501 TCGv t0;
1503 if (rt == 0) {
1504 /* If no destination, treat it as a NOP. */
1505 MIPS_DEBUG("NOP");
1506 return;
1509 t0 = tcg_temp_new();
1510 gen_load_gpr(t0, rs);
1511 switch (opc) {
1512 case OPC_SLL:
1513 tcg_gen_shli_tl(t0, t0, uimm);
1514 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1515 opn = "sll";
1516 break;
1517 case OPC_SRA:
1518 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1519 opn = "sra";
1520 break;
1521 case OPC_SRL:
1522 if (uimm != 0) {
1523 tcg_gen_ext32u_tl(t0, t0);
1524 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1525 } else {
1526 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1528 opn = "srl";
1529 break;
1530 case OPC_ROTR:
1531 if (uimm != 0) {
1532 TCGv_i32 t1 = tcg_temp_new_i32();
1534 tcg_gen_trunc_tl_i32(t1, t0);
1535 tcg_gen_rotri_i32(t1, t1, uimm);
1536 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1537 tcg_temp_free_i32(t1);
1538 } else {
1539 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1541 opn = "rotr";
1542 break;
1543 #if defined(TARGET_MIPS64)
1544 case OPC_DSLL:
1545 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1546 opn = "dsll";
1547 break;
1548 case OPC_DSRA:
1549 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1550 opn = "dsra";
1551 break;
1552 case OPC_DSRL:
1553 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1554 opn = "dsrl";
1555 break;
1556 case OPC_DROTR:
1557 if (uimm != 0) {
1558 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1559 } else {
1560 tcg_gen_mov_tl(cpu_gpr[rt], t0);
1562 opn = "drotr";
1563 break;
1564 case OPC_DSLL32:
1565 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1566 opn = "dsll32";
1567 break;
1568 case OPC_DSRA32:
1569 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1570 opn = "dsra32";
1571 break;
1572 case OPC_DSRL32:
1573 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1574 opn = "dsrl32";
1575 break;
1576 case OPC_DROTR32:
1577 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1578 opn = "drotr32";
1579 break;
1580 #endif
1582 (void)opn; /* avoid a compiler warning */
1583 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1584 tcg_temp_free(t0);
1587 /* Arithmetic */
1588 static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1589 int rd, int rs, int rt)
1591 const char *opn = "arith";
1593 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1594 && opc != OPC_DADD && opc != OPC_DSUB) {
1595 /* If no destination, treat it as a NOP.
1596 For add & sub, we must generate the overflow exception when needed. */
1597 MIPS_DEBUG("NOP");
1598 return;
1601 switch (opc) {
1602 case OPC_ADD:
1604 TCGv t0 = tcg_temp_local_new();
1605 TCGv t1 = tcg_temp_new();
1606 TCGv t2 = tcg_temp_new();
1607 int l1 = gen_new_label();
1609 gen_load_gpr(t1, rs);
1610 gen_load_gpr(t2, rt);
1611 tcg_gen_add_tl(t0, t1, t2);
1612 tcg_gen_ext32s_tl(t0, t0);
1613 tcg_gen_xor_tl(t1, t1, t2);
1614 tcg_gen_xor_tl(t2, t0, t2);
1615 tcg_gen_andc_tl(t1, t2, t1);
1616 tcg_temp_free(t2);
1617 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1618 tcg_temp_free(t1);
1619 /* operands of same sign, result different sign */
1620 generate_exception(ctx, EXCP_OVERFLOW);
1621 gen_set_label(l1);
1622 gen_store_gpr(t0, rd);
1623 tcg_temp_free(t0);
1625 opn = "add";
1626 break;
1627 case OPC_ADDU:
1628 if (rs != 0 && rt != 0) {
1629 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1630 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1631 } else if (rs == 0 && rt != 0) {
1632 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1633 } else if (rs != 0 && rt == 0) {
1634 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1635 } else {
1636 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1638 opn = "addu";
1639 break;
1640 case OPC_SUB:
1642 TCGv t0 = tcg_temp_local_new();
1643 TCGv t1 = tcg_temp_new();
1644 TCGv t2 = tcg_temp_new();
1645 int l1 = gen_new_label();
1647 gen_load_gpr(t1, rs);
1648 gen_load_gpr(t2, rt);
1649 tcg_gen_sub_tl(t0, t1, t2);
1650 tcg_gen_ext32s_tl(t0, t0);
1651 tcg_gen_xor_tl(t2, t1, t2);
1652 tcg_gen_xor_tl(t1, t0, t1);
1653 tcg_gen_and_tl(t1, t1, t2);
1654 tcg_temp_free(t2);
1655 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1656 tcg_temp_free(t1);
1657 /* operands of different sign, first operand and result different sign */
1658 generate_exception(ctx, EXCP_OVERFLOW);
1659 gen_set_label(l1);
1660 gen_store_gpr(t0, rd);
1661 tcg_temp_free(t0);
1663 opn = "sub";
1664 break;
1665 case OPC_SUBU:
1666 if (rs != 0 && rt != 0) {
1667 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1668 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1669 } else if (rs == 0 && rt != 0) {
1670 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1671 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1672 } else if (rs != 0 && rt == 0) {
1673 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1674 } else {
1675 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1677 opn = "subu";
1678 break;
1679 #if defined(TARGET_MIPS64)
1680 case OPC_DADD:
1682 TCGv t0 = tcg_temp_local_new();
1683 TCGv t1 = tcg_temp_new();
1684 TCGv t2 = tcg_temp_new();
1685 int l1 = gen_new_label();
1687 gen_load_gpr(t1, rs);
1688 gen_load_gpr(t2, rt);
1689 tcg_gen_add_tl(t0, t1, t2);
1690 tcg_gen_xor_tl(t1, t1, t2);
1691 tcg_gen_xor_tl(t2, t0, t2);
1692 tcg_gen_andc_tl(t1, t2, t1);
1693 tcg_temp_free(t2);
1694 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1695 tcg_temp_free(t1);
1696 /* operands of same sign, result different sign */
1697 generate_exception(ctx, EXCP_OVERFLOW);
1698 gen_set_label(l1);
1699 gen_store_gpr(t0, rd);
1700 tcg_temp_free(t0);
1702 opn = "dadd";
1703 break;
1704 case OPC_DADDU:
1705 if (rs != 0 && rt != 0) {
1706 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1707 } else if (rs == 0 && rt != 0) {
1708 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1709 } else if (rs != 0 && rt == 0) {
1710 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1711 } else {
1712 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1714 opn = "daddu";
1715 break;
1716 case OPC_DSUB:
1718 TCGv t0 = tcg_temp_local_new();
1719 TCGv t1 = tcg_temp_new();
1720 TCGv t2 = tcg_temp_new();
1721 int l1 = gen_new_label();
1723 gen_load_gpr(t1, rs);
1724 gen_load_gpr(t2, rt);
1725 tcg_gen_sub_tl(t0, t1, t2);
1726 tcg_gen_xor_tl(t2, t1, t2);
1727 tcg_gen_xor_tl(t1, t0, t1);
1728 tcg_gen_and_tl(t1, t1, t2);
1729 tcg_temp_free(t2);
1730 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1731 tcg_temp_free(t1);
1732 /* operands of different sign, first operand and result different sign */
1733 generate_exception(ctx, EXCP_OVERFLOW);
1734 gen_set_label(l1);
1735 gen_store_gpr(t0, rd);
1736 tcg_temp_free(t0);
1738 opn = "dsub";
1739 break;
1740 case OPC_DSUBU:
1741 if (rs != 0 && rt != 0) {
1742 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1743 } else if (rs == 0 && rt != 0) {
1744 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1745 } else if (rs != 0 && rt == 0) {
1746 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1747 } else {
1748 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1750 opn = "dsubu";
1751 break;
1752 #endif
1753 case OPC_MUL:
1754 if (likely(rs != 0 && rt != 0)) {
1755 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1756 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1757 } else {
1758 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1760 opn = "mul";
1761 break;
1763 (void)opn; /* avoid a compiler warning */
1764 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1767 /* Conditional move */
1768 static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1770 const char *opn = "cond move";
1771 int l1;
1773 if (rd == 0) {
1774 /* If no destination, treat it as a NOP.
1775 For add & sub, we must generate the overflow exception when needed. */
1776 MIPS_DEBUG("NOP");
1777 return;
1780 l1 = gen_new_label();
1781 switch (opc) {
1782 case OPC_MOVN:
1783 if (likely(rt != 0))
1784 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1785 else
1786 tcg_gen_br(l1);
1787 opn = "movn";
1788 break;
1789 case OPC_MOVZ:
1790 if (likely(rt != 0))
1791 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1792 opn = "movz";
1793 break;
1795 if (rs != 0)
1796 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1797 else
1798 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1799 gen_set_label(l1);
1801 (void)opn; /* avoid a compiler warning */
1802 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1805 /* Logic */
1806 static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1808 const char *opn = "logic";
1810 if (rd == 0) {
1811 /* If no destination, treat it as a NOP. */
1812 MIPS_DEBUG("NOP");
1813 return;
1816 switch (opc) {
1817 case OPC_AND:
1818 if (likely(rs != 0 && rt != 0)) {
1819 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1820 } else {
1821 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1823 opn = "and";
1824 break;
1825 case OPC_NOR:
1826 if (rs != 0 && rt != 0) {
1827 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1828 } else if (rs == 0 && rt != 0) {
1829 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1830 } else if (rs != 0 && rt == 0) {
1831 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1832 } else {
1833 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1835 opn = "nor";
1836 break;
1837 case OPC_OR:
1838 if (likely(rs != 0 && rt != 0)) {
1839 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1840 } else if (rs == 0 && rt != 0) {
1841 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1842 } else if (rs != 0 && rt == 0) {
1843 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1844 } else {
1845 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1847 opn = "or";
1848 break;
1849 case OPC_XOR:
1850 if (likely(rs != 0 && rt != 0)) {
1851 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1852 } else if (rs == 0 && rt != 0) {
1853 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1854 } else if (rs != 0 && rt == 0) {
1855 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1856 } else {
1857 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1859 opn = "xor";
1860 break;
1862 (void)opn; /* avoid a compiler warning */
1863 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1866 /* Set on lower than */
1867 static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1869 const char *opn = "slt";
1870 TCGv t0, t1;
1872 if (rd == 0) {
1873 /* If no destination, treat it as a NOP. */
1874 MIPS_DEBUG("NOP");
1875 return;
1878 t0 = tcg_temp_new();
1879 t1 = tcg_temp_new();
1880 gen_load_gpr(t0, rs);
1881 gen_load_gpr(t1, rt);
1882 switch (opc) {
1883 case OPC_SLT:
1884 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1885 opn = "slt";
1886 break;
1887 case OPC_SLTU:
1888 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1889 opn = "sltu";
1890 break;
1892 (void)opn; /* avoid a compiler warning */
1893 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1894 tcg_temp_free(t0);
1895 tcg_temp_free(t1);
1898 /* Shifts */
1899 static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1900 int rd, int rs, int rt)
1902 const char *opn = "shifts";
1903 TCGv t0, t1;
1905 if (rd == 0) {
1906 /* If no destination, treat it as a NOP.
1907 For add & sub, we must generate the overflow exception when needed. */
1908 MIPS_DEBUG("NOP");
1909 return;
1912 t0 = tcg_temp_new();
1913 t1 = tcg_temp_new();
1914 gen_load_gpr(t0, rs);
1915 gen_load_gpr(t1, rt);
1916 switch (opc) {
1917 case OPC_SLLV:
1918 tcg_gen_andi_tl(t0, t0, 0x1f);
1919 tcg_gen_shl_tl(t0, t1, t0);
1920 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1921 opn = "sllv";
1922 break;
1923 case OPC_SRAV:
1924 tcg_gen_andi_tl(t0, t0, 0x1f);
1925 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1926 opn = "srav";
1927 break;
1928 case OPC_SRLV:
1929 tcg_gen_ext32u_tl(t1, t1);
1930 tcg_gen_andi_tl(t0, t0, 0x1f);
1931 tcg_gen_shr_tl(t0, t1, t0);
1932 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1933 opn = "srlv";
1934 break;
1935 case OPC_ROTRV:
1937 TCGv_i32 t2 = tcg_temp_new_i32();
1938 TCGv_i32 t3 = tcg_temp_new_i32();
1940 tcg_gen_trunc_tl_i32(t2, t0);
1941 tcg_gen_trunc_tl_i32(t3, t1);
1942 tcg_gen_andi_i32(t2, t2, 0x1f);
1943 tcg_gen_rotr_i32(t2, t3, t2);
1944 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1945 tcg_temp_free_i32(t2);
1946 tcg_temp_free_i32(t3);
1947 opn = "rotrv";
1949 break;
1950 #if defined(TARGET_MIPS64)
1951 case OPC_DSLLV:
1952 tcg_gen_andi_tl(t0, t0, 0x3f);
1953 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1954 opn = "dsllv";
1955 break;
1956 case OPC_DSRAV:
1957 tcg_gen_andi_tl(t0, t0, 0x3f);
1958 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1959 opn = "dsrav";
1960 break;
1961 case OPC_DSRLV:
1962 tcg_gen_andi_tl(t0, t0, 0x3f);
1963 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1964 opn = "dsrlv";
1965 break;
1966 case OPC_DROTRV:
1967 tcg_gen_andi_tl(t0, t0, 0x3f);
1968 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1969 opn = "drotrv";
1970 break;
1971 #endif
1973 (void)opn; /* avoid a compiler warning */
1974 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1975 tcg_temp_free(t0);
1976 tcg_temp_free(t1);
1979 /* Arithmetic on HI/LO registers */
1980 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1982 const char *opn = "hilo";
1984 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1985 /* Treat as NOP. */
1986 MIPS_DEBUG("NOP");
1987 return;
1989 switch (opc) {
1990 case OPC_MFHI:
1991 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1992 opn = "mfhi";
1993 break;
1994 case OPC_MFLO:
1995 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1996 opn = "mflo";
1997 break;
1998 case OPC_MTHI:
1999 if (reg != 0)
2000 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
2001 else
2002 tcg_gen_movi_tl(cpu_HI[0], 0);
2003 opn = "mthi";
2004 break;
2005 case OPC_MTLO:
2006 if (reg != 0)
2007 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2008 else
2009 tcg_gen_movi_tl(cpu_LO[0], 0);
2010 opn = "mtlo";
2011 break;
2013 (void)opn; /* avoid a compiler warning */
2014 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2017 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2018 int rs, int rt)
2020 const char *opn = "mul/div";
2021 TCGv t0, t1;
2023 switch (opc) {
2024 case OPC_DIV:
2025 case OPC_DIVU:
2026 #if defined(TARGET_MIPS64)
2027 case OPC_DDIV:
2028 case OPC_DDIVU:
2029 #endif
2030 t0 = tcg_temp_local_new();
2031 t1 = tcg_temp_local_new();
2032 break;
2033 default:
2034 t0 = tcg_temp_new();
2035 t1 = tcg_temp_new();
2036 break;
2039 gen_load_gpr(t0, rs);
2040 gen_load_gpr(t1, rt);
2041 switch (opc) {
2042 case OPC_DIV:
2044 int l1 = gen_new_label();
2045 int l2 = gen_new_label();
2047 tcg_gen_ext32s_tl(t0, t0);
2048 tcg_gen_ext32s_tl(t1, t1);
2049 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2050 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2051 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2053 tcg_gen_mov_tl(cpu_LO[0], t0);
2054 tcg_gen_movi_tl(cpu_HI[0], 0);
2055 tcg_gen_br(l1);
2056 gen_set_label(l2);
2057 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2058 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2059 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2060 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2061 gen_set_label(l1);
2063 opn = "div";
2064 break;
2065 case OPC_DIVU:
2067 int l1 = gen_new_label();
2069 tcg_gen_ext32u_tl(t0, t0);
2070 tcg_gen_ext32u_tl(t1, t1);
2071 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2072 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2073 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2074 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2075 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2076 gen_set_label(l1);
2078 opn = "divu";
2079 break;
2080 case OPC_MULT:
2082 TCGv_i64 t2 = tcg_temp_new_i64();
2083 TCGv_i64 t3 = tcg_temp_new_i64();
2085 tcg_gen_ext_tl_i64(t2, t0);
2086 tcg_gen_ext_tl_i64(t3, t1);
2087 tcg_gen_mul_i64(t2, t2, t3);
2088 tcg_temp_free_i64(t3);
2089 tcg_gen_trunc_i64_tl(t0, t2);
2090 tcg_gen_shri_i64(t2, t2, 32);
2091 tcg_gen_trunc_i64_tl(t1, t2);
2092 tcg_temp_free_i64(t2);
2093 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2094 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2096 opn = "mult";
2097 break;
2098 case OPC_MULTU:
2100 TCGv_i64 t2 = tcg_temp_new_i64();
2101 TCGv_i64 t3 = tcg_temp_new_i64();
2103 tcg_gen_ext32u_tl(t0, t0);
2104 tcg_gen_ext32u_tl(t1, t1);
2105 tcg_gen_extu_tl_i64(t2, t0);
2106 tcg_gen_extu_tl_i64(t3, t1);
2107 tcg_gen_mul_i64(t2, t2, t3);
2108 tcg_temp_free_i64(t3);
2109 tcg_gen_trunc_i64_tl(t0, t2);
2110 tcg_gen_shri_i64(t2, t2, 32);
2111 tcg_gen_trunc_i64_tl(t1, t2);
2112 tcg_temp_free_i64(t2);
2113 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2114 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2116 opn = "multu";
2117 break;
2118 #if defined(TARGET_MIPS64)
2119 case OPC_DDIV:
2121 int l1 = gen_new_label();
2122 int l2 = gen_new_label();
2124 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2125 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2126 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2127 tcg_gen_mov_tl(cpu_LO[0], t0);
2128 tcg_gen_movi_tl(cpu_HI[0], 0);
2129 tcg_gen_br(l1);
2130 gen_set_label(l2);
2131 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2132 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2133 gen_set_label(l1);
2135 opn = "ddiv";
2136 break;
2137 case OPC_DDIVU:
2139 int l1 = gen_new_label();
2141 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2142 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2143 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2144 gen_set_label(l1);
2146 opn = "ddivu";
2147 break;
2148 case OPC_DMULT:
2149 gen_helper_dmult(t0, t1);
2150 opn = "dmult";
2151 break;
2152 case OPC_DMULTU:
2153 gen_helper_dmultu(t0, t1);
2154 opn = "dmultu";
2155 break;
2156 #endif
2157 case OPC_MADD:
2159 TCGv_i64 t2 = tcg_temp_new_i64();
2160 TCGv_i64 t3 = tcg_temp_new_i64();
2162 tcg_gen_ext_tl_i64(t2, t0);
2163 tcg_gen_ext_tl_i64(t3, t1);
2164 tcg_gen_mul_i64(t2, t2, t3);
2165 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2166 tcg_gen_add_i64(t2, t2, t3);
2167 tcg_temp_free_i64(t3);
2168 tcg_gen_trunc_i64_tl(t0, t2);
2169 tcg_gen_shri_i64(t2, t2, 32);
2170 tcg_gen_trunc_i64_tl(t1, t2);
2171 tcg_temp_free_i64(t2);
2172 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2173 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2175 opn = "madd";
2176 break;
2177 case OPC_MADDU:
2179 TCGv_i64 t2 = tcg_temp_new_i64();
2180 TCGv_i64 t3 = tcg_temp_new_i64();
2182 tcg_gen_ext32u_tl(t0, t0);
2183 tcg_gen_ext32u_tl(t1, t1);
2184 tcg_gen_extu_tl_i64(t2, t0);
2185 tcg_gen_extu_tl_i64(t3, t1);
2186 tcg_gen_mul_i64(t2, t2, t3);
2187 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2188 tcg_gen_add_i64(t2, t2, t3);
2189 tcg_temp_free_i64(t3);
2190 tcg_gen_trunc_i64_tl(t0, t2);
2191 tcg_gen_shri_i64(t2, t2, 32);
2192 tcg_gen_trunc_i64_tl(t1, t2);
2193 tcg_temp_free_i64(t2);
2194 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2195 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2197 opn = "maddu";
2198 break;
2199 case OPC_MSUB:
2201 TCGv_i64 t2 = tcg_temp_new_i64();
2202 TCGv_i64 t3 = tcg_temp_new_i64();
2204 tcg_gen_ext_tl_i64(t2, t0);
2205 tcg_gen_ext_tl_i64(t3, t1);
2206 tcg_gen_mul_i64(t2, t2, t3);
2207 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2208 tcg_gen_sub_i64(t2, t3, t2);
2209 tcg_temp_free_i64(t3);
2210 tcg_gen_trunc_i64_tl(t0, t2);
2211 tcg_gen_shri_i64(t2, t2, 32);
2212 tcg_gen_trunc_i64_tl(t1, t2);
2213 tcg_temp_free_i64(t2);
2214 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2215 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2217 opn = "msub";
2218 break;
2219 case OPC_MSUBU:
2221 TCGv_i64 t2 = tcg_temp_new_i64();
2222 TCGv_i64 t3 = tcg_temp_new_i64();
2224 tcg_gen_ext32u_tl(t0, t0);
2225 tcg_gen_ext32u_tl(t1, t1);
2226 tcg_gen_extu_tl_i64(t2, t0);
2227 tcg_gen_extu_tl_i64(t3, t1);
2228 tcg_gen_mul_i64(t2, t2, t3);
2229 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2230 tcg_gen_sub_i64(t2, t3, t2);
2231 tcg_temp_free_i64(t3);
2232 tcg_gen_trunc_i64_tl(t0, t2);
2233 tcg_gen_shri_i64(t2, t2, 32);
2234 tcg_gen_trunc_i64_tl(t1, t2);
2235 tcg_temp_free_i64(t2);
2236 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2237 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2239 opn = "msubu";
2240 break;
2241 default:
2242 MIPS_INVAL(opn);
2243 generate_exception(ctx, EXCP_RI);
2244 goto out;
2246 (void)opn; /* avoid a compiler warning */
2247 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2248 out:
2249 tcg_temp_free(t0);
2250 tcg_temp_free(t1);
2253 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2254 int rd, int rs, int rt)
2256 const char *opn = "mul vr54xx";
2257 TCGv t0 = tcg_temp_new();
2258 TCGv t1 = tcg_temp_new();
2260 gen_load_gpr(t0, rs);
2261 gen_load_gpr(t1, rt);
2263 switch (opc) {
2264 case OPC_VR54XX_MULS:
2265 gen_helper_muls(t0, t0, t1);
2266 opn = "muls";
2267 break;
2268 case OPC_VR54XX_MULSU:
2269 gen_helper_mulsu(t0, t0, t1);
2270 opn = "mulsu";
2271 break;
2272 case OPC_VR54XX_MACC:
2273 gen_helper_macc(t0, t0, t1);
2274 opn = "macc";
2275 break;
2276 case OPC_VR54XX_MACCU:
2277 gen_helper_maccu(t0, t0, t1);
2278 opn = "maccu";
2279 break;
2280 case OPC_VR54XX_MSAC:
2281 gen_helper_msac(t0, t0, t1);
2282 opn = "msac";
2283 break;
2284 case OPC_VR54XX_MSACU:
2285 gen_helper_msacu(t0, t0, t1);
2286 opn = "msacu";
2287 break;
2288 case OPC_VR54XX_MULHI:
2289 gen_helper_mulhi(t0, t0, t1);
2290 opn = "mulhi";
2291 break;
2292 case OPC_VR54XX_MULHIU:
2293 gen_helper_mulhiu(t0, t0, t1);
2294 opn = "mulhiu";
2295 break;
2296 case OPC_VR54XX_MULSHI:
2297 gen_helper_mulshi(t0, t0, t1);
2298 opn = "mulshi";
2299 break;
2300 case OPC_VR54XX_MULSHIU:
2301 gen_helper_mulshiu(t0, t0, t1);
2302 opn = "mulshiu";
2303 break;
2304 case OPC_VR54XX_MACCHI:
2305 gen_helper_macchi(t0, t0, t1);
2306 opn = "macchi";
2307 break;
2308 case OPC_VR54XX_MACCHIU:
2309 gen_helper_macchiu(t0, t0, t1);
2310 opn = "macchiu";
2311 break;
2312 case OPC_VR54XX_MSACHI:
2313 gen_helper_msachi(t0, t0, t1);
2314 opn = "msachi";
2315 break;
2316 case OPC_VR54XX_MSACHIU:
2317 gen_helper_msachiu(t0, t0, t1);
2318 opn = "msachiu";
2319 break;
2320 default:
2321 MIPS_INVAL("mul vr54xx");
2322 generate_exception(ctx, EXCP_RI);
2323 goto out;
2325 gen_store_gpr(t0, rd);
2326 (void)opn; /* avoid a compiler warning */
2327 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2329 out:
2330 tcg_temp_free(t0);
2331 tcg_temp_free(t1);
2334 static void gen_cl (DisasContext *ctx, uint32_t opc,
2335 int rd, int rs)
2337 const char *opn = "CLx";
2338 TCGv t0;
2340 if (rd == 0) {
2341 /* Treat as NOP. */
2342 MIPS_DEBUG("NOP");
2343 return;
2345 t0 = tcg_temp_new();
2346 gen_load_gpr(t0, rs);
2347 switch (opc) {
2348 case OPC_CLO:
2349 gen_helper_clo(cpu_gpr[rd], t0);
2350 opn = "clo";
2351 break;
2352 case OPC_CLZ:
2353 gen_helper_clz(cpu_gpr[rd], t0);
2354 opn = "clz";
2355 break;
2356 #if defined(TARGET_MIPS64)
2357 case OPC_DCLO:
2358 gen_helper_dclo(cpu_gpr[rd], t0);
2359 opn = "dclo";
2360 break;
2361 case OPC_DCLZ:
2362 gen_helper_dclz(cpu_gpr[rd], t0);
2363 opn = "dclz";
2364 break;
2365 #endif
2367 (void)opn; /* avoid a compiler warning */
2368 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2369 tcg_temp_free(t0);
2372 /* Godson integer instructions */
2373 static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2374 int rd, int rs, int rt)
2376 const char *opn = "loongson";
2377 TCGv t0, t1;
2379 if (rd == 0) {
2380 /* Treat as NOP. */
2381 MIPS_DEBUG("NOP");
2382 return;
2385 switch (opc) {
2386 case OPC_MULT_G_2E:
2387 case OPC_MULT_G_2F:
2388 case OPC_MULTU_G_2E:
2389 case OPC_MULTU_G_2F:
2390 #if defined(TARGET_MIPS64)
2391 case OPC_DMULT_G_2E:
2392 case OPC_DMULT_G_2F:
2393 case OPC_DMULTU_G_2E:
2394 case OPC_DMULTU_G_2F:
2395 #endif
2396 t0 = tcg_temp_new();
2397 t1 = tcg_temp_new();
2398 break;
2399 default:
2400 t0 = tcg_temp_local_new();
2401 t1 = tcg_temp_local_new();
2402 break;
2405 gen_load_gpr(t0, rs);
2406 gen_load_gpr(t1, rt);
2408 switch (opc) {
2409 case OPC_MULT_G_2E:
2410 case OPC_MULT_G_2F:
2411 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2412 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2413 opn = "mult.g";
2414 break;
2415 case OPC_MULTU_G_2E:
2416 case OPC_MULTU_G_2F:
2417 tcg_gen_ext32u_tl(t0, t0);
2418 tcg_gen_ext32u_tl(t1, t1);
2419 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2420 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2421 opn = "multu.g";
2422 break;
2423 case OPC_DIV_G_2E:
2424 case OPC_DIV_G_2F:
2426 int l1 = gen_new_label();
2427 int l2 = gen_new_label();
2428 int l3 = gen_new_label();
2429 tcg_gen_ext32s_tl(t0, t0);
2430 tcg_gen_ext32s_tl(t1, t1);
2431 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2432 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2433 tcg_gen_br(l3);
2434 gen_set_label(l1);
2435 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2436 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2437 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2438 tcg_gen_br(l3);
2439 gen_set_label(l2);
2440 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2441 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2442 gen_set_label(l3);
2444 opn = "div.g";
2445 break;
2446 case OPC_DIVU_G_2E:
2447 case OPC_DIVU_G_2F:
2449 int l1 = gen_new_label();
2450 int l2 = gen_new_label();
2451 tcg_gen_ext32u_tl(t0, t0);
2452 tcg_gen_ext32u_tl(t1, t1);
2453 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2454 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2455 tcg_gen_br(l2);
2456 gen_set_label(l1);
2457 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2458 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2459 gen_set_label(l2);
2461 opn = "divu.g";
2462 break;
2463 case OPC_MOD_G_2E:
2464 case OPC_MOD_G_2F:
2466 int l1 = gen_new_label();
2467 int l2 = gen_new_label();
2468 int l3 = gen_new_label();
2469 tcg_gen_ext32u_tl(t0, t0);
2470 tcg_gen_ext32u_tl(t1, t1);
2471 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2472 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2473 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2474 gen_set_label(l1);
2475 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2476 tcg_gen_br(l3);
2477 gen_set_label(l2);
2478 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2479 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2480 gen_set_label(l3);
2482 opn = "mod.g";
2483 break;
2484 case OPC_MODU_G_2E:
2485 case OPC_MODU_G_2F:
2487 int l1 = gen_new_label();
2488 int l2 = gen_new_label();
2489 tcg_gen_ext32u_tl(t0, t0);
2490 tcg_gen_ext32u_tl(t1, t1);
2491 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2492 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2493 tcg_gen_br(l2);
2494 gen_set_label(l1);
2495 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2496 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2497 gen_set_label(l2);
2499 opn = "modu.g";
2500 break;
2501 #if defined(TARGET_MIPS64)
2502 case OPC_DMULT_G_2E:
2503 case OPC_DMULT_G_2F:
2504 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2505 opn = "dmult.g";
2506 break;
2507 case OPC_DMULTU_G_2E:
2508 case OPC_DMULTU_G_2F:
2509 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2510 opn = "dmultu.g";
2511 break;
2512 case OPC_DDIV_G_2E:
2513 case OPC_DDIV_G_2F:
2515 int l1 = gen_new_label();
2516 int l2 = gen_new_label();
2517 int l3 = gen_new_label();
2518 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2519 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2520 tcg_gen_br(l3);
2521 gen_set_label(l1);
2522 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2523 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2524 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2525 tcg_gen_br(l3);
2526 gen_set_label(l2);
2527 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2528 gen_set_label(l3);
2530 opn = "ddiv.g";
2531 break;
2532 case OPC_DDIVU_G_2E:
2533 case OPC_DDIVU_G_2F:
2535 int l1 = gen_new_label();
2536 int l2 = gen_new_label();
2537 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2538 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2539 tcg_gen_br(l2);
2540 gen_set_label(l1);
2541 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2542 gen_set_label(l2);
2544 opn = "ddivu.g";
2545 break;
2546 case OPC_DMOD_G_2E:
2547 case OPC_DMOD_G_2F:
2549 int l1 = gen_new_label();
2550 int l2 = gen_new_label();
2551 int l3 = gen_new_label();
2552 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2553 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2554 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2555 gen_set_label(l1);
2556 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2557 tcg_gen_br(l3);
2558 gen_set_label(l2);
2559 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2560 gen_set_label(l3);
2562 opn = "dmod.g";
2563 break;
2564 case OPC_DMODU_G_2E:
2565 case OPC_DMODU_G_2F:
2567 int l1 = gen_new_label();
2568 int l2 = gen_new_label();
2569 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2570 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2571 tcg_gen_br(l2);
2572 gen_set_label(l1);
2573 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2574 gen_set_label(l2);
2576 opn = "dmodu.g";
2577 break;
2578 #endif
2581 (void)opn; /* avoid a compiler warning */
2582 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2583 tcg_temp_free(t0);
2584 tcg_temp_free(t1);
2587 /* Traps */
2588 static void gen_trap (DisasContext *ctx, uint32_t opc,
2589 int rs, int rt, int16_t imm)
2591 int cond;
2592 TCGv t0 = tcg_temp_new();
2593 TCGv t1 = tcg_temp_new();
2595 cond = 0;
2596 /* Load needed operands */
2597 switch (opc) {
2598 case OPC_TEQ:
2599 case OPC_TGE:
2600 case OPC_TGEU:
2601 case OPC_TLT:
2602 case OPC_TLTU:
2603 case OPC_TNE:
2604 /* Compare two registers */
2605 if (rs != rt) {
2606 gen_load_gpr(t0, rs);
2607 gen_load_gpr(t1, rt);
2608 cond = 1;
2610 break;
2611 case OPC_TEQI:
2612 case OPC_TGEI:
2613 case OPC_TGEIU:
2614 case OPC_TLTI:
2615 case OPC_TLTIU:
2616 case OPC_TNEI:
2617 /* Compare register to immediate */
2618 if (rs != 0 || imm != 0) {
2619 gen_load_gpr(t0, rs);
2620 tcg_gen_movi_tl(t1, (int32_t)imm);
2621 cond = 1;
2623 break;
2625 if (cond == 0) {
2626 switch (opc) {
2627 case OPC_TEQ: /* rs == rs */
2628 case OPC_TEQI: /* r0 == 0 */
2629 case OPC_TGE: /* rs >= rs */
2630 case OPC_TGEI: /* r0 >= 0 */
2631 case OPC_TGEU: /* rs >= rs unsigned */
2632 case OPC_TGEIU: /* r0 >= 0 unsigned */
2633 /* Always trap */
2634 generate_exception(ctx, EXCP_TRAP);
2635 break;
2636 case OPC_TLT: /* rs < rs */
2637 case OPC_TLTI: /* r0 < 0 */
2638 case OPC_TLTU: /* rs < rs unsigned */
2639 case OPC_TLTIU: /* r0 < 0 unsigned */
2640 case OPC_TNE: /* rs != rs */
2641 case OPC_TNEI: /* r0 != 0 */
2642 /* Never trap: treat as NOP. */
2643 break;
2645 } else {
2646 int l1 = gen_new_label();
2648 switch (opc) {
2649 case OPC_TEQ:
2650 case OPC_TEQI:
2651 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2652 break;
2653 case OPC_TGE:
2654 case OPC_TGEI:
2655 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2656 break;
2657 case OPC_TGEU:
2658 case OPC_TGEIU:
2659 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2660 break;
2661 case OPC_TLT:
2662 case OPC_TLTI:
2663 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2664 break;
2665 case OPC_TLTU:
2666 case OPC_TLTIU:
2667 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2668 break;
2669 case OPC_TNE:
2670 case OPC_TNEI:
2671 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2672 break;
2674 generate_exception(ctx, EXCP_TRAP);
2675 gen_set_label(l1);
2677 tcg_temp_free(t0);
2678 tcg_temp_free(t1);
2681 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2683 TranslationBlock *tb;
2684 tb = ctx->tb;
2685 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2686 likely(!ctx->singlestep_enabled)) {
2687 tcg_gen_goto_tb(n);
2688 gen_save_pc(dest);
2689 tcg_gen_exit_tb((long)tb + n);
2690 } else {
2691 gen_save_pc(dest);
2692 if (ctx->singlestep_enabled) {
2693 save_cpu_state(ctx, 0);
2694 gen_helper_0i(raise_exception, EXCP_DEBUG);
2696 tcg_gen_exit_tb(0);
2700 /* Branches (before delay slot) */
2701 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2702 int insn_bytes,
2703 int rs, int rt, int32_t offset)
2705 target_ulong btgt = -1;
2706 int blink = 0;
2707 int bcond_compute = 0;
2708 TCGv t0 = tcg_temp_new();
2709 TCGv t1 = tcg_temp_new();
2711 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2712 #ifdef MIPS_DEBUG_DISAS
2713 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2714 #endif
2715 generate_exception(ctx, EXCP_RI);
2716 goto out;
2719 /* Load needed operands */
2720 switch (opc) {
2721 case OPC_BEQ:
2722 case OPC_BEQL:
2723 case OPC_BNE:
2724 case OPC_BNEL:
2725 /* Compare two registers */
2726 if (rs != rt) {
2727 gen_load_gpr(t0, rs);
2728 gen_load_gpr(t1, rt);
2729 bcond_compute = 1;
2731 btgt = ctx->pc + insn_bytes + offset;
2732 break;
2733 case OPC_BGEZ:
2734 case OPC_BGEZAL:
2735 case OPC_BGEZALS:
2736 case OPC_BGEZALL:
2737 case OPC_BGEZL:
2738 case OPC_BGTZ:
2739 case OPC_BGTZL:
2740 case OPC_BLEZ:
2741 case OPC_BLEZL:
2742 case OPC_BLTZ:
2743 case OPC_BLTZAL:
2744 case OPC_BLTZALS:
2745 case OPC_BLTZALL:
2746 case OPC_BLTZL:
2747 /* Compare to zero */
2748 if (rs != 0) {
2749 gen_load_gpr(t0, rs);
2750 bcond_compute = 1;
2752 btgt = ctx->pc + insn_bytes + offset;
2753 break;
2754 case OPC_J:
2755 case OPC_JAL:
2756 case OPC_JALX:
2757 case OPC_JALS:
2758 case OPC_JALXS:
2759 /* Jump to immediate */
2760 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2761 break;
2762 case OPC_JR:
2763 case OPC_JALR:
2764 case OPC_JALRC:
2765 case OPC_JALRS:
2766 /* Jump to register */
2767 if (offset != 0 && offset != 16) {
2768 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2769 others are reserved. */
2770 MIPS_INVAL("jump hint");
2771 generate_exception(ctx, EXCP_RI);
2772 goto out;
2774 gen_load_gpr(btarget, rs);
2775 break;
2776 default:
2777 MIPS_INVAL("branch/jump");
2778 generate_exception(ctx, EXCP_RI);
2779 goto out;
2781 if (bcond_compute == 0) {
2782 /* No condition to be computed */
2783 switch (opc) {
2784 case OPC_BEQ: /* rx == rx */
2785 case OPC_BEQL: /* rx == rx likely */
2786 case OPC_BGEZ: /* 0 >= 0 */
2787 case OPC_BGEZL: /* 0 >= 0 likely */
2788 case OPC_BLEZ: /* 0 <= 0 */
2789 case OPC_BLEZL: /* 0 <= 0 likely */
2790 /* Always take */
2791 ctx->hflags |= MIPS_HFLAG_B;
2792 MIPS_DEBUG("balways");
2793 break;
2794 case OPC_BGEZALS:
2795 case OPC_BGEZAL: /* 0 >= 0 */
2796 case OPC_BGEZALL: /* 0 >= 0 likely */
2797 ctx->hflags |= (opc == OPC_BGEZALS
2798 ? MIPS_HFLAG_BDS16
2799 : MIPS_HFLAG_BDS32);
2800 /* Always take and link */
2801 blink = 31;
2802 ctx->hflags |= MIPS_HFLAG_B;
2803 MIPS_DEBUG("balways and link");
2804 break;
2805 case OPC_BNE: /* rx != rx */
2806 case OPC_BGTZ: /* 0 > 0 */
2807 case OPC_BLTZ: /* 0 < 0 */
2808 /* Treat as NOP. */
2809 MIPS_DEBUG("bnever (NOP)");
2810 goto out;
2811 case OPC_BLTZALS:
2812 case OPC_BLTZAL: /* 0 < 0 */
2813 ctx->hflags |= (opc == OPC_BLTZALS
2814 ? MIPS_HFLAG_BDS16
2815 : MIPS_HFLAG_BDS32);
2816 /* Handle as an unconditional branch to get correct delay
2817 slot checking. */
2818 blink = 31;
2819 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2820 ctx->hflags |= MIPS_HFLAG_B;
2821 MIPS_DEBUG("bnever and link");
2822 break;
2823 case OPC_BLTZALL: /* 0 < 0 likely */
2824 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2825 /* Skip the instruction in the delay slot */
2826 MIPS_DEBUG("bnever, link and skip");
2827 ctx->pc += 4;
2828 goto out;
2829 case OPC_BNEL: /* rx != rx likely */
2830 case OPC_BGTZL: /* 0 > 0 likely */
2831 case OPC_BLTZL: /* 0 < 0 likely */
2832 /* Skip the instruction in the delay slot */
2833 MIPS_DEBUG("bnever and skip");
2834 ctx->pc += 4;
2835 goto out;
2836 case OPC_J:
2837 ctx->hflags |= MIPS_HFLAG_B;
2838 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2839 break;
2840 case OPC_JALXS:
2841 case OPC_JALX:
2842 ctx->hflags |= MIPS_HFLAG_BX;
2843 /* Fallthrough */
2844 case OPC_JALS:
2845 case OPC_JAL:
2846 blink = 31;
2847 ctx->hflags |= MIPS_HFLAG_B;
2848 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2849 ? MIPS_HFLAG_BDS16
2850 : MIPS_HFLAG_BDS32);
2851 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2852 break;
2853 case OPC_JR:
2854 ctx->hflags |= MIPS_HFLAG_BR;
2855 if (insn_bytes == 4)
2856 ctx->hflags |= MIPS_HFLAG_BDS32;
2857 MIPS_DEBUG("jr %s", regnames[rs]);
2858 break;
2859 case OPC_JALRS:
2860 case OPC_JALR:
2861 case OPC_JALRC:
2862 blink = rt;
2863 ctx->hflags |= MIPS_HFLAG_BR;
2864 ctx->hflags |= (opc == OPC_JALRS
2865 ? MIPS_HFLAG_BDS16
2866 : MIPS_HFLAG_BDS32);
2867 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2868 break;
2869 default:
2870 MIPS_INVAL("branch/jump");
2871 generate_exception(ctx, EXCP_RI);
2872 goto out;
2874 } else {
2875 switch (opc) {
2876 case OPC_BEQ:
2877 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2878 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2879 regnames[rs], regnames[rt], btgt);
2880 goto not_likely;
2881 case OPC_BEQL:
2882 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2883 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2884 regnames[rs], regnames[rt], btgt);
2885 goto likely;
2886 case OPC_BNE:
2887 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2888 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2889 regnames[rs], regnames[rt], btgt);
2890 goto not_likely;
2891 case OPC_BNEL:
2892 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2893 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2894 regnames[rs], regnames[rt], btgt);
2895 goto likely;
2896 case OPC_BGEZ:
2897 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2898 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2899 goto not_likely;
2900 case OPC_BGEZL:
2901 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2902 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2903 goto likely;
2904 case OPC_BGEZALS:
2905 case OPC_BGEZAL:
2906 ctx->hflags |= (opc == OPC_BGEZALS
2907 ? MIPS_HFLAG_BDS16
2908 : MIPS_HFLAG_BDS32);
2909 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2910 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2911 blink = 31;
2912 goto not_likely;
2913 case OPC_BGEZALL:
2914 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2915 blink = 31;
2916 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2917 goto likely;
2918 case OPC_BGTZ:
2919 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2920 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2921 goto not_likely;
2922 case OPC_BGTZL:
2923 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2924 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2925 goto likely;
2926 case OPC_BLEZ:
2927 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2928 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2929 goto not_likely;
2930 case OPC_BLEZL:
2931 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2932 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2933 goto likely;
2934 case OPC_BLTZ:
2935 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2936 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2937 goto not_likely;
2938 case OPC_BLTZL:
2939 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2940 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2941 goto likely;
2942 case OPC_BLTZALS:
2943 case OPC_BLTZAL:
2944 ctx->hflags |= (opc == OPC_BLTZALS
2945 ? MIPS_HFLAG_BDS16
2946 : MIPS_HFLAG_BDS32);
2947 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2948 blink = 31;
2949 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2950 not_likely:
2951 ctx->hflags |= MIPS_HFLAG_BC;
2952 break;
2953 case OPC_BLTZALL:
2954 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2955 blink = 31;
2956 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2957 likely:
2958 ctx->hflags |= MIPS_HFLAG_BL;
2959 break;
2960 default:
2961 MIPS_INVAL("conditional branch/jump");
2962 generate_exception(ctx, EXCP_RI);
2963 goto out;
2966 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2967 blink, ctx->hflags, btgt);
2969 ctx->btarget = btgt;
2970 if (blink > 0) {
2971 int post_delay = insn_bytes;
2972 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2974 if (opc != OPC_JALRC)
2975 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2977 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2980 out:
2981 if (insn_bytes == 2)
2982 ctx->hflags |= MIPS_HFLAG_B16;
2983 tcg_temp_free(t0);
2984 tcg_temp_free(t1);
2987 /* special3 bitfield operations */
2988 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2989 int rs, int lsb, int msb)
2991 TCGv t0 = tcg_temp_new();
2992 TCGv t1 = tcg_temp_new();
2993 target_ulong mask;
2995 gen_load_gpr(t1, rs);
2996 switch (opc) {
2997 case OPC_EXT:
2998 if (lsb + msb > 31)
2999 goto fail;
3000 tcg_gen_shri_tl(t0, t1, lsb);
3001 if (msb != 31) {
3002 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3003 } else {
3004 tcg_gen_ext32s_tl(t0, t0);
3006 break;
3007 #if defined(TARGET_MIPS64)
3008 case OPC_DEXTM:
3009 tcg_gen_shri_tl(t0, t1, lsb);
3010 if (msb != 31) {
3011 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3013 break;
3014 case OPC_DEXTU:
3015 tcg_gen_shri_tl(t0, t1, lsb + 32);
3016 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3017 break;
3018 case OPC_DEXT:
3019 tcg_gen_shri_tl(t0, t1, lsb);
3020 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3021 break;
3022 #endif
3023 case OPC_INS:
3024 if (lsb > msb)
3025 goto fail;
3026 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3027 gen_load_gpr(t0, rt);
3028 tcg_gen_andi_tl(t0, t0, ~mask);
3029 tcg_gen_shli_tl(t1, t1, lsb);
3030 tcg_gen_andi_tl(t1, t1, mask);
3031 tcg_gen_or_tl(t0, t0, t1);
3032 tcg_gen_ext32s_tl(t0, t0);
3033 break;
3034 #if defined(TARGET_MIPS64)
3035 case OPC_DINSM:
3036 if (lsb > msb)
3037 goto fail;
3038 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3039 gen_load_gpr(t0, rt);
3040 tcg_gen_andi_tl(t0, t0, ~mask);
3041 tcg_gen_shli_tl(t1, t1, lsb);
3042 tcg_gen_andi_tl(t1, t1, mask);
3043 tcg_gen_or_tl(t0, t0, t1);
3044 break;
3045 case OPC_DINSU:
3046 if (lsb > msb)
3047 goto fail;
3048 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3049 gen_load_gpr(t0, rt);
3050 tcg_gen_andi_tl(t0, t0, ~mask);
3051 tcg_gen_shli_tl(t1, t1, lsb + 32);
3052 tcg_gen_andi_tl(t1, t1, mask);
3053 tcg_gen_or_tl(t0, t0, t1);
3054 break;
3055 case OPC_DINS:
3056 if (lsb > msb)
3057 goto fail;
3058 gen_load_gpr(t0, rt);
3059 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3060 gen_load_gpr(t0, rt);
3061 tcg_gen_andi_tl(t0, t0, ~mask);
3062 tcg_gen_shli_tl(t1, t1, lsb);
3063 tcg_gen_andi_tl(t1, t1, mask);
3064 tcg_gen_or_tl(t0, t0, t1);
3065 break;
3066 #endif
3067 default:
3068 fail:
3069 MIPS_INVAL("bitops");
3070 generate_exception(ctx, EXCP_RI);
3071 tcg_temp_free(t0);
3072 tcg_temp_free(t1);
3073 return;
3075 gen_store_gpr(t0, rt);
3076 tcg_temp_free(t0);
3077 tcg_temp_free(t1);
3080 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3082 TCGv t0;
3084 if (rd == 0) {
3085 /* If no destination, treat it as a NOP. */
3086 MIPS_DEBUG("NOP");
3087 return;
3090 t0 = tcg_temp_new();
3091 gen_load_gpr(t0, rt);
3092 switch (op2) {
3093 case OPC_WSBH:
3095 TCGv t1 = tcg_temp_new();
3097 tcg_gen_shri_tl(t1, t0, 8);
3098 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3099 tcg_gen_shli_tl(t0, t0, 8);
3100 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3101 tcg_gen_or_tl(t0, t0, t1);
3102 tcg_temp_free(t1);
3103 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3105 break;
3106 case OPC_SEB:
3107 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3108 break;
3109 case OPC_SEH:
3110 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3111 break;
3112 #if defined(TARGET_MIPS64)
3113 case OPC_DSBH:
3115 TCGv t1 = tcg_temp_new();
3117 tcg_gen_shri_tl(t1, t0, 8);
3118 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
3119 tcg_gen_shli_tl(t0, t0, 8);
3120 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
3121 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3122 tcg_temp_free(t1);
3124 break;
3125 case OPC_DSHD:
3127 TCGv t1 = tcg_temp_new();
3129 tcg_gen_shri_tl(t1, t0, 16);
3130 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
3131 tcg_gen_shli_tl(t0, t0, 16);
3132 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
3133 tcg_gen_or_tl(t0, t0, t1);
3134 tcg_gen_shri_tl(t1, t0, 32);
3135 tcg_gen_shli_tl(t0, t0, 32);
3136 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3137 tcg_temp_free(t1);
3139 break;
3140 #endif
3141 default:
3142 MIPS_INVAL("bsfhl");
3143 generate_exception(ctx, EXCP_RI);
3144 tcg_temp_free(t0);
3145 return;
3147 tcg_temp_free(t0);
3150 #ifndef CONFIG_USER_ONLY
3151 /* CP0 (MMU and control) */
3152 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
3154 TCGv_i32 t0 = tcg_temp_new_i32();
3156 tcg_gen_ld_i32(t0, cpu_env, off);
3157 tcg_gen_ext_i32_tl(arg, t0);
3158 tcg_temp_free_i32(t0);
3161 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
3163 tcg_gen_ld_tl(arg, cpu_env, off);
3164 tcg_gen_ext32s_tl(arg, arg);
3167 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
3169 TCGv_i32 t0 = tcg_temp_new_i32();
3171 tcg_gen_trunc_tl_i32(t0, arg);
3172 tcg_gen_st_i32(t0, cpu_env, off);
3173 tcg_temp_free_i32(t0);
3176 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
3178 tcg_gen_ext32s_tl(arg, arg);
3179 tcg_gen_st_tl(arg, cpu_env, off);
3182 static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3184 const char *rn = "invalid";
3186 if (sel != 0)
3187 check_insn(env, ctx, ISA_MIPS32);
3189 switch (reg) {
3190 case 0:
3191 switch (sel) {
3192 case 0:
3193 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
3194 rn = "Index";
3195 break;
3196 case 1:
3197 check_insn(env, ctx, ASE_MT);
3198 gen_helper_mfc0_mvpcontrol(arg);
3199 rn = "MVPControl";
3200 break;
3201 case 2:
3202 check_insn(env, ctx, ASE_MT);
3203 gen_helper_mfc0_mvpconf0(arg);
3204 rn = "MVPConf0";
3205 break;
3206 case 3:
3207 check_insn(env, ctx, ASE_MT);
3208 gen_helper_mfc0_mvpconf1(arg);
3209 rn = "MVPConf1";
3210 break;
3211 default:
3212 goto die;
3214 break;
3215 case 1:
3216 switch (sel) {
3217 case 0:
3218 gen_helper_mfc0_random(arg);
3219 rn = "Random";
3220 break;
3221 case 1:
3222 check_insn(env, ctx, ASE_MT);
3223 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
3224 rn = "VPEControl";
3225 break;
3226 case 2:
3227 check_insn(env, ctx, ASE_MT);
3228 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
3229 rn = "VPEConf0";
3230 break;
3231 case 3:
3232 check_insn(env, ctx, ASE_MT);
3233 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
3234 rn = "VPEConf1";
3235 break;
3236 case 4:
3237 check_insn(env, ctx, ASE_MT);
3238 gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
3239 rn = "YQMask";
3240 break;
3241 case 5:
3242 check_insn(env, ctx, ASE_MT);
3243 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
3244 rn = "VPESchedule";
3245 break;
3246 case 6:
3247 check_insn(env, ctx, ASE_MT);
3248 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3249 rn = "VPEScheFBack";
3250 break;
3251 case 7:
3252 check_insn(env, ctx, ASE_MT);
3253 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
3254 rn = "VPEOpt";
3255 break;
3256 default:
3257 goto die;
3259 break;
3260 case 2:
3261 switch (sel) {
3262 case 0:
3263 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
3264 tcg_gen_ext32s_tl(arg, arg);
3265 rn = "EntryLo0";
3266 break;
3267 case 1:
3268 check_insn(env, ctx, ASE_MT);
3269 gen_helper_mfc0_tcstatus(arg);
3270 rn = "TCStatus";
3271 break;
3272 case 2:
3273 check_insn(env, ctx, ASE_MT);
3274 gen_helper_mfc0_tcbind(arg);
3275 rn = "TCBind";
3276 break;
3277 case 3:
3278 check_insn(env, ctx, ASE_MT);
3279 gen_helper_mfc0_tcrestart(arg);
3280 rn = "TCRestart";
3281 break;
3282 case 4:
3283 check_insn(env, ctx, ASE_MT);
3284 gen_helper_mfc0_tchalt(arg);
3285 rn = "TCHalt";
3286 break;
3287 case 5:
3288 check_insn(env, ctx, ASE_MT);
3289 gen_helper_mfc0_tccontext(arg);
3290 rn = "TCContext";
3291 break;
3292 case 6:
3293 check_insn(env, ctx, ASE_MT);
3294 gen_helper_mfc0_tcschedule(arg);
3295 rn = "TCSchedule";
3296 break;
3297 case 7:
3298 check_insn(env, ctx, ASE_MT);
3299 gen_helper_mfc0_tcschefback(arg);
3300 rn = "TCScheFBack";
3301 break;
3302 default:
3303 goto die;
3305 break;
3306 case 3:
3307 switch (sel) {
3308 case 0:
3309 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3310 tcg_gen_ext32s_tl(arg, arg);
3311 rn = "EntryLo1";
3312 break;
3313 default:
3314 goto die;
3316 break;
3317 case 4:
3318 switch (sel) {
3319 case 0:
3320 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3321 tcg_gen_ext32s_tl(arg, arg);
3322 rn = "Context";
3323 break;
3324 case 1:
3325 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3326 rn = "ContextConfig";
3327 // break;
3328 default:
3329 goto die;
3331 break;
3332 case 5:
3333 switch (sel) {
3334 case 0:
3335 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3336 rn = "PageMask";
3337 break;
3338 case 1:
3339 check_insn(env, ctx, ISA_MIPS32R2);
3340 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3341 rn = "PageGrain";
3342 break;
3343 default:
3344 goto die;
3346 break;
3347 case 6:
3348 switch (sel) {
3349 case 0:
3350 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3351 rn = "Wired";
3352 break;
3353 case 1:
3354 check_insn(env, ctx, ISA_MIPS32R2);
3355 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3356 rn = "SRSConf0";
3357 break;
3358 case 2:
3359 check_insn(env, ctx, ISA_MIPS32R2);
3360 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3361 rn = "SRSConf1";
3362 break;
3363 case 3:
3364 check_insn(env, ctx, ISA_MIPS32R2);
3365 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3366 rn = "SRSConf2";
3367 break;
3368 case 4:
3369 check_insn(env, ctx, ISA_MIPS32R2);
3370 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3371 rn = "SRSConf3";
3372 break;
3373 case 5:
3374 check_insn(env, ctx, ISA_MIPS32R2);
3375 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3376 rn = "SRSConf4";
3377 break;
3378 default:
3379 goto die;
3381 break;
3382 case 7:
3383 switch (sel) {
3384 case 0:
3385 check_insn(env, ctx, ISA_MIPS32R2);
3386 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3387 rn = "HWREna";
3388 break;
3389 default:
3390 goto die;
3392 break;
3393 case 8:
3394 switch (sel) {
3395 case 0:
3396 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3397 tcg_gen_ext32s_tl(arg, arg);
3398 rn = "BadVAddr";
3399 break;
3400 default:
3401 goto die;
3403 break;
3404 case 9:
3405 switch (sel) {
3406 case 0:
3407 /* Mark as an IO operation because we read the time. */
3408 if (use_icount)
3409 gen_io_start();
3410 gen_helper_mfc0_count(arg);
3411 if (use_icount) {
3412 gen_io_end();
3414 /* Break the TB to be able to take timer interrupts immediately
3415 after reading count. */
3416 ctx->bstate = BS_STOP;
3417 rn = "Count";
3418 break;
3419 /* 6,7 are implementation dependent */
3420 default:
3421 goto die;
3423 break;
3424 case 10:
3425 switch (sel) {
3426 case 0:
3427 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3428 tcg_gen_ext32s_tl(arg, arg);
3429 rn = "EntryHi";
3430 break;
3431 default:
3432 goto die;
3434 break;
3435 case 11:
3436 switch (sel) {
3437 case 0:
3438 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3439 rn = "Compare";
3440 break;
3441 /* 6,7 are implementation dependent */
3442 default:
3443 goto die;
3445 break;
3446 case 12:
3447 switch (sel) {
3448 case 0:
3449 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3450 rn = "Status";
3451 break;
3452 case 1:
3453 check_insn(env, ctx, ISA_MIPS32R2);
3454 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3455 rn = "IntCtl";
3456 break;
3457 case 2:
3458 check_insn(env, ctx, ISA_MIPS32R2);
3459 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3460 rn = "SRSCtl";
3461 break;
3462 case 3:
3463 check_insn(env, ctx, ISA_MIPS32R2);
3464 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3465 rn = "SRSMap";
3466 break;
3467 default:
3468 goto die;
3470 break;
3471 case 13:
3472 switch (sel) {
3473 case 0:
3474 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3475 rn = "Cause";
3476 break;
3477 default:
3478 goto die;
3480 break;
3481 case 14:
3482 switch (sel) {
3483 case 0:
3484 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3485 tcg_gen_ext32s_tl(arg, arg);
3486 rn = "EPC";
3487 break;
3488 default:
3489 goto die;
3491 break;
3492 case 15:
3493 switch (sel) {
3494 case 0:
3495 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3496 rn = "PRid";
3497 break;
3498 case 1:
3499 check_insn(env, ctx, ISA_MIPS32R2);
3500 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3501 rn = "EBase";
3502 break;
3503 default:
3504 goto die;
3506 break;
3507 case 16:
3508 switch (sel) {
3509 case 0:
3510 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3511 rn = "Config";
3512 break;
3513 case 1:
3514 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3515 rn = "Config1";
3516 break;
3517 case 2:
3518 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3519 rn = "Config2";
3520 break;
3521 case 3:
3522 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3523 rn = "Config3";
3524 break;
3525 /* 4,5 are reserved */
3526 /* 6,7 are implementation dependent */
3527 case 6:
3528 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3529 rn = "Config6";
3530 break;
3531 case 7:
3532 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3533 rn = "Config7";
3534 break;
3535 default:
3536 goto die;
3538 break;
3539 case 17:
3540 switch (sel) {
3541 case 0:
3542 gen_helper_mfc0_lladdr(arg);
3543 rn = "LLAddr";
3544 break;
3545 default:
3546 goto die;
3548 break;
3549 case 18:
3550 switch (sel) {
3551 case 0 ... 7:
3552 gen_helper_1i(mfc0_watchlo, arg, sel);
3553 rn = "WatchLo";
3554 break;
3555 default:
3556 goto die;
3558 break;
3559 case 19:
3560 switch (sel) {
3561 case 0 ...7:
3562 gen_helper_1i(mfc0_watchhi, arg, sel);
3563 rn = "WatchHi";
3564 break;
3565 default:
3566 goto die;
3568 break;
3569 case 20:
3570 switch (sel) {
3571 case 0:
3572 #if defined(TARGET_MIPS64)
3573 check_insn(env, ctx, ISA_MIPS3);
3574 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3575 tcg_gen_ext32s_tl(arg, arg);
3576 rn = "XContext";
3577 break;
3578 #endif
3579 default:
3580 goto die;
3582 break;
3583 case 21:
3584 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3585 switch (sel) {
3586 case 0:
3587 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3588 rn = "Framemask";
3589 break;
3590 default:
3591 goto die;
3593 break;
3594 case 22:
3595 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3596 rn = "'Diagnostic"; /* implementation dependent */
3597 break;
3598 case 23:
3599 switch (sel) {
3600 case 0:
3601 gen_helper_mfc0_debug(arg); /* EJTAG support */
3602 rn = "Debug";
3603 break;
3604 case 1:
3605 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3606 rn = "TraceControl";
3607 // break;
3608 case 2:
3609 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3610 rn = "TraceControl2";
3611 // break;
3612 case 3:
3613 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3614 rn = "UserTraceData";
3615 // break;
3616 case 4:
3617 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3618 rn = "TraceBPC";
3619 // break;
3620 default:
3621 goto die;
3623 break;
3624 case 24:
3625 switch (sel) {
3626 case 0:
3627 /* EJTAG support */
3628 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3629 tcg_gen_ext32s_tl(arg, arg);
3630 rn = "DEPC";
3631 break;
3632 default:
3633 goto die;
3635 break;
3636 case 25:
3637 switch (sel) {
3638 case 0:
3639 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3640 rn = "Performance0";
3641 break;
3642 case 1:
3643 // gen_helper_mfc0_performance1(arg);
3644 rn = "Performance1";
3645 // break;
3646 case 2:
3647 // gen_helper_mfc0_performance2(arg);
3648 rn = "Performance2";
3649 // break;
3650 case 3:
3651 // gen_helper_mfc0_performance3(arg);
3652 rn = "Performance3";
3653 // break;
3654 case 4:
3655 // gen_helper_mfc0_performance4(arg);
3656 rn = "Performance4";
3657 // break;
3658 case 5:
3659 // gen_helper_mfc0_performance5(arg);
3660 rn = "Performance5";
3661 // break;
3662 case 6:
3663 // gen_helper_mfc0_performance6(arg);
3664 rn = "Performance6";
3665 // break;
3666 case 7:
3667 // gen_helper_mfc0_performance7(arg);
3668 rn = "Performance7";
3669 // break;
3670 default:
3671 goto die;
3673 break;
3674 case 26:
3675 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3676 rn = "ECC";
3677 break;
3678 case 27:
3679 switch (sel) {
3680 case 0 ... 3:
3681 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3682 rn = "CacheErr";
3683 break;
3684 default:
3685 goto die;
3687 break;
3688 case 28:
3689 switch (sel) {
3690 case 0:
3691 case 2:
3692 case 4:
3693 case 6:
3694 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3695 rn = "TagLo";
3696 break;
3697 case 1:
3698 case 3:
3699 case 5:
3700 case 7:
3701 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3702 rn = "DataLo";
3703 break;
3704 default:
3705 goto die;
3707 break;
3708 case 29:
3709 switch (sel) {
3710 case 0:
3711 case 2:
3712 case 4:
3713 case 6:
3714 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3715 rn = "TagHi";
3716 break;
3717 case 1:
3718 case 3:
3719 case 5:
3720 case 7:
3721 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3722 rn = "DataHi";
3723 break;
3724 default:
3725 goto die;
3727 break;
3728 case 30:
3729 switch (sel) {
3730 case 0:
3731 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3732 tcg_gen_ext32s_tl(arg, arg);
3733 rn = "ErrorEPC";
3734 break;
3735 default:
3736 goto die;
3738 break;
3739 case 31:
3740 switch (sel) {
3741 case 0:
3742 /* EJTAG support */
3743 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3744 rn = "DESAVE";
3745 break;
3746 default:
3747 goto die;
3749 break;
3750 default:
3751 goto die;
3753 (void)rn; /* avoid a compiler warning */
3754 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3755 return;
3757 die:
3758 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3759 generate_exception(ctx, EXCP_RI);
3762 static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3764 const char *rn = "invalid";
3766 if (sel != 0)
3767 check_insn(env, ctx, ISA_MIPS32);
3769 if (use_icount)
3770 gen_io_start();
3772 switch (reg) {
3773 case 0:
3774 switch (sel) {
3775 case 0:
3776 gen_helper_mtc0_index(arg);
3777 rn = "Index";
3778 break;
3779 case 1:
3780 check_insn(env, ctx, ASE_MT);
3781 gen_helper_mtc0_mvpcontrol(arg);
3782 rn = "MVPControl";
3783 break;
3784 case 2:
3785 check_insn(env, ctx, ASE_MT);
3786 /* ignored */
3787 rn = "MVPConf0";
3788 break;
3789 case 3:
3790 check_insn(env, ctx, ASE_MT);
3791 /* ignored */
3792 rn = "MVPConf1";
3793 break;
3794 default:
3795 goto die;
3797 break;
3798 case 1:
3799 switch (sel) {
3800 case 0:
3801 /* ignored */
3802 rn = "Random";
3803 break;
3804 case 1:
3805 check_insn(env, ctx, ASE_MT);
3806 gen_helper_mtc0_vpecontrol(arg);
3807 rn = "VPEControl";
3808 break;
3809 case 2:
3810 check_insn(env, ctx, ASE_MT);
3811 gen_helper_mtc0_vpeconf0(arg);
3812 rn = "VPEConf0";
3813 break;
3814 case 3:
3815 check_insn(env, ctx, ASE_MT);
3816 gen_helper_mtc0_vpeconf1(arg);
3817 rn = "VPEConf1";
3818 break;
3819 case 4:
3820 check_insn(env, ctx, ASE_MT);
3821 gen_helper_mtc0_yqmask(arg);
3822 rn = "YQMask";
3823 break;
3824 case 5:
3825 check_insn(env, ctx, ASE_MT);
3826 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3827 rn = "VPESchedule";
3828 break;
3829 case 6:
3830 check_insn(env, ctx, ASE_MT);
3831 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3832 rn = "VPEScheFBack";
3833 break;
3834 case 7:
3835 check_insn(env, ctx, ASE_MT);
3836 gen_helper_mtc0_vpeopt(arg);
3837 rn = "VPEOpt";
3838 break;
3839 default:
3840 goto die;
3842 break;
3843 case 2:
3844 switch (sel) {
3845 case 0:
3846 gen_helper_mtc0_entrylo0(arg);
3847 rn = "EntryLo0";
3848 break;
3849 case 1:
3850 check_insn(env, ctx, ASE_MT);
3851 gen_helper_mtc0_tcstatus(arg);
3852 rn = "TCStatus";
3853 break;
3854 case 2:
3855 check_insn(env, ctx, ASE_MT);
3856 gen_helper_mtc0_tcbind(arg);
3857 rn = "TCBind";
3858 break;
3859 case 3:
3860 check_insn(env, ctx, ASE_MT);
3861 gen_helper_mtc0_tcrestart(arg);
3862 rn = "TCRestart";
3863 break;
3864 case 4:
3865 check_insn(env, ctx, ASE_MT);
3866 gen_helper_mtc0_tchalt(arg);
3867 rn = "TCHalt";
3868 break;
3869 case 5:
3870 check_insn(env, ctx, ASE_MT);
3871 gen_helper_mtc0_tccontext(arg);
3872 rn = "TCContext";
3873 break;
3874 case 6:
3875 check_insn(env, ctx, ASE_MT);
3876 gen_helper_mtc0_tcschedule(arg);
3877 rn = "TCSchedule";
3878 break;
3879 case 7:
3880 check_insn(env, ctx, ASE_MT);
3881 gen_helper_mtc0_tcschefback(arg);
3882 rn = "TCScheFBack";
3883 break;
3884 default:
3885 goto die;
3887 break;
3888 case 3:
3889 switch (sel) {
3890 case 0:
3891 gen_helper_mtc0_entrylo1(arg);
3892 rn = "EntryLo1";
3893 break;
3894 default:
3895 goto die;
3897 break;
3898 case 4:
3899 switch (sel) {
3900 case 0:
3901 gen_helper_mtc0_context(arg);
3902 rn = "Context";
3903 break;
3904 case 1:
3905 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3906 rn = "ContextConfig";
3907 // break;
3908 default:
3909 goto die;
3911 break;
3912 case 5:
3913 switch (sel) {
3914 case 0:
3915 gen_helper_mtc0_pagemask(arg);
3916 rn = "PageMask";
3917 break;
3918 case 1:
3919 check_insn(env, ctx, ISA_MIPS32R2);
3920 gen_helper_mtc0_pagegrain(arg);
3921 rn = "PageGrain";
3922 break;
3923 default:
3924 goto die;
3926 break;
3927 case 6:
3928 switch (sel) {
3929 case 0:
3930 gen_helper_mtc0_wired(arg);
3931 rn = "Wired";
3932 break;
3933 case 1:
3934 check_insn(env, ctx, ISA_MIPS32R2);
3935 gen_helper_mtc0_srsconf0(arg);
3936 rn = "SRSConf0";
3937 break;
3938 case 2:
3939 check_insn(env, ctx, ISA_MIPS32R2);
3940 gen_helper_mtc0_srsconf1(arg);
3941 rn = "SRSConf1";
3942 break;
3943 case 3:
3944 check_insn(env, ctx, ISA_MIPS32R2);
3945 gen_helper_mtc0_srsconf2(arg);
3946 rn = "SRSConf2";
3947 break;
3948 case 4:
3949 check_insn(env, ctx, ISA_MIPS32R2);
3950 gen_helper_mtc0_srsconf3(arg);
3951 rn = "SRSConf3";
3952 break;
3953 case 5:
3954 check_insn(env, ctx, ISA_MIPS32R2);
3955 gen_helper_mtc0_srsconf4(arg);
3956 rn = "SRSConf4";
3957 break;
3958 default:
3959 goto die;
3961 break;
3962 case 7:
3963 switch (sel) {
3964 case 0:
3965 check_insn(env, ctx, ISA_MIPS32R2);
3966 gen_helper_mtc0_hwrena(arg);
3967 rn = "HWREna";
3968 break;
3969 default:
3970 goto die;
3972 break;
3973 case 8:
3974 /* ignored */
3975 rn = "BadVAddr";
3976 break;
3977 case 9:
3978 switch (sel) {
3979 case 0:
3980 gen_helper_mtc0_count(arg);
3981 rn = "Count";
3982 break;
3983 /* 6,7 are implementation dependent */
3984 default:
3985 goto die;
3987 break;
3988 case 10:
3989 switch (sel) {
3990 case 0:
3991 gen_helper_mtc0_entryhi(arg);
3992 rn = "EntryHi";
3993 break;
3994 default:
3995 goto die;
3997 break;
3998 case 11:
3999 switch (sel) {
4000 case 0:
4001 gen_helper_mtc0_compare(arg);
4002 rn = "Compare";
4003 break;
4004 /* 6,7 are implementation dependent */
4005 default:
4006 goto die;
4008 break;
4009 case 12:
4010 switch (sel) {
4011 case 0:
4012 save_cpu_state(ctx, 1);
4013 gen_helper_mtc0_status(arg);
4014 /* BS_STOP isn't good enough here, hflags may have changed. */
4015 gen_save_pc(ctx->pc + 4);
4016 ctx->bstate = BS_EXCP;
4017 rn = "Status";
4018 break;
4019 case 1:
4020 check_insn(env, ctx, ISA_MIPS32R2);
4021 gen_helper_mtc0_intctl(arg);
4022 /* Stop translation as we may have switched the execution mode */
4023 ctx->bstate = BS_STOP;
4024 rn = "IntCtl";
4025 break;
4026 case 2:
4027 check_insn(env, ctx, ISA_MIPS32R2);
4028 gen_helper_mtc0_srsctl(arg);
4029 /* Stop translation as we may have switched the execution mode */
4030 ctx->bstate = BS_STOP;
4031 rn = "SRSCtl";
4032 break;
4033 case 3:
4034 check_insn(env, ctx, ISA_MIPS32R2);
4035 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4036 /* Stop translation as we may have switched the execution mode */
4037 ctx->bstate = BS_STOP;
4038 rn = "SRSMap";
4039 break;
4040 default:
4041 goto die;
4043 break;
4044 case 13:
4045 switch (sel) {
4046 case 0:
4047 save_cpu_state(ctx, 1);
4048 gen_helper_mtc0_cause(arg);
4049 rn = "Cause";
4050 break;
4051 default:
4052 goto die;
4054 break;
4055 case 14:
4056 switch (sel) {
4057 case 0:
4058 gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
4059 rn = "EPC";
4060 break;
4061 default:
4062 goto die;
4064 break;
4065 case 15:
4066 switch (sel) {
4067 case 0:
4068 /* ignored */
4069 rn = "PRid";
4070 break;
4071 case 1:
4072 check_insn(env, ctx, ISA_MIPS32R2);
4073 gen_helper_mtc0_ebase(arg);
4074 rn = "EBase";
4075 break;
4076 default:
4077 goto die;
4079 break;
4080 case 16:
4081 switch (sel) {
4082 case 0:
4083 gen_helper_mtc0_config0(arg);
4084 rn = "Config";
4085 /* Stop translation as we may have switched the execution mode */
4086 ctx->bstate = BS_STOP;
4087 break;
4088 case 1:
4089 /* ignored, read only */
4090 rn = "Config1";
4091 break;
4092 case 2:
4093 gen_helper_mtc0_config2(arg);
4094 rn = "Config2";
4095 /* Stop translation as we may have switched the execution mode */
4096 ctx->bstate = BS_STOP;
4097 break;
4098 case 3:
4099 /* ignored, read only */
4100 rn = "Config3";
4101 break;
4102 /* 4,5 are reserved */
4103 /* 6,7 are implementation dependent */
4104 case 6:
4105 /* ignored */
4106 rn = "Config6";
4107 break;
4108 case 7:
4109 /* ignored */
4110 rn = "Config7";
4111 break;
4112 default:
4113 rn = "Invalid config selector";
4114 goto die;
4116 break;
4117 case 17:
4118 switch (sel) {
4119 case 0:
4120 gen_helper_mtc0_lladdr(arg);
4121 rn = "LLAddr";
4122 break;
4123 default:
4124 goto die;
4126 break;
4127 case 18:
4128 switch (sel) {
4129 case 0 ... 7:
4130 gen_helper_1i(mtc0_watchlo, arg, sel);
4131 rn = "WatchLo";
4132 break;
4133 default:
4134 goto die;
4136 break;
4137 case 19:
4138 switch (sel) {
4139 case 0 ... 7:
4140 gen_helper_1i(mtc0_watchhi, arg, sel);
4141 rn = "WatchHi";
4142 break;
4143 default:
4144 goto die;
4146 break;
4147 case 20:
4148 switch (sel) {
4149 case 0:
4150 #if defined(TARGET_MIPS64)
4151 check_insn(env, ctx, ISA_MIPS3);
4152 gen_helper_mtc0_xcontext(arg);
4153 rn = "XContext";
4154 break;
4155 #endif
4156 default:
4157 goto die;
4159 break;
4160 case 21:
4161 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4162 switch (sel) {
4163 case 0:
4164 gen_helper_mtc0_framemask(arg);
4165 rn = "Framemask";
4166 break;
4167 default:
4168 goto die;
4170 break;
4171 case 22:
4172 /* ignored */
4173 rn = "Diagnostic"; /* implementation dependent */
4174 break;
4175 case 23:
4176 switch (sel) {
4177 case 0:
4178 gen_helper_mtc0_debug(arg); /* EJTAG support */
4179 /* BS_STOP isn't good enough here, hflags may have changed. */
4180 gen_save_pc(ctx->pc + 4);
4181 ctx->bstate = BS_EXCP;
4182 rn = "Debug";
4183 break;
4184 case 1:
4185 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
4186 rn = "TraceControl";
4187 /* Stop translation as we may have switched the execution mode */
4188 ctx->bstate = BS_STOP;
4189 // break;
4190 case 2:
4191 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
4192 rn = "TraceControl2";
4193 /* Stop translation as we may have switched the execution mode */
4194 ctx->bstate = BS_STOP;
4195 // break;
4196 case 3:
4197 /* Stop translation as we may have switched the execution mode */
4198 ctx->bstate = BS_STOP;
4199 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
4200 rn = "UserTraceData";
4201 /* Stop translation as we may have switched the execution mode */
4202 ctx->bstate = BS_STOP;
4203 // break;
4204 case 4:
4205 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
4206 /* Stop translation as we may have switched the execution mode */
4207 ctx->bstate = BS_STOP;
4208 rn = "TraceBPC";
4209 // break;
4210 default:
4211 goto die;
4213 break;
4214 case 24:
4215 switch (sel) {
4216 case 0:
4217 /* EJTAG support */
4218 gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
4219 rn = "DEPC";
4220 break;
4221 default:
4222 goto die;
4224 break;
4225 case 25:
4226 switch (sel) {
4227 case 0:
4228 gen_helper_mtc0_performance0(arg);
4229 rn = "Performance0";
4230 break;
4231 case 1:
4232 // gen_helper_mtc0_performance1(arg);
4233 rn = "Performance1";
4234 // break;
4235 case 2:
4236 // gen_helper_mtc0_performance2(arg);
4237 rn = "Performance2";
4238 // break;
4239 case 3:
4240 // gen_helper_mtc0_performance3(arg);
4241 rn = "Performance3";
4242 // break;
4243 case 4:
4244 // gen_helper_mtc0_performance4(arg);
4245 rn = "Performance4";
4246 // break;
4247 case 5:
4248 // gen_helper_mtc0_performance5(arg);
4249 rn = "Performance5";
4250 // break;
4251 case 6:
4252 // gen_helper_mtc0_performance6(arg);
4253 rn = "Performance6";
4254 // break;
4255 case 7:
4256 // gen_helper_mtc0_performance7(arg);
4257 rn = "Performance7";
4258 // break;
4259 default:
4260 goto die;
4262 break;
4263 case 26:
4264 /* ignored */
4265 rn = "ECC";
4266 break;
4267 case 27:
4268 switch (sel) {
4269 case 0 ... 3:
4270 /* ignored */
4271 rn = "CacheErr";
4272 break;
4273 default:
4274 goto die;
4276 break;
4277 case 28:
4278 switch (sel) {
4279 case 0:
4280 case 2:
4281 case 4:
4282 case 6:
4283 gen_helper_mtc0_taglo(arg);
4284 rn = "TagLo";
4285 break;
4286 case 1:
4287 case 3:
4288 case 5:
4289 case 7:
4290 gen_helper_mtc0_datalo(arg);
4291 rn = "DataLo";
4292 break;
4293 default:
4294 goto die;
4296 break;
4297 case 29:
4298 switch (sel) {
4299 case 0:
4300 case 2:
4301 case 4:
4302 case 6:
4303 gen_helper_mtc0_taghi(arg);
4304 rn = "TagHi";
4305 break;
4306 case 1:
4307 case 3:
4308 case 5:
4309 case 7:
4310 gen_helper_mtc0_datahi(arg);
4311 rn = "DataHi";
4312 break;
4313 default:
4314 rn = "invalid sel";
4315 goto die;
4317 break;
4318 case 30:
4319 switch (sel) {
4320 case 0:
4321 gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4322 rn = "ErrorEPC";
4323 break;
4324 default:
4325 goto die;
4327 break;
4328 case 31:
4329 switch (sel) {
4330 case 0:
4331 /* EJTAG support */
4332 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4333 rn = "DESAVE";
4334 break;
4335 default:
4336 goto die;
4338 /* Stop translation as we may have switched the execution mode */
4339 ctx->bstate = BS_STOP;
4340 break;
4341 default:
4342 goto die;
4344 (void)rn; /* avoid a compiler warning */
4345 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4346 /* For simplicity assume that all writes can cause interrupts. */
4347 if (use_icount) {
4348 gen_io_end();
4349 ctx->bstate = BS_STOP;
4351 return;
4353 die:
4354 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4355 generate_exception(ctx, EXCP_RI);
4358 #if defined(TARGET_MIPS64)
4359 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4361 const char *rn = "invalid";
4363 if (sel != 0)
4364 check_insn(env, ctx, ISA_MIPS64);
4366 switch (reg) {
4367 case 0:
4368 switch (sel) {
4369 case 0:
4370 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4371 rn = "Index";
4372 break;
4373 case 1:
4374 check_insn(env, ctx, ASE_MT);
4375 gen_helper_mfc0_mvpcontrol(arg);
4376 rn = "MVPControl";
4377 break;
4378 case 2:
4379 check_insn(env, ctx, ASE_MT);
4380 gen_helper_mfc0_mvpconf0(arg);
4381 rn = "MVPConf0";
4382 break;
4383 case 3:
4384 check_insn(env, ctx, ASE_MT);
4385 gen_helper_mfc0_mvpconf1(arg);
4386 rn = "MVPConf1";
4387 break;
4388 default:
4389 goto die;
4391 break;
4392 case 1:
4393 switch (sel) {
4394 case 0:
4395 gen_helper_mfc0_random(arg);
4396 rn = "Random";
4397 break;
4398 case 1:
4399 check_insn(env, ctx, ASE_MT);
4400 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4401 rn = "VPEControl";
4402 break;
4403 case 2:
4404 check_insn(env, ctx, ASE_MT);
4405 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4406 rn = "VPEConf0";
4407 break;
4408 case 3:
4409 check_insn(env, ctx, ASE_MT);
4410 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4411 rn = "VPEConf1";
4412 break;
4413 case 4:
4414 check_insn(env, ctx, ASE_MT);
4415 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4416 rn = "YQMask";
4417 break;
4418 case 5:
4419 check_insn(env, ctx, ASE_MT);
4420 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4421 rn = "VPESchedule";
4422 break;
4423 case 6:
4424 check_insn(env, ctx, ASE_MT);
4425 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4426 rn = "VPEScheFBack";
4427 break;
4428 case 7:
4429 check_insn(env, ctx, ASE_MT);
4430 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4431 rn = "VPEOpt";
4432 break;
4433 default:
4434 goto die;
4436 break;
4437 case 2:
4438 switch (sel) {
4439 case 0:
4440 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4441 rn = "EntryLo0";
4442 break;
4443 case 1:
4444 check_insn(env, ctx, ASE_MT);
4445 gen_helper_mfc0_tcstatus(arg);
4446 rn = "TCStatus";
4447 break;
4448 case 2:
4449 check_insn(env, ctx, ASE_MT);
4450 gen_helper_mfc0_tcbind(arg);
4451 rn = "TCBind";
4452 break;
4453 case 3:
4454 check_insn(env, ctx, ASE_MT);
4455 gen_helper_dmfc0_tcrestart(arg);
4456 rn = "TCRestart";
4457 break;
4458 case 4:
4459 check_insn(env, ctx, ASE_MT);
4460 gen_helper_dmfc0_tchalt(arg);
4461 rn = "TCHalt";
4462 break;
4463 case 5:
4464 check_insn(env, ctx, ASE_MT);
4465 gen_helper_dmfc0_tccontext(arg);
4466 rn = "TCContext";
4467 break;
4468 case 6:
4469 check_insn(env, ctx, ASE_MT);
4470 gen_helper_dmfc0_tcschedule(arg);
4471 rn = "TCSchedule";
4472 break;
4473 case 7:
4474 check_insn(env, ctx, ASE_MT);
4475 gen_helper_dmfc0_tcschefback(arg);
4476 rn = "TCScheFBack";
4477 break;
4478 default:
4479 goto die;
4481 break;
4482 case 3:
4483 switch (sel) {
4484 case 0:
4485 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4486 rn = "EntryLo1";
4487 break;
4488 default:
4489 goto die;
4491 break;
4492 case 4:
4493 switch (sel) {
4494 case 0:
4495 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4496 rn = "Context";
4497 break;
4498 case 1:
4499 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4500 rn = "ContextConfig";
4501 // break;
4502 default:
4503 goto die;
4505 break;
4506 case 5:
4507 switch (sel) {
4508 case 0:
4509 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4510 rn = "PageMask";
4511 break;
4512 case 1:
4513 check_insn(env, ctx, ISA_MIPS32R2);
4514 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4515 rn = "PageGrain";
4516 break;
4517 default:
4518 goto die;
4520 break;
4521 case 6:
4522 switch (sel) {
4523 case 0:
4524 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4525 rn = "Wired";
4526 break;
4527 case 1:
4528 check_insn(env, ctx, ISA_MIPS32R2);
4529 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4530 rn = "SRSConf0";
4531 break;
4532 case 2:
4533 check_insn(env, ctx, ISA_MIPS32R2);
4534 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4535 rn = "SRSConf1";
4536 break;
4537 case 3:
4538 check_insn(env, ctx, ISA_MIPS32R2);
4539 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4540 rn = "SRSConf2";
4541 break;
4542 case 4:
4543 check_insn(env, ctx, ISA_MIPS32R2);
4544 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4545 rn = "SRSConf3";
4546 break;
4547 case 5:
4548 check_insn(env, ctx, ISA_MIPS32R2);
4549 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4550 rn = "SRSConf4";
4551 break;
4552 default:
4553 goto die;
4555 break;
4556 case 7:
4557 switch (sel) {
4558 case 0:
4559 check_insn(env, ctx, ISA_MIPS32R2);
4560 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4561 rn = "HWREna";
4562 break;
4563 default:
4564 goto die;
4566 break;
4567 case 8:
4568 switch (sel) {
4569 case 0:
4570 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4571 rn = "BadVAddr";
4572 break;
4573 default:
4574 goto die;
4576 break;
4577 case 9:
4578 switch (sel) {
4579 case 0:
4580 /* Mark as an IO operation because we read the time. */
4581 if (use_icount)
4582 gen_io_start();
4583 gen_helper_mfc0_count(arg);
4584 if (use_icount) {
4585 gen_io_end();
4587 /* Break the TB to be able to take timer interrupts immediately
4588 after reading count. */
4589 ctx->bstate = BS_STOP;
4590 rn = "Count";
4591 break;
4592 /* 6,7 are implementation dependent */
4593 default:
4594 goto die;
4596 break;
4597 case 10:
4598 switch (sel) {
4599 case 0:
4600 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4601 rn = "EntryHi";
4602 break;
4603 default:
4604 goto die;
4606 break;
4607 case 11:
4608 switch (sel) {
4609 case 0:
4610 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4611 rn = "Compare";
4612 break;
4613 /* 6,7 are implementation dependent */
4614 default:
4615 goto die;
4617 break;
4618 case 12:
4619 switch (sel) {
4620 case 0:
4621 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4622 rn = "Status";
4623 break;
4624 case 1:
4625 check_insn(env, ctx, ISA_MIPS32R2);
4626 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4627 rn = "IntCtl";
4628 break;
4629 case 2:
4630 check_insn(env, ctx, ISA_MIPS32R2);
4631 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4632 rn = "SRSCtl";
4633 break;
4634 case 3:
4635 check_insn(env, ctx, ISA_MIPS32R2);
4636 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4637 rn = "SRSMap";
4638 break;
4639 default:
4640 goto die;
4642 break;
4643 case 13:
4644 switch (sel) {
4645 case 0:
4646 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4647 rn = "Cause";
4648 break;
4649 default:
4650 goto die;
4652 break;
4653 case 14:
4654 switch (sel) {
4655 case 0:
4656 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4657 rn = "EPC";
4658 break;
4659 default:
4660 goto die;
4662 break;
4663 case 15:
4664 switch (sel) {
4665 case 0:
4666 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4667 rn = "PRid";
4668 break;
4669 case 1:
4670 check_insn(env, ctx, ISA_MIPS32R2);
4671 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4672 rn = "EBase";
4673 break;
4674 default:
4675 goto die;
4677 break;
4678 case 16:
4679 switch (sel) {
4680 case 0:
4681 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4682 rn = "Config";
4683 break;
4684 case 1:
4685 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4686 rn = "Config1";
4687 break;
4688 case 2:
4689 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4690 rn = "Config2";
4691 break;
4692 case 3:
4693 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4694 rn = "Config3";
4695 break;
4696 /* 6,7 are implementation dependent */
4697 case 6:
4698 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4699 rn = "Config6";
4700 break;
4701 case 7:
4702 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4703 rn = "Config7";
4704 break;
4705 default:
4706 goto die;
4708 break;
4709 case 17:
4710 switch (sel) {
4711 case 0:
4712 gen_helper_dmfc0_lladdr(arg);
4713 rn = "LLAddr";
4714 break;
4715 default:
4716 goto die;
4718 break;
4719 case 18:
4720 switch (sel) {
4721 case 0 ... 7:
4722 gen_helper_1i(dmfc0_watchlo, arg, sel);
4723 rn = "WatchLo";
4724 break;
4725 default:
4726 goto die;
4728 break;
4729 case 19:
4730 switch (sel) {
4731 case 0 ... 7:
4732 gen_helper_1i(mfc0_watchhi, arg, sel);
4733 rn = "WatchHi";
4734 break;
4735 default:
4736 goto die;
4738 break;
4739 case 20:
4740 switch (sel) {
4741 case 0:
4742 check_insn(env, ctx, ISA_MIPS3);
4743 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4744 rn = "XContext";
4745 break;
4746 default:
4747 goto die;
4749 break;
4750 case 21:
4751 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4752 switch (sel) {
4753 case 0:
4754 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4755 rn = "Framemask";
4756 break;
4757 default:
4758 goto die;
4760 break;
4761 case 22:
4762 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4763 rn = "'Diagnostic"; /* implementation dependent */
4764 break;
4765 case 23:
4766 switch (sel) {
4767 case 0:
4768 gen_helper_mfc0_debug(arg); /* EJTAG support */
4769 rn = "Debug";
4770 break;
4771 case 1:
4772 // gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4773 rn = "TraceControl";
4774 // break;
4775 case 2:
4776 // gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4777 rn = "TraceControl2";
4778 // break;
4779 case 3:
4780 // gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4781 rn = "UserTraceData";
4782 // break;
4783 case 4:
4784 // gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4785 rn = "TraceBPC";
4786 // break;
4787 default:
4788 goto die;
4790 break;
4791 case 24:
4792 switch (sel) {
4793 case 0:
4794 /* EJTAG support */
4795 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4796 rn = "DEPC";
4797 break;
4798 default:
4799 goto die;
4801 break;
4802 case 25:
4803 switch (sel) {
4804 case 0:
4805 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4806 rn = "Performance0";
4807 break;
4808 case 1:
4809 // gen_helper_dmfc0_performance1(arg);
4810 rn = "Performance1";
4811 // break;
4812 case 2:
4813 // gen_helper_dmfc0_performance2(arg);
4814 rn = "Performance2";
4815 // break;
4816 case 3:
4817 // gen_helper_dmfc0_performance3(arg);
4818 rn = "Performance3";
4819 // break;
4820 case 4:
4821 // gen_helper_dmfc0_performance4(arg);
4822 rn = "Performance4";
4823 // break;
4824 case 5:
4825 // gen_helper_dmfc0_performance5(arg);
4826 rn = "Performance5";
4827 // break;
4828 case 6:
4829 // gen_helper_dmfc0_performance6(arg);
4830 rn = "Performance6";
4831 // break;
4832 case 7:
4833 // gen_helper_dmfc0_performance7(arg);
4834 rn = "Performance7";
4835 // break;
4836 default:
4837 goto die;
4839 break;
4840 case 26:
4841 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4842 rn = "ECC";
4843 break;
4844 case 27:
4845 switch (sel) {
4846 /* ignored */
4847 case 0 ... 3:
4848 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4849 rn = "CacheErr";
4850 break;
4851 default:
4852 goto die;
4854 break;
4855 case 28:
4856 switch (sel) {
4857 case 0:
4858 case 2:
4859 case 4:
4860 case 6:
4861 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4862 rn = "TagLo";
4863 break;
4864 case 1:
4865 case 3:
4866 case 5:
4867 case 7:
4868 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4869 rn = "DataLo";
4870 break;
4871 default:
4872 goto die;
4874 break;
4875 case 29:
4876 switch (sel) {
4877 case 0:
4878 case 2:
4879 case 4:
4880 case 6:
4881 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4882 rn = "TagHi";
4883 break;
4884 case 1:
4885 case 3:
4886 case 5:
4887 case 7:
4888 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4889 rn = "DataHi";
4890 break;
4891 default:
4892 goto die;
4894 break;
4895 case 30:
4896 switch (sel) {
4897 case 0:
4898 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4899 rn = "ErrorEPC";
4900 break;
4901 default:
4902 goto die;
4904 break;
4905 case 31:
4906 switch (sel) {
4907 case 0:
4908 /* EJTAG support */
4909 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4910 rn = "DESAVE";
4911 break;
4912 default:
4913 goto die;
4915 break;
4916 default:
4917 goto die;
4919 (void)rn; /* avoid a compiler warning */
4920 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4921 return;
4923 die:
4924 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4925 generate_exception(ctx, EXCP_RI);
4928 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4930 const char *rn = "invalid";
4932 if (sel != 0)
4933 check_insn(env, ctx, ISA_MIPS64);
4935 if (use_icount)
4936 gen_io_start();
4938 switch (reg) {
4939 case 0:
4940 switch (sel) {
4941 case 0:
4942 gen_helper_mtc0_index(arg);
4943 rn = "Index";
4944 break;
4945 case 1:
4946 check_insn(env, ctx, ASE_MT);
4947 gen_helper_mtc0_mvpcontrol(arg);
4948 rn = "MVPControl";
4949 break;
4950 case 2:
4951 check_insn(env, ctx, ASE_MT);
4952 /* ignored */
4953 rn = "MVPConf0";
4954 break;
4955 case 3:
4956 check_insn(env, ctx, ASE_MT);
4957 /* ignored */
4958 rn = "MVPConf1";
4959 break;
4960 default:
4961 goto die;
4963 break;
4964 case 1:
4965 switch (sel) {
4966 case 0:
4967 /* ignored */
4968 rn = "Random";
4969 break;
4970 case 1:
4971 check_insn(env, ctx, ASE_MT);
4972 gen_helper_mtc0_vpecontrol(arg);
4973 rn = "VPEControl";
4974 break;
4975 case 2:
4976 check_insn(env, ctx, ASE_MT);
4977 gen_helper_mtc0_vpeconf0(arg);
4978 rn = "VPEConf0";
4979 break;
4980 case 3:
4981 check_insn(env, ctx, ASE_MT);
4982 gen_helper_mtc0_vpeconf1(arg);
4983 rn = "VPEConf1";
4984 break;
4985 case 4:
4986 check_insn(env, ctx, ASE_MT);
4987 gen_helper_mtc0_yqmask(arg);
4988 rn = "YQMask";
4989 break;
4990 case 5:
4991 check_insn(env, ctx, ASE_MT);
4992 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4993 rn = "VPESchedule";
4994 break;
4995 case 6:
4996 check_insn(env, ctx, ASE_MT);
4997 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4998 rn = "VPEScheFBack";
4999 break;
5000 case 7:
5001 check_insn(env, ctx, ASE_MT);
5002 gen_helper_mtc0_vpeopt(arg);
5003 rn = "VPEOpt";
5004 break;
5005 default:
5006 goto die;
5008 break;
5009 case 2:
5010 switch (sel) {
5011 case 0:
5012 gen_helper_mtc0_entrylo0(arg);
5013 rn = "EntryLo0";
5014 break;
5015 case 1:
5016 check_insn(env, ctx, ASE_MT);
5017 gen_helper_mtc0_tcstatus(arg);
5018 rn = "TCStatus";
5019 break;
5020 case 2:
5021 check_insn(env, ctx, ASE_MT);
5022 gen_helper_mtc0_tcbind(arg);
5023 rn = "TCBind";
5024 break;
5025 case 3:
5026 check_insn(env, ctx, ASE_MT);
5027 gen_helper_mtc0_tcrestart(arg);
5028 rn = "TCRestart";
5029 break;
5030 case 4:
5031 check_insn(env, ctx, ASE_MT);
5032 gen_helper_mtc0_tchalt(arg);
5033 rn = "TCHalt";
5034 break;
5035 case 5:
5036 check_insn(env, ctx, ASE_MT);
5037 gen_helper_mtc0_tccontext(arg);
5038 rn = "TCContext";
5039 break;
5040 case 6:
5041 check_insn(env, ctx, ASE_MT);
5042 gen_helper_mtc0_tcschedule(arg);
5043 rn = "TCSchedule";
5044 break;
5045 case 7:
5046 check_insn(env, ctx, ASE_MT);
5047 gen_helper_mtc0_tcschefback(arg);
5048 rn = "TCScheFBack";
5049 break;
5050 default:
5051 goto die;
5053 break;
5054 case 3:
5055 switch (sel) {
5056 case 0:
5057 gen_helper_mtc0_entrylo1(arg);
5058 rn = "EntryLo1";
5059 break;
5060 default:
5061 goto die;
5063 break;
5064 case 4:
5065 switch (sel) {
5066 case 0:
5067 gen_helper_mtc0_context(arg);
5068 rn = "Context";
5069 break;
5070 case 1:
5071 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
5072 rn = "ContextConfig";
5073 // break;
5074 default:
5075 goto die;
5077 break;
5078 case 5:
5079 switch (sel) {
5080 case 0:
5081 gen_helper_mtc0_pagemask(arg);
5082 rn = "PageMask";
5083 break;
5084 case 1:
5085 check_insn(env, ctx, ISA_MIPS32R2);
5086 gen_helper_mtc0_pagegrain(arg);
5087 rn = "PageGrain";
5088 break;
5089 default:
5090 goto die;
5092 break;
5093 case 6:
5094 switch (sel) {
5095 case 0:
5096 gen_helper_mtc0_wired(arg);
5097 rn = "Wired";
5098 break;
5099 case 1:
5100 check_insn(env, ctx, ISA_MIPS32R2);
5101 gen_helper_mtc0_srsconf0(arg);
5102 rn = "SRSConf0";
5103 break;
5104 case 2:
5105 check_insn(env, ctx, ISA_MIPS32R2);
5106 gen_helper_mtc0_srsconf1(arg);
5107 rn = "SRSConf1";
5108 break;
5109 case 3:
5110 check_insn(env, ctx, ISA_MIPS32R2);
5111 gen_helper_mtc0_srsconf2(arg);
5112 rn = "SRSConf2";
5113 break;
5114 case 4:
5115 check_insn(env, ctx, ISA_MIPS32R2);
5116 gen_helper_mtc0_srsconf3(arg);
5117 rn = "SRSConf3";
5118 break;
5119 case 5:
5120 check_insn(env, ctx, ISA_MIPS32R2);
5121 gen_helper_mtc0_srsconf4(arg);
5122 rn = "SRSConf4";
5123 break;
5124 default:
5125 goto die;
5127 break;
5128 case 7:
5129 switch (sel) {
5130 case 0:
5131 check_insn(env, ctx, ISA_MIPS32R2);
5132 gen_helper_mtc0_hwrena(arg);
5133 rn = "HWREna";
5134 break;
5135 default:
5136 goto die;
5138 break;
5139 case 8:
5140 /* ignored */
5141 rn = "BadVAddr";
5142 break;
5143 case 9:
5144 switch (sel) {
5145 case 0:
5146 gen_helper_mtc0_count(arg);
5147 rn = "Count";
5148 break;
5149 /* 6,7 are implementation dependent */
5150 default:
5151 goto die;
5153 /* Stop translation as we may have switched the execution mode */
5154 ctx->bstate = BS_STOP;
5155 break;
5156 case 10:
5157 switch (sel) {
5158 case 0:
5159 gen_helper_mtc0_entryhi(arg);
5160 rn = "EntryHi";
5161 break;
5162 default:
5163 goto die;
5165 break;
5166 case 11:
5167 switch (sel) {
5168 case 0:
5169 gen_helper_mtc0_compare(arg);
5170 rn = "Compare";
5171 break;
5172 /* 6,7 are implementation dependent */
5173 default:
5174 goto die;
5176 /* Stop translation as we may have switched the execution mode */
5177 ctx->bstate = BS_STOP;
5178 break;
5179 case 12:
5180 switch (sel) {
5181 case 0:
5182 save_cpu_state(ctx, 1);
5183 gen_helper_mtc0_status(arg);
5184 /* BS_STOP isn't good enough here, hflags may have changed. */
5185 gen_save_pc(ctx->pc + 4);
5186 ctx->bstate = BS_EXCP;
5187 rn = "Status";
5188 break;
5189 case 1:
5190 check_insn(env, ctx, ISA_MIPS32R2);
5191 gen_helper_mtc0_intctl(arg);
5192 /* Stop translation as we may have switched the execution mode */
5193 ctx->bstate = BS_STOP;
5194 rn = "IntCtl";
5195 break;
5196 case 2:
5197 check_insn(env, ctx, ISA_MIPS32R2);
5198 gen_helper_mtc0_srsctl(arg);
5199 /* Stop translation as we may have switched the execution mode */
5200 ctx->bstate = BS_STOP;
5201 rn = "SRSCtl";
5202 break;
5203 case 3:
5204 check_insn(env, ctx, ISA_MIPS32R2);
5205 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
5206 /* Stop translation as we may have switched the execution mode */
5207 ctx->bstate = BS_STOP;
5208 rn = "SRSMap";
5209 break;
5210 default:
5211 goto die;
5213 break;
5214 case 13:
5215 switch (sel) {
5216 case 0:
5217 save_cpu_state(ctx, 1);
5218 /* Mark as an IO operation because we may trigger a software
5219 interrupt. */
5220 if (use_icount) {
5221 gen_io_start();
5223 gen_helper_mtc0_cause(arg);
5224 if (use_icount) {
5225 gen_io_end();
5227 /* Stop translation as we may have triggered an intetrupt */
5228 ctx->bstate = BS_STOP;
5229 rn = "Cause";
5230 break;
5231 default:
5232 goto die;
5234 break;
5235 case 14:
5236 switch (sel) {
5237 case 0:
5238 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
5239 rn = "EPC";
5240 break;
5241 default:
5242 goto die;
5244 break;
5245 case 15:
5246 switch (sel) {
5247 case 0:
5248 /* ignored */
5249 rn = "PRid";
5250 break;
5251 case 1:
5252 check_insn(env, ctx, ISA_MIPS32R2);
5253 gen_helper_mtc0_ebase(arg);
5254 rn = "EBase";
5255 break;
5256 default:
5257 goto die;
5259 break;
5260 case 16:
5261 switch (sel) {
5262 case 0:
5263 gen_helper_mtc0_config0(arg);
5264 rn = "Config";
5265 /* Stop translation as we may have switched the execution mode */
5266 ctx->bstate = BS_STOP;
5267 break;
5268 case 1:
5269 /* ignored, read only */
5270 rn = "Config1";
5271 break;
5272 case 2:
5273 gen_helper_mtc0_config2(arg);
5274 rn = "Config2";
5275 /* Stop translation as we may have switched the execution mode */
5276 ctx->bstate = BS_STOP;
5277 break;
5278 case 3:
5279 /* ignored */
5280 rn = "Config3";
5281 break;
5282 /* 6,7 are implementation dependent */
5283 default:
5284 rn = "Invalid config selector";
5285 goto die;
5287 break;
5288 case 17:
5289 switch (sel) {
5290 case 0:
5291 gen_helper_mtc0_lladdr(arg);
5292 rn = "LLAddr";
5293 break;
5294 default:
5295 goto die;
5297 break;
5298 case 18:
5299 switch (sel) {
5300 case 0 ... 7:
5301 gen_helper_1i(mtc0_watchlo, arg, sel);
5302 rn = "WatchLo";
5303 break;
5304 default:
5305 goto die;
5307 break;
5308 case 19:
5309 switch (sel) {
5310 case 0 ... 7:
5311 gen_helper_1i(mtc0_watchhi, arg, sel);
5312 rn = "WatchHi";
5313 break;
5314 default:
5315 goto die;
5317 break;
5318 case 20:
5319 switch (sel) {
5320 case 0:
5321 check_insn(env, ctx, ISA_MIPS3);
5322 gen_helper_mtc0_xcontext(arg);
5323 rn = "XContext";
5324 break;
5325 default:
5326 goto die;
5328 break;
5329 case 21:
5330 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5331 switch (sel) {
5332 case 0:
5333 gen_helper_mtc0_framemask(arg);
5334 rn = "Framemask";
5335 break;
5336 default:
5337 goto die;
5339 break;
5340 case 22:
5341 /* ignored */
5342 rn = "Diagnostic"; /* implementation dependent */
5343 break;
5344 case 23:
5345 switch (sel) {
5346 case 0:
5347 gen_helper_mtc0_debug(arg); /* EJTAG support */
5348 /* BS_STOP isn't good enough here, hflags may have changed. */
5349 gen_save_pc(ctx->pc + 4);
5350 ctx->bstate = BS_EXCP;
5351 rn = "Debug";
5352 break;
5353 case 1:
5354 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5355 /* Stop translation as we may have switched the execution mode */
5356 ctx->bstate = BS_STOP;
5357 rn = "TraceControl";
5358 // break;
5359 case 2:
5360 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5361 /* Stop translation as we may have switched the execution mode */
5362 ctx->bstate = BS_STOP;
5363 rn = "TraceControl2";
5364 // break;
5365 case 3:
5366 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5367 /* Stop translation as we may have switched the execution mode */
5368 ctx->bstate = BS_STOP;
5369 rn = "UserTraceData";
5370 // break;
5371 case 4:
5372 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5373 /* Stop translation as we may have switched the execution mode */
5374 ctx->bstate = BS_STOP;
5375 rn = "TraceBPC";
5376 // break;
5377 default:
5378 goto die;
5380 break;
5381 case 24:
5382 switch (sel) {
5383 case 0:
5384 /* EJTAG support */
5385 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5386 rn = "DEPC";
5387 break;
5388 default:
5389 goto die;
5391 break;
5392 case 25:
5393 switch (sel) {
5394 case 0:
5395 gen_helper_mtc0_performance0(arg);
5396 rn = "Performance0";
5397 break;
5398 case 1:
5399 // gen_helper_mtc0_performance1(arg);
5400 rn = "Performance1";
5401 // break;
5402 case 2:
5403 // gen_helper_mtc0_performance2(arg);
5404 rn = "Performance2";
5405 // break;
5406 case 3:
5407 // gen_helper_mtc0_performance3(arg);
5408 rn = "Performance3";
5409 // break;
5410 case 4:
5411 // gen_helper_mtc0_performance4(arg);
5412 rn = "Performance4";
5413 // break;
5414 case 5:
5415 // gen_helper_mtc0_performance5(arg);
5416 rn = "Performance5";
5417 // break;
5418 case 6:
5419 // gen_helper_mtc0_performance6(arg);
5420 rn = "Performance6";
5421 // break;
5422 case 7:
5423 // gen_helper_mtc0_performance7(arg);
5424 rn = "Performance7";
5425 // break;
5426 default:
5427 goto die;
5429 break;
5430 case 26:
5431 /* ignored */
5432 rn = "ECC";
5433 break;
5434 case 27:
5435 switch (sel) {
5436 case 0 ... 3:
5437 /* ignored */
5438 rn = "CacheErr";
5439 break;
5440 default:
5441 goto die;
5443 break;
5444 case 28:
5445 switch (sel) {
5446 case 0:
5447 case 2:
5448 case 4:
5449 case 6:
5450 gen_helper_mtc0_taglo(arg);
5451 rn = "TagLo";
5452 break;
5453 case 1:
5454 case 3:
5455 case 5:
5456 case 7:
5457 gen_helper_mtc0_datalo(arg);
5458 rn = "DataLo";
5459 break;
5460 default:
5461 goto die;
5463 break;
5464 case 29:
5465 switch (sel) {
5466 case 0:
5467 case 2:
5468 case 4:
5469 case 6:
5470 gen_helper_mtc0_taghi(arg);
5471 rn = "TagHi";
5472 break;
5473 case 1:
5474 case 3:
5475 case 5:
5476 case 7:
5477 gen_helper_mtc0_datahi(arg);
5478 rn = "DataHi";
5479 break;
5480 default:
5481 rn = "invalid sel";
5482 goto die;
5484 break;
5485 case 30:
5486 switch (sel) {
5487 case 0:
5488 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5489 rn = "ErrorEPC";
5490 break;
5491 default:
5492 goto die;
5494 break;
5495 case 31:
5496 switch (sel) {
5497 case 0:
5498 /* EJTAG support */
5499 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5500 rn = "DESAVE";
5501 break;
5502 default:
5503 goto die;
5505 /* Stop translation as we may have switched the execution mode */
5506 ctx->bstate = BS_STOP;
5507 break;
5508 default:
5509 goto die;
5511 (void)rn; /* avoid a compiler warning */
5512 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5513 /* For simplicity assume that all writes can cause interrupts. */
5514 if (use_icount) {
5515 gen_io_end();
5516 ctx->bstate = BS_STOP;
5518 return;
5520 die:
5521 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5522 generate_exception(ctx, EXCP_RI);
5524 #endif /* TARGET_MIPS64 */
5526 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5527 int u, int sel, int h)
5529 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5530 TCGv t0 = tcg_temp_local_new();
5532 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5533 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5534 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5535 tcg_gen_movi_tl(t0, -1);
5536 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5537 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5538 tcg_gen_movi_tl(t0, -1);
5539 else if (u == 0) {
5540 switch (rt) {
5541 case 2:
5542 switch (sel) {
5543 case 1:
5544 gen_helper_mftc0_tcstatus(t0);
5545 break;
5546 case 2:
5547 gen_helper_mftc0_tcbind(t0);
5548 break;
5549 case 3:
5550 gen_helper_mftc0_tcrestart(t0);
5551 break;
5552 case 4:
5553 gen_helper_mftc0_tchalt(t0);
5554 break;
5555 case 5:
5556 gen_helper_mftc0_tccontext(t0);
5557 break;
5558 case 6:
5559 gen_helper_mftc0_tcschedule(t0);
5560 break;
5561 case 7:
5562 gen_helper_mftc0_tcschefback(t0);
5563 break;
5564 default:
5565 gen_mfc0(env, ctx, t0, rt, sel);
5566 break;
5568 break;
5569 case 10:
5570 switch (sel) {
5571 case 0:
5572 gen_helper_mftc0_entryhi(t0);
5573 break;
5574 default:
5575 gen_mfc0(env, ctx, t0, rt, sel);
5576 break;
5578 case 12:
5579 switch (sel) {
5580 case 0:
5581 gen_helper_mftc0_status(t0);
5582 break;
5583 default:
5584 gen_mfc0(env, ctx, t0, rt, sel);
5585 break;
5587 case 23:
5588 switch (sel) {
5589 case 0:
5590 gen_helper_mftc0_debug(t0);
5591 break;
5592 default:
5593 gen_mfc0(env, ctx, t0, rt, sel);
5594 break;
5596 break;
5597 default:
5598 gen_mfc0(env, ctx, t0, rt, sel);
5600 } else switch (sel) {
5601 /* GPR registers. */
5602 case 0:
5603 gen_helper_1i(mftgpr, t0, rt);
5604 break;
5605 /* Auxiliary CPU registers */
5606 case 1:
5607 switch (rt) {
5608 case 0:
5609 gen_helper_1i(mftlo, t0, 0);
5610 break;
5611 case 1:
5612 gen_helper_1i(mfthi, t0, 0);
5613 break;
5614 case 2:
5615 gen_helper_1i(mftacx, t0, 0);
5616 break;
5617 case 4:
5618 gen_helper_1i(mftlo, t0, 1);
5619 break;
5620 case 5:
5621 gen_helper_1i(mfthi, t0, 1);
5622 break;
5623 case 6:
5624 gen_helper_1i(mftacx, t0, 1);
5625 break;
5626 case 8:
5627 gen_helper_1i(mftlo, t0, 2);
5628 break;
5629 case 9:
5630 gen_helper_1i(mfthi, t0, 2);
5631 break;
5632 case 10:
5633 gen_helper_1i(mftacx, t0, 2);
5634 break;
5635 case 12:
5636 gen_helper_1i(mftlo, t0, 3);
5637 break;
5638 case 13:
5639 gen_helper_1i(mfthi, t0, 3);
5640 break;
5641 case 14:
5642 gen_helper_1i(mftacx, t0, 3);
5643 break;
5644 case 16:
5645 gen_helper_mftdsp(t0);
5646 break;
5647 default:
5648 goto die;
5650 break;
5651 /* Floating point (COP1). */
5652 case 2:
5653 /* XXX: For now we support only a single FPU context. */
5654 if (h == 0) {
5655 TCGv_i32 fp0 = tcg_temp_new_i32();
5657 gen_load_fpr32(fp0, rt);
5658 tcg_gen_ext_i32_tl(t0, fp0);
5659 tcg_temp_free_i32(fp0);
5660 } else {
5661 TCGv_i32 fp0 = tcg_temp_new_i32();
5663 gen_load_fpr32h(fp0, rt);
5664 tcg_gen_ext_i32_tl(t0, fp0);
5665 tcg_temp_free_i32(fp0);
5667 break;
5668 case 3:
5669 /* XXX: For now we support only a single FPU context. */
5670 gen_helper_1i(cfc1, t0, rt);
5671 break;
5672 /* COP2: Not implemented. */
5673 case 4:
5674 case 5:
5675 /* fall through */
5676 default:
5677 goto die;
5679 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5680 gen_store_gpr(t0, rd);
5681 tcg_temp_free(t0);
5682 return;
5684 die:
5685 tcg_temp_free(t0);
5686 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5687 generate_exception(ctx, EXCP_RI);
5690 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5691 int u, int sel, int h)
5693 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5694 TCGv t0 = tcg_temp_local_new();
5696 gen_load_gpr(t0, rt);
5697 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5698 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5699 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5700 /* NOP */ ;
5701 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5702 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5703 /* NOP */ ;
5704 else if (u == 0) {
5705 switch (rd) {
5706 case 2:
5707 switch (sel) {
5708 case 1:
5709 gen_helper_mttc0_tcstatus(t0);
5710 break;
5711 case 2:
5712 gen_helper_mttc0_tcbind(t0);
5713 break;
5714 case 3:
5715 gen_helper_mttc0_tcrestart(t0);
5716 break;
5717 case 4:
5718 gen_helper_mttc0_tchalt(t0);
5719 break;
5720 case 5:
5721 gen_helper_mttc0_tccontext(t0);
5722 break;
5723 case 6:
5724 gen_helper_mttc0_tcschedule(t0);
5725 break;
5726 case 7:
5727 gen_helper_mttc0_tcschefback(t0);
5728 break;
5729 default:
5730 gen_mtc0(env, ctx, t0, rd, sel);
5731 break;
5733 break;
5734 case 10:
5735 switch (sel) {
5736 case 0:
5737 gen_helper_mttc0_entryhi(t0);
5738 break;
5739 default:
5740 gen_mtc0(env, ctx, t0, rd, sel);
5741 break;
5743 case 12:
5744 switch (sel) {
5745 case 0:
5746 gen_helper_mttc0_status(t0);
5747 break;
5748 default:
5749 gen_mtc0(env, ctx, t0, rd, sel);
5750 break;
5752 case 23:
5753 switch (sel) {
5754 case 0:
5755 gen_helper_mttc0_debug(t0);
5756 break;
5757 default:
5758 gen_mtc0(env, ctx, t0, rd, sel);
5759 break;
5761 break;
5762 default:
5763 gen_mtc0(env, ctx, t0, rd, sel);
5765 } else switch (sel) {
5766 /* GPR registers. */
5767 case 0:
5768 gen_helper_1i(mttgpr, t0, rd);
5769 break;
5770 /* Auxiliary CPU registers */
5771 case 1:
5772 switch (rd) {
5773 case 0:
5774 gen_helper_1i(mttlo, t0, 0);
5775 break;
5776 case 1:
5777 gen_helper_1i(mtthi, t0, 0);
5778 break;
5779 case 2:
5780 gen_helper_1i(mttacx, t0, 0);
5781 break;
5782 case 4:
5783 gen_helper_1i(mttlo, t0, 1);
5784 break;
5785 case 5:
5786 gen_helper_1i(mtthi, t0, 1);
5787 break;
5788 case 6:
5789 gen_helper_1i(mttacx, t0, 1);
5790 break;
5791 case 8:
5792 gen_helper_1i(mttlo, t0, 2);
5793 break;
5794 case 9:
5795 gen_helper_1i(mtthi, t0, 2);
5796 break;
5797 case 10:
5798 gen_helper_1i(mttacx, t0, 2);
5799 break;
5800 case 12:
5801 gen_helper_1i(mttlo, t0, 3);
5802 break;
5803 case 13:
5804 gen_helper_1i(mtthi, t0, 3);
5805 break;
5806 case 14:
5807 gen_helper_1i(mttacx, t0, 3);
5808 break;
5809 case 16:
5810 gen_helper_mttdsp(t0);
5811 break;
5812 default:
5813 goto die;
5815 break;
5816 /* Floating point (COP1). */
5817 case 2:
5818 /* XXX: For now we support only a single FPU context. */
5819 if (h == 0) {
5820 TCGv_i32 fp0 = tcg_temp_new_i32();
5822 tcg_gen_trunc_tl_i32(fp0, t0);
5823 gen_store_fpr32(fp0, rd);
5824 tcg_temp_free_i32(fp0);
5825 } else {
5826 TCGv_i32 fp0 = tcg_temp_new_i32();
5828 tcg_gen_trunc_tl_i32(fp0, t0);
5829 gen_store_fpr32h(fp0, rd);
5830 tcg_temp_free_i32(fp0);
5832 break;
5833 case 3:
5834 /* XXX: For now we support only a single FPU context. */
5835 gen_helper_1i(ctc1, t0, rd);
5836 break;
5837 /* COP2: Not implemented. */
5838 case 4:
5839 case 5:
5840 /* fall through */
5841 default:
5842 goto die;
5844 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5845 tcg_temp_free(t0);
5846 return;
5848 die:
5849 tcg_temp_free(t0);
5850 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5851 generate_exception(ctx, EXCP_RI);
5854 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5856 const char *opn = "ldst";
5858 switch (opc) {
5859 case OPC_MFC0:
5860 if (rt == 0) {
5861 /* Treat as NOP. */
5862 return;
5864 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5865 opn = "mfc0";
5866 break;
5867 case OPC_MTC0:
5869 TCGv t0 = tcg_temp_new();
5871 gen_load_gpr(t0, rt);
5872 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5873 tcg_temp_free(t0);
5875 opn = "mtc0";
5876 break;
5877 #if defined(TARGET_MIPS64)
5878 case OPC_DMFC0:
5879 check_insn(env, ctx, ISA_MIPS3);
5880 if (rt == 0) {
5881 /* Treat as NOP. */
5882 return;
5884 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5885 opn = "dmfc0";
5886 break;
5887 case OPC_DMTC0:
5888 check_insn(env, ctx, ISA_MIPS3);
5890 TCGv t0 = tcg_temp_new();
5892 gen_load_gpr(t0, rt);
5893 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5894 tcg_temp_free(t0);
5896 opn = "dmtc0";
5897 break;
5898 #endif
5899 case OPC_MFTR:
5900 check_insn(env, ctx, ASE_MT);
5901 if (rd == 0) {
5902 /* Treat as NOP. */
5903 return;
5905 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5906 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5907 opn = "mftr";
5908 break;
5909 case OPC_MTTR:
5910 check_insn(env, ctx, ASE_MT);
5911 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5912 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5913 opn = "mttr";
5914 break;
5915 case OPC_TLBWI:
5916 opn = "tlbwi";
5917 if (!env->tlb->helper_tlbwi)
5918 goto die;
5919 gen_helper_tlbwi();
5920 break;
5921 case OPC_TLBWR:
5922 opn = "tlbwr";
5923 if (!env->tlb->helper_tlbwr)
5924 goto die;
5925 gen_helper_tlbwr();
5926 break;
5927 case OPC_TLBP:
5928 opn = "tlbp";
5929 if (!env->tlb->helper_tlbp)
5930 goto die;
5931 gen_helper_tlbp();
5932 break;
5933 case OPC_TLBR:
5934 opn = "tlbr";
5935 if (!env->tlb->helper_tlbr)
5936 goto die;
5937 gen_helper_tlbr();
5938 break;
5939 case OPC_ERET:
5940 opn = "eret";
5941 check_insn(env, ctx, ISA_MIPS2);
5942 gen_helper_eret();
5943 ctx->bstate = BS_EXCP;
5944 break;
5945 case OPC_DERET:
5946 opn = "deret";
5947 check_insn(env, ctx, ISA_MIPS32);
5948 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5949 MIPS_INVAL(opn);
5950 generate_exception(ctx, EXCP_RI);
5951 } else {
5952 gen_helper_deret();
5953 ctx->bstate = BS_EXCP;
5955 break;
5956 case OPC_WAIT:
5957 opn = "wait";
5958 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5959 /* If we get an exception, we want to restart at next instruction */
5960 ctx->pc += 4;
5961 save_cpu_state(ctx, 1);
5962 ctx->pc -= 4;
5963 gen_helper_wait();
5964 ctx->bstate = BS_EXCP;
5965 break;
5966 default:
5967 die:
5968 MIPS_INVAL(opn);
5969 generate_exception(ctx, EXCP_RI);
5970 return;
5972 (void)opn; /* avoid a compiler warning */
5973 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5975 #endif /* !CONFIG_USER_ONLY */
5977 /* CP1 Branches (before delay slot) */
5978 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5979 int32_t cc, int32_t offset)
5981 target_ulong btarget;
5982 const char *opn = "cp1 cond branch";
5983 TCGv_i32 t0 = tcg_temp_new_i32();
5985 if (cc != 0)
5986 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5988 btarget = ctx->pc + 4 + offset;
5990 switch (op) {
5991 case OPC_BC1F:
5992 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5993 tcg_gen_not_i32(t0, t0);
5994 tcg_gen_andi_i32(t0, t0, 1);
5995 tcg_gen_extu_i32_tl(bcond, t0);
5996 opn = "bc1f";
5997 goto not_likely;
5998 case OPC_BC1FL:
5999 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6000 tcg_gen_not_i32(t0, t0);
6001 tcg_gen_andi_i32(t0, t0, 1);
6002 tcg_gen_extu_i32_tl(bcond, t0);
6003 opn = "bc1fl";
6004 goto likely;
6005 case OPC_BC1T:
6006 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6007 tcg_gen_andi_i32(t0, t0, 1);
6008 tcg_gen_extu_i32_tl(bcond, t0);
6009 opn = "bc1t";
6010 goto not_likely;
6011 case OPC_BC1TL:
6012 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6013 tcg_gen_andi_i32(t0, t0, 1);
6014 tcg_gen_extu_i32_tl(bcond, t0);
6015 opn = "bc1tl";
6016 likely:
6017 ctx->hflags |= MIPS_HFLAG_BL;
6018 break;
6019 case OPC_BC1FANY2:
6021 TCGv_i32 t1 = tcg_temp_new_i32();
6022 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6023 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6024 tcg_gen_nor_i32(t0, t0, t1);
6025 tcg_temp_free_i32(t1);
6026 tcg_gen_andi_i32(t0, t0, 1);
6027 tcg_gen_extu_i32_tl(bcond, t0);
6029 opn = "bc1any2f";
6030 goto not_likely;
6031 case OPC_BC1TANY2:
6033 TCGv_i32 t1 = tcg_temp_new_i32();
6034 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6035 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6036 tcg_gen_or_i32(t0, t0, t1);
6037 tcg_temp_free_i32(t1);
6038 tcg_gen_andi_i32(t0, t0, 1);
6039 tcg_gen_extu_i32_tl(bcond, t0);
6041 opn = "bc1any2t";
6042 goto not_likely;
6043 case OPC_BC1FANY4:
6045 TCGv_i32 t1 = tcg_temp_new_i32();
6046 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6047 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6048 tcg_gen_or_i32(t0, t0, t1);
6049 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6050 tcg_gen_or_i32(t0, t0, t1);
6051 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6052 tcg_gen_nor_i32(t0, t0, t1);
6053 tcg_temp_free_i32(t1);
6054 tcg_gen_andi_i32(t0, t0, 1);
6055 tcg_gen_extu_i32_tl(bcond, t0);
6057 opn = "bc1any4f";
6058 goto not_likely;
6059 case OPC_BC1TANY4:
6061 TCGv_i32 t1 = tcg_temp_new_i32();
6062 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6063 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6064 tcg_gen_or_i32(t0, t0, t1);
6065 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6066 tcg_gen_or_i32(t0, t0, t1);
6067 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6068 tcg_gen_or_i32(t0, t0, t1);
6069 tcg_temp_free_i32(t1);
6070 tcg_gen_andi_i32(t0, t0, 1);
6071 tcg_gen_extu_i32_tl(bcond, t0);
6073 opn = "bc1any4t";
6074 not_likely:
6075 ctx->hflags |= MIPS_HFLAG_BC;
6076 break;
6077 default:
6078 MIPS_INVAL(opn);
6079 generate_exception (ctx, EXCP_RI);
6080 goto out;
6082 (void)opn; /* avoid a compiler warning */
6083 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6084 ctx->hflags, btarget);
6085 ctx->btarget = btarget;
6087 out:
6088 tcg_temp_free_i32(t0);
6091 /* Coprocessor 1 (FPU) */
6093 #define FOP(func, fmt) (((fmt) << 21) | (func))
6095 enum fopcode {
6096 OPC_ADD_S = FOP(0, FMT_S),
6097 OPC_SUB_S = FOP(1, FMT_S),
6098 OPC_MUL_S = FOP(2, FMT_S),
6099 OPC_DIV_S = FOP(3, FMT_S),
6100 OPC_SQRT_S = FOP(4, FMT_S),
6101 OPC_ABS_S = FOP(5, FMT_S),
6102 OPC_MOV_S = FOP(6, FMT_S),
6103 OPC_NEG_S = FOP(7, FMT_S),
6104 OPC_ROUND_L_S = FOP(8, FMT_S),
6105 OPC_TRUNC_L_S = FOP(9, FMT_S),
6106 OPC_CEIL_L_S = FOP(10, FMT_S),
6107 OPC_FLOOR_L_S = FOP(11, FMT_S),
6108 OPC_ROUND_W_S = FOP(12, FMT_S),
6109 OPC_TRUNC_W_S = FOP(13, FMT_S),
6110 OPC_CEIL_W_S = FOP(14, FMT_S),
6111 OPC_FLOOR_W_S = FOP(15, FMT_S),
6112 OPC_MOVCF_S = FOP(17, FMT_S),
6113 OPC_MOVZ_S = FOP(18, FMT_S),
6114 OPC_MOVN_S = FOP(19, FMT_S),
6115 OPC_RECIP_S = FOP(21, FMT_S),
6116 OPC_RSQRT_S = FOP(22, FMT_S),
6117 OPC_RECIP2_S = FOP(28, FMT_S),
6118 OPC_RECIP1_S = FOP(29, FMT_S),
6119 OPC_RSQRT1_S = FOP(30, FMT_S),
6120 OPC_RSQRT2_S = FOP(31, FMT_S),
6121 OPC_CVT_D_S = FOP(33, FMT_S),
6122 OPC_CVT_W_S = FOP(36, FMT_S),
6123 OPC_CVT_L_S = FOP(37, FMT_S),
6124 OPC_CVT_PS_S = FOP(38, FMT_S),
6125 OPC_CMP_F_S = FOP (48, FMT_S),
6126 OPC_CMP_UN_S = FOP (49, FMT_S),
6127 OPC_CMP_EQ_S = FOP (50, FMT_S),
6128 OPC_CMP_UEQ_S = FOP (51, FMT_S),
6129 OPC_CMP_OLT_S = FOP (52, FMT_S),
6130 OPC_CMP_ULT_S = FOP (53, FMT_S),
6131 OPC_CMP_OLE_S = FOP (54, FMT_S),
6132 OPC_CMP_ULE_S = FOP (55, FMT_S),
6133 OPC_CMP_SF_S = FOP (56, FMT_S),
6134 OPC_CMP_NGLE_S = FOP (57, FMT_S),
6135 OPC_CMP_SEQ_S = FOP (58, FMT_S),
6136 OPC_CMP_NGL_S = FOP (59, FMT_S),
6137 OPC_CMP_LT_S = FOP (60, FMT_S),
6138 OPC_CMP_NGE_S = FOP (61, FMT_S),
6139 OPC_CMP_LE_S = FOP (62, FMT_S),
6140 OPC_CMP_NGT_S = FOP (63, FMT_S),
6142 OPC_ADD_D = FOP(0, FMT_D),
6143 OPC_SUB_D = FOP(1, FMT_D),
6144 OPC_MUL_D = FOP(2, FMT_D),
6145 OPC_DIV_D = FOP(3, FMT_D),
6146 OPC_SQRT_D = FOP(4, FMT_D),
6147 OPC_ABS_D = FOP(5, FMT_D),
6148 OPC_MOV_D = FOP(6, FMT_D),
6149 OPC_NEG_D = FOP(7, FMT_D),
6150 OPC_ROUND_L_D = FOP(8, FMT_D),
6151 OPC_TRUNC_L_D = FOP(9, FMT_D),
6152 OPC_CEIL_L_D = FOP(10, FMT_D),
6153 OPC_FLOOR_L_D = FOP(11, FMT_D),
6154 OPC_ROUND_W_D = FOP(12, FMT_D),
6155 OPC_TRUNC_W_D = FOP(13, FMT_D),
6156 OPC_CEIL_W_D = FOP(14, FMT_D),
6157 OPC_FLOOR_W_D = FOP(15, FMT_D),
6158 OPC_MOVCF_D = FOP(17, FMT_D),
6159 OPC_MOVZ_D = FOP(18, FMT_D),
6160 OPC_MOVN_D = FOP(19, FMT_D),
6161 OPC_RECIP_D = FOP(21, FMT_D),
6162 OPC_RSQRT_D = FOP(22, FMT_D),
6163 OPC_RECIP2_D = FOP(28, FMT_D),
6164 OPC_RECIP1_D = FOP(29, FMT_D),
6165 OPC_RSQRT1_D = FOP(30, FMT_D),
6166 OPC_RSQRT2_D = FOP(31, FMT_D),
6167 OPC_CVT_S_D = FOP(32, FMT_D),
6168 OPC_CVT_W_D = FOP(36, FMT_D),
6169 OPC_CVT_L_D = FOP(37, FMT_D),
6170 OPC_CMP_F_D = FOP (48, FMT_D),
6171 OPC_CMP_UN_D = FOP (49, FMT_D),
6172 OPC_CMP_EQ_D = FOP (50, FMT_D),
6173 OPC_CMP_UEQ_D = FOP (51, FMT_D),
6174 OPC_CMP_OLT_D = FOP (52, FMT_D),
6175 OPC_CMP_ULT_D = FOP (53, FMT_D),
6176 OPC_CMP_OLE_D = FOP (54, FMT_D),
6177 OPC_CMP_ULE_D = FOP (55, FMT_D),
6178 OPC_CMP_SF_D = FOP (56, FMT_D),
6179 OPC_CMP_NGLE_D = FOP (57, FMT_D),
6180 OPC_CMP_SEQ_D = FOP (58, FMT_D),
6181 OPC_CMP_NGL_D = FOP (59, FMT_D),
6182 OPC_CMP_LT_D = FOP (60, FMT_D),
6183 OPC_CMP_NGE_D = FOP (61, FMT_D),
6184 OPC_CMP_LE_D = FOP (62, FMT_D),
6185 OPC_CMP_NGT_D = FOP (63, FMT_D),
6187 OPC_CVT_S_W = FOP(32, FMT_W),
6188 OPC_CVT_D_W = FOP(33, FMT_W),
6189 OPC_CVT_S_L = FOP(32, FMT_L),
6190 OPC_CVT_D_L = FOP(33, FMT_L),
6191 OPC_CVT_PS_PW = FOP(38, FMT_W),
6193 OPC_ADD_PS = FOP(0, FMT_PS),
6194 OPC_SUB_PS = FOP(1, FMT_PS),
6195 OPC_MUL_PS = FOP(2, FMT_PS),
6196 OPC_DIV_PS = FOP(3, FMT_PS),
6197 OPC_ABS_PS = FOP(5, FMT_PS),
6198 OPC_MOV_PS = FOP(6, FMT_PS),
6199 OPC_NEG_PS = FOP(7, FMT_PS),
6200 OPC_MOVCF_PS = FOP(17, FMT_PS),
6201 OPC_MOVZ_PS = FOP(18, FMT_PS),
6202 OPC_MOVN_PS = FOP(19, FMT_PS),
6203 OPC_ADDR_PS = FOP(24, FMT_PS),
6204 OPC_MULR_PS = FOP(26, FMT_PS),
6205 OPC_RECIP2_PS = FOP(28, FMT_PS),
6206 OPC_RECIP1_PS = FOP(29, FMT_PS),
6207 OPC_RSQRT1_PS = FOP(30, FMT_PS),
6208 OPC_RSQRT2_PS = FOP(31, FMT_PS),
6210 OPC_CVT_S_PU = FOP(32, FMT_PS),
6211 OPC_CVT_PW_PS = FOP(36, FMT_PS),
6212 OPC_CVT_S_PL = FOP(40, FMT_PS),
6213 OPC_PLL_PS = FOP(44, FMT_PS),
6214 OPC_PLU_PS = FOP(45, FMT_PS),
6215 OPC_PUL_PS = FOP(46, FMT_PS),
6216 OPC_PUU_PS = FOP(47, FMT_PS),
6217 OPC_CMP_F_PS = FOP (48, FMT_PS),
6218 OPC_CMP_UN_PS = FOP (49, FMT_PS),
6219 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
6220 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
6221 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
6222 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
6223 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
6224 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
6225 OPC_CMP_SF_PS = FOP (56, FMT_PS),
6226 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
6227 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
6228 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
6229 OPC_CMP_LT_PS = FOP (60, FMT_PS),
6230 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
6231 OPC_CMP_LE_PS = FOP (62, FMT_PS),
6232 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
6235 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6237 const char *opn = "cp1 move";
6238 TCGv t0 = tcg_temp_new();
6240 switch (opc) {
6241 case OPC_MFC1:
6243 TCGv_i32 fp0 = tcg_temp_new_i32();
6245 gen_load_fpr32(fp0, fs);
6246 tcg_gen_ext_i32_tl(t0, fp0);
6247 tcg_temp_free_i32(fp0);
6249 gen_store_gpr(t0, rt);
6250 opn = "mfc1";
6251 break;
6252 case OPC_MTC1:
6253 gen_load_gpr(t0, rt);
6255 TCGv_i32 fp0 = tcg_temp_new_i32();
6257 tcg_gen_trunc_tl_i32(fp0, t0);
6258 gen_store_fpr32(fp0, fs);
6259 tcg_temp_free_i32(fp0);
6261 opn = "mtc1";
6262 break;
6263 case OPC_CFC1:
6264 gen_helper_1i(cfc1, t0, fs);
6265 gen_store_gpr(t0, rt);
6266 opn = "cfc1";
6267 break;
6268 case OPC_CTC1:
6269 gen_load_gpr(t0, rt);
6270 gen_helper_1i(ctc1, t0, fs);
6271 opn = "ctc1";
6272 break;
6273 #if defined(TARGET_MIPS64)
6274 case OPC_DMFC1:
6275 gen_load_fpr64(ctx, t0, fs);
6276 gen_store_gpr(t0, rt);
6277 opn = "dmfc1";
6278 break;
6279 case OPC_DMTC1:
6280 gen_load_gpr(t0, rt);
6281 gen_store_fpr64(ctx, t0, fs);
6282 opn = "dmtc1";
6283 break;
6284 #endif
6285 case OPC_MFHC1:
6287 TCGv_i32 fp0 = tcg_temp_new_i32();
6289 gen_load_fpr32h(fp0, fs);
6290 tcg_gen_ext_i32_tl(t0, fp0);
6291 tcg_temp_free_i32(fp0);
6293 gen_store_gpr(t0, rt);
6294 opn = "mfhc1";
6295 break;
6296 case OPC_MTHC1:
6297 gen_load_gpr(t0, rt);
6299 TCGv_i32 fp0 = tcg_temp_new_i32();
6301 tcg_gen_trunc_tl_i32(fp0, t0);
6302 gen_store_fpr32h(fp0, fs);
6303 tcg_temp_free_i32(fp0);
6305 opn = "mthc1";
6306 break;
6307 default:
6308 MIPS_INVAL(opn);
6309 generate_exception (ctx, EXCP_RI);
6310 goto out;
6312 (void)opn; /* avoid a compiler warning */
6313 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6315 out:
6316 tcg_temp_free(t0);
6319 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6321 int l1;
6322 TCGCond cond;
6323 TCGv_i32 t0;
6325 if (rd == 0) {
6326 /* Treat as NOP. */
6327 return;
6330 if (tf)
6331 cond = TCG_COND_EQ;
6332 else
6333 cond = TCG_COND_NE;
6335 l1 = gen_new_label();
6336 t0 = tcg_temp_new_i32();
6337 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6338 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6339 tcg_temp_free_i32(t0);
6340 if (rs == 0) {
6341 tcg_gen_movi_tl(cpu_gpr[rd], 0);
6342 } else {
6343 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6345 gen_set_label(l1);
6348 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6350 int cond;
6351 TCGv_i32 t0 = tcg_temp_new_i32();
6352 int l1 = gen_new_label();
6354 if (tf)
6355 cond = TCG_COND_EQ;
6356 else
6357 cond = TCG_COND_NE;
6359 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6360 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6361 gen_load_fpr32(t0, fs);
6362 gen_store_fpr32(t0, fd);
6363 gen_set_label(l1);
6364 tcg_temp_free_i32(t0);
6367 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6369 int cond;
6370 TCGv_i32 t0 = tcg_temp_new_i32();
6371 TCGv_i64 fp0;
6372 int l1 = gen_new_label();
6374 if (tf)
6375 cond = TCG_COND_EQ;
6376 else
6377 cond = TCG_COND_NE;
6379 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6380 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6381 tcg_temp_free_i32(t0);
6382 fp0 = tcg_temp_new_i64();
6383 gen_load_fpr64(ctx, fp0, fs);
6384 gen_store_fpr64(ctx, fp0, fd);
6385 tcg_temp_free_i64(fp0);
6386 gen_set_label(l1);
6389 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6391 int cond;
6392 TCGv_i32 t0 = tcg_temp_new_i32();
6393 int l1 = gen_new_label();
6394 int l2 = gen_new_label();
6396 if (tf)
6397 cond = TCG_COND_EQ;
6398 else
6399 cond = TCG_COND_NE;
6401 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6402 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6403 gen_load_fpr32(t0, fs);
6404 gen_store_fpr32(t0, fd);
6405 gen_set_label(l1);
6407 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6408 tcg_gen_brcondi_i32(cond, t0, 0, l2);
6409 gen_load_fpr32h(t0, fs);
6410 gen_store_fpr32h(t0, fd);
6411 tcg_temp_free_i32(t0);
6412 gen_set_label(l2);
6416 static void gen_farith (DisasContext *ctx, enum fopcode op1,
6417 int ft, int fs, int fd, int cc)
6419 const char *opn = "farith";
6420 const char *condnames[] = {
6421 "c.f",
6422 "c.un",
6423 "c.eq",
6424 "c.ueq",
6425 "c.olt",
6426 "c.ult",
6427 "c.ole",
6428 "c.ule",
6429 "c.sf",
6430 "c.ngle",
6431 "c.seq",
6432 "c.ngl",
6433 "c.lt",
6434 "c.nge",
6435 "c.le",
6436 "c.ngt",
6438 const char *condnames_abs[] = {
6439 "cabs.f",
6440 "cabs.un",
6441 "cabs.eq",
6442 "cabs.ueq",
6443 "cabs.olt",
6444 "cabs.ult",
6445 "cabs.ole",
6446 "cabs.ule",
6447 "cabs.sf",
6448 "cabs.ngle",
6449 "cabs.seq",
6450 "cabs.ngl",
6451 "cabs.lt",
6452 "cabs.nge",
6453 "cabs.le",
6454 "cabs.ngt",
6456 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6457 uint32_t func = ctx->opcode & 0x3f;
6459 switch (op1) {
6460 case OPC_ADD_S:
6462 TCGv_i32 fp0 = tcg_temp_new_i32();
6463 TCGv_i32 fp1 = tcg_temp_new_i32();
6465 gen_load_fpr32(fp0, fs);
6466 gen_load_fpr32(fp1, ft);
6467 gen_helper_float_add_s(fp0, fp0, fp1);
6468 tcg_temp_free_i32(fp1);
6469 gen_store_fpr32(fp0, fd);
6470 tcg_temp_free_i32(fp0);
6472 opn = "add.s";
6473 optype = BINOP;
6474 break;
6475 case OPC_SUB_S:
6477 TCGv_i32 fp0 = tcg_temp_new_i32();
6478 TCGv_i32 fp1 = tcg_temp_new_i32();
6480 gen_load_fpr32(fp0, fs);
6481 gen_load_fpr32(fp1, ft);
6482 gen_helper_float_sub_s(fp0, fp0, fp1);
6483 tcg_temp_free_i32(fp1);
6484 gen_store_fpr32(fp0, fd);
6485 tcg_temp_free_i32(fp0);
6487 opn = "sub.s";
6488 optype = BINOP;
6489 break;
6490 case OPC_MUL_S:
6492 TCGv_i32 fp0 = tcg_temp_new_i32();
6493 TCGv_i32 fp1 = tcg_temp_new_i32();
6495 gen_load_fpr32(fp0, fs);
6496 gen_load_fpr32(fp1, ft);
6497 gen_helper_float_mul_s(fp0, fp0, fp1);
6498 tcg_temp_free_i32(fp1);
6499 gen_store_fpr32(fp0, fd);
6500 tcg_temp_free_i32(fp0);
6502 opn = "mul.s";
6503 optype = BINOP;
6504 break;
6505 case OPC_DIV_S:
6507 TCGv_i32 fp0 = tcg_temp_new_i32();
6508 TCGv_i32 fp1 = tcg_temp_new_i32();
6510 gen_load_fpr32(fp0, fs);
6511 gen_load_fpr32(fp1, ft);
6512 gen_helper_float_div_s(fp0, fp0, fp1);
6513 tcg_temp_free_i32(fp1);
6514 gen_store_fpr32(fp0, fd);
6515 tcg_temp_free_i32(fp0);
6517 opn = "div.s";
6518 optype = BINOP;
6519 break;
6520 case OPC_SQRT_S:
6522 TCGv_i32 fp0 = tcg_temp_new_i32();
6524 gen_load_fpr32(fp0, fs);
6525 gen_helper_float_sqrt_s(fp0, fp0);
6526 gen_store_fpr32(fp0, fd);
6527 tcg_temp_free_i32(fp0);
6529 opn = "sqrt.s";
6530 break;
6531 case OPC_ABS_S:
6533 TCGv_i32 fp0 = tcg_temp_new_i32();
6535 gen_load_fpr32(fp0, fs);
6536 gen_helper_float_abs_s(fp0, fp0);
6537 gen_store_fpr32(fp0, fd);
6538 tcg_temp_free_i32(fp0);
6540 opn = "abs.s";
6541 break;
6542 case OPC_MOV_S:
6544 TCGv_i32 fp0 = tcg_temp_new_i32();
6546 gen_load_fpr32(fp0, fs);
6547 gen_store_fpr32(fp0, fd);
6548 tcg_temp_free_i32(fp0);
6550 opn = "mov.s";
6551 break;
6552 case OPC_NEG_S:
6554 TCGv_i32 fp0 = tcg_temp_new_i32();
6556 gen_load_fpr32(fp0, fs);
6557 gen_helper_float_chs_s(fp0, fp0);
6558 gen_store_fpr32(fp0, fd);
6559 tcg_temp_free_i32(fp0);
6561 opn = "neg.s";
6562 break;
6563 case OPC_ROUND_L_S:
6564 check_cp1_64bitmode(ctx);
6566 TCGv_i32 fp32 = tcg_temp_new_i32();
6567 TCGv_i64 fp64 = tcg_temp_new_i64();
6569 gen_load_fpr32(fp32, fs);
6570 gen_helper_float_roundl_s(fp64, fp32);
6571 tcg_temp_free_i32(fp32);
6572 gen_store_fpr64(ctx, fp64, fd);
6573 tcg_temp_free_i64(fp64);
6575 opn = "round.l.s";
6576 break;
6577 case OPC_TRUNC_L_S:
6578 check_cp1_64bitmode(ctx);
6580 TCGv_i32 fp32 = tcg_temp_new_i32();
6581 TCGv_i64 fp64 = tcg_temp_new_i64();
6583 gen_load_fpr32(fp32, fs);
6584 gen_helper_float_truncl_s(fp64, fp32);
6585 tcg_temp_free_i32(fp32);
6586 gen_store_fpr64(ctx, fp64, fd);
6587 tcg_temp_free_i64(fp64);
6589 opn = "trunc.l.s";
6590 break;
6591 case OPC_CEIL_L_S:
6592 check_cp1_64bitmode(ctx);
6594 TCGv_i32 fp32 = tcg_temp_new_i32();
6595 TCGv_i64 fp64 = tcg_temp_new_i64();
6597 gen_load_fpr32(fp32, fs);
6598 gen_helper_float_ceill_s(fp64, fp32);
6599 tcg_temp_free_i32(fp32);
6600 gen_store_fpr64(ctx, fp64, fd);
6601 tcg_temp_free_i64(fp64);
6603 opn = "ceil.l.s";
6604 break;
6605 case OPC_FLOOR_L_S:
6606 check_cp1_64bitmode(ctx);
6608 TCGv_i32 fp32 = tcg_temp_new_i32();
6609 TCGv_i64 fp64 = tcg_temp_new_i64();
6611 gen_load_fpr32(fp32, fs);
6612 gen_helper_float_floorl_s(fp64, fp32);
6613 tcg_temp_free_i32(fp32);
6614 gen_store_fpr64(ctx, fp64, fd);
6615 tcg_temp_free_i64(fp64);
6617 opn = "floor.l.s";
6618 break;
6619 case OPC_ROUND_W_S:
6621 TCGv_i32 fp0 = tcg_temp_new_i32();
6623 gen_load_fpr32(fp0, fs);
6624 gen_helper_float_roundw_s(fp0, fp0);
6625 gen_store_fpr32(fp0, fd);
6626 tcg_temp_free_i32(fp0);
6628 opn = "round.w.s";
6629 break;
6630 case OPC_TRUNC_W_S:
6632 TCGv_i32 fp0 = tcg_temp_new_i32();
6634 gen_load_fpr32(fp0, fs);
6635 gen_helper_float_truncw_s(fp0, fp0);
6636 gen_store_fpr32(fp0, fd);
6637 tcg_temp_free_i32(fp0);
6639 opn = "trunc.w.s";
6640 break;
6641 case OPC_CEIL_W_S:
6643 TCGv_i32 fp0 = tcg_temp_new_i32();
6645 gen_load_fpr32(fp0, fs);
6646 gen_helper_float_ceilw_s(fp0, fp0);
6647 gen_store_fpr32(fp0, fd);
6648 tcg_temp_free_i32(fp0);
6650 opn = "ceil.w.s";
6651 break;
6652 case OPC_FLOOR_W_S:
6654 TCGv_i32 fp0 = tcg_temp_new_i32();
6656 gen_load_fpr32(fp0, fs);
6657 gen_helper_float_floorw_s(fp0, fp0);
6658 gen_store_fpr32(fp0, fd);
6659 tcg_temp_free_i32(fp0);
6661 opn = "floor.w.s";
6662 break;
6663 case OPC_MOVCF_S:
6664 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6665 opn = "movcf.s";
6666 break;
6667 case OPC_MOVZ_S:
6669 int l1 = gen_new_label();
6670 TCGv_i32 fp0;
6672 if (ft != 0) {
6673 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6675 fp0 = tcg_temp_new_i32();
6676 gen_load_fpr32(fp0, fs);
6677 gen_store_fpr32(fp0, fd);
6678 tcg_temp_free_i32(fp0);
6679 gen_set_label(l1);
6681 opn = "movz.s";
6682 break;
6683 case OPC_MOVN_S:
6685 int l1 = gen_new_label();
6686 TCGv_i32 fp0;
6688 if (ft != 0) {
6689 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6690 fp0 = tcg_temp_new_i32();
6691 gen_load_fpr32(fp0, fs);
6692 gen_store_fpr32(fp0, fd);
6693 tcg_temp_free_i32(fp0);
6694 gen_set_label(l1);
6697 opn = "movn.s";
6698 break;
6699 case OPC_RECIP_S:
6700 check_cop1x(ctx);
6702 TCGv_i32 fp0 = tcg_temp_new_i32();
6704 gen_load_fpr32(fp0, fs);
6705 gen_helper_float_recip_s(fp0, fp0);
6706 gen_store_fpr32(fp0, fd);
6707 tcg_temp_free_i32(fp0);
6709 opn = "recip.s";
6710 break;
6711 case OPC_RSQRT_S:
6712 check_cop1x(ctx);
6714 TCGv_i32 fp0 = tcg_temp_new_i32();
6716 gen_load_fpr32(fp0, fs);
6717 gen_helper_float_rsqrt_s(fp0, fp0);
6718 gen_store_fpr32(fp0, fd);
6719 tcg_temp_free_i32(fp0);
6721 opn = "rsqrt.s";
6722 break;
6723 case OPC_RECIP2_S:
6724 check_cp1_64bitmode(ctx);
6726 TCGv_i32 fp0 = tcg_temp_new_i32();
6727 TCGv_i32 fp1 = tcg_temp_new_i32();
6729 gen_load_fpr32(fp0, fs);
6730 gen_load_fpr32(fp1, fd);
6731 gen_helper_float_recip2_s(fp0, fp0, fp1);
6732 tcg_temp_free_i32(fp1);
6733 gen_store_fpr32(fp0, fd);
6734 tcg_temp_free_i32(fp0);
6736 opn = "recip2.s";
6737 break;
6738 case OPC_RECIP1_S:
6739 check_cp1_64bitmode(ctx);
6741 TCGv_i32 fp0 = tcg_temp_new_i32();
6743 gen_load_fpr32(fp0, fs);
6744 gen_helper_float_recip1_s(fp0, fp0);
6745 gen_store_fpr32(fp0, fd);
6746 tcg_temp_free_i32(fp0);
6748 opn = "recip1.s";
6749 break;
6750 case OPC_RSQRT1_S:
6751 check_cp1_64bitmode(ctx);
6753 TCGv_i32 fp0 = tcg_temp_new_i32();
6755 gen_load_fpr32(fp0, fs);
6756 gen_helper_float_rsqrt1_s(fp0, fp0);
6757 gen_store_fpr32(fp0, fd);
6758 tcg_temp_free_i32(fp0);
6760 opn = "rsqrt1.s";
6761 break;
6762 case OPC_RSQRT2_S:
6763 check_cp1_64bitmode(ctx);
6765 TCGv_i32 fp0 = tcg_temp_new_i32();
6766 TCGv_i32 fp1 = tcg_temp_new_i32();
6768 gen_load_fpr32(fp0, fs);
6769 gen_load_fpr32(fp1, ft);
6770 gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6771 tcg_temp_free_i32(fp1);
6772 gen_store_fpr32(fp0, fd);
6773 tcg_temp_free_i32(fp0);
6775 opn = "rsqrt2.s";
6776 break;
6777 case OPC_CVT_D_S:
6778 check_cp1_registers(ctx, fd);
6780 TCGv_i32 fp32 = tcg_temp_new_i32();
6781 TCGv_i64 fp64 = tcg_temp_new_i64();
6783 gen_load_fpr32(fp32, fs);
6784 gen_helper_float_cvtd_s(fp64, fp32);
6785 tcg_temp_free_i32(fp32);
6786 gen_store_fpr64(ctx, fp64, fd);
6787 tcg_temp_free_i64(fp64);
6789 opn = "cvt.d.s";
6790 break;
6791 case OPC_CVT_W_S:
6793 TCGv_i32 fp0 = tcg_temp_new_i32();
6795 gen_load_fpr32(fp0, fs);
6796 gen_helper_float_cvtw_s(fp0, fp0);
6797 gen_store_fpr32(fp0, fd);
6798 tcg_temp_free_i32(fp0);
6800 opn = "cvt.w.s";
6801 break;
6802 case OPC_CVT_L_S:
6803 check_cp1_64bitmode(ctx);
6805 TCGv_i32 fp32 = tcg_temp_new_i32();
6806 TCGv_i64 fp64 = tcg_temp_new_i64();
6808 gen_load_fpr32(fp32, fs);
6809 gen_helper_float_cvtl_s(fp64, fp32);
6810 tcg_temp_free_i32(fp32);
6811 gen_store_fpr64(ctx, fp64, fd);
6812 tcg_temp_free_i64(fp64);
6814 opn = "cvt.l.s";
6815 break;
6816 case OPC_CVT_PS_S:
6817 check_cp1_64bitmode(ctx);
6819 TCGv_i64 fp64 = tcg_temp_new_i64();
6820 TCGv_i32 fp32_0 = tcg_temp_new_i32();
6821 TCGv_i32 fp32_1 = tcg_temp_new_i32();
6823 gen_load_fpr32(fp32_0, fs);
6824 gen_load_fpr32(fp32_1, ft);
6825 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6826 tcg_temp_free_i32(fp32_1);
6827 tcg_temp_free_i32(fp32_0);
6828 gen_store_fpr64(ctx, fp64, fd);
6829 tcg_temp_free_i64(fp64);
6831 opn = "cvt.ps.s";
6832 break;
6833 case OPC_CMP_F_S:
6834 case OPC_CMP_UN_S:
6835 case OPC_CMP_EQ_S:
6836 case OPC_CMP_UEQ_S:
6837 case OPC_CMP_OLT_S:
6838 case OPC_CMP_ULT_S:
6839 case OPC_CMP_OLE_S:
6840 case OPC_CMP_ULE_S:
6841 case OPC_CMP_SF_S:
6842 case OPC_CMP_NGLE_S:
6843 case OPC_CMP_SEQ_S:
6844 case OPC_CMP_NGL_S:
6845 case OPC_CMP_LT_S:
6846 case OPC_CMP_NGE_S:
6847 case OPC_CMP_LE_S:
6848 case OPC_CMP_NGT_S:
6849 if (ctx->opcode & (1 << 6)) {
6850 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6851 opn = condnames_abs[func-48];
6852 } else {
6853 gen_cmp_s(ctx, func-48, ft, fs, cc);
6854 opn = condnames[func-48];
6856 break;
6857 case OPC_ADD_D:
6858 check_cp1_registers(ctx, fs | ft | fd);
6860 TCGv_i64 fp0 = tcg_temp_new_i64();
6861 TCGv_i64 fp1 = tcg_temp_new_i64();
6863 gen_load_fpr64(ctx, fp0, fs);
6864 gen_load_fpr64(ctx, fp1, ft);
6865 gen_helper_float_add_d(fp0, fp0, fp1);
6866 tcg_temp_free_i64(fp1);
6867 gen_store_fpr64(ctx, fp0, fd);
6868 tcg_temp_free_i64(fp0);
6870 opn = "add.d";
6871 optype = BINOP;
6872 break;
6873 case OPC_SUB_D:
6874 check_cp1_registers(ctx, fs | ft | fd);
6876 TCGv_i64 fp0 = tcg_temp_new_i64();
6877 TCGv_i64 fp1 = tcg_temp_new_i64();
6879 gen_load_fpr64(ctx, fp0, fs);
6880 gen_load_fpr64(ctx, fp1, ft);
6881 gen_helper_float_sub_d(fp0, fp0, fp1);
6882 tcg_temp_free_i64(fp1);
6883 gen_store_fpr64(ctx, fp0, fd);
6884 tcg_temp_free_i64(fp0);
6886 opn = "sub.d";
6887 optype = BINOP;
6888 break;
6889 case OPC_MUL_D:
6890 check_cp1_registers(ctx, fs | ft | fd);
6892 TCGv_i64 fp0 = tcg_temp_new_i64();
6893 TCGv_i64 fp1 = tcg_temp_new_i64();
6895 gen_load_fpr64(ctx, fp0, fs);
6896 gen_load_fpr64(ctx, fp1, ft);
6897 gen_helper_float_mul_d(fp0, fp0, fp1);
6898 tcg_temp_free_i64(fp1);
6899 gen_store_fpr64(ctx, fp0, fd);
6900 tcg_temp_free_i64(fp0);
6902 opn = "mul.d";
6903 optype = BINOP;
6904 break;
6905 case OPC_DIV_D:
6906 check_cp1_registers(ctx, fs | ft | fd);
6908 TCGv_i64 fp0 = tcg_temp_new_i64();
6909 TCGv_i64 fp1 = tcg_temp_new_i64();
6911 gen_load_fpr64(ctx, fp0, fs);
6912 gen_load_fpr64(ctx, fp1, ft);
6913 gen_helper_float_div_d(fp0, fp0, fp1);
6914 tcg_temp_free_i64(fp1);
6915 gen_store_fpr64(ctx, fp0, fd);
6916 tcg_temp_free_i64(fp0);
6918 opn = "div.d";
6919 optype = BINOP;
6920 break;
6921 case OPC_SQRT_D:
6922 check_cp1_registers(ctx, fs | fd);
6924 TCGv_i64 fp0 = tcg_temp_new_i64();
6926 gen_load_fpr64(ctx, fp0, fs);
6927 gen_helper_float_sqrt_d(fp0, fp0);
6928 gen_store_fpr64(ctx, fp0, fd);
6929 tcg_temp_free_i64(fp0);
6931 opn = "sqrt.d";
6932 break;
6933 case OPC_ABS_D:
6934 check_cp1_registers(ctx, fs | fd);
6936 TCGv_i64 fp0 = tcg_temp_new_i64();
6938 gen_load_fpr64(ctx, fp0, fs);
6939 gen_helper_float_abs_d(fp0, fp0);
6940 gen_store_fpr64(ctx, fp0, fd);
6941 tcg_temp_free_i64(fp0);
6943 opn = "abs.d";
6944 break;
6945 case OPC_MOV_D:
6946 check_cp1_registers(ctx, fs | fd);
6948 TCGv_i64 fp0 = tcg_temp_new_i64();
6950 gen_load_fpr64(ctx, fp0, fs);
6951 gen_store_fpr64(ctx, fp0, fd);
6952 tcg_temp_free_i64(fp0);
6954 opn = "mov.d";
6955 break;
6956 case OPC_NEG_D:
6957 check_cp1_registers(ctx, fs | fd);
6959 TCGv_i64 fp0 = tcg_temp_new_i64();
6961 gen_load_fpr64(ctx, fp0, fs);
6962 gen_helper_float_chs_d(fp0, fp0);
6963 gen_store_fpr64(ctx, fp0, fd);
6964 tcg_temp_free_i64(fp0);
6966 opn = "neg.d";
6967 break;
6968 case OPC_ROUND_L_D:
6969 check_cp1_64bitmode(ctx);
6971 TCGv_i64 fp0 = tcg_temp_new_i64();
6973 gen_load_fpr64(ctx, fp0, fs);
6974 gen_helper_float_roundl_d(fp0, fp0);
6975 gen_store_fpr64(ctx, fp0, fd);
6976 tcg_temp_free_i64(fp0);
6978 opn = "round.l.d";
6979 break;
6980 case OPC_TRUNC_L_D:
6981 check_cp1_64bitmode(ctx);
6983 TCGv_i64 fp0 = tcg_temp_new_i64();
6985 gen_load_fpr64(ctx, fp0, fs);
6986 gen_helper_float_truncl_d(fp0, fp0);
6987 gen_store_fpr64(ctx, fp0, fd);
6988 tcg_temp_free_i64(fp0);
6990 opn = "trunc.l.d";
6991 break;
6992 case OPC_CEIL_L_D:
6993 check_cp1_64bitmode(ctx);
6995 TCGv_i64 fp0 = tcg_temp_new_i64();
6997 gen_load_fpr64(ctx, fp0, fs);
6998 gen_helper_float_ceill_d(fp0, fp0);
6999 gen_store_fpr64(ctx, fp0, fd);
7000 tcg_temp_free_i64(fp0);
7002 opn = "ceil.l.d";
7003 break;
7004 case OPC_FLOOR_L_D:
7005 check_cp1_64bitmode(ctx);
7007 TCGv_i64 fp0 = tcg_temp_new_i64();
7009 gen_load_fpr64(ctx, fp0, fs);
7010 gen_helper_float_floorl_d(fp0, fp0);
7011 gen_store_fpr64(ctx, fp0, fd);
7012 tcg_temp_free_i64(fp0);
7014 opn = "floor.l.d";
7015 break;
7016 case OPC_ROUND_W_D:
7017 check_cp1_registers(ctx, fs);
7019 TCGv_i32 fp32 = tcg_temp_new_i32();
7020 TCGv_i64 fp64 = tcg_temp_new_i64();
7022 gen_load_fpr64(ctx, fp64, fs);
7023 gen_helper_float_roundw_d(fp32, fp64);
7024 tcg_temp_free_i64(fp64);
7025 gen_store_fpr32(fp32, fd);
7026 tcg_temp_free_i32(fp32);
7028 opn = "round.w.d";
7029 break;
7030 case OPC_TRUNC_W_D:
7031 check_cp1_registers(ctx, fs);
7033 TCGv_i32 fp32 = tcg_temp_new_i32();
7034 TCGv_i64 fp64 = tcg_temp_new_i64();
7036 gen_load_fpr64(ctx, fp64, fs);
7037 gen_helper_float_truncw_d(fp32, fp64);
7038 tcg_temp_free_i64(fp64);
7039 gen_store_fpr32(fp32, fd);
7040 tcg_temp_free_i32(fp32);
7042 opn = "trunc.w.d";
7043 break;
7044 case OPC_CEIL_W_D:
7045 check_cp1_registers(ctx, fs);
7047 TCGv_i32 fp32 = tcg_temp_new_i32();
7048 TCGv_i64 fp64 = tcg_temp_new_i64();
7050 gen_load_fpr64(ctx, fp64, fs);
7051 gen_helper_float_ceilw_d(fp32, fp64);
7052 tcg_temp_free_i64(fp64);
7053 gen_store_fpr32(fp32, fd);
7054 tcg_temp_free_i32(fp32);
7056 opn = "ceil.w.d";
7057 break;
7058 case OPC_FLOOR_W_D:
7059 check_cp1_registers(ctx, fs);
7061 TCGv_i32 fp32 = tcg_temp_new_i32();
7062 TCGv_i64 fp64 = tcg_temp_new_i64();
7064 gen_load_fpr64(ctx, fp64, fs);
7065 gen_helper_float_floorw_d(fp32, fp64);
7066 tcg_temp_free_i64(fp64);
7067 gen_store_fpr32(fp32, fd);
7068 tcg_temp_free_i32(fp32);
7070 opn = "floor.w.d";
7071 break;
7072 case OPC_MOVCF_D:
7073 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7074 opn = "movcf.d";
7075 break;
7076 case OPC_MOVZ_D:
7078 int l1 = gen_new_label();
7079 TCGv_i64 fp0;
7081 if (ft != 0) {
7082 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7084 fp0 = tcg_temp_new_i64();
7085 gen_load_fpr64(ctx, fp0, fs);
7086 gen_store_fpr64(ctx, fp0, fd);
7087 tcg_temp_free_i64(fp0);
7088 gen_set_label(l1);
7090 opn = "movz.d";
7091 break;
7092 case OPC_MOVN_D:
7094 int l1 = gen_new_label();
7095 TCGv_i64 fp0;
7097 if (ft != 0) {
7098 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7099 fp0 = tcg_temp_new_i64();
7100 gen_load_fpr64(ctx, fp0, fs);
7101 gen_store_fpr64(ctx, fp0, fd);
7102 tcg_temp_free_i64(fp0);
7103 gen_set_label(l1);
7106 opn = "movn.d";
7107 break;
7108 case OPC_RECIP_D:
7109 check_cp1_64bitmode(ctx);
7111 TCGv_i64 fp0 = tcg_temp_new_i64();
7113 gen_load_fpr64(ctx, fp0, fs);
7114 gen_helper_float_recip_d(fp0, fp0);
7115 gen_store_fpr64(ctx, fp0, fd);
7116 tcg_temp_free_i64(fp0);
7118 opn = "recip.d";
7119 break;
7120 case OPC_RSQRT_D:
7121 check_cp1_64bitmode(ctx);
7123 TCGv_i64 fp0 = tcg_temp_new_i64();
7125 gen_load_fpr64(ctx, fp0, fs);
7126 gen_helper_float_rsqrt_d(fp0, fp0);
7127 gen_store_fpr64(ctx, fp0, fd);
7128 tcg_temp_free_i64(fp0);
7130 opn = "rsqrt.d";
7131 break;
7132 case OPC_RECIP2_D:
7133 check_cp1_64bitmode(ctx);
7135 TCGv_i64 fp0 = tcg_temp_new_i64();
7136 TCGv_i64 fp1 = tcg_temp_new_i64();
7138 gen_load_fpr64(ctx, fp0, fs);
7139 gen_load_fpr64(ctx, fp1, ft);
7140 gen_helper_float_recip2_d(fp0, fp0, fp1);
7141 tcg_temp_free_i64(fp1);
7142 gen_store_fpr64(ctx, fp0, fd);
7143 tcg_temp_free_i64(fp0);
7145 opn = "recip2.d";
7146 break;
7147 case OPC_RECIP1_D:
7148 check_cp1_64bitmode(ctx);
7150 TCGv_i64 fp0 = tcg_temp_new_i64();
7152 gen_load_fpr64(ctx, fp0, fs);
7153 gen_helper_float_recip1_d(fp0, fp0);
7154 gen_store_fpr64(ctx, fp0, fd);
7155 tcg_temp_free_i64(fp0);
7157 opn = "recip1.d";
7158 break;
7159 case OPC_RSQRT1_D:
7160 check_cp1_64bitmode(ctx);
7162 TCGv_i64 fp0 = tcg_temp_new_i64();
7164 gen_load_fpr64(ctx, fp0, fs);
7165 gen_helper_float_rsqrt1_d(fp0, fp0);
7166 gen_store_fpr64(ctx, fp0, fd);
7167 tcg_temp_free_i64(fp0);
7169 opn = "rsqrt1.d";
7170 break;
7171 case OPC_RSQRT2_D:
7172 check_cp1_64bitmode(ctx);
7174 TCGv_i64 fp0 = tcg_temp_new_i64();
7175 TCGv_i64 fp1 = tcg_temp_new_i64();
7177 gen_load_fpr64(ctx, fp0, fs);
7178 gen_load_fpr64(ctx, fp1, ft);
7179 gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
7180 tcg_temp_free_i64(fp1);
7181 gen_store_fpr64(ctx, fp0, fd);
7182 tcg_temp_free_i64(fp0);
7184 opn = "rsqrt2.d";
7185 break;
7186 case OPC_CMP_F_D:
7187 case OPC_CMP_UN_D:
7188 case OPC_CMP_EQ_D:
7189 case OPC_CMP_UEQ_D:
7190 case OPC_CMP_OLT_D:
7191 case OPC_CMP_ULT_D:
7192 case OPC_CMP_OLE_D:
7193 case OPC_CMP_ULE_D:
7194 case OPC_CMP_SF_D:
7195 case OPC_CMP_NGLE_D:
7196 case OPC_CMP_SEQ_D:
7197 case OPC_CMP_NGL_D:
7198 case OPC_CMP_LT_D:
7199 case OPC_CMP_NGE_D:
7200 case OPC_CMP_LE_D:
7201 case OPC_CMP_NGT_D:
7202 if (ctx->opcode & (1 << 6)) {
7203 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7204 opn = condnames_abs[func-48];
7205 } else {
7206 gen_cmp_d(ctx, func-48, ft, fs, cc);
7207 opn = condnames[func-48];
7209 break;
7210 case OPC_CVT_S_D:
7211 check_cp1_registers(ctx, fs);
7213 TCGv_i32 fp32 = tcg_temp_new_i32();
7214 TCGv_i64 fp64 = tcg_temp_new_i64();
7216 gen_load_fpr64(ctx, fp64, fs);
7217 gen_helper_float_cvts_d(fp32, fp64);
7218 tcg_temp_free_i64(fp64);
7219 gen_store_fpr32(fp32, fd);
7220 tcg_temp_free_i32(fp32);
7222 opn = "cvt.s.d";
7223 break;
7224 case OPC_CVT_W_D:
7225 check_cp1_registers(ctx, fs);
7227 TCGv_i32 fp32 = tcg_temp_new_i32();
7228 TCGv_i64 fp64 = tcg_temp_new_i64();
7230 gen_load_fpr64(ctx, fp64, fs);
7231 gen_helper_float_cvtw_d(fp32, fp64);
7232 tcg_temp_free_i64(fp64);
7233 gen_store_fpr32(fp32, fd);
7234 tcg_temp_free_i32(fp32);
7236 opn = "cvt.w.d";
7237 break;
7238 case OPC_CVT_L_D:
7239 check_cp1_64bitmode(ctx);
7241 TCGv_i64 fp0 = tcg_temp_new_i64();
7243 gen_load_fpr64(ctx, fp0, fs);
7244 gen_helper_float_cvtl_d(fp0, fp0);
7245 gen_store_fpr64(ctx, fp0, fd);
7246 tcg_temp_free_i64(fp0);
7248 opn = "cvt.l.d";
7249 break;
7250 case OPC_CVT_S_W:
7252 TCGv_i32 fp0 = tcg_temp_new_i32();
7254 gen_load_fpr32(fp0, fs);
7255 gen_helper_float_cvts_w(fp0, fp0);
7256 gen_store_fpr32(fp0, fd);
7257 tcg_temp_free_i32(fp0);
7259 opn = "cvt.s.w";
7260 break;
7261 case OPC_CVT_D_W:
7262 check_cp1_registers(ctx, fd);
7264 TCGv_i32 fp32 = tcg_temp_new_i32();
7265 TCGv_i64 fp64 = tcg_temp_new_i64();
7267 gen_load_fpr32(fp32, fs);
7268 gen_helper_float_cvtd_w(fp64, fp32);
7269 tcg_temp_free_i32(fp32);
7270 gen_store_fpr64(ctx, fp64, fd);
7271 tcg_temp_free_i64(fp64);
7273 opn = "cvt.d.w";
7274 break;
7275 case OPC_CVT_S_L:
7276 check_cp1_64bitmode(ctx);
7278 TCGv_i32 fp32 = tcg_temp_new_i32();
7279 TCGv_i64 fp64 = tcg_temp_new_i64();
7281 gen_load_fpr64(ctx, fp64, fs);
7282 gen_helper_float_cvts_l(fp32, fp64);
7283 tcg_temp_free_i64(fp64);
7284 gen_store_fpr32(fp32, fd);
7285 tcg_temp_free_i32(fp32);
7287 opn = "cvt.s.l";
7288 break;
7289 case OPC_CVT_D_L:
7290 check_cp1_64bitmode(ctx);
7292 TCGv_i64 fp0 = tcg_temp_new_i64();
7294 gen_load_fpr64(ctx, fp0, fs);
7295 gen_helper_float_cvtd_l(fp0, fp0);
7296 gen_store_fpr64(ctx, fp0, fd);
7297 tcg_temp_free_i64(fp0);
7299 opn = "cvt.d.l";
7300 break;
7301 case OPC_CVT_PS_PW:
7302 check_cp1_64bitmode(ctx);
7304 TCGv_i64 fp0 = tcg_temp_new_i64();
7306 gen_load_fpr64(ctx, fp0, fs);
7307 gen_helper_float_cvtps_pw(fp0, fp0);
7308 gen_store_fpr64(ctx, fp0, fd);
7309 tcg_temp_free_i64(fp0);
7311 opn = "cvt.ps.pw";
7312 break;
7313 case OPC_ADD_PS:
7314 check_cp1_64bitmode(ctx);
7316 TCGv_i64 fp0 = tcg_temp_new_i64();
7317 TCGv_i64 fp1 = tcg_temp_new_i64();
7319 gen_load_fpr64(ctx, fp0, fs);
7320 gen_load_fpr64(ctx, fp1, ft);
7321 gen_helper_float_add_ps(fp0, fp0, fp1);
7322 tcg_temp_free_i64(fp1);
7323 gen_store_fpr64(ctx, fp0, fd);
7324 tcg_temp_free_i64(fp0);
7326 opn = "add.ps";
7327 break;
7328 case OPC_SUB_PS:
7329 check_cp1_64bitmode(ctx);
7331 TCGv_i64 fp0 = tcg_temp_new_i64();
7332 TCGv_i64 fp1 = tcg_temp_new_i64();
7334 gen_load_fpr64(ctx, fp0, fs);
7335 gen_load_fpr64(ctx, fp1, ft);
7336 gen_helper_float_sub_ps(fp0, fp0, fp1);
7337 tcg_temp_free_i64(fp1);
7338 gen_store_fpr64(ctx, fp0, fd);
7339 tcg_temp_free_i64(fp0);
7341 opn = "sub.ps";
7342 break;
7343 case OPC_MUL_PS:
7344 check_cp1_64bitmode(ctx);
7346 TCGv_i64 fp0 = tcg_temp_new_i64();
7347 TCGv_i64 fp1 = tcg_temp_new_i64();
7349 gen_load_fpr64(ctx, fp0, fs);
7350 gen_load_fpr64(ctx, fp1, ft);
7351 gen_helper_float_mul_ps(fp0, fp0, fp1);
7352 tcg_temp_free_i64(fp1);
7353 gen_store_fpr64(ctx, fp0, fd);
7354 tcg_temp_free_i64(fp0);
7356 opn = "mul.ps";
7357 break;
7358 case OPC_ABS_PS:
7359 check_cp1_64bitmode(ctx);
7361 TCGv_i64 fp0 = tcg_temp_new_i64();
7363 gen_load_fpr64(ctx, fp0, fs);
7364 gen_helper_float_abs_ps(fp0, fp0);
7365 gen_store_fpr64(ctx, fp0, fd);
7366 tcg_temp_free_i64(fp0);
7368 opn = "abs.ps";
7369 break;
7370 case OPC_MOV_PS:
7371 check_cp1_64bitmode(ctx);
7373 TCGv_i64 fp0 = tcg_temp_new_i64();
7375 gen_load_fpr64(ctx, fp0, fs);
7376 gen_store_fpr64(ctx, fp0, fd);
7377 tcg_temp_free_i64(fp0);
7379 opn = "mov.ps";
7380 break;
7381 case OPC_NEG_PS:
7382 check_cp1_64bitmode(ctx);
7384 TCGv_i64 fp0 = tcg_temp_new_i64();
7386 gen_load_fpr64(ctx, fp0, fs);
7387 gen_helper_float_chs_ps(fp0, fp0);
7388 gen_store_fpr64(ctx, fp0, fd);
7389 tcg_temp_free_i64(fp0);
7391 opn = "neg.ps";
7392 break;
7393 case OPC_MOVCF_PS:
7394 check_cp1_64bitmode(ctx);
7395 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7396 opn = "movcf.ps";
7397 break;
7398 case OPC_MOVZ_PS:
7399 check_cp1_64bitmode(ctx);
7401 int l1 = gen_new_label();
7402 TCGv_i64 fp0;
7404 if (ft != 0)
7405 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7406 fp0 = tcg_temp_new_i64();
7407 gen_load_fpr64(ctx, fp0, fs);
7408 gen_store_fpr64(ctx, fp0, fd);
7409 tcg_temp_free_i64(fp0);
7410 gen_set_label(l1);
7412 opn = "movz.ps";
7413 break;
7414 case OPC_MOVN_PS:
7415 check_cp1_64bitmode(ctx);
7417 int l1 = gen_new_label();
7418 TCGv_i64 fp0;
7420 if (ft != 0) {
7421 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7422 fp0 = tcg_temp_new_i64();
7423 gen_load_fpr64(ctx, fp0, fs);
7424 gen_store_fpr64(ctx, fp0, fd);
7425 tcg_temp_free_i64(fp0);
7426 gen_set_label(l1);
7429 opn = "movn.ps";
7430 break;
7431 case OPC_ADDR_PS:
7432 check_cp1_64bitmode(ctx);
7434 TCGv_i64 fp0 = tcg_temp_new_i64();
7435 TCGv_i64 fp1 = tcg_temp_new_i64();
7437 gen_load_fpr64(ctx, fp0, ft);
7438 gen_load_fpr64(ctx, fp1, fs);
7439 gen_helper_float_addr_ps(fp0, fp0, fp1);
7440 tcg_temp_free_i64(fp1);
7441 gen_store_fpr64(ctx, fp0, fd);
7442 tcg_temp_free_i64(fp0);
7444 opn = "addr.ps";
7445 break;
7446 case OPC_MULR_PS:
7447 check_cp1_64bitmode(ctx);
7449 TCGv_i64 fp0 = tcg_temp_new_i64();
7450 TCGv_i64 fp1 = tcg_temp_new_i64();
7452 gen_load_fpr64(ctx, fp0, ft);
7453 gen_load_fpr64(ctx, fp1, fs);
7454 gen_helper_float_mulr_ps(fp0, fp0, fp1);
7455 tcg_temp_free_i64(fp1);
7456 gen_store_fpr64(ctx, fp0, fd);
7457 tcg_temp_free_i64(fp0);
7459 opn = "mulr.ps";
7460 break;
7461 case OPC_RECIP2_PS:
7462 check_cp1_64bitmode(ctx);
7464 TCGv_i64 fp0 = tcg_temp_new_i64();
7465 TCGv_i64 fp1 = tcg_temp_new_i64();
7467 gen_load_fpr64(ctx, fp0, fs);
7468 gen_load_fpr64(ctx, fp1, fd);
7469 gen_helper_float_recip2_ps(fp0, fp0, fp1);
7470 tcg_temp_free_i64(fp1);
7471 gen_store_fpr64(ctx, fp0, fd);
7472 tcg_temp_free_i64(fp0);
7474 opn = "recip2.ps";
7475 break;
7476 case OPC_RECIP1_PS:
7477 check_cp1_64bitmode(ctx);
7479 TCGv_i64 fp0 = tcg_temp_new_i64();
7481 gen_load_fpr64(ctx, fp0, fs);
7482 gen_helper_float_recip1_ps(fp0, fp0);
7483 gen_store_fpr64(ctx, fp0, fd);
7484 tcg_temp_free_i64(fp0);
7486 opn = "recip1.ps";
7487 break;
7488 case OPC_RSQRT1_PS:
7489 check_cp1_64bitmode(ctx);
7491 TCGv_i64 fp0 = tcg_temp_new_i64();
7493 gen_load_fpr64(ctx, fp0, fs);
7494 gen_helper_float_rsqrt1_ps(fp0, fp0);
7495 gen_store_fpr64(ctx, fp0, fd);
7496 tcg_temp_free_i64(fp0);
7498 opn = "rsqrt1.ps";
7499 break;
7500 case OPC_RSQRT2_PS:
7501 check_cp1_64bitmode(ctx);
7503 TCGv_i64 fp0 = tcg_temp_new_i64();
7504 TCGv_i64 fp1 = tcg_temp_new_i64();
7506 gen_load_fpr64(ctx, fp0, fs);
7507 gen_load_fpr64(ctx, fp1, ft);
7508 gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7509 tcg_temp_free_i64(fp1);
7510 gen_store_fpr64(ctx, fp0, fd);
7511 tcg_temp_free_i64(fp0);
7513 opn = "rsqrt2.ps";
7514 break;
7515 case OPC_CVT_S_PU:
7516 check_cp1_64bitmode(ctx);
7518 TCGv_i32 fp0 = tcg_temp_new_i32();
7520 gen_load_fpr32h(fp0, fs);
7521 gen_helper_float_cvts_pu(fp0, fp0);
7522 gen_store_fpr32(fp0, fd);
7523 tcg_temp_free_i32(fp0);
7525 opn = "cvt.s.pu";
7526 break;
7527 case OPC_CVT_PW_PS:
7528 check_cp1_64bitmode(ctx);
7530 TCGv_i64 fp0 = tcg_temp_new_i64();
7532 gen_load_fpr64(ctx, fp0, fs);
7533 gen_helper_float_cvtpw_ps(fp0, fp0);
7534 gen_store_fpr64(ctx, fp0, fd);
7535 tcg_temp_free_i64(fp0);
7537 opn = "cvt.pw.ps";
7538 break;
7539 case OPC_CVT_S_PL:
7540 check_cp1_64bitmode(ctx);
7542 TCGv_i32 fp0 = tcg_temp_new_i32();
7544 gen_load_fpr32(fp0, fs);
7545 gen_helper_float_cvts_pl(fp0, fp0);
7546 gen_store_fpr32(fp0, fd);
7547 tcg_temp_free_i32(fp0);
7549 opn = "cvt.s.pl";
7550 break;
7551 case OPC_PLL_PS:
7552 check_cp1_64bitmode(ctx);
7554 TCGv_i32 fp0 = tcg_temp_new_i32();
7555 TCGv_i32 fp1 = tcg_temp_new_i32();
7557 gen_load_fpr32(fp0, fs);
7558 gen_load_fpr32(fp1, ft);
7559 gen_store_fpr32h(fp0, fd);
7560 gen_store_fpr32(fp1, fd);
7561 tcg_temp_free_i32(fp0);
7562 tcg_temp_free_i32(fp1);
7564 opn = "pll.ps";
7565 break;
7566 case OPC_PLU_PS:
7567 check_cp1_64bitmode(ctx);
7569 TCGv_i32 fp0 = tcg_temp_new_i32();
7570 TCGv_i32 fp1 = tcg_temp_new_i32();
7572 gen_load_fpr32(fp0, fs);
7573 gen_load_fpr32h(fp1, ft);
7574 gen_store_fpr32(fp1, fd);
7575 gen_store_fpr32h(fp0, fd);
7576 tcg_temp_free_i32(fp0);
7577 tcg_temp_free_i32(fp1);
7579 opn = "plu.ps";
7580 break;
7581 case OPC_PUL_PS:
7582 check_cp1_64bitmode(ctx);
7584 TCGv_i32 fp0 = tcg_temp_new_i32();
7585 TCGv_i32 fp1 = tcg_temp_new_i32();
7587 gen_load_fpr32h(fp0, fs);
7588 gen_load_fpr32(fp1, ft);
7589 gen_store_fpr32(fp1, fd);
7590 gen_store_fpr32h(fp0, fd);
7591 tcg_temp_free_i32(fp0);
7592 tcg_temp_free_i32(fp1);
7594 opn = "pul.ps";
7595 break;
7596 case OPC_PUU_PS:
7597 check_cp1_64bitmode(ctx);
7599 TCGv_i32 fp0 = tcg_temp_new_i32();
7600 TCGv_i32 fp1 = tcg_temp_new_i32();
7602 gen_load_fpr32h(fp0, fs);
7603 gen_load_fpr32h(fp1, ft);
7604 gen_store_fpr32(fp1, fd);
7605 gen_store_fpr32h(fp0, fd);
7606 tcg_temp_free_i32(fp0);
7607 tcg_temp_free_i32(fp1);
7609 opn = "puu.ps";
7610 break;
7611 case OPC_CMP_F_PS:
7612 case OPC_CMP_UN_PS:
7613 case OPC_CMP_EQ_PS:
7614 case OPC_CMP_UEQ_PS:
7615 case OPC_CMP_OLT_PS:
7616 case OPC_CMP_ULT_PS:
7617 case OPC_CMP_OLE_PS:
7618 case OPC_CMP_ULE_PS:
7619 case OPC_CMP_SF_PS:
7620 case OPC_CMP_NGLE_PS:
7621 case OPC_CMP_SEQ_PS:
7622 case OPC_CMP_NGL_PS:
7623 case OPC_CMP_LT_PS:
7624 case OPC_CMP_NGE_PS:
7625 case OPC_CMP_LE_PS:
7626 case OPC_CMP_NGT_PS:
7627 if (ctx->opcode & (1 << 6)) {
7628 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7629 opn = condnames_abs[func-48];
7630 } else {
7631 gen_cmp_ps(ctx, func-48, ft, fs, cc);
7632 opn = condnames[func-48];
7634 break;
7635 default:
7636 MIPS_INVAL(opn);
7637 generate_exception (ctx, EXCP_RI);
7638 return;
7640 (void)opn; /* avoid a compiler warning */
7641 switch (optype) {
7642 case BINOP:
7643 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7644 break;
7645 case CMPOP:
7646 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7647 break;
7648 default:
7649 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7650 break;
7654 /* Coprocessor 3 (FPU) */
7655 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7656 int fd, int fs, int base, int index)
7658 const char *opn = "extended float load/store";
7659 int store = 0;
7660 TCGv t0 = tcg_temp_new();
7662 if (base == 0) {
7663 gen_load_gpr(t0, index);
7664 } else if (index == 0) {
7665 gen_load_gpr(t0, base);
7666 } else {
7667 gen_load_gpr(t0, index);
7668 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7670 /* Don't do NOP if destination is zero: we must perform the actual
7671 memory access. */
7672 save_cpu_state(ctx, 0);
7673 switch (opc) {
7674 case OPC_LWXC1:
7675 check_cop1x(ctx);
7677 TCGv_i32 fp0 = tcg_temp_new_i32();
7679 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7680 tcg_gen_trunc_tl_i32(fp0, t0);
7681 gen_store_fpr32(fp0, fd);
7682 tcg_temp_free_i32(fp0);
7684 opn = "lwxc1";
7685 break;
7686 case OPC_LDXC1:
7687 check_cop1x(ctx);
7688 check_cp1_registers(ctx, fd);
7690 TCGv_i64 fp0 = tcg_temp_new_i64();
7692 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7693 gen_store_fpr64(ctx, fp0, fd);
7694 tcg_temp_free_i64(fp0);
7696 opn = "ldxc1";
7697 break;
7698 case OPC_LUXC1:
7699 check_cp1_64bitmode(ctx);
7700 tcg_gen_andi_tl(t0, t0, ~0x7);
7702 TCGv_i64 fp0 = tcg_temp_new_i64();
7704 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7705 gen_store_fpr64(ctx, fp0, fd);
7706 tcg_temp_free_i64(fp0);
7708 opn = "luxc1";
7709 break;
7710 case OPC_SWXC1:
7711 check_cop1x(ctx);
7713 TCGv_i32 fp0 = tcg_temp_new_i32();
7714 TCGv t1 = tcg_temp_new();
7716 gen_load_fpr32(fp0, fs);
7717 tcg_gen_extu_i32_tl(t1, fp0);
7718 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7719 tcg_temp_free_i32(fp0);
7720 tcg_temp_free(t1);
7722 opn = "swxc1";
7723 store = 1;
7724 break;
7725 case OPC_SDXC1:
7726 check_cop1x(ctx);
7727 check_cp1_registers(ctx, fs);
7729 TCGv_i64 fp0 = tcg_temp_new_i64();
7731 gen_load_fpr64(ctx, fp0, fs);
7732 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7733 tcg_temp_free_i64(fp0);
7735 opn = "sdxc1";
7736 store = 1;
7737 break;
7738 case OPC_SUXC1:
7739 check_cp1_64bitmode(ctx);
7740 tcg_gen_andi_tl(t0, t0, ~0x7);
7742 TCGv_i64 fp0 = tcg_temp_new_i64();
7744 gen_load_fpr64(ctx, fp0, fs);
7745 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7746 tcg_temp_free_i64(fp0);
7748 opn = "suxc1";
7749 store = 1;
7750 break;
7752 tcg_temp_free(t0);
7753 (void)opn; (void)store; /* avoid compiler warnings */
7754 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7755 regnames[index], regnames[base]);
7758 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7759 int fd, int fr, int fs, int ft)
7761 const char *opn = "flt3_arith";
7763 switch (opc) {
7764 case OPC_ALNV_PS:
7765 check_cp1_64bitmode(ctx);
7767 TCGv t0 = tcg_temp_local_new();
7768 TCGv_i32 fp = tcg_temp_new_i32();
7769 TCGv_i32 fph = tcg_temp_new_i32();
7770 int l1 = gen_new_label();
7771 int l2 = gen_new_label();
7773 gen_load_gpr(t0, fr);
7774 tcg_gen_andi_tl(t0, t0, 0x7);
7776 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7777 gen_load_fpr32(fp, fs);
7778 gen_load_fpr32h(fph, fs);
7779 gen_store_fpr32(fp, fd);
7780 gen_store_fpr32h(fph, fd);
7781 tcg_gen_br(l2);
7782 gen_set_label(l1);
7783 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7784 tcg_temp_free(t0);
7785 #ifdef TARGET_WORDS_BIGENDIAN
7786 gen_load_fpr32(fp, fs);
7787 gen_load_fpr32h(fph, ft);
7788 gen_store_fpr32h(fp, fd);
7789 gen_store_fpr32(fph, fd);
7790 #else
7791 gen_load_fpr32h(fph, fs);
7792 gen_load_fpr32(fp, ft);
7793 gen_store_fpr32(fph, fd);
7794 gen_store_fpr32h(fp, fd);
7795 #endif
7796 gen_set_label(l2);
7797 tcg_temp_free_i32(fp);
7798 tcg_temp_free_i32(fph);
7800 opn = "alnv.ps";
7801 break;
7802 case OPC_MADD_S:
7803 check_cop1x(ctx);
7805 TCGv_i32 fp0 = tcg_temp_new_i32();
7806 TCGv_i32 fp1 = tcg_temp_new_i32();
7807 TCGv_i32 fp2 = tcg_temp_new_i32();
7809 gen_load_fpr32(fp0, fs);
7810 gen_load_fpr32(fp1, ft);
7811 gen_load_fpr32(fp2, fr);
7812 gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7813 tcg_temp_free_i32(fp0);
7814 tcg_temp_free_i32(fp1);
7815 gen_store_fpr32(fp2, fd);
7816 tcg_temp_free_i32(fp2);
7818 opn = "madd.s";
7819 break;
7820 case OPC_MADD_D:
7821 check_cop1x(ctx);
7822 check_cp1_registers(ctx, fd | fs | ft | fr);
7824 TCGv_i64 fp0 = tcg_temp_new_i64();
7825 TCGv_i64 fp1 = tcg_temp_new_i64();
7826 TCGv_i64 fp2 = tcg_temp_new_i64();
7828 gen_load_fpr64(ctx, fp0, fs);
7829 gen_load_fpr64(ctx, fp1, ft);
7830 gen_load_fpr64(ctx, fp2, fr);
7831 gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7832 tcg_temp_free_i64(fp0);
7833 tcg_temp_free_i64(fp1);
7834 gen_store_fpr64(ctx, fp2, fd);
7835 tcg_temp_free_i64(fp2);
7837 opn = "madd.d";
7838 break;
7839 case OPC_MADD_PS:
7840 check_cp1_64bitmode(ctx);
7842 TCGv_i64 fp0 = tcg_temp_new_i64();
7843 TCGv_i64 fp1 = tcg_temp_new_i64();
7844 TCGv_i64 fp2 = tcg_temp_new_i64();
7846 gen_load_fpr64(ctx, fp0, fs);
7847 gen_load_fpr64(ctx, fp1, ft);
7848 gen_load_fpr64(ctx, fp2, fr);
7849 gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7850 tcg_temp_free_i64(fp0);
7851 tcg_temp_free_i64(fp1);
7852 gen_store_fpr64(ctx, fp2, fd);
7853 tcg_temp_free_i64(fp2);
7855 opn = "madd.ps";
7856 break;
7857 case OPC_MSUB_S:
7858 check_cop1x(ctx);
7860 TCGv_i32 fp0 = tcg_temp_new_i32();
7861 TCGv_i32 fp1 = tcg_temp_new_i32();
7862 TCGv_i32 fp2 = tcg_temp_new_i32();
7864 gen_load_fpr32(fp0, fs);
7865 gen_load_fpr32(fp1, ft);
7866 gen_load_fpr32(fp2, fr);
7867 gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7868 tcg_temp_free_i32(fp0);
7869 tcg_temp_free_i32(fp1);
7870 gen_store_fpr32(fp2, fd);
7871 tcg_temp_free_i32(fp2);
7873 opn = "msub.s";
7874 break;
7875 case OPC_MSUB_D:
7876 check_cop1x(ctx);
7877 check_cp1_registers(ctx, fd | fs | ft | fr);
7879 TCGv_i64 fp0 = tcg_temp_new_i64();
7880 TCGv_i64 fp1 = tcg_temp_new_i64();
7881 TCGv_i64 fp2 = tcg_temp_new_i64();
7883 gen_load_fpr64(ctx, fp0, fs);
7884 gen_load_fpr64(ctx, fp1, ft);
7885 gen_load_fpr64(ctx, fp2, fr);
7886 gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7887 tcg_temp_free_i64(fp0);
7888 tcg_temp_free_i64(fp1);
7889 gen_store_fpr64(ctx, fp2, fd);
7890 tcg_temp_free_i64(fp2);
7892 opn = "msub.d";
7893 break;
7894 case OPC_MSUB_PS:
7895 check_cp1_64bitmode(ctx);
7897 TCGv_i64 fp0 = tcg_temp_new_i64();
7898 TCGv_i64 fp1 = tcg_temp_new_i64();
7899 TCGv_i64 fp2 = tcg_temp_new_i64();
7901 gen_load_fpr64(ctx, fp0, fs);
7902 gen_load_fpr64(ctx, fp1, ft);
7903 gen_load_fpr64(ctx, fp2, fr);
7904 gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7905 tcg_temp_free_i64(fp0);
7906 tcg_temp_free_i64(fp1);
7907 gen_store_fpr64(ctx, fp2, fd);
7908 tcg_temp_free_i64(fp2);
7910 opn = "msub.ps";
7911 break;
7912 case OPC_NMADD_S:
7913 check_cop1x(ctx);
7915 TCGv_i32 fp0 = tcg_temp_new_i32();
7916 TCGv_i32 fp1 = tcg_temp_new_i32();
7917 TCGv_i32 fp2 = tcg_temp_new_i32();
7919 gen_load_fpr32(fp0, fs);
7920 gen_load_fpr32(fp1, ft);
7921 gen_load_fpr32(fp2, fr);
7922 gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7923 tcg_temp_free_i32(fp0);
7924 tcg_temp_free_i32(fp1);
7925 gen_store_fpr32(fp2, fd);
7926 tcg_temp_free_i32(fp2);
7928 opn = "nmadd.s";
7929 break;
7930 case OPC_NMADD_D:
7931 check_cop1x(ctx);
7932 check_cp1_registers(ctx, fd | fs | ft | fr);
7934 TCGv_i64 fp0 = tcg_temp_new_i64();
7935 TCGv_i64 fp1 = tcg_temp_new_i64();
7936 TCGv_i64 fp2 = tcg_temp_new_i64();
7938 gen_load_fpr64(ctx, fp0, fs);
7939 gen_load_fpr64(ctx, fp1, ft);
7940 gen_load_fpr64(ctx, fp2, fr);
7941 gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7942 tcg_temp_free_i64(fp0);
7943 tcg_temp_free_i64(fp1);
7944 gen_store_fpr64(ctx, fp2, fd);
7945 tcg_temp_free_i64(fp2);
7947 opn = "nmadd.d";
7948 break;
7949 case OPC_NMADD_PS:
7950 check_cp1_64bitmode(ctx);
7952 TCGv_i64 fp0 = tcg_temp_new_i64();
7953 TCGv_i64 fp1 = tcg_temp_new_i64();
7954 TCGv_i64 fp2 = tcg_temp_new_i64();
7956 gen_load_fpr64(ctx, fp0, fs);
7957 gen_load_fpr64(ctx, fp1, ft);
7958 gen_load_fpr64(ctx, fp2, fr);
7959 gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7960 tcg_temp_free_i64(fp0);
7961 tcg_temp_free_i64(fp1);
7962 gen_store_fpr64(ctx, fp2, fd);
7963 tcg_temp_free_i64(fp2);
7965 opn = "nmadd.ps";
7966 break;
7967 case OPC_NMSUB_S:
7968 check_cop1x(ctx);
7970 TCGv_i32 fp0 = tcg_temp_new_i32();
7971 TCGv_i32 fp1 = tcg_temp_new_i32();
7972 TCGv_i32 fp2 = tcg_temp_new_i32();
7974 gen_load_fpr32(fp0, fs);
7975 gen_load_fpr32(fp1, ft);
7976 gen_load_fpr32(fp2, fr);
7977 gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7978 tcg_temp_free_i32(fp0);
7979 tcg_temp_free_i32(fp1);
7980 gen_store_fpr32(fp2, fd);
7981 tcg_temp_free_i32(fp2);
7983 opn = "nmsub.s";
7984 break;
7985 case OPC_NMSUB_D:
7986 check_cop1x(ctx);
7987 check_cp1_registers(ctx, fd | fs | ft | fr);
7989 TCGv_i64 fp0 = tcg_temp_new_i64();
7990 TCGv_i64 fp1 = tcg_temp_new_i64();
7991 TCGv_i64 fp2 = tcg_temp_new_i64();
7993 gen_load_fpr64(ctx, fp0, fs);
7994 gen_load_fpr64(ctx, fp1, ft);
7995 gen_load_fpr64(ctx, fp2, fr);
7996 gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7997 tcg_temp_free_i64(fp0);
7998 tcg_temp_free_i64(fp1);
7999 gen_store_fpr64(ctx, fp2, fd);
8000 tcg_temp_free_i64(fp2);
8002 opn = "nmsub.d";
8003 break;
8004 case OPC_NMSUB_PS:
8005 check_cp1_64bitmode(ctx);
8007 TCGv_i64 fp0 = tcg_temp_new_i64();
8008 TCGv_i64 fp1 = tcg_temp_new_i64();
8009 TCGv_i64 fp2 = tcg_temp_new_i64();
8011 gen_load_fpr64(ctx, fp0, fs);
8012 gen_load_fpr64(ctx, fp1, ft);
8013 gen_load_fpr64(ctx, fp2, fr);
8014 gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
8015 tcg_temp_free_i64(fp0);
8016 tcg_temp_free_i64(fp1);
8017 gen_store_fpr64(ctx, fp2, fd);
8018 tcg_temp_free_i64(fp2);
8020 opn = "nmsub.ps";
8021 break;
8022 default:
8023 MIPS_INVAL(opn);
8024 generate_exception (ctx, EXCP_RI);
8025 return;
8027 (void)opn; /* avoid a compiler warning */
8028 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
8029 fregnames[fs], fregnames[ft]);
8032 static void
8033 gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
8035 TCGv t0;
8037 check_insn(env, ctx, ISA_MIPS32R2);
8038 t0 = tcg_temp_new();
8040 switch (rd) {
8041 case 0:
8042 save_cpu_state(ctx, 1);
8043 gen_helper_rdhwr_cpunum(t0);
8044 gen_store_gpr(t0, rt);
8045 break;
8046 case 1:
8047 save_cpu_state(ctx, 1);
8048 gen_helper_rdhwr_synci_step(t0);
8049 gen_store_gpr(t0, rt);
8050 break;
8051 case 2:
8052 save_cpu_state(ctx, 1);
8053 gen_helper_rdhwr_cc(t0);
8054 gen_store_gpr(t0, rt);
8055 break;
8056 case 3:
8057 save_cpu_state(ctx, 1);
8058 gen_helper_rdhwr_ccres(t0);
8059 gen_store_gpr(t0, rt);
8060 break;
8061 case 29:
8062 #if defined(CONFIG_USER_ONLY)
8063 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
8064 gen_store_gpr(t0, rt);
8065 break;
8066 #else
8067 /* XXX: Some CPUs implement this in hardware.
8068 Not supported yet. */
8069 #endif
8070 default: /* Invalid */
8071 MIPS_INVAL("rdhwr");
8072 generate_exception(ctx, EXCP_RI);
8073 break;
8075 tcg_temp_free(t0);
8078 static void handle_delay_slot (CPUState *env, DisasContext *ctx,
8079 int insn_bytes)
8081 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8082 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8083 /* Branches completion */
8084 ctx->hflags &= ~MIPS_HFLAG_BMASK;
8085 ctx->bstate = BS_BRANCH;
8086 save_cpu_state(ctx, 0);
8087 /* FIXME: Need to clear can_do_io. */
8088 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
8089 case MIPS_HFLAG_B:
8090 /* unconditional branch */
8091 MIPS_DEBUG("unconditional branch");
8092 if (proc_hflags & MIPS_HFLAG_BX) {
8093 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
8095 gen_goto_tb(ctx, 0, ctx->btarget);
8096 break;
8097 case MIPS_HFLAG_BL:
8098 /* blikely taken case */
8099 MIPS_DEBUG("blikely branch taken");
8100 gen_goto_tb(ctx, 0, ctx->btarget);
8101 break;
8102 case MIPS_HFLAG_BC:
8103 /* Conditional branch */
8104 MIPS_DEBUG("conditional branch");
8106 int l1 = gen_new_label();
8108 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8109 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
8110 gen_set_label(l1);
8111 gen_goto_tb(ctx, 0, ctx->btarget);
8113 break;
8114 case MIPS_HFLAG_BR:
8115 /* unconditional branch to register */
8116 MIPS_DEBUG("branch to register");
8117 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
8118 TCGv t0 = tcg_temp_new();
8119 TCGv_i32 t1 = tcg_temp_new_i32();
8121 tcg_gen_andi_tl(t0, btarget, 0x1);
8122 tcg_gen_trunc_tl_i32(t1, t0);
8123 tcg_temp_free(t0);
8124 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
8125 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
8126 tcg_gen_or_i32(hflags, hflags, t1);
8127 tcg_temp_free_i32(t1);
8129 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
8130 } else {
8131 tcg_gen_mov_tl(cpu_PC, btarget);
8133 if (ctx->singlestep_enabled) {
8134 save_cpu_state(ctx, 0);
8135 gen_helper_0i(raise_exception, EXCP_DEBUG);
8137 tcg_gen_exit_tb(0);
8138 break;
8139 default:
8140 MIPS_DEBUG("unknown branch");
8141 break;
8146 /* ISA extensions (ASEs) */
8147 /* MIPS16 extension to MIPS32 */
8149 /* MIPS16 major opcodes */
8150 enum {
8151 M16_OPC_ADDIUSP = 0x00,
8152 M16_OPC_ADDIUPC = 0x01,
8153 M16_OPC_B = 0x02,
8154 M16_OPC_JAL = 0x03,
8155 M16_OPC_BEQZ = 0x04,
8156 M16_OPC_BNEQZ = 0x05,
8157 M16_OPC_SHIFT = 0x06,
8158 M16_OPC_LD = 0x07,
8159 M16_OPC_RRIA = 0x08,
8160 M16_OPC_ADDIU8 = 0x09,
8161 M16_OPC_SLTI = 0x0a,
8162 M16_OPC_SLTIU = 0x0b,
8163 M16_OPC_I8 = 0x0c,
8164 M16_OPC_LI = 0x0d,
8165 M16_OPC_CMPI = 0x0e,
8166 M16_OPC_SD = 0x0f,
8167 M16_OPC_LB = 0x10,
8168 M16_OPC_LH = 0x11,
8169 M16_OPC_LWSP = 0x12,
8170 M16_OPC_LW = 0x13,
8171 M16_OPC_LBU = 0x14,
8172 M16_OPC_LHU = 0x15,
8173 M16_OPC_LWPC = 0x16,
8174 M16_OPC_LWU = 0x17,
8175 M16_OPC_SB = 0x18,
8176 M16_OPC_SH = 0x19,
8177 M16_OPC_SWSP = 0x1a,
8178 M16_OPC_SW = 0x1b,
8179 M16_OPC_RRR = 0x1c,
8180 M16_OPC_RR = 0x1d,
8181 M16_OPC_EXTEND = 0x1e,
8182 M16_OPC_I64 = 0x1f
8185 /* I8 funct field */
8186 enum {
8187 I8_BTEQZ = 0x0,
8188 I8_BTNEZ = 0x1,
8189 I8_SWRASP = 0x2,
8190 I8_ADJSP = 0x3,
8191 I8_SVRS = 0x4,
8192 I8_MOV32R = 0x5,
8193 I8_MOVR32 = 0x7
8196 /* RRR f field */
8197 enum {
8198 RRR_DADDU = 0x0,
8199 RRR_ADDU = 0x1,
8200 RRR_DSUBU = 0x2,
8201 RRR_SUBU = 0x3
8204 /* RR funct field */
8205 enum {
8206 RR_JR = 0x00,
8207 RR_SDBBP = 0x01,
8208 RR_SLT = 0x02,
8209 RR_SLTU = 0x03,
8210 RR_SLLV = 0x04,
8211 RR_BREAK = 0x05,
8212 RR_SRLV = 0x06,
8213 RR_SRAV = 0x07,
8214 RR_DSRL = 0x08,
8215 RR_CMP = 0x0a,
8216 RR_NEG = 0x0b,
8217 RR_AND = 0x0c,
8218 RR_OR = 0x0d,
8219 RR_XOR = 0x0e,
8220 RR_NOT = 0x0f,
8221 RR_MFHI = 0x10,
8222 RR_CNVT = 0x11,
8223 RR_MFLO = 0x12,
8224 RR_DSRA = 0x13,
8225 RR_DSLLV = 0x14,
8226 RR_DSRLV = 0x16,
8227 RR_DSRAV = 0x17,
8228 RR_MULT = 0x18,
8229 RR_MULTU = 0x19,
8230 RR_DIV = 0x1a,
8231 RR_DIVU = 0x1b,
8232 RR_DMULT = 0x1c,
8233 RR_DMULTU = 0x1d,
8234 RR_DDIV = 0x1e,
8235 RR_DDIVU = 0x1f
8238 /* I64 funct field */
8239 enum {
8240 I64_LDSP = 0x0,
8241 I64_SDSP = 0x1,
8242 I64_SDRASP = 0x2,
8243 I64_DADJSP = 0x3,
8244 I64_LDPC = 0x4,
8245 I64_DADDIU5 = 0x5,
8246 I64_DADDIUPC = 0x6,
8247 I64_DADDIUSP = 0x7
8250 /* RR ry field for CNVT */
8251 enum {
8252 RR_RY_CNVT_ZEB = 0x0,
8253 RR_RY_CNVT_ZEH = 0x1,
8254 RR_RY_CNVT_ZEW = 0x2,
8255 RR_RY_CNVT_SEB = 0x4,
8256 RR_RY_CNVT_SEH = 0x5,
8257 RR_RY_CNVT_SEW = 0x6,
8260 static int xlat (int r)
8262 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8264 return map[r];
8267 static void gen_mips16_save (DisasContext *ctx,
8268 int xsregs, int aregs,
8269 int do_ra, int do_s0, int do_s1,
8270 int framesize)
8272 TCGv t0 = tcg_temp_new();
8273 TCGv t1 = tcg_temp_new();
8274 int args, astatic;
8276 switch (aregs) {
8277 case 0:
8278 case 1:
8279 case 2:
8280 case 3:
8281 case 11:
8282 args = 0;
8283 break;
8284 case 4:
8285 case 5:
8286 case 6:
8287 case 7:
8288 args = 1;
8289 break;
8290 case 8:
8291 case 9:
8292 case 10:
8293 args = 2;
8294 break;
8295 case 12:
8296 case 13:
8297 args = 3;
8298 break;
8299 case 14:
8300 args = 4;
8301 break;
8302 default:
8303 generate_exception(ctx, EXCP_RI);
8304 return;
8307 switch (args) {
8308 case 4:
8309 gen_base_offset_addr(ctx, t0, 29, 12);
8310 gen_load_gpr(t1, 7);
8311 op_st_sw(t1, t0, ctx);
8312 /* Fall through */
8313 case 3:
8314 gen_base_offset_addr(ctx, t0, 29, 8);
8315 gen_load_gpr(t1, 6);
8316 op_st_sw(t1, t0, ctx);
8317 /* Fall through */
8318 case 2:
8319 gen_base_offset_addr(ctx, t0, 29, 4);
8320 gen_load_gpr(t1, 5);
8321 op_st_sw(t1, t0, ctx);
8322 /* Fall through */
8323 case 1:
8324 gen_base_offset_addr(ctx, t0, 29, 0);
8325 gen_load_gpr(t1, 4);
8326 op_st_sw(t1, t0, ctx);
8329 gen_load_gpr(t0, 29);
8331 #define DECR_AND_STORE(reg) do { \
8332 tcg_gen_subi_tl(t0, t0, 4); \
8333 gen_load_gpr(t1, reg); \
8334 op_st_sw(t1, t0, ctx); \
8335 } while (0)
8337 if (do_ra) {
8338 DECR_AND_STORE(31);
8341 switch (xsregs) {
8342 case 7:
8343 DECR_AND_STORE(30);
8344 /* Fall through */
8345 case 6:
8346 DECR_AND_STORE(23);
8347 /* Fall through */
8348 case 5:
8349 DECR_AND_STORE(22);
8350 /* Fall through */
8351 case 4:
8352 DECR_AND_STORE(21);
8353 /* Fall through */
8354 case 3:
8355 DECR_AND_STORE(20);
8356 /* Fall through */
8357 case 2:
8358 DECR_AND_STORE(19);
8359 /* Fall through */
8360 case 1:
8361 DECR_AND_STORE(18);
8364 if (do_s1) {
8365 DECR_AND_STORE(17);
8367 if (do_s0) {
8368 DECR_AND_STORE(16);
8371 switch (aregs) {
8372 case 0:
8373 case 4:
8374 case 8:
8375 case 12:
8376 case 14:
8377 astatic = 0;
8378 break;
8379 case 1:
8380 case 5:
8381 case 9:
8382 case 13:
8383 astatic = 1;
8384 break;
8385 case 2:
8386 case 6:
8387 case 10:
8388 astatic = 2;
8389 break;
8390 case 3:
8391 case 7:
8392 astatic = 3;
8393 break;
8394 case 11:
8395 astatic = 4;
8396 break;
8397 default:
8398 generate_exception(ctx, EXCP_RI);
8399 return;
8402 if (astatic > 0) {
8403 DECR_AND_STORE(7);
8404 if (astatic > 1) {
8405 DECR_AND_STORE(6);
8406 if (astatic > 2) {
8407 DECR_AND_STORE(5);
8408 if (astatic > 3) {
8409 DECR_AND_STORE(4);
8414 #undef DECR_AND_STORE
8416 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8417 tcg_temp_free(t0);
8418 tcg_temp_free(t1);
8421 static void gen_mips16_restore (DisasContext *ctx,
8422 int xsregs, int aregs,
8423 int do_ra, int do_s0, int do_s1,
8424 int framesize)
8426 int astatic;
8427 TCGv t0 = tcg_temp_new();
8428 TCGv t1 = tcg_temp_new();
8430 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8432 #define DECR_AND_LOAD(reg) do { \
8433 tcg_gen_subi_tl(t0, t0, 4); \
8434 op_ld_lw(t1, t0, ctx); \
8435 gen_store_gpr(t1, reg); \
8436 } while (0)
8438 if (do_ra) {
8439 DECR_AND_LOAD(31);
8442 switch (xsregs) {
8443 case 7:
8444 DECR_AND_LOAD(30);
8445 /* Fall through */
8446 case 6:
8447 DECR_AND_LOAD(23);
8448 /* Fall through */
8449 case 5:
8450 DECR_AND_LOAD(22);
8451 /* Fall through */
8452 case 4:
8453 DECR_AND_LOAD(21);
8454 /* Fall through */
8455 case 3:
8456 DECR_AND_LOAD(20);
8457 /* Fall through */
8458 case 2:
8459 DECR_AND_LOAD(19);
8460 /* Fall through */
8461 case 1:
8462 DECR_AND_LOAD(18);
8465 if (do_s1) {
8466 DECR_AND_LOAD(17);
8468 if (do_s0) {
8469 DECR_AND_LOAD(16);
8472 switch (aregs) {
8473 case 0:
8474 case 4:
8475 case 8:
8476 case 12:
8477 case 14:
8478 astatic = 0;
8479 break;
8480 case 1:
8481 case 5:
8482 case 9:
8483 case 13:
8484 astatic = 1;
8485 break;
8486 case 2:
8487 case 6:
8488 case 10:
8489 astatic = 2;
8490 break;
8491 case 3:
8492 case 7:
8493 astatic = 3;
8494 break;
8495 case 11:
8496 astatic = 4;
8497 break;
8498 default:
8499 generate_exception(ctx, EXCP_RI);
8500 return;
8503 if (astatic > 0) {
8504 DECR_AND_LOAD(7);
8505 if (astatic > 1) {
8506 DECR_AND_LOAD(6);
8507 if (astatic > 2) {
8508 DECR_AND_LOAD(5);
8509 if (astatic > 3) {
8510 DECR_AND_LOAD(4);
8515 #undef DECR_AND_LOAD
8517 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8518 tcg_temp_free(t0);
8519 tcg_temp_free(t1);
8522 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8523 int is_64_bit, int extended)
8525 TCGv t0;
8527 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8528 generate_exception(ctx, EXCP_RI);
8529 return;
8532 t0 = tcg_temp_new();
8534 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8535 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8536 if (!is_64_bit) {
8537 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8540 tcg_temp_free(t0);
8543 #if defined(TARGET_MIPS64)
8544 static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8545 int ry, int funct, int16_t offset,
8546 int extended)
8548 switch (funct) {
8549 case I64_LDSP:
8550 check_mips_64(ctx);
8551 offset = extended ? offset : offset << 3;
8552 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
8553 break;
8554 case I64_SDSP:
8555 check_mips_64(ctx);
8556 offset = extended ? offset : offset << 3;
8557 gen_st(ctx, OPC_SD, ry, 29, offset);
8558 break;
8559 case I64_SDRASP:
8560 check_mips_64(ctx);
8561 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8562 gen_st(ctx, OPC_SD, 31, 29, offset);
8563 break;
8564 case I64_DADJSP:
8565 check_mips_64(ctx);
8566 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8567 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8568 break;
8569 case I64_LDPC:
8570 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8571 generate_exception(ctx, EXCP_RI);
8572 } else {
8573 offset = extended ? offset : offset << 3;
8574 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
8576 break;
8577 case I64_DADDIU5:
8578 check_mips_64(ctx);
8579 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8580 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8581 break;
8582 case I64_DADDIUPC:
8583 check_mips_64(ctx);
8584 offset = extended ? offset : offset << 2;
8585 gen_addiupc(ctx, ry, offset, 1, extended);
8586 break;
8587 case I64_DADDIUSP:
8588 check_mips_64(ctx);
8589 offset = extended ? offset : offset << 2;
8590 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8591 break;
8594 #endif
8596 static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8597 int *is_branch)
8599 int extend = lduw_code(ctx->pc + 2);
8600 int op, rx, ry, funct, sa;
8601 int16_t imm, offset;
8603 ctx->opcode = (ctx->opcode << 16) | extend;
8604 op = (ctx->opcode >> 11) & 0x1f;
8605 sa = (ctx->opcode >> 22) & 0x1f;
8606 funct = (ctx->opcode >> 8) & 0x7;
8607 rx = xlat((ctx->opcode >> 8) & 0x7);
8608 ry = xlat((ctx->opcode >> 5) & 0x7);
8609 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8610 | ((ctx->opcode >> 21) & 0x3f) << 5
8611 | (ctx->opcode & 0x1f));
8613 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8614 counterparts. */
8615 switch (op) {
8616 case M16_OPC_ADDIUSP:
8617 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8618 break;
8619 case M16_OPC_ADDIUPC:
8620 gen_addiupc(ctx, rx, imm, 0, 1);
8621 break;
8622 case M16_OPC_B:
8623 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8624 /* No delay slot, so just process as a normal instruction */
8625 break;
8626 case M16_OPC_BEQZ:
8627 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8628 /* No delay slot, so just process as a normal instruction */
8629 break;
8630 case M16_OPC_BNEQZ:
8631 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8632 /* No delay slot, so just process as a normal instruction */
8633 break;
8634 case M16_OPC_SHIFT:
8635 switch (ctx->opcode & 0x3) {
8636 case 0x0:
8637 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8638 break;
8639 case 0x1:
8640 #if defined(TARGET_MIPS64)
8641 check_mips_64(ctx);
8642 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8643 #else
8644 generate_exception(ctx, EXCP_RI);
8645 #endif
8646 break;
8647 case 0x2:
8648 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8649 break;
8650 case 0x3:
8651 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8652 break;
8654 break;
8655 #if defined(TARGET_MIPS64)
8656 case M16_OPC_LD:
8657 check_mips_64(ctx);
8658 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
8659 break;
8660 #endif
8661 case M16_OPC_RRIA:
8662 imm = ctx->opcode & 0xf;
8663 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8664 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8665 imm = (int16_t) (imm << 1) >> 1;
8666 if ((ctx->opcode >> 4) & 0x1) {
8667 #if defined(TARGET_MIPS64)
8668 check_mips_64(ctx);
8669 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8670 #else
8671 generate_exception(ctx, EXCP_RI);
8672 #endif
8673 } else {
8674 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8676 break;
8677 case M16_OPC_ADDIU8:
8678 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8679 break;
8680 case M16_OPC_SLTI:
8681 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8682 break;
8683 case M16_OPC_SLTIU:
8684 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8685 break;
8686 case M16_OPC_I8:
8687 switch (funct) {
8688 case I8_BTEQZ:
8689 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8690 break;
8691 case I8_BTNEZ:
8692 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8693 break;
8694 case I8_SWRASP:
8695 gen_st(ctx, OPC_SW, 31, 29, imm);
8696 break;
8697 case I8_ADJSP:
8698 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8699 break;
8700 case I8_SVRS:
8702 int xsregs = (ctx->opcode >> 24) & 0x7;
8703 int aregs = (ctx->opcode >> 16) & 0xf;
8704 int do_ra = (ctx->opcode >> 6) & 0x1;
8705 int do_s0 = (ctx->opcode >> 5) & 0x1;
8706 int do_s1 = (ctx->opcode >> 4) & 0x1;
8707 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8708 | (ctx->opcode & 0xf)) << 3;
8710 if (ctx->opcode & (1 << 7)) {
8711 gen_mips16_save(ctx, xsregs, aregs,
8712 do_ra, do_s0, do_s1,
8713 framesize);
8714 } else {
8715 gen_mips16_restore(ctx, xsregs, aregs,
8716 do_ra, do_s0, do_s1,
8717 framesize);
8720 break;
8721 default:
8722 generate_exception(ctx, EXCP_RI);
8723 break;
8725 break;
8726 case M16_OPC_LI:
8727 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8728 break;
8729 case M16_OPC_CMPI:
8730 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8731 break;
8732 #if defined(TARGET_MIPS64)
8733 case M16_OPC_SD:
8734 gen_st(ctx, OPC_SD, ry, rx, offset);
8735 break;
8736 #endif
8737 case M16_OPC_LB:
8738 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8739 break;
8740 case M16_OPC_LH:
8741 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
8742 break;
8743 case M16_OPC_LWSP:
8744 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
8745 break;
8746 case M16_OPC_LW:
8747 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
8748 break;
8749 case M16_OPC_LBU:
8750 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8751 break;
8752 case M16_OPC_LHU:
8753 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
8754 break;
8755 case M16_OPC_LWPC:
8756 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
8757 break;
8758 #if defined(TARGET_MIPS64)
8759 case M16_OPC_LWU:
8760 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
8761 break;
8762 #endif
8763 case M16_OPC_SB:
8764 gen_st(ctx, OPC_SB, ry, rx, offset);
8765 break;
8766 case M16_OPC_SH:
8767 gen_st(ctx, OPC_SH, ry, rx, offset);
8768 break;
8769 case M16_OPC_SWSP:
8770 gen_st(ctx, OPC_SW, rx, 29, offset);
8771 break;
8772 case M16_OPC_SW:
8773 gen_st(ctx, OPC_SW, ry, rx, offset);
8774 break;
8775 #if defined(TARGET_MIPS64)
8776 case M16_OPC_I64:
8777 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8778 break;
8779 #endif
8780 default:
8781 generate_exception(ctx, EXCP_RI);
8782 break;
8785 return 4;
8788 static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8789 int *is_branch)
8791 int rx, ry;
8792 int sa;
8793 int op, cnvt_op, op1, offset;
8794 int funct;
8795 int n_bytes;
8797 op = (ctx->opcode >> 11) & 0x1f;
8798 sa = (ctx->opcode >> 2) & 0x7;
8799 sa = sa == 0 ? 8 : sa;
8800 rx = xlat((ctx->opcode >> 8) & 0x7);
8801 cnvt_op = (ctx->opcode >> 5) & 0x7;
8802 ry = xlat((ctx->opcode >> 5) & 0x7);
8803 op1 = offset = ctx->opcode & 0x1f;
8805 n_bytes = 2;
8807 switch (op) {
8808 case M16_OPC_ADDIUSP:
8810 int16_t imm = ((uint8_t) ctx->opcode) << 2;
8812 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8814 break;
8815 case M16_OPC_ADDIUPC:
8816 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8817 break;
8818 case M16_OPC_B:
8819 offset = (ctx->opcode & 0x7ff) << 1;
8820 offset = (int16_t)(offset << 4) >> 4;
8821 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8822 /* No delay slot, so just process as a normal instruction */
8823 break;
8824 case M16_OPC_JAL:
8825 offset = lduw_code(ctx->pc + 2);
8826 offset = (((ctx->opcode & 0x1f) << 21)
8827 | ((ctx->opcode >> 5) & 0x1f) << 16
8828 | offset) << 2;
8829 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8830 gen_compute_branch(ctx, op, 4, rx, ry, offset);
8831 n_bytes = 4;
8832 *is_branch = 1;
8833 break;
8834 case M16_OPC_BEQZ:
8835 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8836 /* No delay slot, so just process as a normal instruction */
8837 break;
8838 case M16_OPC_BNEQZ:
8839 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8840 /* No delay slot, so just process as a normal instruction */
8841 break;
8842 case M16_OPC_SHIFT:
8843 switch (ctx->opcode & 0x3) {
8844 case 0x0:
8845 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8846 break;
8847 case 0x1:
8848 #if defined(TARGET_MIPS64)
8849 check_mips_64(ctx);
8850 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8851 #else
8852 generate_exception(ctx, EXCP_RI);
8853 #endif
8854 break;
8855 case 0x2:
8856 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8857 break;
8858 case 0x3:
8859 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8860 break;
8862 break;
8863 #if defined(TARGET_MIPS64)
8864 case M16_OPC_LD:
8865 check_mips_64(ctx);
8866 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
8867 break;
8868 #endif
8869 case M16_OPC_RRIA:
8871 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8873 if ((ctx->opcode >> 4) & 1) {
8874 #if defined(TARGET_MIPS64)
8875 check_mips_64(ctx);
8876 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8877 #else
8878 generate_exception(ctx, EXCP_RI);
8879 #endif
8880 } else {
8881 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8884 break;
8885 case M16_OPC_ADDIU8:
8887 int16_t imm = (int8_t) ctx->opcode;
8889 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8891 break;
8892 case M16_OPC_SLTI:
8894 int16_t imm = (uint8_t) ctx->opcode;
8896 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8898 break;
8899 case M16_OPC_SLTIU:
8901 int16_t imm = (uint8_t) ctx->opcode;
8903 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8905 break;
8906 case M16_OPC_I8:
8908 int reg32;
8910 funct = (ctx->opcode >> 8) & 0x7;
8911 switch (funct) {
8912 case I8_BTEQZ:
8913 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8914 ((int8_t)ctx->opcode) << 1);
8915 break;
8916 case I8_BTNEZ:
8917 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
8918 ((int8_t)ctx->opcode) << 1);
8919 break;
8920 case I8_SWRASP:
8921 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
8922 break;
8923 case I8_ADJSP:
8924 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
8925 ((int8_t)ctx->opcode) << 3);
8926 break;
8927 case I8_SVRS:
8929 int do_ra = ctx->opcode & (1 << 6);
8930 int do_s0 = ctx->opcode & (1 << 5);
8931 int do_s1 = ctx->opcode & (1 << 4);
8932 int framesize = ctx->opcode & 0xf;
8934 if (framesize == 0) {
8935 framesize = 128;
8936 } else {
8937 framesize = framesize << 3;
8940 if (ctx->opcode & (1 << 7)) {
8941 gen_mips16_save(ctx, 0, 0,
8942 do_ra, do_s0, do_s1, framesize);
8943 } else {
8944 gen_mips16_restore(ctx, 0, 0,
8945 do_ra, do_s0, do_s1, framesize);
8948 break;
8949 case I8_MOV32R:
8951 int rz = xlat(ctx->opcode & 0x7);
8953 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
8954 ((ctx->opcode >> 5) & 0x7);
8955 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
8957 break;
8958 case I8_MOVR32:
8959 reg32 = ctx->opcode & 0x1f;
8960 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
8961 break;
8962 default:
8963 generate_exception(ctx, EXCP_RI);
8964 break;
8967 break;
8968 case M16_OPC_LI:
8970 int16_t imm = (uint8_t) ctx->opcode;
8972 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
8974 break;
8975 case M16_OPC_CMPI:
8977 int16_t imm = (uint8_t) ctx->opcode;
8979 gen_logic_imm(env, OPC_XORI, 24, rx, imm);
8981 break;
8982 #if defined(TARGET_MIPS64)
8983 case M16_OPC_SD:
8984 check_mips_64(ctx);
8985 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
8986 break;
8987 #endif
8988 case M16_OPC_LB:
8989 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8990 break;
8991 case M16_OPC_LH:
8992 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
8993 break;
8994 case M16_OPC_LWSP:
8995 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8996 break;
8997 case M16_OPC_LW:
8998 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
8999 break;
9000 case M16_OPC_LBU:
9001 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9002 break;
9003 case M16_OPC_LHU:
9004 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9005 break;
9006 case M16_OPC_LWPC:
9007 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9008 break;
9009 #if defined (TARGET_MIPS64)
9010 case M16_OPC_LWU:
9011 check_mips_64(ctx);
9012 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9013 break;
9014 #endif
9015 case M16_OPC_SB:
9016 gen_st(ctx, OPC_SB, ry, rx, offset);
9017 break;
9018 case M16_OPC_SH:
9019 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9020 break;
9021 case M16_OPC_SWSP:
9022 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9023 break;
9024 case M16_OPC_SW:
9025 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9026 break;
9027 case M16_OPC_RRR:
9029 int rz = xlat((ctx->opcode >> 2) & 0x7);
9030 int mips32_op;
9032 switch (ctx->opcode & 0x3) {
9033 case RRR_ADDU:
9034 mips32_op = OPC_ADDU;
9035 break;
9036 case RRR_SUBU:
9037 mips32_op = OPC_SUBU;
9038 break;
9039 #if defined(TARGET_MIPS64)
9040 case RRR_DADDU:
9041 mips32_op = OPC_DADDU;
9042 check_mips_64(ctx);
9043 break;
9044 case RRR_DSUBU:
9045 mips32_op = OPC_DSUBU;
9046 check_mips_64(ctx);
9047 break;
9048 #endif
9049 default:
9050 generate_exception(ctx, EXCP_RI);
9051 goto done;
9054 gen_arith(env, ctx, mips32_op, rz, rx, ry);
9055 done:
9058 break;
9059 case M16_OPC_RR:
9060 switch (op1) {
9061 case RR_JR:
9063 int nd = (ctx->opcode >> 7) & 0x1;
9064 int link = (ctx->opcode >> 6) & 0x1;
9065 int ra = (ctx->opcode >> 5) & 0x1;
9067 if (link) {
9068 op = nd ? OPC_JALRC : OPC_JALRS;
9069 } else {
9070 op = OPC_JR;
9073 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9074 if (!nd) {
9075 *is_branch = 1;
9078 break;
9079 case RR_SDBBP:
9080 /* XXX: not clear which exception should be raised
9081 * when in debug mode...
9083 check_insn(env, ctx, ISA_MIPS32);
9084 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9085 generate_exception(ctx, EXCP_DBp);
9086 } else {
9087 generate_exception(ctx, EXCP_DBp);
9089 break;
9090 case RR_SLT:
9091 gen_slt(env, OPC_SLT, 24, rx, ry);
9092 break;
9093 case RR_SLTU:
9094 gen_slt(env, OPC_SLTU, 24, rx, ry);
9095 break;
9096 case RR_BREAK:
9097 generate_exception(ctx, EXCP_BREAK);
9098 break;
9099 case RR_SLLV:
9100 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9101 break;
9102 case RR_SRLV:
9103 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9104 break;
9105 case RR_SRAV:
9106 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9107 break;
9108 #if defined (TARGET_MIPS64)
9109 case RR_DSRL:
9110 check_mips_64(ctx);
9111 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9112 break;
9113 #endif
9114 case RR_CMP:
9115 gen_logic(env, OPC_XOR, 24, rx, ry);
9116 break;
9117 case RR_NEG:
9118 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9119 break;
9120 case RR_AND:
9121 gen_logic(env, OPC_AND, rx, rx, ry);
9122 break;
9123 case RR_OR:
9124 gen_logic(env, OPC_OR, rx, rx, ry);
9125 break;
9126 case RR_XOR:
9127 gen_logic(env, OPC_XOR, rx, rx, ry);
9128 break;
9129 case RR_NOT:
9130 gen_logic(env, OPC_NOR, rx, ry, 0);
9131 break;
9132 case RR_MFHI:
9133 gen_HILO(ctx, OPC_MFHI, rx);
9134 break;
9135 case RR_CNVT:
9136 switch (cnvt_op) {
9137 case RR_RY_CNVT_ZEB:
9138 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9139 break;
9140 case RR_RY_CNVT_ZEH:
9141 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9142 break;
9143 case RR_RY_CNVT_SEB:
9144 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9145 break;
9146 case RR_RY_CNVT_SEH:
9147 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9148 break;
9149 #if defined (TARGET_MIPS64)
9150 case RR_RY_CNVT_ZEW:
9151 check_mips_64(ctx);
9152 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9153 break;
9154 case RR_RY_CNVT_SEW:
9155 check_mips_64(ctx);
9156 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9157 break;
9158 #endif
9159 default:
9160 generate_exception(ctx, EXCP_RI);
9161 break;
9163 break;
9164 case RR_MFLO:
9165 gen_HILO(ctx, OPC_MFLO, rx);
9166 break;
9167 #if defined (TARGET_MIPS64)
9168 case RR_DSRA:
9169 check_mips_64(ctx);
9170 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9171 break;
9172 case RR_DSLLV:
9173 check_mips_64(ctx);
9174 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9175 break;
9176 case RR_DSRLV:
9177 check_mips_64(ctx);
9178 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9179 break;
9180 case RR_DSRAV:
9181 check_mips_64(ctx);
9182 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9183 break;
9184 #endif
9185 case RR_MULT:
9186 gen_muldiv(ctx, OPC_MULT, rx, ry);
9187 break;
9188 case RR_MULTU:
9189 gen_muldiv(ctx, OPC_MULTU, rx, ry);
9190 break;
9191 case RR_DIV:
9192 gen_muldiv(ctx, OPC_DIV, rx, ry);
9193 break;
9194 case RR_DIVU:
9195 gen_muldiv(ctx, OPC_DIVU, rx, ry);
9196 break;
9197 #if defined (TARGET_MIPS64)
9198 case RR_DMULT:
9199 check_mips_64(ctx);
9200 gen_muldiv(ctx, OPC_DMULT, rx, ry);
9201 break;
9202 case RR_DMULTU:
9203 check_mips_64(ctx);
9204 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9205 break;
9206 case RR_DDIV:
9207 check_mips_64(ctx);
9208 gen_muldiv(ctx, OPC_DDIV, rx, ry);
9209 break;
9210 case RR_DDIVU:
9211 check_mips_64(ctx);
9212 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9213 break;
9214 #endif
9215 default:
9216 generate_exception(ctx, EXCP_RI);
9217 break;
9219 break;
9220 case M16_OPC_EXTEND:
9221 decode_extended_mips16_opc(env, ctx, is_branch);
9222 n_bytes = 4;
9223 break;
9224 #if defined(TARGET_MIPS64)
9225 case M16_OPC_I64:
9226 funct = (ctx->opcode >> 8) & 0x7;
9227 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9228 break;
9229 #endif
9230 default:
9231 generate_exception(ctx, EXCP_RI);
9232 break;
9235 return n_bytes;
9238 /* microMIPS extension to MIPS32 */
9240 /* microMIPS32 major opcodes */
9242 enum {
9243 POOL32A = 0x00,
9244 POOL16A = 0x01,
9245 LBU16 = 0x02,
9246 MOVE16 = 0x03,
9247 ADDI32 = 0x04,
9248 LBU32 = 0x05,
9249 SB32 = 0x06,
9250 LB32 = 0x07,
9252 POOL32B = 0x08,
9253 POOL16B = 0x09,
9254 LHU16 = 0x0a,
9255 ANDI16 = 0x0b,
9256 ADDIU32 = 0x0c,
9257 LHU32 = 0x0d,
9258 SH32 = 0x0e,
9259 LH32 = 0x0f,
9261 POOL32I = 0x10,
9262 POOL16C = 0x11,
9263 LWSP16 = 0x12,
9264 POOL16D = 0x13,
9265 ORI32 = 0x14,
9266 POOL32F = 0x15,
9267 POOL32S = 0x16,
9268 DADDIU32 = 0x17,
9270 POOL32C = 0x18,
9271 LWGP16 = 0x19,
9272 LW16 = 0x1a,
9273 POOL16E = 0x1b,
9274 XORI32 = 0x1c,
9275 JALS32 = 0x1d,
9276 ADDIUPC = 0x1e,
9277 POOL48A = 0x1f,
9279 /* 0x20 is reserved */
9280 RES_20 = 0x20,
9281 POOL16F = 0x21,
9282 SB16 = 0x22,
9283 BEQZ16 = 0x23,
9284 SLTI32 = 0x24,
9285 BEQ32 = 0x25,
9286 SWC132 = 0x26,
9287 LWC132 = 0x27,
9289 /* 0x28 and 0x29 are reserved */
9290 RES_28 = 0x28,
9291 RES_29 = 0x29,
9292 SH16 = 0x2a,
9293 BNEZ16 = 0x2b,
9294 SLTIU32 = 0x2c,
9295 BNE32 = 0x2d,
9296 SDC132 = 0x2e,
9297 LDC132 = 0x2f,
9299 /* 0x30 and 0x31 are reserved */
9300 RES_30 = 0x30,
9301 RES_31 = 0x31,
9302 SWSP16 = 0x32,
9303 B16 = 0x33,
9304 ANDI32 = 0x34,
9305 J32 = 0x35,
9306 SD32 = 0x36,
9307 LD32 = 0x37,
9309 /* 0x38 and 0x39 are reserved */
9310 RES_38 = 0x38,
9311 RES_39 = 0x39,
9312 SW16 = 0x3a,
9313 LI16 = 0x3b,
9314 JALX32 = 0x3c,
9315 JAL32 = 0x3d,
9316 SW32 = 0x3e,
9317 LW32 = 0x3f
9320 /* POOL32A encoding of minor opcode field */
9322 enum {
9323 /* These opcodes are distinguished only by bits 9..6; those bits are
9324 * what are recorded below. */
9325 SLL32 = 0x0,
9326 SRL32 = 0x1,
9327 SRA = 0x2,
9328 ROTR = 0x3,
9330 SLLV = 0x0,
9331 SRLV = 0x1,
9332 SRAV = 0x2,
9333 ROTRV = 0x3,
9334 ADD = 0x4,
9335 ADDU32 = 0x5,
9336 SUB = 0x6,
9337 SUBU32 = 0x7,
9338 MUL = 0x8,
9339 AND = 0x9,
9340 OR32 = 0xa,
9341 NOR = 0xb,
9342 XOR32 = 0xc,
9343 SLT = 0xd,
9344 SLTU = 0xe,
9346 MOVN = 0x0,
9347 MOVZ = 0x1,
9348 LWXS = 0x4,
9350 /* The following can be distinguished by their lower 6 bits. */
9351 INS = 0x0c,
9352 EXT = 0x2c,
9353 POOL32AXF = 0x3c
9356 /* POOL32AXF encoding of minor opcode field extension */
9358 enum {
9359 /* bits 11..6 */
9360 TEQ = 0x00,
9361 TGE = 0x08,
9362 TGEU = 0x10,
9363 TLT = 0x20,
9364 TLTU = 0x28,
9365 TNE = 0x30,
9367 MFC0 = 0x03,
9368 MTC0 = 0x0b,
9370 /* bits 13..12 for 0x01 */
9371 MFHI_ACC = 0x0,
9372 MFLO_ACC = 0x1,
9373 MTHI_ACC = 0x2,
9374 MTLO_ACC = 0x3,
9376 /* bits 13..12 for 0x2a */
9377 MADD_ACC = 0x0,
9378 MADDU_ACC = 0x1,
9379 MSUB_ACC = 0x2,
9380 MSUBU_ACC = 0x3,
9382 /* bits 13..12 for 0x32 */
9383 MULT_ACC = 0x0,
9384 MULTU_ACC = 0x0,
9386 /* bits 15..12 for 0x2c */
9387 SEB = 0x2,
9388 SEH = 0x3,
9389 CLO = 0x4,
9390 CLZ = 0x5,
9391 RDHWR = 0x6,
9392 WSBH = 0x7,
9393 MULT = 0x8,
9394 MULTU = 0x9,
9395 DIV = 0xa,
9396 DIVU = 0xb,
9397 MADD = 0xc,
9398 MADDU = 0xd,
9399 MSUB = 0xe,
9400 MSUBU = 0xf,
9402 /* bits 15..12 for 0x34 */
9403 MFC2 = 0x4,
9404 MTC2 = 0x5,
9405 MFHC2 = 0x8,
9406 MTHC2 = 0x9,
9407 CFC2 = 0xc,
9408 CTC2 = 0xd,
9410 /* bits 15..12 for 0x3c */
9411 JALR = 0x0,
9412 JR = 0x0, /* alias */
9413 JALR_HB = 0x1,
9414 JALRS = 0x4,
9415 JALRS_HB = 0x5,
9417 /* bits 15..12 for 0x05 */
9418 RDPGPR = 0xe,
9419 WRPGPR = 0xf,
9421 /* bits 15..12 for 0x0d */
9422 TLBP = 0x0,
9423 TLBR = 0x1,
9424 TLBWI = 0x2,
9425 TLBWR = 0x3,
9426 WAIT = 0x9,
9427 IRET = 0xd,
9428 DERET = 0xe,
9429 ERET = 0xf,
9431 /* bits 15..12 for 0x15 */
9432 DMT = 0x0,
9433 DVPE = 0x1,
9434 EMT = 0x2,
9435 EVPE = 0x3,
9437 /* bits 15..12 for 0x1d */
9438 DI = 0x4,
9439 EI = 0x5,
9441 /* bits 15..12 for 0x2d */
9442 SYNC = 0x6,
9443 SYSCALL = 0x8,
9444 SDBBP = 0xd,
9446 /* bits 15..12 for 0x35 */
9447 MFHI32 = 0x0,
9448 MFLO32 = 0x1,
9449 MTHI32 = 0x2,
9450 MTLO32 = 0x3,
9453 /* POOL32B encoding of minor opcode field (bits 15..12) */
9455 enum {
9456 LWC2 = 0x0,
9457 LWP = 0x1,
9458 LDP = 0x4,
9459 LWM32 = 0x5,
9460 CACHE = 0x6,
9461 LDM = 0x7,
9462 SWC2 = 0x8,
9463 SWP = 0x9,
9464 SDP = 0xc,
9465 SWM32 = 0xd,
9466 SDM = 0xf
9469 /* POOL32C encoding of minor opcode field (bits 15..12) */
9471 enum {
9472 LWL = 0x0,
9473 SWL = 0x8,
9474 LWR = 0x1,
9475 SWR = 0x9,
9476 PREF = 0x2,
9477 /* 0xa is reserved */
9478 LL = 0x3,
9479 SC = 0xb,
9480 LDL = 0x4,
9481 SDL = 0xc,
9482 LDR = 0x5,
9483 SDR = 0xd,
9484 /* 0x6 is reserved */
9485 LWU = 0xe,
9486 LLD = 0x7,
9487 SCD = 0xf
9490 /* POOL32F encoding of minor opcode field (bits 5..0) */
9492 enum {
9493 /* These are the bit 7..6 values */
9494 ADD_FMT = 0x0,
9495 MOVN_FMT = 0x0,
9497 SUB_FMT = 0x1,
9498 MOVZ_FMT = 0x1,
9500 MUL_FMT = 0x2,
9502 DIV_FMT = 0x3,
9504 /* These are the bit 8..6 values */
9505 RSQRT2_FMT = 0x0,
9506 MOVF_FMT = 0x0,
9508 LWXC1 = 0x1,
9509 MOVT_FMT = 0x1,
9511 PLL_PS = 0x2,
9512 SWXC1 = 0x2,
9514 PLU_PS = 0x3,
9515 LDXC1 = 0x3,
9517 PUL_PS = 0x4,
9518 SDXC1 = 0x4,
9519 RECIP2_FMT = 0x4,
9521 PUU_PS = 0x5,
9522 LUXC1 = 0x5,
9524 CVT_PS_S = 0x6,
9525 SUXC1 = 0x6,
9526 ADDR_PS = 0x6,
9527 PREFX = 0x6,
9529 MULR_PS = 0x7,
9531 MADD_S = 0x01,
9532 MADD_D = 0x09,
9533 MADD_PS = 0x11,
9534 ALNV_PS = 0x19,
9535 MSUB_S = 0x21,
9536 MSUB_D = 0x29,
9537 MSUB_PS = 0x31,
9539 NMADD_S = 0x02,
9540 NMADD_D = 0x0a,
9541 NMADD_PS = 0x12,
9542 NMSUB_S = 0x22,
9543 NMSUB_D = 0x2a,
9544 NMSUB_PS = 0x32,
9546 POOL32FXF = 0x3b,
9548 CABS_COND_FMT = 0x1c, /* MIPS3D */
9549 C_COND_FMT = 0x3c
9552 /* POOL32Fxf encoding of minor opcode extension field */
9554 enum {
9555 CVT_L = 0x04,
9556 RSQRT_FMT = 0x08,
9557 FLOOR_L = 0x0c,
9558 CVT_PW_PS = 0x1c,
9559 CVT_W = 0x24,
9560 SQRT_FMT = 0x28,
9561 FLOOR_W = 0x2c,
9562 CVT_PS_PW = 0x3c,
9563 CFC1 = 0x40,
9564 RECIP_FMT = 0x48,
9565 CEIL_L = 0x4c,
9566 CTC1 = 0x60,
9567 CEIL_W = 0x6c,
9568 MFC1 = 0x80,
9569 CVT_S_PL = 0x84,
9570 TRUNC_L = 0x8c,
9571 MTC1 = 0xa0,
9572 CVT_S_PU = 0xa4,
9573 TRUNC_W = 0xac,
9574 MFHC1 = 0xc0,
9575 ROUND_L = 0xcc,
9576 MTHC1 = 0xe0,
9577 ROUND_W = 0xec,
9579 MOV_FMT = 0x01,
9580 MOVF = 0x05,
9581 ABS_FMT = 0x0d,
9582 RSQRT1_FMT = 0x1d,
9583 MOVT = 0x25,
9584 NEG_FMT = 0x2d,
9585 CVT_D = 0x4d,
9586 RECIP1_FMT = 0x5d,
9587 CVT_S = 0x6d
9590 /* POOL32I encoding of minor opcode field (bits 25..21) */
9592 enum {
9593 BLTZ = 0x00,
9594 BLTZAL = 0x01,
9595 BGEZ = 0x02,
9596 BGEZAL = 0x03,
9597 BLEZ = 0x04,
9598 BNEZC = 0x05,
9599 BGTZ = 0x06,
9600 BEQZC = 0x07,
9601 TLTI = 0x08,
9602 TGEI = 0x09,
9603 TLTIU = 0x0a,
9604 TGEIU = 0x0b,
9605 TNEI = 0x0c,
9606 LUI = 0x0d,
9607 TEQI = 0x0e,
9608 SYNCI = 0x10,
9609 BLTZALS = 0x11,
9610 BGEZALS = 0x13,
9611 BC2F = 0x14,
9612 BC2T = 0x15,
9613 BPOSGE64 = 0x1a,
9614 BPOSGE32 = 0x1b,
9615 /* These overlap and are distinguished by bit16 of the instruction */
9616 BC1F = 0x1c,
9617 BC1T = 0x1d,
9618 BC1ANY2F = 0x1c,
9619 BC1ANY2T = 0x1d,
9620 BC1ANY4F = 0x1e,
9621 BC1ANY4T = 0x1f
9624 /* POOL16A encoding of minor opcode field */
9626 enum {
9627 ADDU16 = 0x0,
9628 SUBU16 = 0x1
9631 /* POOL16B encoding of minor opcode field */
9633 enum {
9634 SLL16 = 0x0,
9635 SRL16 = 0x1
9638 /* POOL16C encoding of minor opcode field */
9640 enum {
9641 NOT16 = 0x00,
9642 XOR16 = 0x04,
9643 AND16 = 0x08,
9644 OR16 = 0x0c,
9645 LWM16 = 0x10,
9646 SWM16 = 0x14,
9647 JR16 = 0x18,
9648 JRC16 = 0x1a,
9649 JALR16 = 0x1c,
9650 JALR16S = 0x1e,
9651 MFHI16 = 0x20,
9652 MFLO16 = 0x24,
9653 BREAK16 = 0x28,
9654 SDBBP16 = 0x2c,
9655 JRADDIUSP = 0x30
9658 /* POOL16D encoding of minor opcode field */
9660 enum {
9661 ADDIUS5 = 0x0,
9662 ADDIUSP = 0x1
9665 /* POOL16E encoding of minor opcode field */
9667 enum {
9668 ADDIUR2 = 0x0,
9669 ADDIUR1SP = 0x1
9672 static int mmreg (int r)
9674 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9676 return map[r];
9679 /* Used for 16-bit store instructions. */
9680 static int mmreg2 (int r)
9682 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9684 return map[r];
9687 #define uMIPS_RD(op) ((op >> 7) & 0x7)
9688 #define uMIPS_RS(op) ((op >> 4) & 0x7)
9689 #define uMIPS_RS2(op) uMIPS_RS(op)
9690 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
9691 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9692 #define uMIPS_RS5(op) (op & 0x1f)
9694 /* Signed immediate */
9695 #define SIMM(op, start, width) \
9696 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
9697 << (32-width)) \
9698 >> (32-width))
9699 /* Zero-extended immediate */
9700 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9702 static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
9704 int rd = mmreg(uMIPS_RD(ctx->opcode));
9706 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9709 static void gen_addiur2 (CPUState *env, DisasContext *ctx)
9711 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9712 int rd = mmreg(uMIPS_RD(ctx->opcode));
9713 int rs = mmreg(uMIPS_RS(ctx->opcode));
9715 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9718 static void gen_addiusp (CPUState *env, DisasContext *ctx)
9720 int encoded = ZIMM(ctx->opcode, 1, 9);
9721 int decoded;
9723 if (encoded <= 1) {
9724 decoded = 256 + encoded;
9725 } else if (encoded <= 255) {
9726 decoded = encoded;
9727 } else if (encoded <= 509) {
9728 decoded = encoded - 512;
9729 } else {
9730 decoded = encoded - 768;
9733 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9736 static void gen_addius5 (CPUState *env, DisasContext *ctx)
9738 int imm = SIMM(ctx->opcode, 1, 4);
9739 int rd = (ctx->opcode >> 5) & 0x1f;
9741 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9744 static void gen_andi16 (CPUState *env, DisasContext *ctx)
9746 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9747 31, 32, 63, 64, 255, 32768, 65535 };
9748 int rd = mmreg(uMIPS_RD(ctx->opcode));
9749 int rs = mmreg(uMIPS_RS(ctx->opcode));
9750 int encoded = ZIMM(ctx->opcode, 0, 4);
9752 gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9755 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9756 int base, int16_t offset)
9758 TCGv t0, t1;
9759 TCGv_i32 t2;
9761 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9762 generate_exception(ctx, EXCP_RI);
9763 return;
9766 t0 = tcg_temp_new();
9768 gen_base_offset_addr(ctx, t0, base, offset);
9770 t1 = tcg_const_tl(reglist);
9771 t2 = tcg_const_i32(ctx->mem_idx);
9773 save_cpu_state(ctx, 1);
9774 switch (opc) {
9775 case LWM32:
9776 gen_helper_lwm(t0, t1, t2);
9777 break;
9778 case SWM32:
9779 gen_helper_swm(t0, t1, t2);
9780 break;
9781 #ifdef TARGET_MIPS64
9782 case LDM:
9783 gen_helper_ldm(t0, t1, t2);
9784 break;
9785 case SDM:
9786 gen_helper_sdm(t0, t1, t2);
9787 break;
9788 #endif
9790 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9791 tcg_temp_free(t0);
9792 tcg_temp_free(t1);
9793 tcg_temp_free_i32(t2);
9797 static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
9799 int rd = mmreg((ctx->opcode >> 3) & 0x7);
9800 int rs = mmreg(ctx->opcode & 0x7);
9801 int opc;
9803 switch (((ctx->opcode) >> 4) & 0x3f) {
9804 case NOT16 + 0:
9805 case NOT16 + 1:
9806 case NOT16 + 2:
9807 case NOT16 + 3:
9808 gen_logic(env, OPC_NOR, rd, rs, 0);
9809 break;
9810 case XOR16 + 0:
9811 case XOR16 + 1:
9812 case XOR16 + 2:
9813 case XOR16 + 3:
9814 gen_logic(env, OPC_XOR, rd, rd, rs);
9815 break;
9816 case AND16 + 0:
9817 case AND16 + 1:
9818 case AND16 + 2:
9819 case AND16 + 3:
9820 gen_logic(env, OPC_AND, rd, rd, rs);
9821 break;
9822 case OR16 + 0:
9823 case OR16 + 1:
9824 case OR16 + 2:
9825 case OR16 + 3:
9826 gen_logic(env, OPC_OR, rd, rd, rs);
9827 break;
9828 case LWM16 + 0:
9829 case LWM16 + 1:
9830 case LWM16 + 2:
9831 case LWM16 + 3:
9833 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9834 int offset = ZIMM(ctx->opcode, 0, 4);
9836 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9837 29, offset << 2);
9839 break;
9840 case SWM16 + 0:
9841 case SWM16 + 1:
9842 case SWM16 + 2:
9843 case SWM16 + 3:
9845 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9846 int offset = ZIMM(ctx->opcode, 0, 4);
9848 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9849 29, offset << 2);
9851 break;
9852 case JR16 + 0:
9853 case JR16 + 1:
9855 int reg = ctx->opcode & 0x1f;
9857 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9859 *is_branch = 1;
9860 break;
9861 case JRC16 + 0:
9862 case JRC16 + 1:
9864 int reg = ctx->opcode & 0x1f;
9866 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9867 /* Let normal delay slot handling in our caller take us
9868 to the branch target. */
9870 break;
9871 case JALR16 + 0:
9872 case JALR16 + 1:
9873 opc = OPC_JALR;
9874 goto do_jalr;
9875 case JALR16S + 0:
9876 case JALR16S + 1:
9877 opc = OPC_JALRS;
9878 do_jalr:
9880 int reg = ctx->opcode & 0x1f;
9882 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9884 *is_branch = 1;
9885 break;
9886 case MFHI16 + 0:
9887 case MFHI16 + 1:
9888 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9889 break;
9890 case MFLO16 + 0:
9891 case MFLO16 + 1:
9892 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9893 break;
9894 case BREAK16:
9895 generate_exception(ctx, EXCP_BREAK);
9896 break;
9897 case SDBBP16:
9898 /* XXX: not clear which exception should be raised
9899 * when in debug mode...
9901 check_insn(env, ctx, ISA_MIPS32);
9902 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9903 generate_exception(ctx, EXCP_DBp);
9904 } else {
9905 generate_exception(ctx, EXCP_DBp);
9907 break;
9908 case JRADDIUSP + 0:
9909 case JRADDIUSP + 1:
9911 int imm = ZIMM(ctx->opcode, 0, 5);
9913 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9914 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
9915 /* Let normal delay slot handling in our caller take us
9916 to the branch target. */
9918 break;
9919 default:
9920 generate_exception(ctx, EXCP_RI);
9921 break;
9925 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
9927 TCGv t0 = tcg_temp_new();
9928 TCGv t1 = tcg_temp_new();
9930 gen_load_gpr(t0, base);
9932 if (index != 0) {
9933 gen_load_gpr(t1, index);
9934 tcg_gen_shli_tl(t1, t1, 2);
9935 gen_op_addr_add(ctx, t0, t1, t0);
9938 save_cpu_state(ctx, 0);
9939 op_ld_lw(t1, t0, ctx);
9940 gen_store_gpr(t1, rd);
9942 tcg_temp_free(t0);
9943 tcg_temp_free(t1);
9946 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
9947 int base, int16_t offset)
9949 const char *opn = "ldst_pair";
9950 TCGv t0, t1;
9952 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
9953 generate_exception(ctx, EXCP_RI);
9954 return;
9957 t0 = tcg_temp_new();
9958 t1 = tcg_temp_new();
9960 gen_base_offset_addr(ctx, t0, base, offset);
9962 switch (opc) {
9963 case LWP:
9964 save_cpu_state(ctx, 0);
9965 op_ld_lw(t1, t0, ctx);
9966 gen_store_gpr(t1, rd);
9967 tcg_gen_movi_tl(t1, 4);
9968 gen_op_addr_add(ctx, t0, t0, t1);
9969 op_ld_lw(t1, t0, ctx);
9970 gen_store_gpr(t1, rd+1);
9971 opn = "lwp";
9972 break;
9973 case SWP:
9974 save_cpu_state(ctx, 0);
9975 gen_load_gpr(t1, rd);
9976 op_st_sw(t1, t0, ctx);
9977 tcg_gen_movi_tl(t1, 4);
9978 gen_op_addr_add(ctx, t0, t0, t1);
9979 gen_load_gpr(t1, rd+1);
9980 op_st_sw(t1, t0, ctx);
9981 opn = "swp";
9982 break;
9983 #ifdef TARGET_MIPS64
9984 case LDP:
9985 save_cpu_state(ctx, 0);
9986 op_ld_ld(t1, t0, ctx);
9987 gen_store_gpr(t1, rd);
9988 tcg_gen_movi_tl(t1, 8);
9989 gen_op_addr_add(ctx, t0, t0, t1);
9990 op_ld_ld(t1, t0, ctx);
9991 gen_store_gpr(t1, rd+1);
9992 opn = "ldp";
9993 break;
9994 case SDP:
9995 save_cpu_state(ctx, 0);
9996 gen_load_gpr(t1, rd);
9997 op_st_sd(t1, t0, ctx);
9998 tcg_gen_movi_tl(t1, 8);
9999 gen_op_addr_add(ctx, t0, t0, t1);
10000 gen_load_gpr(t1, rd+1);
10001 op_st_sd(t1, t0, ctx);
10002 opn = "sdp";
10003 break;
10004 #endif
10006 (void)opn; /* avoid a compiler warning */
10007 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10008 tcg_temp_free(t0);
10009 tcg_temp_free(t1);
10012 static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
10013 int *is_branch)
10015 int extension = (ctx->opcode >> 6) & 0x3f;
10016 int minor = (ctx->opcode >> 12) & 0xf;
10017 uint32_t mips32_op;
10019 switch (extension) {
10020 case TEQ:
10021 mips32_op = OPC_TEQ;
10022 goto do_trap;
10023 case TGE:
10024 mips32_op = OPC_TGE;
10025 goto do_trap;
10026 case TGEU:
10027 mips32_op = OPC_TGEU;
10028 goto do_trap;
10029 case TLT:
10030 mips32_op = OPC_TLT;
10031 goto do_trap;
10032 case TLTU:
10033 mips32_op = OPC_TLTU;
10034 goto do_trap;
10035 case TNE:
10036 mips32_op = OPC_TNE;
10037 do_trap:
10038 gen_trap(ctx, mips32_op, rs, rt, -1);
10039 break;
10040 #ifndef CONFIG_USER_ONLY
10041 case MFC0:
10042 case MFC0 + 32:
10043 if (rt == 0) {
10044 /* Treat as NOP. */
10045 break;
10047 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10048 break;
10049 case MTC0:
10050 case MTC0 + 32:
10052 TCGv t0 = tcg_temp_new();
10054 gen_load_gpr(t0, rt);
10055 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
10056 tcg_temp_free(t0);
10058 break;
10059 #endif
10060 case 0x2c:
10061 switch (minor) {
10062 case SEB:
10063 gen_bshfl(ctx, OPC_SEB, rs, rt);
10064 break;
10065 case SEH:
10066 gen_bshfl(ctx, OPC_SEH, rs, rt);
10067 break;
10068 case CLO:
10069 mips32_op = OPC_CLO;
10070 goto do_cl;
10071 case CLZ:
10072 mips32_op = OPC_CLZ;
10073 do_cl:
10074 check_insn(env, ctx, ISA_MIPS32);
10075 gen_cl(ctx, mips32_op, rt, rs);
10076 break;
10077 case RDHWR:
10078 gen_rdhwr(env, ctx, rt, rs);
10079 break;
10080 case WSBH:
10081 gen_bshfl(ctx, OPC_WSBH, rs, rt);
10082 break;
10083 case MULT:
10084 mips32_op = OPC_MULT;
10085 goto do_muldiv;
10086 case MULTU:
10087 mips32_op = OPC_MULTU;
10088 goto do_muldiv;
10089 case DIV:
10090 mips32_op = OPC_DIV;
10091 goto do_muldiv;
10092 case DIVU:
10093 mips32_op = OPC_DIVU;
10094 goto do_muldiv;
10095 case MADD:
10096 mips32_op = OPC_MADD;
10097 goto do_muldiv;
10098 case MADDU:
10099 mips32_op = OPC_MADDU;
10100 goto do_muldiv;
10101 case MSUB:
10102 mips32_op = OPC_MSUB;
10103 goto do_muldiv;
10104 case MSUBU:
10105 mips32_op = OPC_MSUBU;
10106 do_muldiv:
10107 check_insn(env, ctx, ISA_MIPS32);
10108 gen_muldiv(ctx, mips32_op, rs, rt);
10109 break;
10110 default:
10111 goto pool32axf_invalid;
10113 break;
10114 case 0x34:
10115 switch (minor) {
10116 case MFC2:
10117 case MTC2:
10118 case MFHC2:
10119 case MTHC2:
10120 case CFC2:
10121 case CTC2:
10122 generate_exception_err(ctx, EXCP_CpU, 2);
10123 break;
10124 default:
10125 goto pool32axf_invalid;
10127 break;
10128 case 0x3c:
10129 switch (minor) {
10130 case JALR:
10131 case JALR_HB:
10132 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10133 *is_branch = 1;
10134 break;
10135 case JALRS:
10136 case JALRS_HB:
10137 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10138 *is_branch = 1;
10139 break;
10140 default:
10141 goto pool32axf_invalid;
10143 break;
10144 case 0x05:
10145 switch (minor) {
10146 case RDPGPR:
10147 check_insn(env, ctx, ISA_MIPS32R2);
10148 gen_load_srsgpr(rt, rs);
10149 break;
10150 case WRPGPR:
10151 check_insn(env, ctx, ISA_MIPS32R2);
10152 gen_store_srsgpr(rt, rs);
10153 break;
10154 default:
10155 goto pool32axf_invalid;
10157 break;
10158 #ifndef CONFIG_USER_ONLY
10159 case 0x0d:
10160 switch (minor) {
10161 case TLBP:
10162 mips32_op = OPC_TLBP;
10163 goto do_cp0;
10164 case TLBR:
10165 mips32_op = OPC_TLBR;
10166 goto do_cp0;
10167 case TLBWI:
10168 mips32_op = OPC_TLBWI;
10169 goto do_cp0;
10170 case TLBWR:
10171 mips32_op = OPC_TLBWR;
10172 goto do_cp0;
10173 case WAIT:
10174 mips32_op = OPC_WAIT;
10175 goto do_cp0;
10176 case DERET:
10177 mips32_op = OPC_DERET;
10178 goto do_cp0;
10179 case ERET:
10180 mips32_op = OPC_ERET;
10181 do_cp0:
10182 gen_cp0(env, ctx, mips32_op, rt, rs);
10183 break;
10184 default:
10185 goto pool32axf_invalid;
10187 break;
10188 case 0x1d:
10189 switch (minor) {
10190 case DI:
10192 TCGv t0 = tcg_temp_new();
10194 save_cpu_state(ctx, 1);
10195 gen_helper_di(t0);
10196 gen_store_gpr(t0, rs);
10197 /* Stop translation as we may have switched the execution mode */
10198 ctx->bstate = BS_STOP;
10199 tcg_temp_free(t0);
10201 break;
10202 case EI:
10204 TCGv t0 = tcg_temp_new();
10206 save_cpu_state(ctx, 1);
10207 gen_helper_ei(t0);
10208 gen_store_gpr(t0, rs);
10209 /* Stop translation as we may have switched the execution mode */
10210 ctx->bstate = BS_STOP;
10211 tcg_temp_free(t0);
10213 break;
10214 default:
10215 goto pool32axf_invalid;
10217 break;
10218 #endif
10219 case 0x2d:
10220 switch (minor) {
10221 case SYNC:
10222 /* NOP */
10223 break;
10224 case SYSCALL:
10225 generate_exception(ctx, EXCP_SYSCALL);
10226 ctx->bstate = BS_STOP;
10227 break;
10228 case SDBBP:
10229 check_insn(env, ctx, ISA_MIPS32);
10230 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10231 generate_exception(ctx, EXCP_DBp);
10232 } else {
10233 generate_exception(ctx, EXCP_DBp);
10235 break;
10236 default:
10237 goto pool32axf_invalid;
10239 break;
10240 case 0x35:
10241 switch (minor) {
10242 case MFHI32:
10243 gen_HILO(ctx, OPC_MFHI, rs);
10244 break;
10245 case MFLO32:
10246 gen_HILO(ctx, OPC_MFLO, rs);
10247 break;
10248 case MTHI32:
10249 gen_HILO(ctx, OPC_MTHI, rs);
10250 break;
10251 case MTLO32:
10252 gen_HILO(ctx, OPC_MTLO, rs);
10253 break;
10254 default:
10255 goto pool32axf_invalid;
10257 break;
10258 default:
10259 pool32axf_invalid:
10260 MIPS_INVAL("pool32axf");
10261 generate_exception(ctx, EXCP_RI);
10262 break;
10266 /* Values for microMIPS fmt field. Variable-width, depending on which
10267 formats the instruction supports. */
10269 enum {
10270 FMT_SD_S = 0,
10271 FMT_SD_D = 1,
10273 FMT_SDPS_S = 0,
10274 FMT_SDPS_D = 1,
10275 FMT_SDPS_PS = 2,
10277 FMT_SWL_S = 0,
10278 FMT_SWL_W = 1,
10279 FMT_SWL_L = 2,
10281 FMT_DWL_D = 0,
10282 FMT_DWL_W = 1,
10283 FMT_DWL_L = 2
10286 static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
10288 int extension = (ctx->opcode >> 6) & 0x3ff;
10289 uint32_t mips32_op;
10291 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10292 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10293 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10295 switch (extension) {
10296 case FLOAT_1BIT_FMT(CFC1, 0):
10297 mips32_op = OPC_CFC1;
10298 goto do_cp1;
10299 case FLOAT_1BIT_FMT(CTC1, 0):
10300 mips32_op = OPC_CTC1;
10301 goto do_cp1;
10302 case FLOAT_1BIT_FMT(MFC1, 0):
10303 mips32_op = OPC_MFC1;
10304 goto do_cp1;
10305 case FLOAT_1BIT_FMT(MTC1, 0):
10306 mips32_op = OPC_MTC1;
10307 goto do_cp1;
10308 case FLOAT_1BIT_FMT(MFHC1, 0):
10309 mips32_op = OPC_MFHC1;
10310 goto do_cp1;
10311 case FLOAT_1BIT_FMT(MTHC1, 0):
10312 mips32_op = OPC_MTHC1;
10313 do_cp1:
10314 gen_cp1(ctx, mips32_op, rt, rs);
10315 break;
10317 /* Reciprocal square root */
10318 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10319 mips32_op = OPC_RSQRT_S;
10320 goto do_unaryfp;
10321 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10322 mips32_op = OPC_RSQRT_D;
10323 goto do_unaryfp;
10325 /* Square root */
10326 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10327 mips32_op = OPC_SQRT_S;
10328 goto do_unaryfp;
10329 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10330 mips32_op = OPC_SQRT_D;
10331 goto do_unaryfp;
10333 /* Reciprocal */
10334 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10335 mips32_op = OPC_RECIP_S;
10336 goto do_unaryfp;
10337 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10338 mips32_op = OPC_RECIP_D;
10339 goto do_unaryfp;
10341 /* Floor */
10342 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10343 mips32_op = OPC_FLOOR_L_S;
10344 goto do_unaryfp;
10345 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10346 mips32_op = OPC_FLOOR_L_D;
10347 goto do_unaryfp;
10348 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10349 mips32_op = OPC_FLOOR_W_S;
10350 goto do_unaryfp;
10351 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10352 mips32_op = OPC_FLOOR_W_D;
10353 goto do_unaryfp;
10355 /* Ceiling */
10356 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10357 mips32_op = OPC_CEIL_L_S;
10358 goto do_unaryfp;
10359 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10360 mips32_op = OPC_CEIL_L_D;
10361 goto do_unaryfp;
10362 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10363 mips32_op = OPC_CEIL_W_S;
10364 goto do_unaryfp;
10365 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10366 mips32_op = OPC_CEIL_W_D;
10367 goto do_unaryfp;
10369 /* Truncation */
10370 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10371 mips32_op = OPC_TRUNC_L_S;
10372 goto do_unaryfp;
10373 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10374 mips32_op = OPC_TRUNC_L_D;
10375 goto do_unaryfp;
10376 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10377 mips32_op = OPC_TRUNC_W_S;
10378 goto do_unaryfp;
10379 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10380 mips32_op = OPC_TRUNC_W_D;
10381 goto do_unaryfp;
10383 /* Round */
10384 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10385 mips32_op = OPC_ROUND_L_S;
10386 goto do_unaryfp;
10387 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10388 mips32_op = OPC_ROUND_L_D;
10389 goto do_unaryfp;
10390 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10391 mips32_op = OPC_ROUND_W_S;
10392 goto do_unaryfp;
10393 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10394 mips32_op = OPC_ROUND_W_D;
10395 goto do_unaryfp;
10397 /* Integer to floating-point conversion */
10398 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10399 mips32_op = OPC_CVT_L_S;
10400 goto do_unaryfp;
10401 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10402 mips32_op = OPC_CVT_L_D;
10403 goto do_unaryfp;
10404 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10405 mips32_op = OPC_CVT_W_S;
10406 goto do_unaryfp;
10407 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10408 mips32_op = OPC_CVT_W_D;
10409 goto do_unaryfp;
10411 /* Paired-foo conversions */
10412 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10413 mips32_op = OPC_CVT_S_PL;
10414 goto do_unaryfp;
10415 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10416 mips32_op = OPC_CVT_S_PU;
10417 goto do_unaryfp;
10418 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10419 mips32_op = OPC_CVT_PW_PS;
10420 goto do_unaryfp;
10421 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10422 mips32_op = OPC_CVT_PS_PW;
10423 goto do_unaryfp;
10425 /* Floating-point moves */
10426 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10427 mips32_op = OPC_MOV_S;
10428 goto do_unaryfp;
10429 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10430 mips32_op = OPC_MOV_D;
10431 goto do_unaryfp;
10432 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10433 mips32_op = OPC_MOV_PS;
10434 goto do_unaryfp;
10436 /* Absolute value */
10437 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10438 mips32_op = OPC_ABS_S;
10439 goto do_unaryfp;
10440 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10441 mips32_op = OPC_ABS_D;
10442 goto do_unaryfp;
10443 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10444 mips32_op = OPC_ABS_PS;
10445 goto do_unaryfp;
10447 /* Negation */
10448 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10449 mips32_op = OPC_NEG_S;
10450 goto do_unaryfp;
10451 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10452 mips32_op = OPC_NEG_D;
10453 goto do_unaryfp;
10454 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10455 mips32_op = OPC_NEG_PS;
10456 goto do_unaryfp;
10458 /* Reciprocal square root step */
10459 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10460 mips32_op = OPC_RSQRT1_S;
10461 goto do_unaryfp;
10462 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10463 mips32_op = OPC_RSQRT1_D;
10464 goto do_unaryfp;
10465 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10466 mips32_op = OPC_RSQRT1_PS;
10467 goto do_unaryfp;
10469 /* Reciprocal step */
10470 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10471 mips32_op = OPC_RECIP1_S;
10472 goto do_unaryfp;
10473 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10474 mips32_op = OPC_RECIP1_S;
10475 goto do_unaryfp;
10476 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10477 mips32_op = OPC_RECIP1_PS;
10478 goto do_unaryfp;
10480 /* Conversions from double */
10481 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10482 mips32_op = OPC_CVT_D_S;
10483 goto do_unaryfp;
10484 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10485 mips32_op = OPC_CVT_D_W;
10486 goto do_unaryfp;
10487 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10488 mips32_op = OPC_CVT_D_L;
10489 goto do_unaryfp;
10491 /* Conversions from single */
10492 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10493 mips32_op = OPC_CVT_S_D;
10494 goto do_unaryfp;
10495 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10496 mips32_op = OPC_CVT_S_W;
10497 goto do_unaryfp;
10498 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10499 mips32_op = OPC_CVT_S_L;
10500 do_unaryfp:
10501 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10502 break;
10504 /* Conditional moves on floating-point codes */
10505 case COND_FLOAT_MOV(MOVT, 0):
10506 case COND_FLOAT_MOV(MOVT, 1):
10507 case COND_FLOAT_MOV(MOVT, 2):
10508 case COND_FLOAT_MOV(MOVT, 3):
10509 case COND_FLOAT_MOV(MOVT, 4):
10510 case COND_FLOAT_MOV(MOVT, 5):
10511 case COND_FLOAT_MOV(MOVT, 6):
10512 case COND_FLOAT_MOV(MOVT, 7):
10513 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10514 break;
10515 case COND_FLOAT_MOV(MOVF, 0):
10516 case COND_FLOAT_MOV(MOVF, 1):
10517 case COND_FLOAT_MOV(MOVF, 2):
10518 case COND_FLOAT_MOV(MOVF, 3):
10519 case COND_FLOAT_MOV(MOVF, 4):
10520 case COND_FLOAT_MOV(MOVF, 5):
10521 case COND_FLOAT_MOV(MOVF, 6):
10522 case COND_FLOAT_MOV(MOVF, 7):
10523 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10524 break;
10525 default:
10526 MIPS_INVAL("pool32fxf");
10527 generate_exception(ctx, EXCP_RI);
10528 break;
10532 static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
10533 uint16_t insn_hw1, int *is_branch)
10535 int32_t offset;
10536 uint16_t insn;
10537 int rt, rs, rd, rr;
10538 int16_t imm;
10539 uint32_t op, minor, mips32_op;
10540 uint32_t cond, fmt, cc;
10542 insn = lduw_code(ctx->pc + 2);
10543 ctx->opcode = (ctx->opcode << 16) | insn;
10545 rt = (ctx->opcode >> 21) & 0x1f;
10546 rs = (ctx->opcode >> 16) & 0x1f;
10547 rd = (ctx->opcode >> 11) & 0x1f;
10548 rr = (ctx->opcode >> 6) & 0x1f;
10549 imm = (int16_t) ctx->opcode;
10551 op = (ctx->opcode >> 26) & 0x3f;
10552 switch (op) {
10553 case POOL32A:
10554 minor = ctx->opcode & 0x3f;
10555 switch (minor) {
10556 case 0x00:
10557 minor = (ctx->opcode >> 6) & 0xf;
10558 switch (minor) {
10559 case SLL32:
10560 mips32_op = OPC_SLL;
10561 goto do_shifti;
10562 case SRA:
10563 mips32_op = OPC_SRA;
10564 goto do_shifti;
10565 case SRL32:
10566 mips32_op = OPC_SRL;
10567 goto do_shifti;
10568 case ROTR:
10569 mips32_op = OPC_ROTR;
10570 do_shifti:
10571 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10572 break;
10573 default:
10574 goto pool32a_invalid;
10576 break;
10577 case 0x10:
10578 minor = (ctx->opcode >> 6) & 0xf;
10579 switch (minor) {
10580 /* Arithmetic */
10581 case ADD:
10582 mips32_op = OPC_ADD;
10583 goto do_arith;
10584 case ADDU32:
10585 mips32_op = OPC_ADDU;
10586 goto do_arith;
10587 case SUB:
10588 mips32_op = OPC_SUB;
10589 goto do_arith;
10590 case SUBU32:
10591 mips32_op = OPC_SUBU;
10592 goto do_arith;
10593 case MUL:
10594 mips32_op = OPC_MUL;
10595 do_arith:
10596 gen_arith(env, ctx, mips32_op, rd, rs, rt);
10597 break;
10598 /* Shifts */
10599 case SLLV:
10600 mips32_op = OPC_SLLV;
10601 goto do_shift;
10602 case SRLV:
10603 mips32_op = OPC_SRLV;
10604 goto do_shift;
10605 case SRAV:
10606 mips32_op = OPC_SRAV;
10607 goto do_shift;
10608 case ROTRV:
10609 mips32_op = OPC_ROTRV;
10610 do_shift:
10611 gen_shift(env, ctx, mips32_op, rd, rs, rt);
10612 break;
10613 /* Logical operations */
10614 case AND:
10615 mips32_op = OPC_AND;
10616 goto do_logic;
10617 case OR32:
10618 mips32_op = OPC_OR;
10619 goto do_logic;
10620 case NOR:
10621 mips32_op = OPC_NOR;
10622 goto do_logic;
10623 case XOR32:
10624 mips32_op = OPC_XOR;
10625 do_logic:
10626 gen_logic(env, mips32_op, rd, rs, rt);
10627 break;
10628 /* Set less than */
10629 case SLT:
10630 mips32_op = OPC_SLT;
10631 goto do_slt;
10632 case SLTU:
10633 mips32_op = OPC_SLTU;
10634 do_slt:
10635 gen_slt(env, mips32_op, rd, rs, rt);
10636 break;
10637 default:
10638 goto pool32a_invalid;
10640 break;
10641 case 0x18:
10642 minor = (ctx->opcode >> 6) & 0xf;
10643 switch (minor) {
10644 /* Conditional moves */
10645 case MOVN:
10646 mips32_op = OPC_MOVN;
10647 goto do_cmov;
10648 case MOVZ:
10649 mips32_op = OPC_MOVZ;
10650 do_cmov:
10651 gen_cond_move(env, mips32_op, rd, rs, rt);
10652 break;
10653 case LWXS:
10654 gen_ldxs(ctx, rs, rt, rd);
10655 break;
10656 default:
10657 goto pool32a_invalid;
10659 break;
10660 case INS:
10661 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10662 return;
10663 case EXT:
10664 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10665 return;
10666 case POOL32AXF:
10667 gen_pool32axf(env, ctx, rt, rs, is_branch);
10668 break;
10669 case 0x07:
10670 generate_exception(ctx, EXCP_BREAK);
10671 break;
10672 default:
10673 pool32a_invalid:
10674 MIPS_INVAL("pool32a");
10675 generate_exception(ctx, EXCP_RI);
10676 break;
10678 break;
10679 case POOL32B:
10680 minor = (ctx->opcode >> 12) & 0xf;
10681 switch (minor) {
10682 case CACHE:
10683 /* Treat as no-op. */
10684 break;
10685 case LWC2:
10686 case SWC2:
10687 /* COP2: Not implemented. */
10688 generate_exception_err(ctx, EXCP_CpU, 2);
10689 break;
10690 case LWP:
10691 case SWP:
10692 #ifdef TARGET_MIPS64
10693 case LDP:
10694 case SDP:
10695 #endif
10696 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10697 break;
10698 case LWM32:
10699 case SWM32:
10700 #ifdef TARGET_MIPS64
10701 case LDM:
10702 case SDM:
10703 #endif
10704 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10705 break;
10706 default:
10707 MIPS_INVAL("pool32b");
10708 generate_exception(ctx, EXCP_RI);
10709 break;
10711 break;
10712 case POOL32F:
10713 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10714 minor = ctx->opcode & 0x3f;
10715 check_cp1_enabled(ctx);
10716 switch (minor) {
10717 case ALNV_PS:
10718 mips32_op = OPC_ALNV_PS;
10719 goto do_madd;
10720 case MADD_S:
10721 mips32_op = OPC_MADD_S;
10722 goto do_madd;
10723 case MADD_D:
10724 mips32_op = OPC_MADD_D;
10725 goto do_madd;
10726 case MADD_PS:
10727 mips32_op = OPC_MADD_PS;
10728 goto do_madd;
10729 case MSUB_S:
10730 mips32_op = OPC_MSUB_S;
10731 goto do_madd;
10732 case MSUB_D:
10733 mips32_op = OPC_MSUB_D;
10734 goto do_madd;
10735 case MSUB_PS:
10736 mips32_op = OPC_MSUB_PS;
10737 goto do_madd;
10738 case NMADD_S:
10739 mips32_op = OPC_NMADD_S;
10740 goto do_madd;
10741 case NMADD_D:
10742 mips32_op = OPC_NMADD_D;
10743 goto do_madd;
10744 case NMADD_PS:
10745 mips32_op = OPC_NMADD_PS;
10746 goto do_madd;
10747 case NMSUB_S:
10748 mips32_op = OPC_NMSUB_S;
10749 goto do_madd;
10750 case NMSUB_D:
10751 mips32_op = OPC_NMSUB_D;
10752 goto do_madd;
10753 case NMSUB_PS:
10754 mips32_op = OPC_NMSUB_PS;
10755 do_madd:
10756 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10757 break;
10758 case CABS_COND_FMT:
10759 cond = (ctx->opcode >> 6) & 0xf;
10760 cc = (ctx->opcode >> 13) & 0x7;
10761 fmt = (ctx->opcode >> 10) & 0x3;
10762 switch (fmt) {
10763 case 0x0:
10764 gen_cmpabs_s(ctx, cond, rt, rs, cc);
10765 break;
10766 case 0x1:
10767 gen_cmpabs_d(ctx, cond, rt, rs, cc);
10768 break;
10769 case 0x2:
10770 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10771 break;
10772 default:
10773 goto pool32f_invalid;
10775 break;
10776 case C_COND_FMT:
10777 cond = (ctx->opcode >> 6) & 0xf;
10778 cc = (ctx->opcode >> 13) & 0x7;
10779 fmt = (ctx->opcode >> 10) & 0x3;
10780 switch (fmt) {
10781 case 0x0:
10782 gen_cmp_s(ctx, cond, rt, rs, cc);
10783 break;
10784 case 0x1:
10785 gen_cmp_d(ctx, cond, rt, rs, cc);
10786 break;
10787 case 0x2:
10788 gen_cmp_ps(ctx, cond, rt, rs, cc);
10789 break;
10790 default:
10791 goto pool32f_invalid;
10793 break;
10794 case POOL32FXF:
10795 gen_pool32fxf(env, ctx, rt, rs);
10796 break;
10797 case 0x00:
10798 /* PLL foo */
10799 switch ((ctx->opcode >> 6) & 0x7) {
10800 case PLL_PS:
10801 mips32_op = OPC_PLL_PS;
10802 goto do_ps;
10803 case PLU_PS:
10804 mips32_op = OPC_PLU_PS;
10805 goto do_ps;
10806 case PUL_PS:
10807 mips32_op = OPC_PUL_PS;
10808 goto do_ps;
10809 case PUU_PS:
10810 mips32_op = OPC_PUU_PS;
10811 goto do_ps;
10812 case CVT_PS_S:
10813 mips32_op = OPC_CVT_PS_S;
10814 do_ps:
10815 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10816 break;
10817 default:
10818 goto pool32f_invalid;
10820 break;
10821 case 0x08:
10822 /* [LS][WDU]XC1 */
10823 switch ((ctx->opcode >> 6) & 0x7) {
10824 case LWXC1:
10825 mips32_op = OPC_LWXC1;
10826 goto do_ldst_cp1;
10827 case SWXC1:
10828 mips32_op = OPC_SWXC1;
10829 goto do_ldst_cp1;
10830 case LDXC1:
10831 mips32_op = OPC_LDXC1;
10832 goto do_ldst_cp1;
10833 case SDXC1:
10834 mips32_op = OPC_SDXC1;
10835 goto do_ldst_cp1;
10836 case LUXC1:
10837 mips32_op = OPC_LUXC1;
10838 goto do_ldst_cp1;
10839 case SUXC1:
10840 mips32_op = OPC_SUXC1;
10841 do_ldst_cp1:
10842 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10843 break;
10844 default:
10845 goto pool32f_invalid;
10847 break;
10848 case 0x18:
10849 /* 3D insns */
10850 fmt = (ctx->opcode >> 9) & 0x3;
10851 switch ((ctx->opcode >> 6) & 0x7) {
10852 case RSQRT2_FMT:
10853 switch (fmt) {
10854 case FMT_SDPS_S:
10855 mips32_op = OPC_RSQRT2_S;
10856 goto do_3d;
10857 case FMT_SDPS_D:
10858 mips32_op = OPC_RSQRT2_D;
10859 goto do_3d;
10860 case FMT_SDPS_PS:
10861 mips32_op = OPC_RSQRT2_PS;
10862 goto do_3d;
10863 default:
10864 goto pool32f_invalid;
10866 break;
10867 case RECIP2_FMT:
10868 switch (fmt) {
10869 case FMT_SDPS_S:
10870 mips32_op = OPC_RECIP2_S;
10871 goto do_3d;
10872 case FMT_SDPS_D:
10873 mips32_op = OPC_RECIP2_D;
10874 goto do_3d;
10875 case FMT_SDPS_PS:
10876 mips32_op = OPC_RECIP2_PS;
10877 goto do_3d;
10878 default:
10879 goto pool32f_invalid;
10881 break;
10882 case ADDR_PS:
10883 mips32_op = OPC_ADDR_PS;
10884 goto do_3d;
10885 case MULR_PS:
10886 mips32_op = OPC_MULR_PS;
10887 do_3d:
10888 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10889 break;
10890 default:
10891 goto pool32f_invalid;
10893 break;
10894 case 0x20:
10895 /* MOV[FT].fmt and PREFX */
10896 cc = (ctx->opcode >> 13) & 0x7;
10897 fmt = (ctx->opcode >> 9) & 0x3;
10898 switch ((ctx->opcode >> 6) & 0x7) {
10899 case MOVF_FMT:
10900 switch (fmt) {
10901 case FMT_SDPS_S:
10902 gen_movcf_s(rs, rt, cc, 0);
10903 break;
10904 case FMT_SDPS_D:
10905 gen_movcf_d(ctx, rs, rt, cc, 0);
10906 break;
10907 case FMT_SDPS_PS:
10908 gen_movcf_ps(rs, rt, cc, 0);
10909 break;
10910 default:
10911 goto pool32f_invalid;
10913 break;
10914 case MOVT_FMT:
10915 switch (fmt) {
10916 case FMT_SDPS_S:
10917 gen_movcf_s(rs, rt, cc, 1);
10918 break;
10919 case FMT_SDPS_D:
10920 gen_movcf_d(ctx, rs, rt, cc, 1);
10921 break;
10922 case FMT_SDPS_PS:
10923 gen_movcf_ps(rs, rt, cc, 1);
10924 break;
10925 default:
10926 goto pool32f_invalid;
10928 break;
10929 case PREFX:
10930 break;
10931 default:
10932 goto pool32f_invalid;
10934 break;
10935 #define FINSN_3ARG_SDPS(prfx) \
10936 switch ((ctx->opcode >> 8) & 0x3) { \
10937 case FMT_SDPS_S: \
10938 mips32_op = OPC_##prfx##_S; \
10939 goto do_fpop; \
10940 case FMT_SDPS_D: \
10941 mips32_op = OPC_##prfx##_D; \
10942 goto do_fpop; \
10943 case FMT_SDPS_PS: \
10944 mips32_op = OPC_##prfx##_PS; \
10945 goto do_fpop; \
10946 default: \
10947 goto pool32f_invalid; \
10949 case 0x30:
10950 /* regular FP ops */
10951 switch ((ctx->opcode >> 6) & 0x3) {
10952 case ADD_FMT:
10953 FINSN_3ARG_SDPS(ADD);
10954 break;
10955 case SUB_FMT:
10956 FINSN_3ARG_SDPS(SUB);
10957 break;
10958 case MUL_FMT:
10959 FINSN_3ARG_SDPS(MUL);
10960 break;
10961 case DIV_FMT:
10962 fmt = (ctx->opcode >> 8) & 0x3;
10963 if (fmt == 1) {
10964 mips32_op = OPC_DIV_D;
10965 } else if (fmt == 0) {
10966 mips32_op = OPC_DIV_S;
10967 } else {
10968 goto pool32f_invalid;
10970 goto do_fpop;
10971 default:
10972 goto pool32f_invalid;
10974 break;
10975 case 0x38:
10976 /* cmovs */
10977 switch ((ctx->opcode >> 6) & 0x3) {
10978 case MOVN_FMT:
10979 FINSN_3ARG_SDPS(MOVN);
10980 break;
10981 case MOVZ_FMT:
10982 FINSN_3ARG_SDPS(MOVZ);
10983 break;
10984 default:
10985 goto pool32f_invalid;
10987 break;
10988 do_fpop:
10989 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10990 break;
10991 default:
10992 pool32f_invalid:
10993 MIPS_INVAL("pool32f");
10994 generate_exception(ctx, EXCP_RI);
10995 break;
10997 } else {
10998 generate_exception_err(ctx, EXCP_CpU, 1);
11000 break;
11001 case POOL32I:
11002 minor = (ctx->opcode >> 21) & 0x1f;
11003 switch (minor) {
11004 case BLTZ:
11005 mips32_op = OPC_BLTZ;
11006 goto do_branch;
11007 case BLTZAL:
11008 mips32_op = OPC_BLTZAL;
11009 goto do_branch;
11010 case BLTZALS:
11011 mips32_op = OPC_BLTZALS;
11012 goto do_branch;
11013 case BGEZ:
11014 mips32_op = OPC_BGEZ;
11015 goto do_branch;
11016 case BGEZAL:
11017 mips32_op = OPC_BGEZAL;
11018 goto do_branch;
11019 case BGEZALS:
11020 mips32_op = OPC_BGEZALS;
11021 goto do_branch;
11022 case BLEZ:
11023 mips32_op = OPC_BLEZ;
11024 goto do_branch;
11025 case BGTZ:
11026 mips32_op = OPC_BGTZ;
11027 do_branch:
11028 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
11029 *is_branch = 1;
11030 break;
11032 /* Traps */
11033 case TLTI:
11034 mips32_op = OPC_TLTI;
11035 goto do_trapi;
11036 case TGEI:
11037 mips32_op = OPC_TGEI;
11038 goto do_trapi;
11039 case TLTIU:
11040 mips32_op = OPC_TLTIU;
11041 goto do_trapi;
11042 case TGEIU:
11043 mips32_op = OPC_TGEIU;
11044 goto do_trapi;
11045 case TNEI:
11046 mips32_op = OPC_TNEI;
11047 goto do_trapi;
11048 case TEQI:
11049 mips32_op = OPC_TEQI;
11050 do_trapi:
11051 gen_trap(ctx, mips32_op, rs, -1, imm);
11052 break;
11054 case BNEZC:
11055 case BEQZC:
11056 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
11057 4, rs, 0, imm << 1);
11058 /* Compact branches don't have a delay slot, so just let
11059 the normal delay slot handling take us to the branch
11060 target. */
11061 break;
11062 case LUI:
11063 gen_logic_imm(env, OPC_LUI, rs, -1, imm);
11064 break;
11065 case SYNCI:
11066 break;
11067 case BC2F:
11068 case BC2T:
11069 /* COP2: Not implemented. */
11070 generate_exception_err(ctx, EXCP_CpU, 2);
11071 break;
11072 case BC1F:
11073 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11074 goto do_cp1branch;
11075 case BC1T:
11076 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11077 goto do_cp1branch;
11078 case BC1ANY4F:
11079 mips32_op = OPC_BC1FANY4;
11080 goto do_cp1mips3d;
11081 case BC1ANY4T:
11082 mips32_op = OPC_BC1TANY4;
11083 do_cp1mips3d:
11084 check_cop1x(ctx);
11085 check_insn(env, ctx, ASE_MIPS3D);
11086 /* Fall through */
11087 do_cp1branch:
11088 gen_compute_branch1(env, ctx, mips32_op,
11089 (ctx->opcode >> 18) & 0x7, imm << 1);
11090 *is_branch = 1;
11091 break;
11092 case BPOSGE64:
11093 case BPOSGE32:
11094 /* MIPS DSP: not implemented */
11095 /* Fall through */
11096 default:
11097 MIPS_INVAL("pool32i");
11098 generate_exception(ctx, EXCP_RI);
11099 break;
11101 break;
11102 case POOL32C:
11103 minor = (ctx->opcode >> 12) & 0xf;
11104 switch (minor) {
11105 case LWL:
11106 mips32_op = OPC_LWL;
11107 goto do_ld_lr;
11108 case SWL:
11109 mips32_op = OPC_SWL;
11110 goto do_st_lr;
11111 case LWR:
11112 mips32_op = OPC_LWR;
11113 goto do_ld_lr;
11114 case SWR:
11115 mips32_op = OPC_SWR;
11116 goto do_st_lr;
11117 #if defined(TARGET_MIPS64)
11118 case LDL:
11119 mips32_op = OPC_LDL;
11120 goto do_ld_lr;
11121 case SDL:
11122 mips32_op = OPC_SDL;
11123 goto do_st_lr;
11124 case LDR:
11125 mips32_op = OPC_LDR;
11126 goto do_ld_lr;
11127 case SDR:
11128 mips32_op = OPC_SDR;
11129 goto do_st_lr;
11130 case LWU:
11131 mips32_op = OPC_LWU;
11132 goto do_ld_lr;
11133 case LLD:
11134 mips32_op = OPC_LLD;
11135 goto do_ld_lr;
11136 #endif
11137 case LL:
11138 mips32_op = OPC_LL;
11139 goto do_ld_lr;
11140 do_ld_lr:
11141 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11142 break;
11143 do_st_lr:
11144 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11145 break;
11146 case SC:
11147 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11148 break;
11149 #if defined(TARGET_MIPS64)
11150 case SCD:
11151 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11152 break;
11153 #endif
11154 case PREF:
11155 /* Treat as no-op */
11156 break;
11157 default:
11158 MIPS_INVAL("pool32c");
11159 generate_exception(ctx, EXCP_RI);
11160 break;
11162 break;
11163 case ADDI32:
11164 mips32_op = OPC_ADDI;
11165 goto do_addi;
11166 case ADDIU32:
11167 mips32_op = OPC_ADDIU;
11168 do_addi:
11169 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11170 break;
11172 /* Logical operations */
11173 case ORI32:
11174 mips32_op = OPC_ORI;
11175 goto do_logici;
11176 case XORI32:
11177 mips32_op = OPC_XORI;
11178 goto do_logici;
11179 case ANDI32:
11180 mips32_op = OPC_ANDI;
11181 do_logici:
11182 gen_logic_imm(env, mips32_op, rt, rs, imm);
11183 break;
11185 /* Set less than immediate */
11186 case SLTI32:
11187 mips32_op = OPC_SLTI;
11188 goto do_slti;
11189 case SLTIU32:
11190 mips32_op = OPC_SLTIU;
11191 do_slti:
11192 gen_slt_imm(env, mips32_op, rt, rs, imm);
11193 break;
11194 case JALX32:
11195 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11196 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11197 *is_branch = 1;
11198 break;
11199 case JALS32:
11200 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11201 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11202 *is_branch = 1;
11203 break;
11204 case BEQ32:
11205 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11206 *is_branch = 1;
11207 break;
11208 case BNE32:
11209 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11210 *is_branch = 1;
11211 break;
11212 case J32:
11213 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11214 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11215 *is_branch = 1;
11216 break;
11217 case JAL32:
11218 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11219 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11220 *is_branch = 1;
11221 break;
11222 /* Floating point (COP1) */
11223 case LWC132:
11224 mips32_op = OPC_LWC1;
11225 goto do_cop1;
11226 case LDC132:
11227 mips32_op = OPC_LDC1;
11228 goto do_cop1;
11229 case SWC132:
11230 mips32_op = OPC_SWC1;
11231 goto do_cop1;
11232 case SDC132:
11233 mips32_op = OPC_SDC1;
11234 do_cop1:
11235 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11236 break;
11237 case ADDIUPC:
11239 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
11240 int offset = SIMM(ctx->opcode, 0, 23) << 2;
11242 gen_addiupc(ctx, reg, offset, 0, 0);
11244 break;
11245 /* Loads and stores */
11246 case LB32:
11247 mips32_op = OPC_LB;
11248 goto do_ld;
11249 case LBU32:
11250 mips32_op = OPC_LBU;
11251 goto do_ld;
11252 case LH32:
11253 mips32_op = OPC_LH;
11254 goto do_ld;
11255 case LHU32:
11256 mips32_op = OPC_LHU;
11257 goto do_ld;
11258 case LW32:
11259 mips32_op = OPC_LW;
11260 goto do_ld;
11261 #ifdef TARGET_MIPS64
11262 case LD32:
11263 mips32_op = OPC_LD;
11264 goto do_ld;
11265 case SD32:
11266 mips32_op = OPC_SD;
11267 goto do_st;
11268 #endif
11269 case SB32:
11270 mips32_op = OPC_SB;
11271 goto do_st;
11272 case SH32:
11273 mips32_op = OPC_SH;
11274 goto do_st;
11275 case SW32:
11276 mips32_op = OPC_SW;
11277 goto do_st;
11278 do_ld:
11279 gen_ld(env, ctx, mips32_op, rt, rs, imm);
11280 break;
11281 do_st:
11282 gen_st(ctx, mips32_op, rt, rs, imm);
11283 break;
11284 default:
11285 generate_exception(ctx, EXCP_RI);
11286 break;
11290 static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11292 uint32_t op;
11294 /* make sure instructions are on a halfword boundary */
11295 if (ctx->pc & 0x1) {
11296 env->CP0_BadVAddr = ctx->pc;
11297 generate_exception(ctx, EXCP_AdEL);
11298 ctx->bstate = BS_STOP;
11299 return 2;
11302 op = (ctx->opcode >> 10) & 0x3f;
11303 /* Enforce properly-sized instructions in a delay slot */
11304 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11305 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11307 switch (op) {
11308 case POOL32A:
11309 case POOL32B:
11310 case POOL32I:
11311 case POOL32C:
11312 case ADDI32:
11313 case ADDIU32:
11314 case ORI32:
11315 case XORI32:
11316 case SLTI32:
11317 case SLTIU32:
11318 case ANDI32:
11319 case JALX32:
11320 case LBU32:
11321 case LHU32:
11322 case POOL32F:
11323 case JALS32:
11324 case BEQ32:
11325 case BNE32:
11326 case J32:
11327 case JAL32:
11328 case SB32:
11329 case SH32:
11330 case POOL32S:
11331 case ADDIUPC:
11332 case SWC132:
11333 case SDC132:
11334 case SD32:
11335 case SW32:
11336 case LB32:
11337 case LH32:
11338 case DADDIU32:
11339 case POOL48A: /* ??? */
11340 case LWC132:
11341 case LDC132:
11342 case LD32:
11343 case LW32:
11344 if (bits & MIPS_HFLAG_BDS16) {
11345 generate_exception(ctx, EXCP_RI);
11346 /* Just stop translation; the user is confused. */
11347 ctx->bstate = BS_STOP;
11348 return 2;
11350 break;
11351 case POOL16A:
11352 case POOL16B:
11353 case POOL16C:
11354 case LWGP16:
11355 case POOL16F:
11356 case LBU16:
11357 case LHU16:
11358 case LWSP16:
11359 case LW16:
11360 case SB16:
11361 case SH16:
11362 case SWSP16:
11363 case SW16:
11364 case MOVE16:
11365 case ANDI16:
11366 case POOL16D:
11367 case POOL16E:
11368 case BEQZ16:
11369 case BNEZ16:
11370 case B16:
11371 case LI16:
11372 if (bits & MIPS_HFLAG_BDS32) {
11373 generate_exception(ctx, EXCP_RI);
11374 /* Just stop translation; the user is confused. */
11375 ctx->bstate = BS_STOP;
11376 return 2;
11378 break;
11379 default:
11380 break;
11383 switch (op) {
11384 case POOL16A:
11386 int rd = mmreg(uMIPS_RD(ctx->opcode));
11387 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11388 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11389 uint32_t opc = 0;
11391 switch (ctx->opcode & 0x1) {
11392 case ADDU16:
11393 opc = OPC_ADDU;
11394 break;
11395 case SUBU16:
11396 opc = OPC_SUBU;
11397 break;
11400 gen_arith(env, ctx, opc, rd, rs1, rs2);
11402 break;
11403 case POOL16B:
11405 int rd = mmreg(uMIPS_RD(ctx->opcode));
11406 int rs = mmreg(uMIPS_RS(ctx->opcode));
11407 int amount = (ctx->opcode >> 1) & 0x7;
11408 uint32_t opc = 0;
11409 amount = amount == 0 ? 8 : amount;
11411 switch (ctx->opcode & 0x1) {
11412 case SLL16:
11413 opc = OPC_SLL;
11414 break;
11415 case SRL16:
11416 opc = OPC_SRL;
11417 break;
11420 gen_shift_imm(env, ctx, opc, rd, rs, amount);
11422 break;
11423 case POOL16C:
11424 gen_pool16c_insn(env, ctx, is_branch);
11425 break;
11426 case LWGP16:
11428 int rd = mmreg(uMIPS_RD(ctx->opcode));
11429 int rb = 28; /* GP */
11430 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11432 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11434 break;
11435 case POOL16F:
11436 if (ctx->opcode & 1) {
11437 generate_exception(ctx, EXCP_RI);
11438 } else {
11439 /* MOVEP */
11440 int enc_dest = uMIPS_RD(ctx->opcode);
11441 int enc_rt = uMIPS_RS2(ctx->opcode);
11442 int enc_rs = uMIPS_RS1(ctx->opcode);
11443 int rd, rs, re, rt;
11444 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11445 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11446 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11448 rd = rd_enc[enc_dest];
11449 re = re_enc[enc_dest];
11450 rs = rs_rt_enc[enc_rs];
11451 rt = rs_rt_enc[enc_rt];
11453 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11454 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11456 break;
11457 case LBU16:
11459 int rd = mmreg(uMIPS_RD(ctx->opcode));
11460 int rb = mmreg(uMIPS_RS(ctx->opcode));
11461 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11462 offset = (offset == 0xf ? -1 : offset);
11464 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
11466 break;
11467 case LHU16:
11469 int rd = mmreg(uMIPS_RD(ctx->opcode));
11470 int rb = mmreg(uMIPS_RS(ctx->opcode));
11471 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11473 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
11475 break;
11476 case LWSP16:
11478 int rd = (ctx->opcode >> 5) & 0x1f;
11479 int rb = 29; /* SP */
11480 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11482 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11484 break;
11485 case LW16:
11487 int rd = mmreg(uMIPS_RD(ctx->opcode));
11488 int rb = mmreg(uMIPS_RS(ctx->opcode));
11489 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11491 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11493 break;
11494 case SB16:
11496 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11497 int rb = mmreg(uMIPS_RS(ctx->opcode));
11498 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11500 gen_st(ctx, OPC_SB, rd, rb, offset);
11502 break;
11503 case SH16:
11505 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11506 int rb = mmreg(uMIPS_RS(ctx->opcode));
11507 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11509 gen_st(ctx, OPC_SH, rd, rb, offset);
11511 break;
11512 case SWSP16:
11514 int rd = (ctx->opcode >> 5) & 0x1f;
11515 int rb = 29; /* SP */
11516 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11518 gen_st(ctx, OPC_SW, rd, rb, offset);
11520 break;
11521 case SW16:
11523 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11524 int rb = mmreg(uMIPS_RS(ctx->opcode));
11525 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11527 gen_st(ctx, OPC_SW, rd, rb, offset);
11529 break;
11530 case MOVE16:
11532 int rd = uMIPS_RD5(ctx->opcode);
11533 int rs = uMIPS_RS5(ctx->opcode);
11535 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11537 break;
11538 case ANDI16:
11539 gen_andi16(env, ctx);
11540 break;
11541 case POOL16D:
11542 switch (ctx->opcode & 0x1) {
11543 case ADDIUS5:
11544 gen_addius5(env, ctx);
11545 break;
11546 case ADDIUSP:
11547 gen_addiusp(env, ctx);
11548 break;
11550 break;
11551 case POOL16E:
11552 switch (ctx->opcode & 0x1) {
11553 case ADDIUR2:
11554 gen_addiur2(env, ctx);
11555 break;
11556 case ADDIUR1SP:
11557 gen_addiur1sp(env, ctx);
11558 break;
11560 break;
11561 case B16:
11562 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11563 SIMM(ctx->opcode, 0, 10) << 1);
11564 *is_branch = 1;
11565 break;
11566 case BNEZ16:
11567 case BEQZ16:
11568 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11569 mmreg(uMIPS_RD(ctx->opcode)),
11570 0, SIMM(ctx->opcode, 0, 7) << 1);
11571 *is_branch = 1;
11572 break;
11573 case LI16:
11575 int reg = mmreg(uMIPS_RD(ctx->opcode));
11576 int imm = ZIMM(ctx->opcode, 0, 7);
11578 imm = (imm == 0x7f ? -1 : imm);
11579 tcg_gen_movi_tl(cpu_gpr[reg], imm);
11581 break;
11582 case RES_20:
11583 case RES_28:
11584 case RES_29:
11585 case RES_30:
11586 case RES_31:
11587 case RES_38:
11588 case RES_39:
11589 generate_exception(ctx, EXCP_RI);
11590 break;
11591 default:
11592 decode_micromips32_opc (env, ctx, op, is_branch);
11593 return 4;
11596 return 2;
11599 /* SmartMIPS extension to MIPS32 */
11601 #if defined(TARGET_MIPS64)
11603 /* MDMX extension to MIPS64 */
11605 #endif
11607 static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11609 int32_t offset;
11610 int rs, rt, rd, sa;
11611 uint32_t op, op1, op2;
11612 int16_t imm;
11614 /* make sure instructions are on a word boundary */
11615 if (ctx->pc & 0x3) {
11616 env->CP0_BadVAddr = ctx->pc;
11617 generate_exception(ctx, EXCP_AdEL);
11618 return;
11621 /* Handle blikely not taken case */
11622 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11623 int l1 = gen_new_label();
11625 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11626 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11627 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11628 gen_goto_tb(ctx, 1, ctx->pc + 4);
11629 gen_set_label(l1);
11632 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11633 tcg_gen_debug_insn_start(ctx->pc);
11635 op = MASK_OP_MAJOR(ctx->opcode);
11636 rs = (ctx->opcode >> 21) & 0x1f;
11637 rt = (ctx->opcode >> 16) & 0x1f;
11638 rd = (ctx->opcode >> 11) & 0x1f;
11639 sa = (ctx->opcode >> 6) & 0x1f;
11640 imm = (int16_t)ctx->opcode;
11641 switch (op) {
11642 case OPC_SPECIAL:
11643 op1 = MASK_SPECIAL(ctx->opcode);
11644 switch (op1) {
11645 case OPC_SLL: /* Shift with immediate */
11646 case OPC_SRA:
11647 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11648 break;
11649 case OPC_SRL:
11650 switch ((ctx->opcode >> 21) & 0x1f) {
11651 case 1:
11652 /* rotr is decoded as srl on non-R2 CPUs */
11653 if (env->insn_flags & ISA_MIPS32R2) {
11654 op1 = OPC_ROTR;
11656 /* Fallthrough */
11657 case 0:
11658 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11659 break;
11660 default:
11661 generate_exception(ctx, EXCP_RI);
11662 break;
11664 break;
11665 case OPC_MOVN: /* Conditional move */
11666 case OPC_MOVZ:
11667 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11668 INSN_LOONGSON2E | INSN_LOONGSON2F);
11669 gen_cond_move(env, op1, rd, rs, rt);
11670 break;
11671 case OPC_ADD ... OPC_SUBU:
11672 gen_arith(env, ctx, op1, rd, rs, rt);
11673 break;
11674 case OPC_SLLV: /* Shifts */
11675 case OPC_SRAV:
11676 gen_shift(env, ctx, op1, rd, rs, rt);
11677 break;
11678 case OPC_SRLV:
11679 switch ((ctx->opcode >> 6) & 0x1f) {
11680 case 1:
11681 /* rotrv is decoded as srlv on non-R2 CPUs */
11682 if (env->insn_flags & ISA_MIPS32R2) {
11683 op1 = OPC_ROTRV;
11685 /* Fallthrough */
11686 case 0:
11687 gen_shift(env, ctx, op1, rd, rs, rt);
11688 break;
11689 default:
11690 generate_exception(ctx, EXCP_RI);
11691 break;
11693 break;
11694 case OPC_SLT: /* Set on less than */
11695 case OPC_SLTU:
11696 gen_slt(env, op1, rd, rs, rt);
11697 break;
11698 case OPC_AND: /* Logic*/
11699 case OPC_OR:
11700 case OPC_NOR:
11701 case OPC_XOR:
11702 gen_logic(env, op1, rd, rs, rt);
11703 break;
11704 case OPC_MULT ... OPC_DIVU:
11705 if (sa) {
11706 check_insn(env, ctx, INSN_VR54XX);
11707 op1 = MASK_MUL_VR54XX(ctx->opcode);
11708 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11709 } else
11710 gen_muldiv(ctx, op1, rs, rt);
11711 break;
11712 case OPC_JR ... OPC_JALR:
11713 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11714 *is_branch = 1;
11715 break;
11716 case OPC_TGE ... OPC_TEQ: /* Traps */
11717 case OPC_TNE:
11718 gen_trap(ctx, op1, rs, rt, -1);
11719 break;
11720 case OPC_MFHI: /* Move from HI/LO */
11721 case OPC_MFLO:
11722 gen_HILO(ctx, op1, rd);
11723 break;
11724 case OPC_MTHI:
11725 case OPC_MTLO: /* Move to HI/LO */
11726 gen_HILO(ctx, op1, rs);
11727 break;
11728 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
11729 #ifdef MIPS_STRICT_STANDARD
11730 MIPS_INVAL("PMON / selsl");
11731 generate_exception(ctx, EXCP_RI);
11732 #else
11733 gen_helper_0i(pmon, sa);
11734 #endif
11735 break;
11736 case OPC_SYSCALL:
11737 generate_exception(ctx, EXCP_SYSCALL);
11738 ctx->bstate = BS_STOP;
11739 break;
11740 case OPC_BREAK:
11741 generate_exception(ctx, EXCP_BREAK);
11742 break;
11743 case OPC_SPIM:
11744 #ifdef MIPS_STRICT_STANDARD
11745 MIPS_INVAL("SPIM");
11746 generate_exception(ctx, EXCP_RI);
11747 #else
11748 /* Implemented as RI exception for now. */
11749 MIPS_INVAL("spim (unofficial)");
11750 generate_exception(ctx, EXCP_RI);
11751 #endif
11752 break;
11753 case OPC_SYNC:
11754 /* Treat as NOP. */
11755 break;
11757 case OPC_MOVCI:
11758 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11759 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11760 check_cp1_enabled(ctx);
11761 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11762 (ctx->opcode >> 16) & 1);
11763 } else {
11764 generate_exception_err(ctx, EXCP_CpU, 1);
11766 break;
11768 #if defined(TARGET_MIPS64)
11769 /* MIPS64 specific opcodes */
11770 case OPC_DSLL:
11771 case OPC_DSRA:
11772 case OPC_DSLL32:
11773 case OPC_DSRA32:
11774 check_insn(env, ctx, ISA_MIPS3);
11775 check_mips_64(ctx);
11776 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11777 break;
11778 case OPC_DSRL:
11779 switch ((ctx->opcode >> 21) & 0x1f) {
11780 case 1:
11781 /* drotr is decoded as dsrl on non-R2 CPUs */
11782 if (env->insn_flags & ISA_MIPS32R2) {
11783 op1 = OPC_DROTR;
11785 /* Fallthrough */
11786 case 0:
11787 check_insn(env, ctx, ISA_MIPS3);
11788 check_mips_64(ctx);
11789 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11790 break;
11791 default:
11792 generate_exception(ctx, EXCP_RI);
11793 break;
11795 break;
11796 case OPC_DSRL32:
11797 switch ((ctx->opcode >> 21) & 0x1f) {
11798 case 1:
11799 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11800 if (env->insn_flags & ISA_MIPS32R2) {
11801 op1 = OPC_DROTR32;
11803 /* Fallthrough */
11804 case 0:
11805 check_insn(env, ctx, ISA_MIPS3);
11806 check_mips_64(ctx);
11807 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11808 break;
11809 default:
11810 generate_exception(ctx, EXCP_RI);
11811 break;
11813 break;
11814 case OPC_DADD ... OPC_DSUBU:
11815 check_insn(env, ctx, ISA_MIPS3);
11816 check_mips_64(ctx);
11817 gen_arith(env, ctx, op1, rd, rs, rt);
11818 break;
11819 case OPC_DSLLV:
11820 case OPC_DSRAV:
11821 check_insn(env, ctx, ISA_MIPS3);
11822 check_mips_64(ctx);
11823 gen_shift(env, ctx, op1, rd, rs, rt);
11824 break;
11825 case OPC_DSRLV:
11826 switch ((ctx->opcode >> 6) & 0x1f) {
11827 case 1:
11828 /* drotrv is decoded as dsrlv on non-R2 CPUs */
11829 if (env->insn_flags & ISA_MIPS32R2) {
11830 op1 = OPC_DROTRV;
11832 /* Fallthrough */
11833 case 0:
11834 check_insn(env, ctx, ISA_MIPS3);
11835 check_mips_64(ctx);
11836 gen_shift(env, ctx, op1, rd, rs, rt);
11837 break;
11838 default:
11839 generate_exception(ctx, EXCP_RI);
11840 break;
11842 break;
11843 case OPC_DMULT ... OPC_DDIVU:
11844 check_insn(env, ctx, ISA_MIPS3);
11845 check_mips_64(ctx);
11846 gen_muldiv(ctx, op1, rs, rt);
11847 break;
11848 #endif
11849 default: /* Invalid */
11850 MIPS_INVAL("special");
11851 generate_exception(ctx, EXCP_RI);
11852 break;
11854 break;
11855 case OPC_SPECIAL2:
11856 op1 = MASK_SPECIAL2(ctx->opcode);
11857 switch (op1) {
11858 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11859 case OPC_MSUB ... OPC_MSUBU:
11860 check_insn(env, ctx, ISA_MIPS32);
11861 gen_muldiv(ctx, op1, rs, rt);
11862 break;
11863 case OPC_MUL:
11864 gen_arith(env, ctx, op1, rd, rs, rt);
11865 break;
11866 case OPC_CLO:
11867 case OPC_CLZ:
11868 check_insn(env, ctx, ISA_MIPS32);
11869 gen_cl(ctx, op1, rd, rs);
11870 break;
11871 case OPC_SDBBP:
11872 /* XXX: not clear which exception should be raised
11873 * when in debug mode...
11875 check_insn(env, ctx, ISA_MIPS32);
11876 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11877 generate_exception(ctx, EXCP_DBp);
11878 } else {
11879 generate_exception(ctx, EXCP_DBp);
11881 /* Treat as NOP. */
11882 break;
11883 case OPC_DIV_G_2F:
11884 case OPC_DIVU_G_2F:
11885 case OPC_MULT_G_2F:
11886 case OPC_MULTU_G_2F:
11887 case OPC_MOD_G_2F:
11888 case OPC_MODU_G_2F:
11889 check_insn(env, ctx, INSN_LOONGSON2F);
11890 gen_loongson_integer(ctx, op1, rd, rs, rt);
11891 break;
11892 #if defined(TARGET_MIPS64)
11893 case OPC_DCLO:
11894 case OPC_DCLZ:
11895 check_insn(env, ctx, ISA_MIPS64);
11896 check_mips_64(ctx);
11897 gen_cl(ctx, op1, rd, rs);
11898 break;
11899 case OPC_DMULT_G_2F:
11900 case OPC_DMULTU_G_2F:
11901 case OPC_DDIV_G_2F:
11902 case OPC_DDIVU_G_2F:
11903 case OPC_DMOD_G_2F:
11904 case OPC_DMODU_G_2F:
11905 check_insn(env, ctx, INSN_LOONGSON2F);
11906 gen_loongson_integer(ctx, op1, rd, rs, rt);
11907 break;
11908 #endif
11909 default: /* Invalid */
11910 MIPS_INVAL("special2");
11911 generate_exception(ctx, EXCP_RI);
11912 break;
11914 break;
11915 case OPC_SPECIAL3:
11916 op1 = MASK_SPECIAL3(ctx->opcode);
11917 switch (op1) {
11918 case OPC_EXT:
11919 case OPC_INS:
11920 check_insn(env, ctx, ISA_MIPS32R2);
11921 gen_bitops(ctx, op1, rt, rs, sa, rd);
11922 break;
11923 case OPC_BSHFL:
11924 check_insn(env, ctx, ISA_MIPS32R2);
11925 op2 = MASK_BSHFL(ctx->opcode);
11926 gen_bshfl(ctx, op2, rt, rd);
11927 break;
11928 case OPC_RDHWR:
11929 gen_rdhwr(env, ctx, rt, rd);
11930 break;
11931 case OPC_FORK:
11932 check_insn(env, ctx, ASE_MT);
11934 TCGv t0 = tcg_temp_new();
11935 TCGv t1 = tcg_temp_new();
11937 gen_load_gpr(t0, rt);
11938 gen_load_gpr(t1, rs);
11939 gen_helper_fork(t0, t1);
11940 tcg_temp_free(t0);
11941 tcg_temp_free(t1);
11943 break;
11944 case OPC_YIELD:
11945 check_insn(env, ctx, ASE_MT);
11947 TCGv t0 = tcg_temp_new();
11949 save_cpu_state(ctx, 1);
11950 gen_load_gpr(t0, rs);
11951 gen_helper_yield(t0, t0);
11952 gen_store_gpr(t0, rd);
11953 tcg_temp_free(t0);
11955 break;
11956 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
11957 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
11958 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
11959 check_insn(env, ctx, INSN_LOONGSON2E);
11960 gen_loongson_integer(ctx, op1, rd, rs, rt);
11961 break;
11962 #if defined(TARGET_MIPS64)
11963 case OPC_DEXTM ... OPC_DEXT:
11964 case OPC_DINSM ... OPC_DINS:
11965 check_insn(env, ctx, ISA_MIPS64R2);
11966 check_mips_64(ctx);
11967 gen_bitops(ctx, op1, rt, rs, sa, rd);
11968 break;
11969 case OPC_DBSHFL:
11970 check_insn(env, ctx, ISA_MIPS64R2);
11971 check_mips_64(ctx);
11972 op2 = MASK_DBSHFL(ctx->opcode);
11973 gen_bshfl(ctx, op2, rt, rd);
11974 break;
11975 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
11976 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
11977 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
11978 check_insn(env, ctx, INSN_LOONGSON2E);
11979 gen_loongson_integer(ctx, op1, rd, rs, rt);
11980 break;
11981 #endif
11982 default: /* Invalid */
11983 MIPS_INVAL("special3");
11984 generate_exception(ctx, EXCP_RI);
11985 break;
11987 break;
11988 case OPC_REGIMM:
11989 op1 = MASK_REGIMM(ctx->opcode);
11990 switch (op1) {
11991 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
11992 case OPC_BLTZAL ... OPC_BGEZALL:
11993 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
11994 *is_branch = 1;
11995 break;
11996 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
11997 case OPC_TNEI:
11998 gen_trap(ctx, op1, rs, -1, imm);
11999 break;
12000 case OPC_SYNCI:
12001 check_insn(env, ctx, ISA_MIPS32R2);
12002 /* Treat as NOP. */
12003 break;
12004 default: /* Invalid */
12005 MIPS_INVAL("regimm");
12006 generate_exception(ctx, EXCP_RI);
12007 break;
12009 break;
12010 case OPC_CP0:
12011 check_cp0_enabled(ctx);
12012 op1 = MASK_CP0(ctx->opcode);
12013 switch (op1) {
12014 case OPC_MFC0:
12015 case OPC_MTC0:
12016 case OPC_MFTR:
12017 case OPC_MTTR:
12018 #if defined(TARGET_MIPS64)
12019 case OPC_DMFC0:
12020 case OPC_DMTC0:
12021 #endif
12022 #ifndef CONFIG_USER_ONLY
12023 gen_cp0(env, ctx, op1, rt, rd);
12024 #endif /* !CONFIG_USER_ONLY */
12025 break;
12026 case OPC_C0_FIRST ... OPC_C0_LAST:
12027 #ifndef CONFIG_USER_ONLY
12028 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
12029 #endif /* !CONFIG_USER_ONLY */
12030 break;
12031 case OPC_MFMC0:
12032 #ifndef CONFIG_USER_ONLY
12034 TCGv t0 = tcg_temp_new();
12036 op2 = MASK_MFMC0(ctx->opcode);
12037 switch (op2) {
12038 case OPC_DMT:
12039 check_insn(env, ctx, ASE_MT);
12040 gen_helper_dmt(t0);
12041 gen_store_gpr(t0, rt);
12042 break;
12043 case OPC_EMT:
12044 check_insn(env, ctx, ASE_MT);
12045 gen_helper_emt(t0);
12046 gen_store_gpr(t0, rt);
12047 break;
12048 case OPC_DVPE:
12049 check_insn(env, ctx, ASE_MT);
12050 gen_helper_dvpe(t0);
12051 gen_store_gpr(t0, rt);
12052 break;
12053 case OPC_EVPE:
12054 check_insn(env, ctx, ASE_MT);
12055 gen_helper_evpe(t0);
12056 gen_store_gpr(t0, rt);
12057 break;
12058 case OPC_DI:
12059 check_insn(env, ctx, ISA_MIPS32R2);
12060 save_cpu_state(ctx, 1);
12061 gen_helper_di(t0);
12062 gen_store_gpr(t0, rt);
12063 /* Stop translation as we may have switched the execution mode */
12064 ctx->bstate = BS_STOP;
12065 break;
12066 case OPC_EI:
12067 check_insn(env, ctx, ISA_MIPS32R2);
12068 save_cpu_state(ctx, 1);
12069 gen_helper_ei(t0);
12070 gen_store_gpr(t0, rt);
12071 /* Stop translation as we may have switched the execution mode */
12072 ctx->bstate = BS_STOP;
12073 break;
12074 default: /* Invalid */
12075 MIPS_INVAL("mfmc0");
12076 generate_exception(ctx, EXCP_RI);
12077 break;
12079 tcg_temp_free(t0);
12081 #endif /* !CONFIG_USER_ONLY */
12082 break;
12083 case OPC_RDPGPR:
12084 check_insn(env, ctx, ISA_MIPS32R2);
12085 gen_load_srsgpr(rt, rd);
12086 break;
12087 case OPC_WRPGPR:
12088 check_insn(env, ctx, ISA_MIPS32R2);
12089 gen_store_srsgpr(rt, rd);
12090 break;
12091 default:
12092 MIPS_INVAL("cp0");
12093 generate_exception(ctx, EXCP_RI);
12094 break;
12096 break;
12097 case OPC_ADDI: /* Arithmetic with immediate opcode */
12098 case OPC_ADDIU:
12099 gen_arith_imm(env, ctx, op, rt, rs, imm);
12100 break;
12101 case OPC_SLTI: /* Set on less than with immediate opcode */
12102 case OPC_SLTIU:
12103 gen_slt_imm(env, op, rt, rs, imm);
12104 break;
12105 case OPC_ANDI: /* Arithmetic with immediate opcode */
12106 case OPC_LUI:
12107 case OPC_ORI:
12108 case OPC_XORI:
12109 gen_logic_imm(env, op, rt, rs, imm);
12110 break;
12111 case OPC_J ... OPC_JAL: /* Jump */
12112 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12113 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12114 *is_branch = 1;
12115 break;
12116 case OPC_BEQ ... OPC_BGTZ: /* Branch */
12117 case OPC_BEQL ... OPC_BGTZL:
12118 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12119 *is_branch = 1;
12120 break;
12121 case OPC_LB ... OPC_LWR: /* Load and stores */
12122 case OPC_LL:
12123 gen_ld(env, ctx, op, rt, rs, imm);
12124 break;
12125 case OPC_SB ... OPC_SW:
12126 case OPC_SWR:
12127 gen_st(ctx, op, rt, rs, imm);
12128 break;
12129 case OPC_SC:
12130 gen_st_cond(ctx, op, rt, rs, imm);
12131 break;
12132 case OPC_CACHE:
12133 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12134 /* Treat as NOP. */
12135 break;
12136 case OPC_PREF:
12137 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12138 /* Treat as NOP. */
12139 break;
12141 /* Floating point (COP1). */
12142 case OPC_LWC1:
12143 case OPC_LDC1:
12144 case OPC_SWC1:
12145 case OPC_SDC1:
12146 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12147 break;
12149 case OPC_CP1:
12150 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12151 check_cp1_enabled(ctx);
12152 op1 = MASK_CP1(ctx->opcode);
12153 switch (op1) {
12154 case OPC_MFHC1:
12155 case OPC_MTHC1:
12156 check_insn(env, ctx, ISA_MIPS32R2);
12157 case OPC_MFC1:
12158 case OPC_CFC1:
12159 case OPC_MTC1:
12160 case OPC_CTC1:
12161 gen_cp1(ctx, op1, rt, rd);
12162 break;
12163 #if defined(TARGET_MIPS64)
12164 case OPC_DMFC1:
12165 case OPC_DMTC1:
12166 check_insn(env, ctx, ISA_MIPS3);
12167 gen_cp1(ctx, op1, rt, rd);
12168 break;
12169 #endif
12170 case OPC_BC1ANY2:
12171 case OPC_BC1ANY4:
12172 check_cop1x(ctx);
12173 check_insn(env, ctx, ASE_MIPS3D);
12174 /* fall through */
12175 case OPC_BC1:
12176 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12177 (rt >> 2) & 0x7, imm << 2);
12178 *is_branch = 1;
12179 break;
12180 case OPC_S_FMT:
12181 case OPC_D_FMT:
12182 case OPC_W_FMT:
12183 case OPC_L_FMT:
12184 case OPC_PS_FMT:
12185 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12186 (imm >> 8) & 0x7);
12187 break;
12188 default:
12189 MIPS_INVAL("cp1");
12190 generate_exception (ctx, EXCP_RI);
12191 break;
12193 } else {
12194 generate_exception_err(ctx, EXCP_CpU, 1);
12196 break;
12198 /* COP2. */
12199 case OPC_LWC2:
12200 case OPC_LDC2:
12201 case OPC_SWC2:
12202 case OPC_SDC2:
12203 case OPC_CP2:
12204 /* COP2: Not implemented. */
12205 generate_exception_err(ctx, EXCP_CpU, 2);
12206 break;
12208 case OPC_CP3:
12209 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12210 check_cp1_enabled(ctx);
12211 op1 = MASK_CP3(ctx->opcode);
12212 switch (op1) {
12213 case OPC_LWXC1:
12214 case OPC_LDXC1:
12215 case OPC_LUXC1:
12216 case OPC_SWXC1:
12217 case OPC_SDXC1:
12218 case OPC_SUXC1:
12219 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12220 break;
12221 case OPC_PREFX:
12222 /* Treat as NOP. */
12223 break;
12224 case OPC_ALNV_PS:
12225 case OPC_MADD_S:
12226 case OPC_MADD_D:
12227 case OPC_MADD_PS:
12228 case OPC_MSUB_S:
12229 case OPC_MSUB_D:
12230 case OPC_MSUB_PS:
12231 case OPC_NMADD_S:
12232 case OPC_NMADD_D:
12233 case OPC_NMADD_PS:
12234 case OPC_NMSUB_S:
12235 case OPC_NMSUB_D:
12236 case OPC_NMSUB_PS:
12237 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12238 break;
12239 default:
12240 MIPS_INVAL("cp3");
12241 generate_exception (ctx, EXCP_RI);
12242 break;
12244 } else {
12245 generate_exception_err(ctx, EXCP_CpU, 1);
12247 break;
12249 #if defined(TARGET_MIPS64)
12250 /* MIPS64 opcodes */
12251 case OPC_LWU:
12252 case OPC_LDL ... OPC_LDR:
12253 case OPC_LLD:
12254 case OPC_LD:
12255 check_insn(env, ctx, ISA_MIPS3);
12256 check_mips_64(ctx);
12257 gen_ld(env, ctx, op, rt, rs, imm);
12258 break;
12259 case OPC_SDL ... OPC_SDR:
12260 case OPC_SD:
12261 check_insn(env, ctx, ISA_MIPS3);
12262 check_mips_64(ctx);
12263 gen_st(ctx, op, rt, rs, imm);
12264 break;
12265 case OPC_SCD:
12266 check_insn(env, ctx, ISA_MIPS3);
12267 check_mips_64(ctx);
12268 gen_st_cond(ctx, op, rt, rs, imm);
12269 break;
12270 case OPC_DADDI:
12271 case OPC_DADDIU:
12272 check_insn(env, ctx, ISA_MIPS3);
12273 check_mips_64(ctx);
12274 gen_arith_imm(env, ctx, op, rt, rs, imm);
12275 break;
12276 #endif
12277 case OPC_JALX:
12278 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
12279 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12280 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12281 *is_branch = 1;
12282 break;
12283 case OPC_MDMX:
12284 check_insn(env, ctx, ASE_MDMX);
12285 /* MDMX: Not implemented. */
12286 default: /* Invalid */
12287 MIPS_INVAL("major opcode");
12288 generate_exception(ctx, EXCP_RI);
12289 break;
12293 static inline void
12294 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
12295 int search_pc)
12297 DisasContext ctx;
12298 target_ulong pc_start;
12299 uint16_t *gen_opc_end;
12300 CPUBreakpoint *bp;
12301 int j, lj = -1;
12302 int num_insns;
12303 int max_insns;
12304 int insn_bytes;
12305 int is_branch;
12307 if (search_pc)
12308 qemu_log("search pc %d\n", search_pc);
12310 pc_start = tb->pc;
12311 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12312 ctx.pc = pc_start;
12313 ctx.saved_pc = -1;
12314 ctx.singlestep_enabled = env->singlestep_enabled;
12315 ctx.tb = tb;
12316 ctx.bstate = BS_NONE;
12317 /* Restore delay slot state from the tb context. */
12318 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
12319 restore_cpu_state(env, &ctx);
12320 #ifdef CONFIG_USER_ONLY
12321 ctx.mem_idx = MIPS_HFLAG_UM;
12322 #else
12323 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12324 #endif
12325 num_insns = 0;
12326 max_insns = tb->cflags & CF_COUNT_MASK;
12327 if (max_insns == 0)
12328 max_insns = CF_COUNT_MASK;
12329 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
12330 gen_icount_start();
12331 while (ctx.bstate == BS_NONE) {
12332 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
12333 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
12334 if (bp->pc == ctx.pc) {
12335 save_cpu_state(&ctx, 1);
12336 ctx.bstate = BS_BRANCH;
12337 gen_helper_0i(raise_exception, EXCP_DEBUG);
12338 /* Include the breakpoint location or the tb won't
12339 * be flushed when it must be. */
12340 ctx.pc += 4;
12341 goto done_generating;
12346 if (search_pc) {
12347 j = gen_opc_ptr - gen_opc_buf;
12348 if (lj < j) {
12349 lj++;
12350 while (lj < j)
12351 gen_opc_instr_start[lj++] = 0;
12353 gen_opc_pc[lj] = ctx.pc;
12354 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12355 gen_opc_instr_start[lj] = 1;
12356 gen_opc_icount[lj] = num_insns;
12358 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12359 gen_io_start();
12361 is_branch = 0;
12362 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12363 ctx.opcode = ldl_code(ctx.pc);
12364 insn_bytes = 4;
12365 decode_opc(env, &ctx, &is_branch);
12366 } else if (env->insn_flags & ASE_MICROMIPS) {
12367 ctx.opcode = lduw_code(ctx.pc);
12368 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12369 } else if (env->insn_flags & ASE_MIPS16) {
12370 ctx.opcode = lduw_code(ctx.pc);
12371 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12372 } else {
12373 generate_exception(&ctx, EXCP_RI);
12374 ctx.bstate = BS_STOP;
12375 break;
12377 if (!is_branch) {
12378 handle_delay_slot(env, &ctx, insn_bytes);
12380 ctx.pc += insn_bytes;
12382 num_insns++;
12384 /* Execute a branch and its delay slot as a single instruction.
12385 This is what GDB expects and is consistent with what the
12386 hardware does (e.g. if a delay slot instruction faults, the
12387 reported PC is the PC of the branch). */
12388 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12389 break;
12391 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12392 break;
12394 if (gen_opc_ptr >= gen_opc_end)
12395 break;
12397 if (num_insns >= max_insns)
12398 break;
12400 if (singlestep)
12401 break;
12403 if (tb->cflags & CF_LAST_IO)
12404 gen_io_end();
12405 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12406 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12407 gen_helper_0i(raise_exception, EXCP_DEBUG);
12408 } else {
12409 switch (ctx.bstate) {
12410 case BS_STOP:
12411 gen_goto_tb(&ctx, 0, ctx.pc);
12412 break;
12413 case BS_NONE:
12414 save_cpu_state(&ctx, 0);
12415 gen_goto_tb(&ctx, 0, ctx.pc);
12416 break;
12417 case BS_EXCP:
12418 tcg_gen_exit_tb(0);
12419 break;
12420 case BS_BRANCH:
12421 default:
12422 break;
12425 done_generating:
12426 gen_icount_end(tb, num_insns);
12427 *gen_opc_ptr = INDEX_op_end;
12428 if (search_pc) {
12429 j = gen_opc_ptr - gen_opc_buf;
12430 lj++;
12431 while (lj <= j)
12432 gen_opc_instr_start[lj++] = 0;
12433 } else {
12434 tb->size = ctx.pc - pc_start;
12435 tb->icount = num_insns;
12437 #ifdef DEBUG_DISAS
12438 LOG_DISAS("\n");
12439 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12440 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12441 log_target_disas(pc_start, ctx.pc - pc_start, 0);
12442 qemu_log("\n");
12444 #endif
12447 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
12449 gen_intermediate_code_internal(env, tb, 0);
12452 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
12454 gen_intermediate_code_internal(env, tb, 1);
12457 static void fpu_dump_state(CPUState *env, FILE *f, fprintf_function fpu_fprintf,
12458 int flags)
12460 int i;
12461 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12463 #define printfpr(fp) \
12464 do { \
12465 if (is_fpu64) \
12466 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12467 " fd:%13g fs:%13g psu: %13g\n", \
12468 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
12469 (double)(fp)->fd, \
12470 (double)(fp)->fs[FP_ENDIAN_IDX], \
12471 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
12472 else { \
12473 fpr_t tmp; \
12474 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
12475 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
12476 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12477 " fd:%13g fs:%13g psu:%13g\n", \
12478 tmp.w[FP_ENDIAN_IDX], tmp.d, \
12479 (double)tmp.fd, \
12480 (double)tmp.fs[FP_ENDIAN_IDX], \
12481 (double)tmp.fs[!FP_ENDIAN_IDX]); \
12483 } while(0)
12486 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
12487 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
12488 get_float_exception_flags(&env->active_fpu.fp_status));
12489 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12490 fpu_fprintf(f, "%3s: ", fregnames[i]);
12491 printfpr(&env->active_fpu.fpr[i]);
12494 #undef printfpr
12497 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12498 /* Debug help: The architecture requires 32bit code to maintain proper
12499 sign-extended values on 64bit machines. */
12501 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12503 static void
12504 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
12505 fprintf_function cpu_fprintf,
12506 int flags)
12508 int i;
12510 if (!SIGN_EXT_P(env->active_tc.PC))
12511 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12512 if (!SIGN_EXT_P(env->active_tc.HI[0]))
12513 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12514 if (!SIGN_EXT_P(env->active_tc.LO[0]))
12515 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12516 if (!SIGN_EXT_P(env->btarget))
12517 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12519 for (i = 0; i < 32; i++) {
12520 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12521 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12524 if (!SIGN_EXT_P(env->CP0_EPC))
12525 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12526 if (!SIGN_EXT_P(env->lladdr))
12527 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12529 #endif
12531 void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
12532 int flags)
12534 int i;
12536 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12537 " LO=0x" TARGET_FMT_lx " ds %04x "
12538 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12539 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12540 env->hflags, env->btarget, env->bcond);
12541 for (i = 0; i < 32; i++) {
12542 if ((i & 3) == 0)
12543 cpu_fprintf(f, "GPR%02d:", i);
12544 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12545 if ((i & 3) == 3)
12546 cpu_fprintf(f, "\n");
12549 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
12550 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12551 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12552 env->CP0_Config0, env->CP0_Config1, env->lladdr);
12553 if (env->hflags & MIPS_HFLAG_FPU)
12554 fpu_dump_state(env, f, cpu_fprintf, flags);
12555 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12556 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12557 #endif
12560 static void mips_tcg_init(void)
12562 int i;
12563 static int inited;
12565 /* Initialize various static tables. */
12566 if (inited)
12567 return;
12569 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12570 TCGV_UNUSED(cpu_gpr[0]);
12571 for (i = 1; i < 32; i++)
12572 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12573 offsetof(CPUState, active_tc.gpr[i]),
12574 regnames[i]);
12575 cpu_PC = tcg_global_mem_new(TCG_AREG0,
12576 offsetof(CPUState, active_tc.PC), "PC");
12577 for (i = 0; i < MIPS_DSP_ACC; i++) {
12578 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12579 offsetof(CPUState, active_tc.HI[i]),
12580 regnames_HI[i]);
12581 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12582 offsetof(CPUState, active_tc.LO[i]),
12583 regnames_LO[i]);
12584 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12585 offsetof(CPUState, active_tc.ACX[i]),
12586 regnames_ACX[i]);
12588 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12589 offsetof(CPUState, active_tc.DSPControl),
12590 "DSPControl");
12591 bcond = tcg_global_mem_new(TCG_AREG0,
12592 offsetof(CPUState, bcond), "bcond");
12593 btarget = tcg_global_mem_new(TCG_AREG0,
12594 offsetof(CPUState, btarget), "btarget");
12595 hflags = tcg_global_mem_new_i32(TCG_AREG0,
12596 offsetof(CPUState, hflags), "hflags");
12598 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12599 offsetof(CPUState, active_fpu.fcr0),
12600 "fcr0");
12601 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12602 offsetof(CPUState, active_fpu.fcr31),
12603 "fcr31");
12605 /* register helpers */
12606 #define GEN_HELPER 2
12607 #include "helper.h"
12609 inited = 1;
12612 #include "translate_init.c"
12614 CPUMIPSState *cpu_mips_init (const char *cpu_model)
12616 CPUMIPSState *env;
12617 const mips_def_t *def;
12619 def = cpu_mips_find_by_name(cpu_model);
12620 if (!def)
12621 return NULL;
12622 env = qemu_mallocz(sizeof(CPUMIPSState));
12623 env->cpu_model = def;
12624 env->cpu_model_str = cpu_model;
12626 cpu_exec_init(env);
12627 #ifndef CONFIG_USER_ONLY
12628 mmu_init(env, def);
12629 #endif
12630 fpu_init(env, def);
12631 mvp_init(env, def);
12632 mips_tcg_init();
12633 cpu_reset(env);
12634 qemu_init_vcpu(env);
12635 return env;
12638 void cpu_reset (CPUMIPSState *env)
12640 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12641 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12642 log_cpu_state(env, 0);
12645 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12646 tlb_flush(env, 1);
12648 /* Reset registers to their default values */
12649 env->CP0_PRid = env->cpu_model->CP0_PRid;
12650 env->CP0_Config0 = env->cpu_model->CP0_Config0;
12651 #ifdef TARGET_WORDS_BIGENDIAN
12652 env->CP0_Config0 |= (1 << CP0C0_BE);
12653 #endif
12654 env->CP0_Config1 = env->cpu_model->CP0_Config1;
12655 env->CP0_Config2 = env->cpu_model->CP0_Config2;
12656 env->CP0_Config3 = env->cpu_model->CP0_Config3;
12657 env->CP0_Config6 = env->cpu_model->CP0_Config6;
12658 env->CP0_Config7 = env->cpu_model->CP0_Config7;
12659 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12660 << env->cpu_model->CP0_LLAddr_shift;
12661 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12662 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12663 env->CCRes = env->cpu_model->CCRes;
12664 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12665 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12666 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12667 env->current_tc = 0;
12668 env->SEGBITS = env->cpu_model->SEGBITS;
12669 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12670 #if defined(TARGET_MIPS64)
12671 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12672 env->SEGMask |= 3ULL << 62;
12674 #endif
12675 env->PABITS = env->cpu_model->PABITS;
12676 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12677 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12678 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12679 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12680 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12681 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12682 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12683 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12684 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12685 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12686 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12687 env->insn_flags = env->cpu_model->insn_flags;
12689 #if defined(CONFIG_USER_ONLY)
12690 env->hflags = MIPS_HFLAG_UM;
12691 /* Enable access to the SYNCI_Step register. */
12692 env->CP0_HWREna |= (1 << 1);
12693 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12694 env->hflags |= MIPS_HFLAG_FPU;
12696 #ifdef TARGET_MIPS64
12697 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12698 env->hflags |= MIPS_HFLAG_F64;
12700 #endif
12701 #else
12702 if (env->hflags & MIPS_HFLAG_BMASK) {
12703 /* If the exception was raised from a delay slot,
12704 come back to the jump. */
12705 env->CP0_ErrorEPC = env->active_tc.PC - 4;
12706 } else {
12707 env->CP0_ErrorEPC = env->active_tc.PC;
12709 env->active_tc.PC = (int32_t)0xBFC00000;
12710 env->CP0_Random = env->tlb->nb_tlb - 1;
12711 env->tlb->tlb_in_use = env->tlb->nb_tlb;
12712 env->CP0_Wired = 0;
12713 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
12714 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12715 /* vectored interrupts not implemented, timer on int 7,
12716 no performance counters. */
12717 env->CP0_IntCtl = 0xe0000000;
12719 int i;
12721 for (i = 0; i < 7; i++) {
12722 env->CP0_WatchLo[i] = 0;
12723 env->CP0_WatchHi[i] = 0x80000000;
12725 env->CP0_WatchLo[7] = 0;
12726 env->CP0_WatchHi[7] = 0;
12728 /* Count register increments in debug mode, EJTAG version 1 */
12729 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12730 env->hflags = MIPS_HFLAG_CP0;
12731 #endif
12732 #if defined(TARGET_MIPS64)
12733 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12734 env->hflags |= MIPS_HFLAG_64;
12736 #endif
12737 env->exception_index = EXCP_NONE;
12740 void gen_pc_load(CPUState *env, TranslationBlock *tb,
12741 unsigned long searched_pc, int pc_pos, void *puc)
12743 env->active_tc.PC = gen_opc_pc[pc_pos];
12744 env->hflags &= ~MIPS_HFLAG_BMASK;
12745 env->hflags |= gen_opc_hflags[pc_pos];