qemu-ga: add Windows service integration
[qemu/qmp-unstable.git] / target-mips / translate.c
blobd5b1c765fb9d701662baa7b178afb1fa95e198d3
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 "disas.h"
31 #include "tcg-op.h"
32 #include "qemu-common.h"
34 #include "helper.h"
35 #define GEN_HELPER 1
36 #include "helper.h"
38 //#define MIPS_DEBUG_DISAS
39 //#define MIPS_DEBUG_SIGN_EXTENSIONS
41 /* MIPS major opcodes */
42 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
44 enum {
45 /* indirect opcode tables */
46 OPC_SPECIAL = (0x00 << 26),
47 OPC_REGIMM = (0x01 << 26),
48 OPC_CP0 = (0x10 << 26),
49 OPC_CP1 = (0x11 << 26),
50 OPC_CP2 = (0x12 << 26),
51 OPC_CP3 = (0x13 << 26),
52 OPC_SPECIAL2 = (0x1C << 26),
53 OPC_SPECIAL3 = (0x1F << 26),
54 /* arithmetic with immediate */
55 OPC_ADDI = (0x08 << 26),
56 OPC_ADDIU = (0x09 << 26),
57 OPC_SLTI = (0x0A << 26),
58 OPC_SLTIU = (0x0B << 26),
59 /* logic with immediate */
60 OPC_ANDI = (0x0C << 26),
61 OPC_ORI = (0x0D << 26),
62 OPC_XORI = (0x0E << 26),
63 OPC_LUI = (0x0F << 26),
64 /* arithmetic with immediate */
65 OPC_DADDI = (0x18 << 26),
66 OPC_DADDIU = (0x19 << 26),
67 /* Jump and branches */
68 OPC_J = (0x02 << 26),
69 OPC_JAL = (0x03 << 26),
70 OPC_JALS = OPC_JAL | 0x5,
71 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
72 OPC_BEQL = (0x14 << 26),
73 OPC_BNE = (0x05 << 26),
74 OPC_BNEL = (0x15 << 26),
75 OPC_BLEZ = (0x06 << 26),
76 OPC_BLEZL = (0x16 << 26),
77 OPC_BGTZ = (0x07 << 26),
78 OPC_BGTZL = (0x17 << 26),
79 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
80 OPC_JALXS = OPC_JALX | 0x5,
81 /* Load and stores */
82 OPC_LDL = (0x1A << 26),
83 OPC_LDR = (0x1B << 26),
84 OPC_LB = (0x20 << 26),
85 OPC_LH = (0x21 << 26),
86 OPC_LWL = (0x22 << 26),
87 OPC_LW = (0x23 << 26),
88 OPC_LWPC = OPC_LW | 0x5,
89 OPC_LBU = (0x24 << 26),
90 OPC_LHU = (0x25 << 26),
91 OPC_LWR = (0x26 << 26),
92 OPC_LWU = (0x27 << 26),
93 OPC_SB = (0x28 << 26),
94 OPC_SH = (0x29 << 26),
95 OPC_SWL = (0x2A << 26),
96 OPC_SW = (0x2B << 26),
97 OPC_SDL = (0x2C << 26),
98 OPC_SDR = (0x2D << 26),
99 OPC_SWR = (0x2E << 26),
100 OPC_LL = (0x30 << 26),
101 OPC_LLD = (0x34 << 26),
102 OPC_LD = (0x37 << 26),
103 OPC_LDPC = OPC_LD | 0x5,
104 OPC_SC = (0x38 << 26),
105 OPC_SCD = (0x3C << 26),
106 OPC_SD = (0x3F << 26),
107 /* Floating point load/store */
108 OPC_LWC1 = (0x31 << 26),
109 OPC_LWC2 = (0x32 << 26),
110 OPC_LDC1 = (0x35 << 26),
111 OPC_LDC2 = (0x36 << 26),
112 OPC_SWC1 = (0x39 << 26),
113 OPC_SWC2 = (0x3A << 26),
114 OPC_SDC1 = (0x3D << 26),
115 OPC_SDC2 = (0x3E << 26),
116 /* MDMX ASE specific */
117 OPC_MDMX = (0x1E << 26),
118 /* Cache and prefetch */
119 OPC_CACHE = (0x2F << 26),
120 OPC_PREF = (0x33 << 26),
121 /* Reserved major opcode */
122 OPC_MAJOR3B_RESERVED = (0x3B << 26),
125 /* MIPS special opcodes */
126 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
128 enum {
129 /* Shifts */
130 OPC_SLL = 0x00 | OPC_SPECIAL,
131 /* NOP is SLL r0, r0, 0 */
132 /* SSNOP is SLL r0, r0, 1 */
133 /* EHB is SLL r0, r0, 3 */
134 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
135 OPC_ROTR = OPC_SRL | (1 << 21),
136 OPC_SRA = 0x03 | OPC_SPECIAL,
137 OPC_SLLV = 0x04 | OPC_SPECIAL,
138 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
139 OPC_ROTRV = OPC_SRLV | (1 << 6),
140 OPC_SRAV = 0x07 | OPC_SPECIAL,
141 OPC_DSLLV = 0x14 | OPC_SPECIAL,
142 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
143 OPC_DROTRV = OPC_DSRLV | (1 << 6),
144 OPC_DSRAV = 0x17 | OPC_SPECIAL,
145 OPC_DSLL = 0x38 | OPC_SPECIAL,
146 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
147 OPC_DROTR = OPC_DSRL | (1 << 21),
148 OPC_DSRA = 0x3B | OPC_SPECIAL,
149 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
150 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
151 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
152 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
153 /* Multiplication / division */
154 OPC_MULT = 0x18 | OPC_SPECIAL,
155 OPC_MULTU = 0x19 | OPC_SPECIAL,
156 OPC_DIV = 0x1A | OPC_SPECIAL,
157 OPC_DIVU = 0x1B | OPC_SPECIAL,
158 OPC_DMULT = 0x1C | OPC_SPECIAL,
159 OPC_DMULTU = 0x1D | OPC_SPECIAL,
160 OPC_DDIV = 0x1E | OPC_SPECIAL,
161 OPC_DDIVU = 0x1F | OPC_SPECIAL,
162 /* 2 registers arithmetic / logic */
163 OPC_ADD = 0x20 | OPC_SPECIAL,
164 OPC_ADDU = 0x21 | OPC_SPECIAL,
165 OPC_SUB = 0x22 | OPC_SPECIAL,
166 OPC_SUBU = 0x23 | OPC_SPECIAL,
167 OPC_AND = 0x24 | OPC_SPECIAL,
168 OPC_OR = 0x25 | OPC_SPECIAL,
169 OPC_XOR = 0x26 | OPC_SPECIAL,
170 OPC_NOR = 0x27 | OPC_SPECIAL,
171 OPC_SLT = 0x2A | OPC_SPECIAL,
172 OPC_SLTU = 0x2B | OPC_SPECIAL,
173 OPC_DADD = 0x2C | OPC_SPECIAL,
174 OPC_DADDU = 0x2D | OPC_SPECIAL,
175 OPC_DSUB = 0x2E | OPC_SPECIAL,
176 OPC_DSUBU = 0x2F | OPC_SPECIAL,
177 /* Jumps */
178 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
179 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
180 OPC_JALRC = OPC_JALR | (0x5 << 6),
181 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
182 /* Traps */
183 OPC_TGE = 0x30 | OPC_SPECIAL,
184 OPC_TGEU = 0x31 | OPC_SPECIAL,
185 OPC_TLT = 0x32 | OPC_SPECIAL,
186 OPC_TLTU = 0x33 | OPC_SPECIAL,
187 OPC_TEQ = 0x34 | OPC_SPECIAL,
188 OPC_TNE = 0x36 | OPC_SPECIAL,
189 /* HI / LO registers load & stores */
190 OPC_MFHI = 0x10 | OPC_SPECIAL,
191 OPC_MTHI = 0x11 | OPC_SPECIAL,
192 OPC_MFLO = 0x12 | OPC_SPECIAL,
193 OPC_MTLO = 0x13 | OPC_SPECIAL,
194 /* Conditional moves */
195 OPC_MOVZ = 0x0A | OPC_SPECIAL,
196 OPC_MOVN = 0x0B | OPC_SPECIAL,
198 OPC_MOVCI = 0x01 | OPC_SPECIAL,
200 /* Special */
201 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
202 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
203 OPC_BREAK = 0x0D | OPC_SPECIAL,
204 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
205 OPC_SYNC = 0x0F | OPC_SPECIAL,
207 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
208 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
209 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
210 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
211 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
212 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
213 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
216 /* Multiplication variants of the vr54xx. */
217 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
219 enum {
220 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
221 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
222 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
223 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
224 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
225 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
226 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
227 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
228 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
229 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
230 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
231 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
232 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
233 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
236 /* REGIMM (rt field) opcodes */
237 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
239 enum {
240 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
241 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
242 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
243 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
244 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
245 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
246 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
247 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
248 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
249 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
250 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
251 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
252 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
253 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
254 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
255 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
256 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
259 /* Special2 opcodes */
260 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
262 enum {
263 /* Multiply & xxx operations */
264 OPC_MADD = 0x00 | OPC_SPECIAL2,
265 OPC_MADDU = 0x01 | OPC_SPECIAL2,
266 OPC_MUL = 0x02 | OPC_SPECIAL2,
267 OPC_MSUB = 0x04 | OPC_SPECIAL2,
268 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
269 /* Loongson 2F */
270 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
271 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
272 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
273 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
274 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
275 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
276 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
277 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
278 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
279 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
280 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
281 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
282 /* Misc */
283 OPC_CLZ = 0x20 | OPC_SPECIAL2,
284 OPC_CLO = 0x21 | OPC_SPECIAL2,
285 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
286 OPC_DCLO = 0x25 | OPC_SPECIAL2,
287 /* Special */
288 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
291 /* Special3 opcodes */
292 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
294 enum {
295 OPC_EXT = 0x00 | OPC_SPECIAL3,
296 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
297 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
298 OPC_DEXT = 0x03 | OPC_SPECIAL3,
299 OPC_INS = 0x04 | OPC_SPECIAL3,
300 OPC_DINSM = 0x05 | OPC_SPECIAL3,
301 OPC_DINSU = 0x06 | OPC_SPECIAL3,
302 OPC_DINS = 0x07 | OPC_SPECIAL3,
303 OPC_FORK = 0x08 | OPC_SPECIAL3,
304 OPC_YIELD = 0x09 | OPC_SPECIAL3,
305 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
306 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
307 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
309 /* Loongson 2E */
310 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
311 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
312 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
313 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
314 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
315 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
316 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
317 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
318 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
319 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
320 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
321 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
324 /* BSHFL opcodes */
325 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
327 enum {
328 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
329 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
330 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
333 /* DBSHFL opcodes */
334 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
336 enum {
337 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
338 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
341 /* Coprocessor 0 (rs field) */
342 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
344 enum {
345 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
346 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
347 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
348 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
349 OPC_MFTR = (0x08 << 21) | OPC_CP0,
350 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
351 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
352 OPC_MTTR = (0x0C << 21) | OPC_CP0,
353 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
354 OPC_C0 = (0x10 << 21) | OPC_CP0,
355 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
356 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
359 /* MFMC0 opcodes */
360 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
362 enum {
363 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
364 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
365 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
366 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
367 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
368 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
371 /* Coprocessor 0 (with rs == C0) */
372 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
374 enum {
375 OPC_TLBR = 0x01 | OPC_C0,
376 OPC_TLBWI = 0x02 | OPC_C0,
377 OPC_TLBWR = 0x06 | OPC_C0,
378 OPC_TLBP = 0x08 | OPC_C0,
379 OPC_RFE = 0x10 | OPC_C0,
380 OPC_ERET = 0x18 | OPC_C0,
381 OPC_DERET = 0x1F | OPC_C0,
382 OPC_WAIT = 0x20 | OPC_C0,
385 /* Coprocessor 1 (rs field) */
386 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
388 /* Values for the fmt field in FP instructions */
389 enum {
390 /* 0 - 15 are reserved */
391 FMT_S = 16, /* single fp */
392 FMT_D = 17, /* double fp */
393 FMT_E = 18, /* extended fp */
394 FMT_Q = 19, /* quad fp */
395 FMT_W = 20, /* 32-bit fixed */
396 FMT_L = 21, /* 64-bit fixed */
397 FMT_PS = 22, /* paired single fp */
398 /* 23 - 31 are reserved */
401 enum {
402 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
403 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
404 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
405 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
406 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
407 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
408 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
409 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
410 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
411 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
412 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
413 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
414 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
415 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
416 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
417 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
418 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
419 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
422 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
423 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
425 enum {
426 OPC_BC1F = (0x00 << 16) | OPC_BC1,
427 OPC_BC1T = (0x01 << 16) | OPC_BC1,
428 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
429 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
432 enum {
433 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
434 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
437 enum {
438 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
439 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
442 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
444 enum {
445 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
446 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
447 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
448 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
449 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
450 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
451 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
452 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
453 OPC_BC2 = (0x08 << 21) | OPC_CP2,
456 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
458 enum {
459 OPC_LWXC1 = 0x00 | OPC_CP3,
460 OPC_LDXC1 = 0x01 | OPC_CP3,
461 OPC_LUXC1 = 0x05 | OPC_CP3,
462 OPC_SWXC1 = 0x08 | OPC_CP3,
463 OPC_SDXC1 = 0x09 | OPC_CP3,
464 OPC_SUXC1 = 0x0D | OPC_CP3,
465 OPC_PREFX = 0x0F | OPC_CP3,
466 OPC_ALNV_PS = 0x1E | OPC_CP3,
467 OPC_MADD_S = 0x20 | OPC_CP3,
468 OPC_MADD_D = 0x21 | OPC_CP3,
469 OPC_MADD_PS = 0x26 | OPC_CP3,
470 OPC_MSUB_S = 0x28 | OPC_CP3,
471 OPC_MSUB_D = 0x29 | OPC_CP3,
472 OPC_MSUB_PS = 0x2E | OPC_CP3,
473 OPC_NMADD_S = 0x30 | OPC_CP3,
474 OPC_NMADD_D = 0x31 | OPC_CP3,
475 OPC_NMADD_PS= 0x36 | OPC_CP3,
476 OPC_NMSUB_S = 0x38 | OPC_CP3,
477 OPC_NMSUB_D = 0x39 | OPC_CP3,
478 OPC_NMSUB_PS= 0x3E | OPC_CP3,
481 /* global register indices */
482 static TCGv_ptr cpu_env;
483 static TCGv cpu_gpr[32], cpu_PC;
484 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
485 static TCGv cpu_dspctrl, btarget, bcond;
486 static TCGv_i32 hflags;
487 static TCGv_i32 fpu_fcr0, fpu_fcr31;
489 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
491 #include "gen-icount.h"
493 #define gen_helper_0i(name, arg) do { \
494 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
495 gen_helper_##name(helper_tmp); \
496 tcg_temp_free_i32(helper_tmp); \
497 } while(0)
499 #define gen_helper_1i(name, arg1, arg2) do { \
500 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
501 gen_helper_##name(arg1, helper_tmp); \
502 tcg_temp_free_i32(helper_tmp); \
503 } while(0)
505 #define gen_helper_2i(name, arg1, arg2, arg3) do { \
506 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
507 gen_helper_##name(arg1, arg2, helper_tmp); \
508 tcg_temp_free_i32(helper_tmp); \
509 } while(0)
511 #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do { \
512 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
513 gen_helper_##name(arg1, arg2, arg3, helper_tmp); \
514 tcg_temp_free_i32(helper_tmp); \
515 } while(0)
517 typedef struct DisasContext {
518 struct TranslationBlock *tb;
519 target_ulong pc, saved_pc;
520 uint32_t opcode;
521 int singlestep_enabled;
522 /* Routine used to access memory */
523 int mem_idx;
524 uint32_t hflags, saved_hflags;
525 int bstate;
526 target_ulong btarget;
527 } DisasContext;
529 enum {
530 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
531 * exception condition */
532 BS_STOP = 1, /* We want to stop translation for any reason */
533 BS_BRANCH = 2, /* We reached a branch condition */
534 BS_EXCP = 3, /* We reached an exception condition */
537 static const char *regnames[] =
538 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
539 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
540 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
541 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
543 static const char *regnames_HI[] =
544 { "HI0", "HI1", "HI2", "HI3", };
546 static const char *regnames_LO[] =
547 { "LO0", "LO1", "LO2", "LO3", };
549 static const char *regnames_ACX[] =
550 { "ACX0", "ACX1", "ACX2", "ACX3", };
552 static const char *fregnames[] =
553 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
554 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
555 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
556 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
558 #ifdef MIPS_DEBUG_DISAS
559 #define MIPS_DEBUG(fmt, ...) \
560 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
561 TARGET_FMT_lx ": %08x " fmt "\n", \
562 ctx->pc, ctx->opcode , ## __VA_ARGS__)
563 #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
564 #else
565 #define MIPS_DEBUG(fmt, ...) do { } while(0)
566 #define LOG_DISAS(...) do { } while (0)
567 #endif
569 #define MIPS_INVAL(op) \
570 do { \
571 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
572 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
573 } while (0)
575 /* General purpose registers moves. */
576 static inline void gen_load_gpr (TCGv t, int reg)
578 if (reg == 0)
579 tcg_gen_movi_tl(t, 0);
580 else
581 tcg_gen_mov_tl(t, cpu_gpr[reg]);
584 static inline void gen_store_gpr (TCGv t, int reg)
586 if (reg != 0)
587 tcg_gen_mov_tl(cpu_gpr[reg], t);
590 /* Moves to/from ACX register. */
591 static inline void gen_load_ACX (TCGv t, int reg)
593 tcg_gen_mov_tl(t, cpu_ACX[reg]);
596 static inline void gen_store_ACX (TCGv t, int reg)
598 tcg_gen_mov_tl(cpu_ACX[reg], t);
601 /* Moves to/from shadow registers. */
602 static inline void gen_load_srsgpr (int from, int to)
604 TCGv t0 = tcg_temp_new();
606 if (from == 0)
607 tcg_gen_movi_tl(t0, 0);
608 else {
609 TCGv_i32 t2 = tcg_temp_new_i32();
610 TCGv_ptr addr = tcg_temp_new_ptr();
612 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
613 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
614 tcg_gen_andi_i32(t2, t2, 0xf);
615 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
616 tcg_gen_ext_i32_ptr(addr, t2);
617 tcg_gen_add_ptr(addr, cpu_env, addr);
619 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
620 tcg_temp_free_ptr(addr);
621 tcg_temp_free_i32(t2);
623 gen_store_gpr(t0, to);
624 tcg_temp_free(t0);
627 static inline void gen_store_srsgpr (int from, int to)
629 if (to != 0) {
630 TCGv t0 = tcg_temp_new();
631 TCGv_i32 t2 = tcg_temp_new_i32();
632 TCGv_ptr addr = tcg_temp_new_ptr();
634 gen_load_gpr(t0, from);
635 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
636 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
637 tcg_gen_andi_i32(t2, t2, 0xf);
638 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
639 tcg_gen_ext_i32_ptr(addr, t2);
640 tcg_gen_add_ptr(addr, cpu_env, addr);
642 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
643 tcg_temp_free_ptr(addr);
644 tcg_temp_free_i32(t2);
645 tcg_temp_free(t0);
649 /* Floating point register moves. */
650 static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
652 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
655 static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
657 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
660 static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
662 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
665 static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
667 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
670 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
672 if (ctx->hflags & MIPS_HFLAG_F64) {
673 tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
674 } else {
675 TCGv_i32 t0 = tcg_temp_new_i32();
676 TCGv_i32 t1 = tcg_temp_new_i32();
677 gen_load_fpr32(t0, reg & ~1);
678 gen_load_fpr32(t1, reg | 1);
679 tcg_gen_concat_i32_i64(t, t0, t1);
680 tcg_temp_free_i32(t0);
681 tcg_temp_free_i32(t1);
685 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
687 if (ctx->hflags & MIPS_HFLAG_F64) {
688 tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
689 } else {
690 TCGv_i64 t0 = tcg_temp_new_i64();
691 TCGv_i32 t1 = tcg_temp_new_i32();
692 tcg_gen_trunc_i64_i32(t1, t);
693 gen_store_fpr32(t1, reg & ~1);
694 tcg_gen_shri_i64(t0, t, 32);
695 tcg_gen_trunc_i64_i32(t1, t0);
696 gen_store_fpr32(t1, reg | 1);
697 tcg_temp_free_i32(t1);
698 tcg_temp_free_i64(t0);
702 static inline int get_fp_bit (int cc)
704 if (cc)
705 return 24 + cc;
706 else
707 return 23;
710 /* Tests */
711 static inline void gen_save_pc(target_ulong pc)
713 tcg_gen_movi_tl(cpu_PC, pc);
716 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
718 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
719 if (do_save_pc && ctx->pc != ctx->saved_pc) {
720 gen_save_pc(ctx->pc);
721 ctx->saved_pc = ctx->pc;
723 if (ctx->hflags != ctx->saved_hflags) {
724 tcg_gen_movi_i32(hflags, ctx->hflags);
725 ctx->saved_hflags = ctx->hflags;
726 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
727 case MIPS_HFLAG_BR:
728 break;
729 case MIPS_HFLAG_BC:
730 case MIPS_HFLAG_BL:
731 case MIPS_HFLAG_B:
732 tcg_gen_movi_tl(btarget, ctx->btarget);
733 break;
738 static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
740 ctx->saved_hflags = ctx->hflags;
741 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
742 case MIPS_HFLAG_BR:
743 break;
744 case MIPS_HFLAG_BC:
745 case MIPS_HFLAG_BL:
746 case MIPS_HFLAG_B:
747 ctx->btarget = env->btarget;
748 break;
752 static inline void
753 generate_exception_err (DisasContext *ctx, int excp, int err)
755 TCGv_i32 texcp = tcg_const_i32(excp);
756 TCGv_i32 terr = tcg_const_i32(err);
757 save_cpu_state(ctx, 1);
758 gen_helper_raise_exception_err(texcp, terr);
759 tcg_temp_free_i32(terr);
760 tcg_temp_free_i32(texcp);
763 static inline void
764 generate_exception (DisasContext *ctx, int excp)
766 save_cpu_state(ctx, 1);
767 gen_helper_0i(raise_exception, excp);
770 /* Addresses computation */
771 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
773 tcg_gen_add_tl(ret, arg0, arg1);
775 #if defined(TARGET_MIPS64)
776 /* For compatibility with 32-bit code, data reference in user mode
777 with Status_UX = 0 should be casted to 32-bit and sign extended.
778 See the MIPS64 PRA manual, section 4.10. */
779 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
780 !(ctx->hflags & MIPS_HFLAG_UX)) {
781 tcg_gen_ext32s_i64(ret, ret);
783 #endif
786 static inline void check_cp0_enabled(DisasContext *ctx)
788 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
789 generate_exception_err(ctx, EXCP_CpU, 0);
792 static inline void check_cp1_enabled(DisasContext *ctx)
794 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
795 generate_exception_err(ctx, EXCP_CpU, 1);
798 /* Verify that the processor is running with COP1X instructions enabled.
799 This is associated with the nabla symbol in the MIPS32 and MIPS64
800 opcode tables. */
802 static inline void check_cop1x(DisasContext *ctx)
804 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
805 generate_exception(ctx, EXCP_RI);
808 /* Verify that the processor is running with 64-bit floating-point
809 operations enabled. */
811 static inline void check_cp1_64bitmode(DisasContext *ctx)
813 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
814 generate_exception(ctx, EXCP_RI);
818 * Verify if floating point register is valid; an operation is not defined
819 * if bit 0 of any register specification is set and the FR bit in the
820 * Status register equals zero, since the register numbers specify an
821 * even-odd pair of adjacent coprocessor general registers. When the FR bit
822 * in the Status register equals one, both even and odd register numbers
823 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
825 * Multiple 64 bit wide registers can be checked by calling
826 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
828 static inline void check_cp1_registers(DisasContext *ctx, int regs)
830 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
831 generate_exception(ctx, EXCP_RI);
834 /* This code generates a "reserved instruction" exception if the
835 CPU does not support the instruction set corresponding to flags. */
836 static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
838 if (unlikely(!(env->insn_flags & flags)))
839 generate_exception(ctx, EXCP_RI);
842 /* This code generates a "reserved instruction" exception if 64-bit
843 instructions are not enabled. */
844 static inline void check_mips_64(DisasContext *ctx)
846 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
847 generate_exception(ctx, EXCP_RI);
850 /* Define small wrappers for gen_load_fpr* so that we have a uniform
851 calling interface for 32 and 64-bit FPRs. No sense in changing
852 all callers for gen_load_fpr32 when we need the CTX parameter for
853 this one use. */
854 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
855 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
856 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
857 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
858 int ft, int fs, int cc) \
860 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
861 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
862 switch (ifmt) { \
863 case FMT_PS: \
864 check_cp1_64bitmode(ctx); \
865 break; \
866 case FMT_D: \
867 if (abs) { \
868 check_cop1x(ctx); \
870 check_cp1_registers(ctx, fs | ft); \
871 break; \
872 case FMT_S: \
873 if (abs) { \
874 check_cop1x(ctx); \
876 break; \
878 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
879 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
880 switch (n) { \
881 case 0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
882 case 1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
883 case 2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
884 case 3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
885 case 4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
886 case 5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
887 case 6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
888 case 7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
889 case 8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
890 case 9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
891 case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
892 case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
893 case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
894 case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
895 case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
896 case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
897 default: abort(); \
899 tcg_temp_free_i##bits (fp0); \
900 tcg_temp_free_i##bits (fp1); \
903 FOP_CONDS(, 0, d, FMT_D, 64)
904 FOP_CONDS(abs, 1, d, FMT_D, 64)
905 FOP_CONDS(, 0, s, FMT_S, 32)
906 FOP_CONDS(abs, 1, s, FMT_S, 32)
907 FOP_CONDS(, 0, ps, FMT_PS, 64)
908 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
909 #undef FOP_CONDS
910 #undef gen_ldcmp_fpr32
911 #undef gen_ldcmp_fpr64
913 /* load/store instructions. */
914 #define OP_LD(insn,fname) \
915 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
917 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
919 OP_LD(lb,ld8s);
920 OP_LD(lbu,ld8u);
921 OP_LD(lh,ld16s);
922 OP_LD(lhu,ld16u);
923 OP_LD(lw,ld32s);
924 #if defined(TARGET_MIPS64)
925 OP_LD(lwu,ld32u);
926 OP_LD(ld,ld64);
927 #endif
928 #undef OP_LD
930 #define OP_ST(insn,fname) \
931 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
933 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
935 OP_ST(sb,st8);
936 OP_ST(sh,st16);
937 OP_ST(sw,st32);
938 #if defined(TARGET_MIPS64)
939 OP_ST(sd,st64);
940 #endif
941 #undef OP_ST
943 #ifdef CONFIG_USER_ONLY
944 #define OP_LD_ATOMIC(insn,fname) \
945 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
947 TCGv t0 = tcg_temp_new(); \
948 tcg_gen_mov_tl(t0, arg1); \
949 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
950 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
951 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval)); \
952 tcg_temp_free(t0); \
954 #else
955 #define OP_LD_ATOMIC(insn,fname) \
956 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
958 gen_helper_2i(insn, ret, arg1, ctx->mem_idx); \
960 #endif
961 OP_LD_ATOMIC(ll,ld32s);
962 #if defined(TARGET_MIPS64)
963 OP_LD_ATOMIC(lld,ld64);
964 #endif
965 #undef OP_LD_ATOMIC
967 #ifdef CONFIG_USER_ONLY
968 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
969 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
971 TCGv t0 = tcg_temp_new(); \
972 int l1 = gen_new_label(); \
973 int l2 = gen_new_label(); \
975 tcg_gen_andi_tl(t0, arg2, almask); \
976 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
977 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
978 generate_exception(ctx, EXCP_AdES); \
979 gen_set_label(l1); \
980 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
981 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
982 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
983 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg)); \
984 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval)); \
985 gen_helper_0i(raise_exception, EXCP_SC); \
986 gen_set_label(l2); \
987 tcg_gen_movi_tl(t0, 0); \
988 gen_store_gpr(t0, rt); \
989 tcg_temp_free(t0); \
991 #else
992 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
993 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
995 TCGv t0 = tcg_temp_new(); \
996 gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx); \
997 gen_store_gpr(t0, rt); \
998 tcg_temp_free(t0); \
1000 #endif
1001 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1002 #if defined(TARGET_MIPS64)
1003 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1004 #endif
1005 #undef OP_ST_ATOMIC
1007 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1008 int base, int16_t offset)
1010 if (base == 0) {
1011 tcg_gen_movi_tl(addr, offset);
1012 } else if (offset == 0) {
1013 gen_load_gpr(addr, base);
1014 } else {
1015 tcg_gen_movi_tl(addr, offset);
1016 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1020 static target_ulong pc_relative_pc (DisasContext *ctx)
1022 target_ulong pc = ctx->pc;
1024 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1025 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1027 pc -= branch_bytes;
1030 pc &= ~(target_ulong)3;
1031 return pc;
1034 /* Load */
1035 static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
1036 int rt, int base, int16_t offset)
1038 const char *opn = "ld";
1039 TCGv t0, t1;
1041 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1042 /* Loongson CPU uses a load to zero register for prefetch.
1043 We emulate it as a NOP. On other CPU we must perform the
1044 actual memory access. */
1045 MIPS_DEBUG("NOP");
1046 return;
1049 t0 = tcg_temp_new();
1050 t1 = tcg_temp_new();
1051 gen_base_offset_addr(ctx, t0, base, offset);
1053 switch (opc) {
1054 #if defined(TARGET_MIPS64)
1055 case OPC_LWU:
1056 save_cpu_state(ctx, 0);
1057 op_ld_lwu(t0, t0, ctx);
1058 gen_store_gpr(t0, rt);
1059 opn = "lwu";
1060 break;
1061 case OPC_LD:
1062 save_cpu_state(ctx, 0);
1063 op_ld_ld(t0, t0, ctx);
1064 gen_store_gpr(t0, rt);
1065 opn = "ld";
1066 break;
1067 case OPC_LLD:
1068 save_cpu_state(ctx, 1);
1069 op_ld_lld(t0, t0, ctx);
1070 gen_store_gpr(t0, rt);
1071 opn = "lld";
1072 break;
1073 case OPC_LDL:
1074 save_cpu_state(ctx, 1);
1075 gen_load_gpr(t1, rt);
1076 gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1077 gen_store_gpr(t1, rt);
1078 opn = "ldl";
1079 break;
1080 case OPC_LDR:
1081 save_cpu_state(ctx, 1);
1082 gen_load_gpr(t1, rt);
1083 gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1084 gen_store_gpr(t1, rt);
1085 opn = "ldr";
1086 break;
1087 case OPC_LDPC:
1088 save_cpu_state(ctx, 0);
1089 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1090 gen_op_addr_add(ctx, t0, t0, t1);
1091 op_ld_ld(t0, t0, ctx);
1092 gen_store_gpr(t0, rt);
1093 opn = "ldpc";
1094 break;
1095 #endif
1096 case OPC_LWPC:
1097 save_cpu_state(ctx, 0);
1098 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1099 gen_op_addr_add(ctx, t0, t0, t1);
1100 op_ld_lw(t0, t0, ctx);
1101 gen_store_gpr(t0, rt);
1102 opn = "lwpc";
1103 break;
1104 case OPC_LW:
1105 save_cpu_state(ctx, 0);
1106 op_ld_lw(t0, t0, ctx);
1107 gen_store_gpr(t0, rt);
1108 opn = "lw";
1109 break;
1110 case OPC_LH:
1111 save_cpu_state(ctx, 0);
1112 op_ld_lh(t0, t0, ctx);
1113 gen_store_gpr(t0, rt);
1114 opn = "lh";
1115 break;
1116 case OPC_LHU:
1117 save_cpu_state(ctx, 0);
1118 op_ld_lhu(t0, t0, ctx);
1119 gen_store_gpr(t0, rt);
1120 opn = "lhu";
1121 break;
1122 case OPC_LB:
1123 save_cpu_state(ctx, 0);
1124 op_ld_lb(t0, t0, ctx);
1125 gen_store_gpr(t0, rt);
1126 opn = "lb";
1127 break;
1128 case OPC_LBU:
1129 save_cpu_state(ctx, 0);
1130 op_ld_lbu(t0, t0, ctx);
1131 gen_store_gpr(t0, rt);
1132 opn = "lbu";
1133 break;
1134 case OPC_LWL:
1135 save_cpu_state(ctx, 1);
1136 gen_load_gpr(t1, rt);
1137 gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1138 gen_store_gpr(t1, rt);
1139 opn = "lwl";
1140 break;
1141 case OPC_LWR:
1142 save_cpu_state(ctx, 1);
1143 gen_load_gpr(t1, rt);
1144 gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1145 gen_store_gpr(t1, rt);
1146 opn = "lwr";
1147 break;
1148 case OPC_LL:
1149 save_cpu_state(ctx, 1);
1150 op_ld_ll(t0, t0, ctx);
1151 gen_store_gpr(t0, rt);
1152 opn = "ll";
1153 break;
1155 (void)opn; /* avoid a compiler warning */
1156 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1157 tcg_temp_free(t0);
1158 tcg_temp_free(t1);
1161 /* Store */
1162 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1163 int base, int16_t offset)
1165 const char *opn = "st";
1166 TCGv t0 = tcg_temp_new();
1167 TCGv t1 = tcg_temp_new();
1169 gen_base_offset_addr(ctx, t0, base, offset);
1170 gen_load_gpr(t1, rt);
1171 switch (opc) {
1172 #if defined(TARGET_MIPS64)
1173 case OPC_SD:
1174 save_cpu_state(ctx, 0);
1175 op_st_sd(t1, t0, ctx);
1176 opn = "sd";
1177 break;
1178 case OPC_SDL:
1179 save_cpu_state(ctx, 1);
1180 gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1181 opn = "sdl";
1182 break;
1183 case OPC_SDR:
1184 save_cpu_state(ctx, 1);
1185 gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1186 opn = "sdr";
1187 break;
1188 #endif
1189 case OPC_SW:
1190 save_cpu_state(ctx, 0);
1191 op_st_sw(t1, t0, ctx);
1192 opn = "sw";
1193 break;
1194 case OPC_SH:
1195 save_cpu_state(ctx, 0);
1196 op_st_sh(t1, t0, ctx);
1197 opn = "sh";
1198 break;
1199 case OPC_SB:
1200 save_cpu_state(ctx, 0);
1201 op_st_sb(t1, t0, ctx);
1202 opn = "sb";
1203 break;
1204 case OPC_SWL:
1205 save_cpu_state(ctx, 1);
1206 gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1207 opn = "swl";
1208 break;
1209 case OPC_SWR:
1210 save_cpu_state(ctx, 1);
1211 gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1212 opn = "swr";
1213 break;
1215 (void)opn; /* avoid a compiler warning */
1216 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1217 tcg_temp_free(t0);
1218 tcg_temp_free(t1);
1222 /* Store conditional */
1223 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1224 int base, int16_t offset)
1226 const char *opn = "st_cond";
1227 TCGv t0, t1;
1229 t0 = tcg_temp_local_new();
1231 gen_base_offset_addr(ctx, t0, base, offset);
1232 /* Don't do NOP if destination is zero: we must perform the actual
1233 memory access. */
1235 t1 = tcg_temp_local_new();
1236 gen_load_gpr(t1, rt);
1237 switch (opc) {
1238 #if defined(TARGET_MIPS64)
1239 case OPC_SCD:
1240 save_cpu_state(ctx, 1);
1241 op_st_scd(t1, t0, rt, ctx);
1242 opn = "scd";
1243 break;
1244 #endif
1245 case OPC_SC:
1246 save_cpu_state(ctx, 1);
1247 op_st_sc(t1, t0, rt, ctx);
1248 opn = "sc";
1249 break;
1251 (void)opn; /* avoid a compiler warning */
1252 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1253 tcg_temp_free(t1);
1254 tcg_temp_free(t0);
1257 /* Load and store */
1258 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1259 int base, int16_t offset)
1261 const char *opn = "flt_ldst";
1262 TCGv t0 = tcg_temp_new();
1264 gen_base_offset_addr(ctx, t0, base, offset);
1265 /* Don't do NOP if destination is zero: we must perform the actual
1266 memory access. */
1267 switch (opc) {
1268 case OPC_LWC1:
1270 TCGv_i32 fp0 = tcg_temp_new_i32();
1272 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1273 tcg_gen_trunc_tl_i32(fp0, t0);
1274 gen_store_fpr32(fp0, ft);
1275 tcg_temp_free_i32(fp0);
1277 opn = "lwc1";
1278 break;
1279 case OPC_SWC1:
1281 TCGv_i32 fp0 = tcg_temp_new_i32();
1282 TCGv t1 = tcg_temp_new();
1284 gen_load_fpr32(fp0, ft);
1285 tcg_gen_extu_i32_tl(t1, fp0);
1286 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1287 tcg_temp_free(t1);
1288 tcg_temp_free_i32(fp0);
1290 opn = "swc1";
1291 break;
1292 case OPC_LDC1:
1294 TCGv_i64 fp0 = tcg_temp_new_i64();
1296 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1297 gen_store_fpr64(ctx, fp0, ft);
1298 tcg_temp_free_i64(fp0);
1300 opn = "ldc1";
1301 break;
1302 case OPC_SDC1:
1304 TCGv_i64 fp0 = tcg_temp_new_i64();
1306 gen_load_fpr64(ctx, fp0, ft);
1307 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1308 tcg_temp_free_i64(fp0);
1310 opn = "sdc1";
1311 break;
1312 default:
1313 MIPS_INVAL(opn);
1314 generate_exception(ctx, EXCP_RI);
1315 goto out;
1317 (void)opn; /* avoid a compiler warning */
1318 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1319 out:
1320 tcg_temp_free(t0);
1323 static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1324 uint32_t op, int rt, int rs, int16_t imm)
1326 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1327 check_cp1_enabled(ctx);
1328 gen_flt_ldst(ctx, op, rt, rs, imm);
1329 } else {
1330 generate_exception_err(ctx, EXCP_CpU, 1);
1334 /* Arithmetic with immediate operand */
1335 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1336 int rt, int rs, int16_t imm)
1338 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1339 const char *opn = "imm arith";
1341 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1342 /* If no destination, treat it as a NOP.
1343 For addi, we must generate the overflow exception when needed. */
1344 MIPS_DEBUG("NOP");
1345 return;
1347 switch (opc) {
1348 case OPC_ADDI:
1350 TCGv t0 = tcg_temp_local_new();
1351 TCGv t1 = tcg_temp_new();
1352 TCGv t2 = tcg_temp_new();
1353 int l1 = gen_new_label();
1355 gen_load_gpr(t1, rs);
1356 tcg_gen_addi_tl(t0, t1, uimm);
1357 tcg_gen_ext32s_tl(t0, t0);
1359 tcg_gen_xori_tl(t1, t1, ~uimm);
1360 tcg_gen_xori_tl(t2, t0, uimm);
1361 tcg_gen_and_tl(t1, t1, t2);
1362 tcg_temp_free(t2);
1363 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1364 tcg_temp_free(t1);
1365 /* operands of same sign, result different sign */
1366 generate_exception(ctx, EXCP_OVERFLOW);
1367 gen_set_label(l1);
1368 tcg_gen_ext32s_tl(t0, t0);
1369 gen_store_gpr(t0, rt);
1370 tcg_temp_free(t0);
1372 opn = "addi";
1373 break;
1374 case OPC_ADDIU:
1375 if (rs != 0) {
1376 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1377 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1378 } else {
1379 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1381 opn = "addiu";
1382 break;
1383 #if defined(TARGET_MIPS64)
1384 case OPC_DADDI:
1386 TCGv t0 = tcg_temp_local_new();
1387 TCGv t1 = tcg_temp_new();
1388 TCGv t2 = tcg_temp_new();
1389 int l1 = gen_new_label();
1391 gen_load_gpr(t1, rs);
1392 tcg_gen_addi_tl(t0, t1, uimm);
1394 tcg_gen_xori_tl(t1, t1, ~uimm);
1395 tcg_gen_xori_tl(t2, t0, uimm);
1396 tcg_gen_and_tl(t1, t1, t2);
1397 tcg_temp_free(t2);
1398 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1399 tcg_temp_free(t1);
1400 /* operands of same sign, result different sign */
1401 generate_exception(ctx, EXCP_OVERFLOW);
1402 gen_set_label(l1);
1403 gen_store_gpr(t0, rt);
1404 tcg_temp_free(t0);
1406 opn = "daddi";
1407 break;
1408 case OPC_DADDIU:
1409 if (rs != 0) {
1410 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1411 } else {
1412 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1414 opn = "daddiu";
1415 break;
1416 #endif
1418 (void)opn; /* avoid a compiler warning */
1419 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1422 /* Logic with immediate operand */
1423 static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1425 target_ulong uimm;
1426 const char *opn = "imm logic";
1428 if (rt == 0) {
1429 /* If no destination, treat it as a NOP. */
1430 MIPS_DEBUG("NOP");
1431 return;
1433 uimm = (uint16_t)imm;
1434 switch (opc) {
1435 case OPC_ANDI:
1436 if (likely(rs != 0))
1437 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1438 else
1439 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1440 opn = "andi";
1441 break;
1442 case OPC_ORI:
1443 if (rs != 0)
1444 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1445 else
1446 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1447 opn = "ori";
1448 break;
1449 case OPC_XORI:
1450 if (likely(rs != 0))
1451 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1452 else
1453 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1454 opn = "xori";
1455 break;
1456 case OPC_LUI:
1457 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1458 opn = "lui";
1459 break;
1461 (void)opn; /* avoid a compiler warning */
1462 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1465 /* Set on less than with immediate operand */
1466 static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1468 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1469 const char *opn = "imm arith";
1470 TCGv t0;
1472 if (rt == 0) {
1473 /* If no destination, treat it as a NOP. */
1474 MIPS_DEBUG("NOP");
1475 return;
1477 t0 = tcg_temp_new();
1478 gen_load_gpr(t0, rs);
1479 switch (opc) {
1480 case OPC_SLTI:
1481 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1482 opn = "slti";
1483 break;
1484 case OPC_SLTIU:
1485 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1486 opn = "sltiu";
1487 break;
1489 (void)opn; /* avoid a compiler warning */
1490 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1491 tcg_temp_free(t0);
1494 /* Shifts with immediate operand */
1495 static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1496 int rt, int rs, int16_t imm)
1498 target_ulong uimm = ((uint16_t)imm) & 0x1f;
1499 const char *opn = "imm shift";
1500 TCGv t0;
1502 if (rt == 0) {
1503 /* If no destination, treat it as a NOP. */
1504 MIPS_DEBUG("NOP");
1505 return;
1508 t0 = tcg_temp_new();
1509 gen_load_gpr(t0, rs);
1510 switch (opc) {
1511 case OPC_SLL:
1512 tcg_gen_shli_tl(t0, t0, uimm);
1513 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1514 opn = "sll";
1515 break;
1516 case OPC_SRA:
1517 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1518 opn = "sra";
1519 break;
1520 case OPC_SRL:
1521 if (uimm != 0) {
1522 tcg_gen_ext32u_tl(t0, t0);
1523 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1524 } else {
1525 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1527 opn = "srl";
1528 break;
1529 case OPC_ROTR:
1530 if (uimm != 0) {
1531 TCGv_i32 t1 = tcg_temp_new_i32();
1533 tcg_gen_trunc_tl_i32(t1, t0);
1534 tcg_gen_rotri_i32(t1, t1, uimm);
1535 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1536 tcg_temp_free_i32(t1);
1537 } else {
1538 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1540 opn = "rotr";
1541 break;
1542 #if defined(TARGET_MIPS64)
1543 case OPC_DSLL:
1544 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1545 opn = "dsll";
1546 break;
1547 case OPC_DSRA:
1548 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1549 opn = "dsra";
1550 break;
1551 case OPC_DSRL:
1552 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1553 opn = "dsrl";
1554 break;
1555 case OPC_DROTR:
1556 if (uimm != 0) {
1557 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1558 } else {
1559 tcg_gen_mov_tl(cpu_gpr[rt], t0);
1561 opn = "drotr";
1562 break;
1563 case OPC_DSLL32:
1564 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1565 opn = "dsll32";
1566 break;
1567 case OPC_DSRA32:
1568 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1569 opn = "dsra32";
1570 break;
1571 case OPC_DSRL32:
1572 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1573 opn = "dsrl32";
1574 break;
1575 case OPC_DROTR32:
1576 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1577 opn = "drotr32";
1578 break;
1579 #endif
1581 (void)opn; /* avoid a compiler warning */
1582 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1583 tcg_temp_free(t0);
1586 /* Arithmetic */
1587 static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1588 int rd, int rs, int rt)
1590 const char *opn = "arith";
1592 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1593 && opc != OPC_DADD && opc != OPC_DSUB) {
1594 /* If no destination, treat it as a NOP.
1595 For add & sub, we must generate the overflow exception when needed. */
1596 MIPS_DEBUG("NOP");
1597 return;
1600 switch (opc) {
1601 case OPC_ADD:
1603 TCGv t0 = tcg_temp_local_new();
1604 TCGv t1 = tcg_temp_new();
1605 TCGv t2 = tcg_temp_new();
1606 int l1 = gen_new_label();
1608 gen_load_gpr(t1, rs);
1609 gen_load_gpr(t2, rt);
1610 tcg_gen_add_tl(t0, t1, t2);
1611 tcg_gen_ext32s_tl(t0, t0);
1612 tcg_gen_xor_tl(t1, t1, t2);
1613 tcg_gen_xor_tl(t2, t0, t2);
1614 tcg_gen_andc_tl(t1, t2, t1);
1615 tcg_temp_free(t2);
1616 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1617 tcg_temp_free(t1);
1618 /* operands of same sign, result different sign */
1619 generate_exception(ctx, EXCP_OVERFLOW);
1620 gen_set_label(l1);
1621 gen_store_gpr(t0, rd);
1622 tcg_temp_free(t0);
1624 opn = "add";
1625 break;
1626 case OPC_ADDU:
1627 if (rs != 0 && rt != 0) {
1628 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1629 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1630 } else if (rs == 0 && rt != 0) {
1631 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1632 } else if (rs != 0 && rt == 0) {
1633 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1634 } else {
1635 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1637 opn = "addu";
1638 break;
1639 case OPC_SUB:
1641 TCGv t0 = tcg_temp_local_new();
1642 TCGv t1 = tcg_temp_new();
1643 TCGv t2 = tcg_temp_new();
1644 int l1 = gen_new_label();
1646 gen_load_gpr(t1, rs);
1647 gen_load_gpr(t2, rt);
1648 tcg_gen_sub_tl(t0, t1, t2);
1649 tcg_gen_ext32s_tl(t0, t0);
1650 tcg_gen_xor_tl(t2, t1, t2);
1651 tcg_gen_xor_tl(t1, t0, t1);
1652 tcg_gen_and_tl(t1, t1, t2);
1653 tcg_temp_free(t2);
1654 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1655 tcg_temp_free(t1);
1656 /* operands of different sign, first operand and result different sign */
1657 generate_exception(ctx, EXCP_OVERFLOW);
1658 gen_set_label(l1);
1659 gen_store_gpr(t0, rd);
1660 tcg_temp_free(t0);
1662 opn = "sub";
1663 break;
1664 case OPC_SUBU:
1665 if (rs != 0 && rt != 0) {
1666 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1667 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1668 } else if (rs == 0 && rt != 0) {
1669 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1670 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1671 } else if (rs != 0 && rt == 0) {
1672 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1673 } else {
1674 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1676 opn = "subu";
1677 break;
1678 #if defined(TARGET_MIPS64)
1679 case OPC_DADD:
1681 TCGv t0 = tcg_temp_local_new();
1682 TCGv t1 = tcg_temp_new();
1683 TCGv t2 = tcg_temp_new();
1684 int l1 = gen_new_label();
1686 gen_load_gpr(t1, rs);
1687 gen_load_gpr(t2, rt);
1688 tcg_gen_add_tl(t0, t1, t2);
1689 tcg_gen_xor_tl(t1, t1, t2);
1690 tcg_gen_xor_tl(t2, t0, t2);
1691 tcg_gen_andc_tl(t1, t2, t1);
1692 tcg_temp_free(t2);
1693 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1694 tcg_temp_free(t1);
1695 /* operands of same sign, result different sign */
1696 generate_exception(ctx, EXCP_OVERFLOW);
1697 gen_set_label(l1);
1698 gen_store_gpr(t0, rd);
1699 tcg_temp_free(t0);
1701 opn = "dadd";
1702 break;
1703 case OPC_DADDU:
1704 if (rs != 0 && rt != 0) {
1705 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1706 } else if (rs == 0 && rt != 0) {
1707 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1708 } else if (rs != 0 && rt == 0) {
1709 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1710 } else {
1711 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1713 opn = "daddu";
1714 break;
1715 case OPC_DSUB:
1717 TCGv t0 = tcg_temp_local_new();
1718 TCGv t1 = tcg_temp_new();
1719 TCGv t2 = tcg_temp_new();
1720 int l1 = gen_new_label();
1722 gen_load_gpr(t1, rs);
1723 gen_load_gpr(t2, rt);
1724 tcg_gen_sub_tl(t0, t1, t2);
1725 tcg_gen_xor_tl(t2, t1, t2);
1726 tcg_gen_xor_tl(t1, t0, t1);
1727 tcg_gen_and_tl(t1, t1, t2);
1728 tcg_temp_free(t2);
1729 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1730 tcg_temp_free(t1);
1731 /* operands of different sign, first operand and result different sign */
1732 generate_exception(ctx, EXCP_OVERFLOW);
1733 gen_set_label(l1);
1734 gen_store_gpr(t0, rd);
1735 tcg_temp_free(t0);
1737 opn = "dsub";
1738 break;
1739 case OPC_DSUBU:
1740 if (rs != 0 && rt != 0) {
1741 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1742 } else if (rs == 0 && rt != 0) {
1743 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1744 } else if (rs != 0 && rt == 0) {
1745 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1746 } else {
1747 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1749 opn = "dsubu";
1750 break;
1751 #endif
1752 case OPC_MUL:
1753 if (likely(rs != 0 && rt != 0)) {
1754 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1755 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1756 } else {
1757 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1759 opn = "mul";
1760 break;
1762 (void)opn; /* avoid a compiler warning */
1763 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1766 /* Conditional move */
1767 static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1769 const char *opn = "cond move";
1770 int l1;
1772 if (rd == 0) {
1773 /* If no destination, treat it as a NOP.
1774 For add & sub, we must generate the overflow exception when needed. */
1775 MIPS_DEBUG("NOP");
1776 return;
1779 l1 = gen_new_label();
1780 switch (opc) {
1781 case OPC_MOVN:
1782 if (likely(rt != 0))
1783 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1784 else
1785 tcg_gen_br(l1);
1786 opn = "movn";
1787 break;
1788 case OPC_MOVZ:
1789 if (likely(rt != 0))
1790 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1791 opn = "movz";
1792 break;
1794 if (rs != 0)
1795 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1796 else
1797 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1798 gen_set_label(l1);
1800 (void)opn; /* avoid a compiler warning */
1801 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1804 /* Logic */
1805 static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1807 const char *opn = "logic";
1809 if (rd == 0) {
1810 /* If no destination, treat it as a NOP. */
1811 MIPS_DEBUG("NOP");
1812 return;
1815 switch (opc) {
1816 case OPC_AND:
1817 if (likely(rs != 0 && rt != 0)) {
1818 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1819 } else {
1820 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1822 opn = "and";
1823 break;
1824 case OPC_NOR:
1825 if (rs != 0 && rt != 0) {
1826 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1827 } else if (rs == 0 && rt != 0) {
1828 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1829 } else if (rs != 0 && rt == 0) {
1830 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1831 } else {
1832 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1834 opn = "nor";
1835 break;
1836 case OPC_OR:
1837 if (likely(rs != 0 && rt != 0)) {
1838 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1839 } else if (rs == 0 && rt != 0) {
1840 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1841 } else if (rs != 0 && rt == 0) {
1842 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1843 } else {
1844 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1846 opn = "or";
1847 break;
1848 case OPC_XOR:
1849 if (likely(rs != 0 && rt != 0)) {
1850 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1851 } else if (rs == 0 && rt != 0) {
1852 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1853 } else if (rs != 0 && rt == 0) {
1854 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1855 } else {
1856 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1858 opn = "xor";
1859 break;
1861 (void)opn; /* avoid a compiler warning */
1862 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1865 /* Set on lower than */
1866 static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1868 const char *opn = "slt";
1869 TCGv t0, t1;
1871 if (rd == 0) {
1872 /* If no destination, treat it as a NOP. */
1873 MIPS_DEBUG("NOP");
1874 return;
1877 t0 = tcg_temp_new();
1878 t1 = tcg_temp_new();
1879 gen_load_gpr(t0, rs);
1880 gen_load_gpr(t1, rt);
1881 switch (opc) {
1882 case OPC_SLT:
1883 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1884 opn = "slt";
1885 break;
1886 case OPC_SLTU:
1887 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1888 opn = "sltu";
1889 break;
1891 (void)opn; /* avoid a compiler warning */
1892 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1893 tcg_temp_free(t0);
1894 tcg_temp_free(t1);
1897 /* Shifts */
1898 static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1899 int rd, int rs, int rt)
1901 const char *opn = "shifts";
1902 TCGv t0, t1;
1904 if (rd == 0) {
1905 /* If no destination, treat it as a NOP.
1906 For add & sub, we must generate the overflow exception when needed. */
1907 MIPS_DEBUG("NOP");
1908 return;
1911 t0 = tcg_temp_new();
1912 t1 = tcg_temp_new();
1913 gen_load_gpr(t0, rs);
1914 gen_load_gpr(t1, rt);
1915 switch (opc) {
1916 case OPC_SLLV:
1917 tcg_gen_andi_tl(t0, t0, 0x1f);
1918 tcg_gen_shl_tl(t0, t1, t0);
1919 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1920 opn = "sllv";
1921 break;
1922 case OPC_SRAV:
1923 tcg_gen_andi_tl(t0, t0, 0x1f);
1924 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1925 opn = "srav";
1926 break;
1927 case OPC_SRLV:
1928 tcg_gen_ext32u_tl(t1, t1);
1929 tcg_gen_andi_tl(t0, t0, 0x1f);
1930 tcg_gen_shr_tl(t0, t1, t0);
1931 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1932 opn = "srlv";
1933 break;
1934 case OPC_ROTRV:
1936 TCGv_i32 t2 = tcg_temp_new_i32();
1937 TCGv_i32 t3 = tcg_temp_new_i32();
1939 tcg_gen_trunc_tl_i32(t2, t0);
1940 tcg_gen_trunc_tl_i32(t3, t1);
1941 tcg_gen_andi_i32(t2, t2, 0x1f);
1942 tcg_gen_rotr_i32(t2, t3, t2);
1943 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1944 tcg_temp_free_i32(t2);
1945 tcg_temp_free_i32(t3);
1946 opn = "rotrv";
1948 break;
1949 #if defined(TARGET_MIPS64)
1950 case OPC_DSLLV:
1951 tcg_gen_andi_tl(t0, t0, 0x3f);
1952 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1953 opn = "dsllv";
1954 break;
1955 case OPC_DSRAV:
1956 tcg_gen_andi_tl(t0, t0, 0x3f);
1957 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1958 opn = "dsrav";
1959 break;
1960 case OPC_DSRLV:
1961 tcg_gen_andi_tl(t0, t0, 0x3f);
1962 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1963 opn = "dsrlv";
1964 break;
1965 case OPC_DROTRV:
1966 tcg_gen_andi_tl(t0, t0, 0x3f);
1967 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1968 opn = "drotrv";
1969 break;
1970 #endif
1972 (void)opn; /* avoid a compiler warning */
1973 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1974 tcg_temp_free(t0);
1975 tcg_temp_free(t1);
1978 /* Arithmetic on HI/LO registers */
1979 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1981 const char *opn = "hilo";
1983 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1984 /* Treat as NOP. */
1985 MIPS_DEBUG("NOP");
1986 return;
1988 switch (opc) {
1989 case OPC_MFHI:
1990 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1991 opn = "mfhi";
1992 break;
1993 case OPC_MFLO:
1994 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1995 opn = "mflo";
1996 break;
1997 case OPC_MTHI:
1998 if (reg != 0)
1999 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
2000 else
2001 tcg_gen_movi_tl(cpu_HI[0], 0);
2002 opn = "mthi";
2003 break;
2004 case OPC_MTLO:
2005 if (reg != 0)
2006 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2007 else
2008 tcg_gen_movi_tl(cpu_LO[0], 0);
2009 opn = "mtlo";
2010 break;
2012 (void)opn; /* avoid a compiler warning */
2013 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2016 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2017 int rs, int rt)
2019 const char *opn = "mul/div";
2020 TCGv t0, t1;
2022 switch (opc) {
2023 case OPC_DIV:
2024 case OPC_DIVU:
2025 #if defined(TARGET_MIPS64)
2026 case OPC_DDIV:
2027 case OPC_DDIVU:
2028 #endif
2029 t0 = tcg_temp_local_new();
2030 t1 = tcg_temp_local_new();
2031 break;
2032 default:
2033 t0 = tcg_temp_new();
2034 t1 = tcg_temp_new();
2035 break;
2038 gen_load_gpr(t0, rs);
2039 gen_load_gpr(t1, rt);
2040 switch (opc) {
2041 case OPC_DIV:
2043 int l1 = gen_new_label();
2044 int l2 = gen_new_label();
2046 tcg_gen_ext32s_tl(t0, t0);
2047 tcg_gen_ext32s_tl(t1, t1);
2048 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2049 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2050 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2052 tcg_gen_mov_tl(cpu_LO[0], t0);
2053 tcg_gen_movi_tl(cpu_HI[0], 0);
2054 tcg_gen_br(l1);
2055 gen_set_label(l2);
2056 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2057 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2058 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2059 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2060 gen_set_label(l1);
2062 opn = "div";
2063 break;
2064 case OPC_DIVU:
2066 int l1 = gen_new_label();
2068 tcg_gen_ext32u_tl(t0, t0);
2069 tcg_gen_ext32u_tl(t1, t1);
2070 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2071 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2072 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2073 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2074 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2075 gen_set_label(l1);
2077 opn = "divu";
2078 break;
2079 case OPC_MULT:
2081 TCGv_i64 t2 = tcg_temp_new_i64();
2082 TCGv_i64 t3 = tcg_temp_new_i64();
2084 tcg_gen_ext_tl_i64(t2, t0);
2085 tcg_gen_ext_tl_i64(t3, t1);
2086 tcg_gen_mul_i64(t2, t2, t3);
2087 tcg_temp_free_i64(t3);
2088 tcg_gen_trunc_i64_tl(t0, t2);
2089 tcg_gen_shri_i64(t2, t2, 32);
2090 tcg_gen_trunc_i64_tl(t1, t2);
2091 tcg_temp_free_i64(t2);
2092 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2093 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2095 opn = "mult";
2096 break;
2097 case OPC_MULTU:
2099 TCGv_i64 t2 = tcg_temp_new_i64();
2100 TCGv_i64 t3 = tcg_temp_new_i64();
2102 tcg_gen_ext32u_tl(t0, t0);
2103 tcg_gen_ext32u_tl(t1, t1);
2104 tcg_gen_extu_tl_i64(t2, t0);
2105 tcg_gen_extu_tl_i64(t3, t1);
2106 tcg_gen_mul_i64(t2, t2, t3);
2107 tcg_temp_free_i64(t3);
2108 tcg_gen_trunc_i64_tl(t0, t2);
2109 tcg_gen_shri_i64(t2, t2, 32);
2110 tcg_gen_trunc_i64_tl(t1, t2);
2111 tcg_temp_free_i64(t2);
2112 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2113 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2115 opn = "multu";
2116 break;
2117 #if defined(TARGET_MIPS64)
2118 case OPC_DDIV:
2120 int l1 = gen_new_label();
2121 int l2 = gen_new_label();
2123 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2124 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2125 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2126 tcg_gen_mov_tl(cpu_LO[0], t0);
2127 tcg_gen_movi_tl(cpu_HI[0], 0);
2128 tcg_gen_br(l1);
2129 gen_set_label(l2);
2130 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2131 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2132 gen_set_label(l1);
2134 opn = "ddiv";
2135 break;
2136 case OPC_DDIVU:
2138 int l1 = gen_new_label();
2140 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2141 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2142 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2143 gen_set_label(l1);
2145 opn = "ddivu";
2146 break;
2147 case OPC_DMULT:
2148 gen_helper_dmult(t0, t1);
2149 opn = "dmult";
2150 break;
2151 case OPC_DMULTU:
2152 gen_helper_dmultu(t0, t1);
2153 opn = "dmultu";
2154 break;
2155 #endif
2156 case OPC_MADD:
2158 TCGv_i64 t2 = tcg_temp_new_i64();
2159 TCGv_i64 t3 = tcg_temp_new_i64();
2161 tcg_gen_ext_tl_i64(t2, t0);
2162 tcg_gen_ext_tl_i64(t3, t1);
2163 tcg_gen_mul_i64(t2, t2, t3);
2164 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2165 tcg_gen_add_i64(t2, t2, t3);
2166 tcg_temp_free_i64(t3);
2167 tcg_gen_trunc_i64_tl(t0, t2);
2168 tcg_gen_shri_i64(t2, t2, 32);
2169 tcg_gen_trunc_i64_tl(t1, t2);
2170 tcg_temp_free_i64(t2);
2171 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2172 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2174 opn = "madd";
2175 break;
2176 case OPC_MADDU:
2178 TCGv_i64 t2 = tcg_temp_new_i64();
2179 TCGv_i64 t3 = tcg_temp_new_i64();
2181 tcg_gen_ext32u_tl(t0, t0);
2182 tcg_gen_ext32u_tl(t1, t1);
2183 tcg_gen_extu_tl_i64(t2, t0);
2184 tcg_gen_extu_tl_i64(t3, t1);
2185 tcg_gen_mul_i64(t2, t2, t3);
2186 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2187 tcg_gen_add_i64(t2, t2, t3);
2188 tcg_temp_free_i64(t3);
2189 tcg_gen_trunc_i64_tl(t0, t2);
2190 tcg_gen_shri_i64(t2, t2, 32);
2191 tcg_gen_trunc_i64_tl(t1, t2);
2192 tcg_temp_free_i64(t2);
2193 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2194 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2196 opn = "maddu";
2197 break;
2198 case OPC_MSUB:
2200 TCGv_i64 t2 = tcg_temp_new_i64();
2201 TCGv_i64 t3 = tcg_temp_new_i64();
2203 tcg_gen_ext_tl_i64(t2, t0);
2204 tcg_gen_ext_tl_i64(t3, t1);
2205 tcg_gen_mul_i64(t2, t2, t3);
2206 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2207 tcg_gen_sub_i64(t2, t3, t2);
2208 tcg_temp_free_i64(t3);
2209 tcg_gen_trunc_i64_tl(t0, t2);
2210 tcg_gen_shri_i64(t2, t2, 32);
2211 tcg_gen_trunc_i64_tl(t1, t2);
2212 tcg_temp_free_i64(t2);
2213 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2214 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2216 opn = "msub";
2217 break;
2218 case OPC_MSUBU:
2220 TCGv_i64 t2 = tcg_temp_new_i64();
2221 TCGv_i64 t3 = tcg_temp_new_i64();
2223 tcg_gen_ext32u_tl(t0, t0);
2224 tcg_gen_ext32u_tl(t1, t1);
2225 tcg_gen_extu_tl_i64(t2, t0);
2226 tcg_gen_extu_tl_i64(t3, t1);
2227 tcg_gen_mul_i64(t2, t2, t3);
2228 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2229 tcg_gen_sub_i64(t2, t3, t2);
2230 tcg_temp_free_i64(t3);
2231 tcg_gen_trunc_i64_tl(t0, t2);
2232 tcg_gen_shri_i64(t2, t2, 32);
2233 tcg_gen_trunc_i64_tl(t1, t2);
2234 tcg_temp_free_i64(t2);
2235 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2236 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2238 opn = "msubu";
2239 break;
2240 default:
2241 MIPS_INVAL(opn);
2242 generate_exception(ctx, EXCP_RI);
2243 goto out;
2245 (void)opn; /* avoid a compiler warning */
2246 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2247 out:
2248 tcg_temp_free(t0);
2249 tcg_temp_free(t1);
2252 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2253 int rd, int rs, int rt)
2255 const char *opn = "mul vr54xx";
2256 TCGv t0 = tcg_temp_new();
2257 TCGv t1 = tcg_temp_new();
2259 gen_load_gpr(t0, rs);
2260 gen_load_gpr(t1, rt);
2262 switch (opc) {
2263 case OPC_VR54XX_MULS:
2264 gen_helper_muls(t0, t0, t1);
2265 opn = "muls";
2266 break;
2267 case OPC_VR54XX_MULSU:
2268 gen_helper_mulsu(t0, t0, t1);
2269 opn = "mulsu";
2270 break;
2271 case OPC_VR54XX_MACC:
2272 gen_helper_macc(t0, t0, t1);
2273 opn = "macc";
2274 break;
2275 case OPC_VR54XX_MACCU:
2276 gen_helper_maccu(t0, t0, t1);
2277 opn = "maccu";
2278 break;
2279 case OPC_VR54XX_MSAC:
2280 gen_helper_msac(t0, t0, t1);
2281 opn = "msac";
2282 break;
2283 case OPC_VR54XX_MSACU:
2284 gen_helper_msacu(t0, t0, t1);
2285 opn = "msacu";
2286 break;
2287 case OPC_VR54XX_MULHI:
2288 gen_helper_mulhi(t0, t0, t1);
2289 opn = "mulhi";
2290 break;
2291 case OPC_VR54XX_MULHIU:
2292 gen_helper_mulhiu(t0, t0, t1);
2293 opn = "mulhiu";
2294 break;
2295 case OPC_VR54XX_MULSHI:
2296 gen_helper_mulshi(t0, t0, t1);
2297 opn = "mulshi";
2298 break;
2299 case OPC_VR54XX_MULSHIU:
2300 gen_helper_mulshiu(t0, t0, t1);
2301 opn = "mulshiu";
2302 break;
2303 case OPC_VR54XX_MACCHI:
2304 gen_helper_macchi(t0, t0, t1);
2305 opn = "macchi";
2306 break;
2307 case OPC_VR54XX_MACCHIU:
2308 gen_helper_macchiu(t0, t0, t1);
2309 opn = "macchiu";
2310 break;
2311 case OPC_VR54XX_MSACHI:
2312 gen_helper_msachi(t0, t0, t1);
2313 opn = "msachi";
2314 break;
2315 case OPC_VR54XX_MSACHIU:
2316 gen_helper_msachiu(t0, t0, t1);
2317 opn = "msachiu";
2318 break;
2319 default:
2320 MIPS_INVAL("mul vr54xx");
2321 generate_exception(ctx, EXCP_RI);
2322 goto out;
2324 gen_store_gpr(t0, rd);
2325 (void)opn; /* avoid a compiler warning */
2326 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2328 out:
2329 tcg_temp_free(t0);
2330 tcg_temp_free(t1);
2333 static void gen_cl (DisasContext *ctx, uint32_t opc,
2334 int rd, int rs)
2336 const char *opn = "CLx";
2337 TCGv t0;
2339 if (rd == 0) {
2340 /* Treat as NOP. */
2341 MIPS_DEBUG("NOP");
2342 return;
2344 t0 = tcg_temp_new();
2345 gen_load_gpr(t0, rs);
2346 switch (opc) {
2347 case OPC_CLO:
2348 gen_helper_clo(cpu_gpr[rd], t0);
2349 opn = "clo";
2350 break;
2351 case OPC_CLZ:
2352 gen_helper_clz(cpu_gpr[rd], t0);
2353 opn = "clz";
2354 break;
2355 #if defined(TARGET_MIPS64)
2356 case OPC_DCLO:
2357 gen_helper_dclo(cpu_gpr[rd], t0);
2358 opn = "dclo";
2359 break;
2360 case OPC_DCLZ:
2361 gen_helper_dclz(cpu_gpr[rd], t0);
2362 opn = "dclz";
2363 break;
2364 #endif
2366 (void)opn; /* avoid a compiler warning */
2367 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2368 tcg_temp_free(t0);
2371 /* Godson integer instructions */
2372 static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2373 int rd, int rs, int rt)
2375 const char *opn = "loongson";
2376 TCGv t0, t1;
2378 if (rd == 0) {
2379 /* Treat as NOP. */
2380 MIPS_DEBUG("NOP");
2381 return;
2384 switch (opc) {
2385 case OPC_MULT_G_2E:
2386 case OPC_MULT_G_2F:
2387 case OPC_MULTU_G_2E:
2388 case OPC_MULTU_G_2F:
2389 #if defined(TARGET_MIPS64)
2390 case OPC_DMULT_G_2E:
2391 case OPC_DMULT_G_2F:
2392 case OPC_DMULTU_G_2E:
2393 case OPC_DMULTU_G_2F:
2394 #endif
2395 t0 = tcg_temp_new();
2396 t1 = tcg_temp_new();
2397 break;
2398 default:
2399 t0 = tcg_temp_local_new();
2400 t1 = tcg_temp_local_new();
2401 break;
2404 gen_load_gpr(t0, rs);
2405 gen_load_gpr(t1, rt);
2407 switch (opc) {
2408 case OPC_MULT_G_2E:
2409 case OPC_MULT_G_2F:
2410 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2411 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2412 opn = "mult.g";
2413 break;
2414 case OPC_MULTU_G_2E:
2415 case OPC_MULTU_G_2F:
2416 tcg_gen_ext32u_tl(t0, t0);
2417 tcg_gen_ext32u_tl(t1, t1);
2418 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2419 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2420 opn = "multu.g";
2421 break;
2422 case OPC_DIV_G_2E:
2423 case OPC_DIV_G_2F:
2425 int l1 = gen_new_label();
2426 int l2 = gen_new_label();
2427 int l3 = gen_new_label();
2428 tcg_gen_ext32s_tl(t0, t0);
2429 tcg_gen_ext32s_tl(t1, t1);
2430 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2431 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2432 tcg_gen_br(l3);
2433 gen_set_label(l1);
2434 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2435 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2436 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2437 tcg_gen_br(l3);
2438 gen_set_label(l2);
2439 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2440 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2441 gen_set_label(l3);
2443 opn = "div.g";
2444 break;
2445 case OPC_DIVU_G_2E:
2446 case OPC_DIVU_G_2F:
2448 int l1 = gen_new_label();
2449 int l2 = gen_new_label();
2450 tcg_gen_ext32u_tl(t0, t0);
2451 tcg_gen_ext32u_tl(t1, t1);
2452 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2453 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2454 tcg_gen_br(l2);
2455 gen_set_label(l1);
2456 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2457 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2458 gen_set_label(l2);
2460 opn = "divu.g";
2461 break;
2462 case OPC_MOD_G_2E:
2463 case OPC_MOD_G_2F:
2465 int l1 = gen_new_label();
2466 int l2 = gen_new_label();
2467 int l3 = gen_new_label();
2468 tcg_gen_ext32u_tl(t0, t0);
2469 tcg_gen_ext32u_tl(t1, t1);
2470 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2471 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2472 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2473 gen_set_label(l1);
2474 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2475 tcg_gen_br(l3);
2476 gen_set_label(l2);
2477 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2478 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2479 gen_set_label(l3);
2481 opn = "mod.g";
2482 break;
2483 case OPC_MODU_G_2E:
2484 case OPC_MODU_G_2F:
2486 int l1 = gen_new_label();
2487 int l2 = gen_new_label();
2488 tcg_gen_ext32u_tl(t0, t0);
2489 tcg_gen_ext32u_tl(t1, t1);
2490 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2491 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2492 tcg_gen_br(l2);
2493 gen_set_label(l1);
2494 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2495 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2496 gen_set_label(l2);
2498 opn = "modu.g";
2499 break;
2500 #if defined(TARGET_MIPS64)
2501 case OPC_DMULT_G_2E:
2502 case OPC_DMULT_G_2F:
2503 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2504 opn = "dmult.g";
2505 break;
2506 case OPC_DMULTU_G_2E:
2507 case OPC_DMULTU_G_2F:
2508 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2509 opn = "dmultu.g";
2510 break;
2511 case OPC_DDIV_G_2E:
2512 case OPC_DDIV_G_2F:
2514 int l1 = gen_new_label();
2515 int l2 = gen_new_label();
2516 int l3 = gen_new_label();
2517 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2518 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2519 tcg_gen_br(l3);
2520 gen_set_label(l1);
2521 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2522 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2523 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2524 tcg_gen_br(l3);
2525 gen_set_label(l2);
2526 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2527 gen_set_label(l3);
2529 opn = "ddiv.g";
2530 break;
2531 case OPC_DDIVU_G_2E:
2532 case OPC_DDIVU_G_2F:
2534 int l1 = gen_new_label();
2535 int l2 = gen_new_label();
2536 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2537 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2538 tcg_gen_br(l2);
2539 gen_set_label(l1);
2540 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2541 gen_set_label(l2);
2543 opn = "ddivu.g";
2544 break;
2545 case OPC_DMOD_G_2E:
2546 case OPC_DMOD_G_2F:
2548 int l1 = gen_new_label();
2549 int l2 = gen_new_label();
2550 int l3 = gen_new_label();
2551 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2552 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2553 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2554 gen_set_label(l1);
2555 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2556 tcg_gen_br(l3);
2557 gen_set_label(l2);
2558 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2559 gen_set_label(l3);
2561 opn = "dmod.g";
2562 break;
2563 case OPC_DMODU_G_2E:
2564 case OPC_DMODU_G_2F:
2566 int l1 = gen_new_label();
2567 int l2 = gen_new_label();
2568 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2569 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2570 tcg_gen_br(l2);
2571 gen_set_label(l1);
2572 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2573 gen_set_label(l2);
2575 opn = "dmodu.g";
2576 break;
2577 #endif
2580 (void)opn; /* avoid a compiler warning */
2581 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2582 tcg_temp_free(t0);
2583 tcg_temp_free(t1);
2586 /* Traps */
2587 static void gen_trap (DisasContext *ctx, uint32_t opc,
2588 int rs, int rt, int16_t imm)
2590 int cond;
2591 TCGv t0 = tcg_temp_new();
2592 TCGv t1 = tcg_temp_new();
2594 cond = 0;
2595 /* Load needed operands */
2596 switch (opc) {
2597 case OPC_TEQ:
2598 case OPC_TGE:
2599 case OPC_TGEU:
2600 case OPC_TLT:
2601 case OPC_TLTU:
2602 case OPC_TNE:
2603 /* Compare two registers */
2604 if (rs != rt) {
2605 gen_load_gpr(t0, rs);
2606 gen_load_gpr(t1, rt);
2607 cond = 1;
2609 break;
2610 case OPC_TEQI:
2611 case OPC_TGEI:
2612 case OPC_TGEIU:
2613 case OPC_TLTI:
2614 case OPC_TLTIU:
2615 case OPC_TNEI:
2616 /* Compare register to immediate */
2617 if (rs != 0 || imm != 0) {
2618 gen_load_gpr(t0, rs);
2619 tcg_gen_movi_tl(t1, (int32_t)imm);
2620 cond = 1;
2622 break;
2624 if (cond == 0) {
2625 switch (opc) {
2626 case OPC_TEQ: /* rs == rs */
2627 case OPC_TEQI: /* r0 == 0 */
2628 case OPC_TGE: /* rs >= rs */
2629 case OPC_TGEI: /* r0 >= 0 */
2630 case OPC_TGEU: /* rs >= rs unsigned */
2631 case OPC_TGEIU: /* r0 >= 0 unsigned */
2632 /* Always trap */
2633 generate_exception(ctx, EXCP_TRAP);
2634 break;
2635 case OPC_TLT: /* rs < rs */
2636 case OPC_TLTI: /* r0 < 0 */
2637 case OPC_TLTU: /* rs < rs unsigned */
2638 case OPC_TLTIU: /* r0 < 0 unsigned */
2639 case OPC_TNE: /* rs != rs */
2640 case OPC_TNEI: /* r0 != 0 */
2641 /* Never trap: treat as NOP. */
2642 break;
2644 } else {
2645 int l1 = gen_new_label();
2647 switch (opc) {
2648 case OPC_TEQ:
2649 case OPC_TEQI:
2650 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2651 break;
2652 case OPC_TGE:
2653 case OPC_TGEI:
2654 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2655 break;
2656 case OPC_TGEU:
2657 case OPC_TGEIU:
2658 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2659 break;
2660 case OPC_TLT:
2661 case OPC_TLTI:
2662 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2663 break;
2664 case OPC_TLTU:
2665 case OPC_TLTIU:
2666 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2667 break;
2668 case OPC_TNE:
2669 case OPC_TNEI:
2670 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2671 break;
2673 generate_exception(ctx, EXCP_TRAP);
2674 gen_set_label(l1);
2676 tcg_temp_free(t0);
2677 tcg_temp_free(t1);
2680 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2682 TranslationBlock *tb;
2683 tb = ctx->tb;
2684 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2685 likely(!ctx->singlestep_enabled)) {
2686 tcg_gen_goto_tb(n);
2687 gen_save_pc(dest);
2688 tcg_gen_exit_tb((tcg_target_long)tb + n);
2689 } else {
2690 gen_save_pc(dest);
2691 if (ctx->singlestep_enabled) {
2692 save_cpu_state(ctx, 0);
2693 gen_helper_0i(raise_exception, EXCP_DEBUG);
2695 tcg_gen_exit_tb(0);
2699 /* Branches (before delay slot) */
2700 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2701 int insn_bytes,
2702 int rs, int rt, int32_t offset)
2704 target_ulong btgt = -1;
2705 int blink = 0;
2706 int bcond_compute = 0;
2707 TCGv t0 = tcg_temp_new();
2708 TCGv t1 = tcg_temp_new();
2710 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2711 #ifdef MIPS_DEBUG_DISAS
2712 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2713 #endif
2714 generate_exception(ctx, EXCP_RI);
2715 goto out;
2718 /* Load needed operands */
2719 switch (opc) {
2720 case OPC_BEQ:
2721 case OPC_BEQL:
2722 case OPC_BNE:
2723 case OPC_BNEL:
2724 /* Compare two registers */
2725 if (rs != rt) {
2726 gen_load_gpr(t0, rs);
2727 gen_load_gpr(t1, rt);
2728 bcond_compute = 1;
2730 btgt = ctx->pc + insn_bytes + offset;
2731 break;
2732 case OPC_BGEZ:
2733 case OPC_BGEZAL:
2734 case OPC_BGEZALS:
2735 case OPC_BGEZALL:
2736 case OPC_BGEZL:
2737 case OPC_BGTZ:
2738 case OPC_BGTZL:
2739 case OPC_BLEZ:
2740 case OPC_BLEZL:
2741 case OPC_BLTZ:
2742 case OPC_BLTZAL:
2743 case OPC_BLTZALS:
2744 case OPC_BLTZALL:
2745 case OPC_BLTZL:
2746 /* Compare to zero */
2747 if (rs != 0) {
2748 gen_load_gpr(t0, rs);
2749 bcond_compute = 1;
2751 btgt = ctx->pc + insn_bytes + offset;
2752 break;
2753 case OPC_J:
2754 case OPC_JAL:
2755 case OPC_JALX:
2756 case OPC_JALS:
2757 case OPC_JALXS:
2758 /* Jump to immediate */
2759 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2760 break;
2761 case OPC_JR:
2762 case OPC_JALR:
2763 case OPC_JALRC:
2764 case OPC_JALRS:
2765 /* Jump to register */
2766 if (offset != 0 && offset != 16) {
2767 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2768 others are reserved. */
2769 MIPS_INVAL("jump hint");
2770 generate_exception(ctx, EXCP_RI);
2771 goto out;
2773 gen_load_gpr(btarget, rs);
2774 break;
2775 default:
2776 MIPS_INVAL("branch/jump");
2777 generate_exception(ctx, EXCP_RI);
2778 goto out;
2780 if (bcond_compute == 0) {
2781 /* No condition to be computed */
2782 switch (opc) {
2783 case OPC_BEQ: /* rx == rx */
2784 case OPC_BEQL: /* rx == rx likely */
2785 case OPC_BGEZ: /* 0 >= 0 */
2786 case OPC_BGEZL: /* 0 >= 0 likely */
2787 case OPC_BLEZ: /* 0 <= 0 */
2788 case OPC_BLEZL: /* 0 <= 0 likely */
2789 /* Always take */
2790 ctx->hflags |= MIPS_HFLAG_B;
2791 MIPS_DEBUG("balways");
2792 break;
2793 case OPC_BGEZALS:
2794 case OPC_BGEZAL: /* 0 >= 0 */
2795 case OPC_BGEZALL: /* 0 >= 0 likely */
2796 ctx->hflags |= (opc == OPC_BGEZALS
2797 ? MIPS_HFLAG_BDS16
2798 : MIPS_HFLAG_BDS32);
2799 /* Always take and link */
2800 blink = 31;
2801 ctx->hflags |= MIPS_HFLAG_B;
2802 MIPS_DEBUG("balways and link");
2803 break;
2804 case OPC_BNE: /* rx != rx */
2805 case OPC_BGTZ: /* 0 > 0 */
2806 case OPC_BLTZ: /* 0 < 0 */
2807 /* Treat as NOP. */
2808 MIPS_DEBUG("bnever (NOP)");
2809 goto out;
2810 case OPC_BLTZALS:
2811 case OPC_BLTZAL: /* 0 < 0 */
2812 ctx->hflags |= (opc == OPC_BLTZALS
2813 ? MIPS_HFLAG_BDS16
2814 : MIPS_HFLAG_BDS32);
2815 /* Handle as an unconditional branch to get correct delay
2816 slot checking. */
2817 blink = 31;
2818 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2819 ctx->hflags |= MIPS_HFLAG_B;
2820 MIPS_DEBUG("bnever and link");
2821 break;
2822 case OPC_BLTZALL: /* 0 < 0 likely */
2823 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2824 /* Skip the instruction in the delay slot */
2825 MIPS_DEBUG("bnever, link and skip");
2826 ctx->pc += 4;
2827 goto out;
2828 case OPC_BNEL: /* rx != rx likely */
2829 case OPC_BGTZL: /* 0 > 0 likely */
2830 case OPC_BLTZL: /* 0 < 0 likely */
2831 /* Skip the instruction in the delay slot */
2832 MIPS_DEBUG("bnever and skip");
2833 ctx->pc += 4;
2834 goto out;
2835 case OPC_J:
2836 ctx->hflags |= MIPS_HFLAG_B;
2837 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2838 break;
2839 case OPC_JALXS:
2840 case OPC_JALX:
2841 ctx->hflags |= MIPS_HFLAG_BX;
2842 /* Fallthrough */
2843 case OPC_JALS:
2844 case OPC_JAL:
2845 blink = 31;
2846 ctx->hflags |= MIPS_HFLAG_B;
2847 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2848 ? MIPS_HFLAG_BDS16
2849 : MIPS_HFLAG_BDS32);
2850 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2851 break;
2852 case OPC_JR:
2853 ctx->hflags |= MIPS_HFLAG_BR;
2854 if (insn_bytes == 4)
2855 ctx->hflags |= MIPS_HFLAG_BDS32;
2856 MIPS_DEBUG("jr %s", regnames[rs]);
2857 break;
2858 case OPC_JALRS:
2859 case OPC_JALR:
2860 case OPC_JALRC:
2861 blink = rt;
2862 ctx->hflags |= MIPS_HFLAG_BR;
2863 ctx->hflags |= (opc == OPC_JALRS
2864 ? MIPS_HFLAG_BDS16
2865 : MIPS_HFLAG_BDS32);
2866 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2867 break;
2868 default:
2869 MIPS_INVAL("branch/jump");
2870 generate_exception(ctx, EXCP_RI);
2871 goto out;
2873 } else {
2874 switch (opc) {
2875 case OPC_BEQ:
2876 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2877 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2878 regnames[rs], regnames[rt], btgt);
2879 goto not_likely;
2880 case OPC_BEQL:
2881 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2882 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2883 regnames[rs], regnames[rt], btgt);
2884 goto likely;
2885 case OPC_BNE:
2886 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2887 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2888 regnames[rs], regnames[rt], btgt);
2889 goto not_likely;
2890 case OPC_BNEL:
2891 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2892 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2893 regnames[rs], regnames[rt], btgt);
2894 goto likely;
2895 case OPC_BGEZ:
2896 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2897 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2898 goto not_likely;
2899 case OPC_BGEZL:
2900 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2901 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2902 goto likely;
2903 case OPC_BGEZALS:
2904 case OPC_BGEZAL:
2905 ctx->hflags |= (opc == OPC_BGEZALS
2906 ? MIPS_HFLAG_BDS16
2907 : MIPS_HFLAG_BDS32);
2908 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2909 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2910 blink = 31;
2911 goto not_likely;
2912 case OPC_BGEZALL:
2913 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2914 blink = 31;
2915 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2916 goto likely;
2917 case OPC_BGTZ:
2918 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2919 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2920 goto not_likely;
2921 case OPC_BGTZL:
2922 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2923 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2924 goto likely;
2925 case OPC_BLEZ:
2926 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2927 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2928 goto not_likely;
2929 case OPC_BLEZL:
2930 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2931 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2932 goto likely;
2933 case OPC_BLTZ:
2934 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2935 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2936 goto not_likely;
2937 case OPC_BLTZL:
2938 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2939 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2940 goto likely;
2941 case OPC_BLTZALS:
2942 case OPC_BLTZAL:
2943 ctx->hflags |= (opc == OPC_BLTZALS
2944 ? MIPS_HFLAG_BDS16
2945 : MIPS_HFLAG_BDS32);
2946 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2947 blink = 31;
2948 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2949 not_likely:
2950 ctx->hflags |= MIPS_HFLAG_BC;
2951 break;
2952 case OPC_BLTZALL:
2953 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2954 blink = 31;
2955 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2956 likely:
2957 ctx->hflags |= MIPS_HFLAG_BL;
2958 break;
2959 default:
2960 MIPS_INVAL("conditional branch/jump");
2961 generate_exception(ctx, EXCP_RI);
2962 goto out;
2965 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2966 blink, ctx->hflags, btgt);
2968 ctx->btarget = btgt;
2969 if (blink > 0) {
2970 int post_delay = insn_bytes;
2971 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2973 if (opc != OPC_JALRC)
2974 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2976 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2979 out:
2980 if (insn_bytes == 2)
2981 ctx->hflags |= MIPS_HFLAG_B16;
2982 tcg_temp_free(t0);
2983 tcg_temp_free(t1);
2986 /* special3 bitfield operations */
2987 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2988 int rs, int lsb, int msb)
2990 TCGv t0 = tcg_temp_new();
2991 TCGv t1 = tcg_temp_new();
2992 target_ulong mask;
2994 gen_load_gpr(t1, rs);
2995 switch (opc) {
2996 case OPC_EXT:
2997 if (lsb + msb > 31)
2998 goto fail;
2999 tcg_gen_shri_tl(t0, t1, lsb);
3000 if (msb != 31) {
3001 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3002 } else {
3003 tcg_gen_ext32s_tl(t0, t0);
3005 break;
3006 #if defined(TARGET_MIPS64)
3007 case OPC_DEXTM:
3008 tcg_gen_shri_tl(t0, t1, lsb);
3009 if (msb != 31) {
3010 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3012 break;
3013 case OPC_DEXTU:
3014 tcg_gen_shri_tl(t0, t1, lsb + 32);
3015 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3016 break;
3017 case OPC_DEXT:
3018 tcg_gen_shri_tl(t0, t1, lsb);
3019 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3020 break;
3021 #endif
3022 case OPC_INS:
3023 if (lsb > msb)
3024 goto fail;
3025 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3026 gen_load_gpr(t0, rt);
3027 tcg_gen_andi_tl(t0, t0, ~mask);
3028 tcg_gen_shli_tl(t1, t1, lsb);
3029 tcg_gen_andi_tl(t1, t1, mask);
3030 tcg_gen_or_tl(t0, t0, t1);
3031 tcg_gen_ext32s_tl(t0, t0);
3032 break;
3033 #if defined(TARGET_MIPS64)
3034 case OPC_DINSM:
3035 if (lsb > msb)
3036 goto fail;
3037 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3038 gen_load_gpr(t0, rt);
3039 tcg_gen_andi_tl(t0, t0, ~mask);
3040 tcg_gen_shli_tl(t1, t1, lsb);
3041 tcg_gen_andi_tl(t1, t1, mask);
3042 tcg_gen_or_tl(t0, t0, t1);
3043 break;
3044 case OPC_DINSU:
3045 if (lsb > msb)
3046 goto fail;
3047 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3048 gen_load_gpr(t0, rt);
3049 tcg_gen_andi_tl(t0, t0, ~mask);
3050 tcg_gen_shli_tl(t1, t1, lsb + 32);
3051 tcg_gen_andi_tl(t1, t1, mask);
3052 tcg_gen_or_tl(t0, t0, t1);
3053 break;
3054 case OPC_DINS:
3055 if (lsb > msb)
3056 goto fail;
3057 gen_load_gpr(t0, rt);
3058 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3059 gen_load_gpr(t0, rt);
3060 tcg_gen_andi_tl(t0, t0, ~mask);
3061 tcg_gen_shli_tl(t1, t1, lsb);
3062 tcg_gen_andi_tl(t1, t1, mask);
3063 tcg_gen_or_tl(t0, t0, t1);
3064 break;
3065 #endif
3066 default:
3067 fail:
3068 MIPS_INVAL("bitops");
3069 generate_exception(ctx, EXCP_RI);
3070 tcg_temp_free(t0);
3071 tcg_temp_free(t1);
3072 return;
3074 gen_store_gpr(t0, rt);
3075 tcg_temp_free(t0);
3076 tcg_temp_free(t1);
3079 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3081 TCGv t0;
3083 if (rd == 0) {
3084 /* If no destination, treat it as a NOP. */
3085 MIPS_DEBUG("NOP");
3086 return;
3089 t0 = tcg_temp_new();
3090 gen_load_gpr(t0, rt);
3091 switch (op2) {
3092 case OPC_WSBH:
3094 TCGv t1 = tcg_temp_new();
3096 tcg_gen_shri_tl(t1, t0, 8);
3097 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3098 tcg_gen_shli_tl(t0, t0, 8);
3099 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3100 tcg_gen_or_tl(t0, t0, t1);
3101 tcg_temp_free(t1);
3102 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3104 break;
3105 case OPC_SEB:
3106 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3107 break;
3108 case OPC_SEH:
3109 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3110 break;
3111 #if defined(TARGET_MIPS64)
3112 case OPC_DSBH:
3114 TCGv t1 = tcg_temp_new();
3116 tcg_gen_shri_tl(t1, t0, 8);
3117 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
3118 tcg_gen_shli_tl(t0, t0, 8);
3119 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
3120 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3121 tcg_temp_free(t1);
3123 break;
3124 case OPC_DSHD:
3126 TCGv t1 = tcg_temp_new();
3128 tcg_gen_shri_tl(t1, t0, 16);
3129 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
3130 tcg_gen_shli_tl(t0, t0, 16);
3131 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
3132 tcg_gen_or_tl(t0, t0, t1);
3133 tcg_gen_shri_tl(t1, t0, 32);
3134 tcg_gen_shli_tl(t0, t0, 32);
3135 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3136 tcg_temp_free(t1);
3138 break;
3139 #endif
3140 default:
3141 MIPS_INVAL("bsfhl");
3142 generate_exception(ctx, EXCP_RI);
3143 tcg_temp_free(t0);
3144 return;
3146 tcg_temp_free(t0);
3149 #ifndef CONFIG_USER_ONLY
3150 /* CP0 (MMU and control) */
3151 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
3153 TCGv_i32 t0 = tcg_temp_new_i32();
3155 tcg_gen_ld_i32(t0, cpu_env, off);
3156 tcg_gen_ext_i32_tl(arg, t0);
3157 tcg_temp_free_i32(t0);
3160 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
3162 tcg_gen_ld_tl(arg, cpu_env, off);
3163 tcg_gen_ext32s_tl(arg, arg);
3166 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
3168 TCGv_i32 t0 = tcg_temp_new_i32();
3170 tcg_gen_trunc_tl_i32(t0, arg);
3171 tcg_gen_st_i32(t0, cpu_env, off);
3172 tcg_temp_free_i32(t0);
3175 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
3177 tcg_gen_ext32s_tl(arg, arg);
3178 tcg_gen_st_tl(arg, cpu_env, off);
3181 static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3183 const char *rn = "invalid";
3185 if (sel != 0)
3186 check_insn(env, ctx, ISA_MIPS32);
3188 switch (reg) {
3189 case 0:
3190 switch (sel) {
3191 case 0:
3192 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
3193 rn = "Index";
3194 break;
3195 case 1:
3196 check_insn(env, ctx, ASE_MT);
3197 gen_helper_mfc0_mvpcontrol(arg);
3198 rn = "MVPControl";
3199 break;
3200 case 2:
3201 check_insn(env, ctx, ASE_MT);
3202 gen_helper_mfc0_mvpconf0(arg);
3203 rn = "MVPConf0";
3204 break;
3205 case 3:
3206 check_insn(env, ctx, ASE_MT);
3207 gen_helper_mfc0_mvpconf1(arg);
3208 rn = "MVPConf1";
3209 break;
3210 default:
3211 goto die;
3213 break;
3214 case 1:
3215 switch (sel) {
3216 case 0:
3217 gen_helper_mfc0_random(arg);
3218 rn = "Random";
3219 break;
3220 case 1:
3221 check_insn(env, ctx, ASE_MT);
3222 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
3223 rn = "VPEControl";
3224 break;
3225 case 2:
3226 check_insn(env, ctx, ASE_MT);
3227 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
3228 rn = "VPEConf0";
3229 break;
3230 case 3:
3231 check_insn(env, ctx, ASE_MT);
3232 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
3233 rn = "VPEConf1";
3234 break;
3235 case 4:
3236 check_insn(env, ctx, ASE_MT);
3237 gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
3238 rn = "YQMask";
3239 break;
3240 case 5:
3241 check_insn(env, ctx, ASE_MT);
3242 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
3243 rn = "VPESchedule";
3244 break;
3245 case 6:
3246 check_insn(env, ctx, ASE_MT);
3247 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3248 rn = "VPEScheFBack";
3249 break;
3250 case 7:
3251 check_insn(env, ctx, ASE_MT);
3252 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
3253 rn = "VPEOpt";
3254 break;
3255 default:
3256 goto die;
3258 break;
3259 case 2:
3260 switch (sel) {
3261 case 0:
3262 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
3263 tcg_gen_ext32s_tl(arg, arg);
3264 rn = "EntryLo0";
3265 break;
3266 case 1:
3267 check_insn(env, ctx, ASE_MT);
3268 gen_helper_mfc0_tcstatus(arg);
3269 rn = "TCStatus";
3270 break;
3271 case 2:
3272 check_insn(env, ctx, ASE_MT);
3273 gen_helper_mfc0_tcbind(arg);
3274 rn = "TCBind";
3275 break;
3276 case 3:
3277 check_insn(env, ctx, ASE_MT);
3278 gen_helper_mfc0_tcrestart(arg);
3279 rn = "TCRestart";
3280 break;
3281 case 4:
3282 check_insn(env, ctx, ASE_MT);
3283 gen_helper_mfc0_tchalt(arg);
3284 rn = "TCHalt";
3285 break;
3286 case 5:
3287 check_insn(env, ctx, ASE_MT);
3288 gen_helper_mfc0_tccontext(arg);
3289 rn = "TCContext";
3290 break;
3291 case 6:
3292 check_insn(env, ctx, ASE_MT);
3293 gen_helper_mfc0_tcschedule(arg);
3294 rn = "TCSchedule";
3295 break;
3296 case 7:
3297 check_insn(env, ctx, ASE_MT);
3298 gen_helper_mfc0_tcschefback(arg);
3299 rn = "TCScheFBack";
3300 break;
3301 default:
3302 goto die;
3304 break;
3305 case 3:
3306 switch (sel) {
3307 case 0:
3308 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3309 tcg_gen_ext32s_tl(arg, arg);
3310 rn = "EntryLo1";
3311 break;
3312 default:
3313 goto die;
3315 break;
3316 case 4:
3317 switch (sel) {
3318 case 0:
3319 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3320 tcg_gen_ext32s_tl(arg, arg);
3321 rn = "Context";
3322 break;
3323 case 1:
3324 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3325 rn = "ContextConfig";
3326 // break;
3327 default:
3328 goto die;
3330 break;
3331 case 5:
3332 switch (sel) {
3333 case 0:
3334 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3335 rn = "PageMask";
3336 break;
3337 case 1:
3338 check_insn(env, ctx, ISA_MIPS32R2);
3339 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3340 rn = "PageGrain";
3341 break;
3342 default:
3343 goto die;
3345 break;
3346 case 6:
3347 switch (sel) {
3348 case 0:
3349 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3350 rn = "Wired";
3351 break;
3352 case 1:
3353 check_insn(env, ctx, ISA_MIPS32R2);
3354 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3355 rn = "SRSConf0";
3356 break;
3357 case 2:
3358 check_insn(env, ctx, ISA_MIPS32R2);
3359 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3360 rn = "SRSConf1";
3361 break;
3362 case 3:
3363 check_insn(env, ctx, ISA_MIPS32R2);
3364 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3365 rn = "SRSConf2";
3366 break;
3367 case 4:
3368 check_insn(env, ctx, ISA_MIPS32R2);
3369 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3370 rn = "SRSConf3";
3371 break;
3372 case 5:
3373 check_insn(env, ctx, ISA_MIPS32R2);
3374 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3375 rn = "SRSConf4";
3376 break;
3377 default:
3378 goto die;
3380 break;
3381 case 7:
3382 switch (sel) {
3383 case 0:
3384 check_insn(env, ctx, ISA_MIPS32R2);
3385 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3386 rn = "HWREna";
3387 break;
3388 default:
3389 goto die;
3391 break;
3392 case 8:
3393 switch (sel) {
3394 case 0:
3395 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3396 tcg_gen_ext32s_tl(arg, arg);
3397 rn = "BadVAddr";
3398 break;
3399 default:
3400 goto die;
3402 break;
3403 case 9:
3404 switch (sel) {
3405 case 0:
3406 /* Mark as an IO operation because we read the time. */
3407 if (use_icount)
3408 gen_io_start();
3409 gen_helper_mfc0_count(arg);
3410 if (use_icount) {
3411 gen_io_end();
3413 /* Break the TB to be able to take timer interrupts immediately
3414 after reading count. */
3415 ctx->bstate = BS_STOP;
3416 rn = "Count";
3417 break;
3418 /* 6,7 are implementation dependent */
3419 default:
3420 goto die;
3422 break;
3423 case 10:
3424 switch (sel) {
3425 case 0:
3426 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3427 tcg_gen_ext32s_tl(arg, arg);
3428 rn = "EntryHi";
3429 break;
3430 default:
3431 goto die;
3433 break;
3434 case 11:
3435 switch (sel) {
3436 case 0:
3437 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3438 rn = "Compare";
3439 break;
3440 /* 6,7 are implementation dependent */
3441 default:
3442 goto die;
3444 break;
3445 case 12:
3446 switch (sel) {
3447 case 0:
3448 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3449 rn = "Status";
3450 break;
3451 case 1:
3452 check_insn(env, ctx, ISA_MIPS32R2);
3453 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3454 rn = "IntCtl";
3455 break;
3456 case 2:
3457 check_insn(env, ctx, ISA_MIPS32R2);
3458 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3459 rn = "SRSCtl";
3460 break;
3461 case 3:
3462 check_insn(env, ctx, ISA_MIPS32R2);
3463 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3464 rn = "SRSMap";
3465 break;
3466 default:
3467 goto die;
3469 break;
3470 case 13:
3471 switch (sel) {
3472 case 0:
3473 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3474 rn = "Cause";
3475 break;
3476 default:
3477 goto die;
3479 break;
3480 case 14:
3481 switch (sel) {
3482 case 0:
3483 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3484 tcg_gen_ext32s_tl(arg, arg);
3485 rn = "EPC";
3486 break;
3487 default:
3488 goto die;
3490 break;
3491 case 15:
3492 switch (sel) {
3493 case 0:
3494 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3495 rn = "PRid";
3496 break;
3497 case 1:
3498 check_insn(env, ctx, ISA_MIPS32R2);
3499 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3500 rn = "EBase";
3501 break;
3502 default:
3503 goto die;
3505 break;
3506 case 16:
3507 switch (sel) {
3508 case 0:
3509 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3510 rn = "Config";
3511 break;
3512 case 1:
3513 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3514 rn = "Config1";
3515 break;
3516 case 2:
3517 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3518 rn = "Config2";
3519 break;
3520 case 3:
3521 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3522 rn = "Config3";
3523 break;
3524 /* 4,5 are reserved */
3525 /* 6,7 are implementation dependent */
3526 case 6:
3527 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3528 rn = "Config6";
3529 break;
3530 case 7:
3531 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3532 rn = "Config7";
3533 break;
3534 default:
3535 goto die;
3537 break;
3538 case 17:
3539 switch (sel) {
3540 case 0:
3541 gen_helper_mfc0_lladdr(arg);
3542 rn = "LLAddr";
3543 break;
3544 default:
3545 goto die;
3547 break;
3548 case 18:
3549 switch (sel) {
3550 case 0 ... 7:
3551 gen_helper_1i(mfc0_watchlo, arg, sel);
3552 rn = "WatchLo";
3553 break;
3554 default:
3555 goto die;
3557 break;
3558 case 19:
3559 switch (sel) {
3560 case 0 ...7:
3561 gen_helper_1i(mfc0_watchhi, arg, sel);
3562 rn = "WatchHi";
3563 break;
3564 default:
3565 goto die;
3567 break;
3568 case 20:
3569 switch (sel) {
3570 case 0:
3571 #if defined(TARGET_MIPS64)
3572 check_insn(env, ctx, ISA_MIPS3);
3573 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3574 tcg_gen_ext32s_tl(arg, arg);
3575 rn = "XContext";
3576 break;
3577 #endif
3578 default:
3579 goto die;
3581 break;
3582 case 21:
3583 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3584 switch (sel) {
3585 case 0:
3586 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3587 rn = "Framemask";
3588 break;
3589 default:
3590 goto die;
3592 break;
3593 case 22:
3594 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3595 rn = "'Diagnostic"; /* implementation dependent */
3596 break;
3597 case 23:
3598 switch (sel) {
3599 case 0:
3600 gen_helper_mfc0_debug(arg); /* EJTAG support */
3601 rn = "Debug";
3602 break;
3603 case 1:
3604 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3605 rn = "TraceControl";
3606 // break;
3607 case 2:
3608 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3609 rn = "TraceControl2";
3610 // break;
3611 case 3:
3612 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3613 rn = "UserTraceData";
3614 // break;
3615 case 4:
3616 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3617 rn = "TraceBPC";
3618 // break;
3619 default:
3620 goto die;
3622 break;
3623 case 24:
3624 switch (sel) {
3625 case 0:
3626 /* EJTAG support */
3627 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3628 tcg_gen_ext32s_tl(arg, arg);
3629 rn = "DEPC";
3630 break;
3631 default:
3632 goto die;
3634 break;
3635 case 25:
3636 switch (sel) {
3637 case 0:
3638 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3639 rn = "Performance0";
3640 break;
3641 case 1:
3642 // gen_helper_mfc0_performance1(arg);
3643 rn = "Performance1";
3644 // break;
3645 case 2:
3646 // gen_helper_mfc0_performance2(arg);
3647 rn = "Performance2";
3648 // break;
3649 case 3:
3650 // gen_helper_mfc0_performance3(arg);
3651 rn = "Performance3";
3652 // break;
3653 case 4:
3654 // gen_helper_mfc0_performance4(arg);
3655 rn = "Performance4";
3656 // break;
3657 case 5:
3658 // gen_helper_mfc0_performance5(arg);
3659 rn = "Performance5";
3660 // break;
3661 case 6:
3662 // gen_helper_mfc0_performance6(arg);
3663 rn = "Performance6";
3664 // break;
3665 case 7:
3666 // gen_helper_mfc0_performance7(arg);
3667 rn = "Performance7";
3668 // break;
3669 default:
3670 goto die;
3672 break;
3673 case 26:
3674 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3675 rn = "ECC";
3676 break;
3677 case 27:
3678 switch (sel) {
3679 case 0 ... 3:
3680 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3681 rn = "CacheErr";
3682 break;
3683 default:
3684 goto die;
3686 break;
3687 case 28:
3688 switch (sel) {
3689 case 0:
3690 case 2:
3691 case 4:
3692 case 6:
3693 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3694 rn = "TagLo";
3695 break;
3696 case 1:
3697 case 3:
3698 case 5:
3699 case 7:
3700 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3701 rn = "DataLo";
3702 break;
3703 default:
3704 goto die;
3706 break;
3707 case 29:
3708 switch (sel) {
3709 case 0:
3710 case 2:
3711 case 4:
3712 case 6:
3713 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3714 rn = "TagHi";
3715 break;
3716 case 1:
3717 case 3:
3718 case 5:
3719 case 7:
3720 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3721 rn = "DataHi";
3722 break;
3723 default:
3724 goto die;
3726 break;
3727 case 30:
3728 switch (sel) {
3729 case 0:
3730 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3731 tcg_gen_ext32s_tl(arg, arg);
3732 rn = "ErrorEPC";
3733 break;
3734 default:
3735 goto die;
3737 break;
3738 case 31:
3739 switch (sel) {
3740 case 0:
3741 /* EJTAG support */
3742 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3743 rn = "DESAVE";
3744 break;
3745 default:
3746 goto die;
3748 break;
3749 default:
3750 goto die;
3752 (void)rn; /* avoid a compiler warning */
3753 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3754 return;
3756 die:
3757 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3758 generate_exception(ctx, EXCP_RI);
3761 static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3763 const char *rn = "invalid";
3765 if (sel != 0)
3766 check_insn(env, ctx, ISA_MIPS32);
3768 if (use_icount)
3769 gen_io_start();
3771 switch (reg) {
3772 case 0:
3773 switch (sel) {
3774 case 0:
3775 gen_helper_mtc0_index(arg);
3776 rn = "Index";
3777 break;
3778 case 1:
3779 check_insn(env, ctx, ASE_MT);
3780 gen_helper_mtc0_mvpcontrol(arg);
3781 rn = "MVPControl";
3782 break;
3783 case 2:
3784 check_insn(env, ctx, ASE_MT);
3785 /* ignored */
3786 rn = "MVPConf0";
3787 break;
3788 case 3:
3789 check_insn(env, ctx, ASE_MT);
3790 /* ignored */
3791 rn = "MVPConf1";
3792 break;
3793 default:
3794 goto die;
3796 break;
3797 case 1:
3798 switch (sel) {
3799 case 0:
3800 /* ignored */
3801 rn = "Random";
3802 break;
3803 case 1:
3804 check_insn(env, ctx, ASE_MT);
3805 gen_helper_mtc0_vpecontrol(arg);
3806 rn = "VPEControl";
3807 break;
3808 case 2:
3809 check_insn(env, ctx, ASE_MT);
3810 gen_helper_mtc0_vpeconf0(arg);
3811 rn = "VPEConf0";
3812 break;
3813 case 3:
3814 check_insn(env, ctx, ASE_MT);
3815 gen_helper_mtc0_vpeconf1(arg);
3816 rn = "VPEConf1";
3817 break;
3818 case 4:
3819 check_insn(env, ctx, ASE_MT);
3820 gen_helper_mtc0_yqmask(arg);
3821 rn = "YQMask";
3822 break;
3823 case 5:
3824 check_insn(env, ctx, ASE_MT);
3825 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3826 rn = "VPESchedule";
3827 break;
3828 case 6:
3829 check_insn(env, ctx, ASE_MT);
3830 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3831 rn = "VPEScheFBack";
3832 break;
3833 case 7:
3834 check_insn(env, ctx, ASE_MT);
3835 gen_helper_mtc0_vpeopt(arg);
3836 rn = "VPEOpt";
3837 break;
3838 default:
3839 goto die;
3841 break;
3842 case 2:
3843 switch (sel) {
3844 case 0:
3845 gen_helper_mtc0_entrylo0(arg);
3846 rn = "EntryLo0";
3847 break;
3848 case 1:
3849 check_insn(env, ctx, ASE_MT);
3850 gen_helper_mtc0_tcstatus(arg);
3851 rn = "TCStatus";
3852 break;
3853 case 2:
3854 check_insn(env, ctx, ASE_MT);
3855 gen_helper_mtc0_tcbind(arg);
3856 rn = "TCBind";
3857 break;
3858 case 3:
3859 check_insn(env, ctx, ASE_MT);
3860 gen_helper_mtc0_tcrestart(arg);
3861 rn = "TCRestart";
3862 break;
3863 case 4:
3864 check_insn(env, ctx, ASE_MT);
3865 gen_helper_mtc0_tchalt(arg);
3866 rn = "TCHalt";
3867 break;
3868 case 5:
3869 check_insn(env, ctx, ASE_MT);
3870 gen_helper_mtc0_tccontext(arg);
3871 rn = "TCContext";
3872 break;
3873 case 6:
3874 check_insn(env, ctx, ASE_MT);
3875 gen_helper_mtc0_tcschedule(arg);
3876 rn = "TCSchedule";
3877 break;
3878 case 7:
3879 check_insn(env, ctx, ASE_MT);
3880 gen_helper_mtc0_tcschefback(arg);
3881 rn = "TCScheFBack";
3882 break;
3883 default:
3884 goto die;
3886 break;
3887 case 3:
3888 switch (sel) {
3889 case 0:
3890 gen_helper_mtc0_entrylo1(arg);
3891 rn = "EntryLo1";
3892 break;
3893 default:
3894 goto die;
3896 break;
3897 case 4:
3898 switch (sel) {
3899 case 0:
3900 gen_helper_mtc0_context(arg);
3901 rn = "Context";
3902 break;
3903 case 1:
3904 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3905 rn = "ContextConfig";
3906 // break;
3907 default:
3908 goto die;
3910 break;
3911 case 5:
3912 switch (sel) {
3913 case 0:
3914 gen_helper_mtc0_pagemask(arg);
3915 rn = "PageMask";
3916 break;
3917 case 1:
3918 check_insn(env, ctx, ISA_MIPS32R2);
3919 gen_helper_mtc0_pagegrain(arg);
3920 rn = "PageGrain";
3921 break;
3922 default:
3923 goto die;
3925 break;
3926 case 6:
3927 switch (sel) {
3928 case 0:
3929 gen_helper_mtc0_wired(arg);
3930 rn = "Wired";
3931 break;
3932 case 1:
3933 check_insn(env, ctx, ISA_MIPS32R2);
3934 gen_helper_mtc0_srsconf0(arg);
3935 rn = "SRSConf0";
3936 break;
3937 case 2:
3938 check_insn(env, ctx, ISA_MIPS32R2);
3939 gen_helper_mtc0_srsconf1(arg);
3940 rn = "SRSConf1";
3941 break;
3942 case 3:
3943 check_insn(env, ctx, ISA_MIPS32R2);
3944 gen_helper_mtc0_srsconf2(arg);
3945 rn = "SRSConf2";
3946 break;
3947 case 4:
3948 check_insn(env, ctx, ISA_MIPS32R2);
3949 gen_helper_mtc0_srsconf3(arg);
3950 rn = "SRSConf3";
3951 break;
3952 case 5:
3953 check_insn(env, ctx, ISA_MIPS32R2);
3954 gen_helper_mtc0_srsconf4(arg);
3955 rn = "SRSConf4";
3956 break;
3957 default:
3958 goto die;
3960 break;
3961 case 7:
3962 switch (sel) {
3963 case 0:
3964 check_insn(env, ctx, ISA_MIPS32R2);
3965 gen_helper_mtc0_hwrena(arg);
3966 rn = "HWREna";
3967 break;
3968 default:
3969 goto die;
3971 break;
3972 case 8:
3973 /* ignored */
3974 rn = "BadVAddr";
3975 break;
3976 case 9:
3977 switch (sel) {
3978 case 0:
3979 gen_helper_mtc0_count(arg);
3980 rn = "Count";
3981 break;
3982 /* 6,7 are implementation dependent */
3983 default:
3984 goto die;
3986 break;
3987 case 10:
3988 switch (sel) {
3989 case 0:
3990 gen_helper_mtc0_entryhi(arg);
3991 rn = "EntryHi";
3992 break;
3993 default:
3994 goto die;
3996 break;
3997 case 11:
3998 switch (sel) {
3999 case 0:
4000 gen_helper_mtc0_compare(arg);
4001 rn = "Compare";
4002 break;
4003 /* 6,7 are implementation dependent */
4004 default:
4005 goto die;
4007 break;
4008 case 12:
4009 switch (sel) {
4010 case 0:
4011 save_cpu_state(ctx, 1);
4012 gen_helper_mtc0_status(arg);
4013 /* BS_STOP isn't good enough here, hflags may have changed. */
4014 gen_save_pc(ctx->pc + 4);
4015 ctx->bstate = BS_EXCP;
4016 rn = "Status";
4017 break;
4018 case 1:
4019 check_insn(env, ctx, ISA_MIPS32R2);
4020 gen_helper_mtc0_intctl(arg);
4021 /* Stop translation as we may have switched the execution mode */
4022 ctx->bstate = BS_STOP;
4023 rn = "IntCtl";
4024 break;
4025 case 2:
4026 check_insn(env, ctx, ISA_MIPS32R2);
4027 gen_helper_mtc0_srsctl(arg);
4028 /* Stop translation as we may have switched the execution mode */
4029 ctx->bstate = BS_STOP;
4030 rn = "SRSCtl";
4031 break;
4032 case 3:
4033 check_insn(env, ctx, ISA_MIPS32R2);
4034 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4035 /* Stop translation as we may have switched the execution mode */
4036 ctx->bstate = BS_STOP;
4037 rn = "SRSMap";
4038 break;
4039 default:
4040 goto die;
4042 break;
4043 case 13:
4044 switch (sel) {
4045 case 0:
4046 save_cpu_state(ctx, 1);
4047 gen_helper_mtc0_cause(arg);
4048 rn = "Cause";
4049 break;
4050 default:
4051 goto die;
4053 break;
4054 case 14:
4055 switch (sel) {
4056 case 0:
4057 gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
4058 rn = "EPC";
4059 break;
4060 default:
4061 goto die;
4063 break;
4064 case 15:
4065 switch (sel) {
4066 case 0:
4067 /* ignored */
4068 rn = "PRid";
4069 break;
4070 case 1:
4071 check_insn(env, ctx, ISA_MIPS32R2);
4072 gen_helper_mtc0_ebase(arg);
4073 rn = "EBase";
4074 break;
4075 default:
4076 goto die;
4078 break;
4079 case 16:
4080 switch (sel) {
4081 case 0:
4082 gen_helper_mtc0_config0(arg);
4083 rn = "Config";
4084 /* Stop translation as we may have switched the execution mode */
4085 ctx->bstate = BS_STOP;
4086 break;
4087 case 1:
4088 /* ignored, read only */
4089 rn = "Config1";
4090 break;
4091 case 2:
4092 gen_helper_mtc0_config2(arg);
4093 rn = "Config2";
4094 /* Stop translation as we may have switched the execution mode */
4095 ctx->bstate = BS_STOP;
4096 break;
4097 case 3:
4098 /* ignored, read only */
4099 rn = "Config3";
4100 break;
4101 /* 4,5 are reserved */
4102 /* 6,7 are implementation dependent */
4103 case 6:
4104 /* ignored */
4105 rn = "Config6";
4106 break;
4107 case 7:
4108 /* ignored */
4109 rn = "Config7";
4110 break;
4111 default:
4112 rn = "Invalid config selector";
4113 goto die;
4115 break;
4116 case 17:
4117 switch (sel) {
4118 case 0:
4119 gen_helper_mtc0_lladdr(arg);
4120 rn = "LLAddr";
4121 break;
4122 default:
4123 goto die;
4125 break;
4126 case 18:
4127 switch (sel) {
4128 case 0 ... 7:
4129 gen_helper_1i(mtc0_watchlo, arg, sel);
4130 rn = "WatchLo";
4131 break;
4132 default:
4133 goto die;
4135 break;
4136 case 19:
4137 switch (sel) {
4138 case 0 ... 7:
4139 gen_helper_1i(mtc0_watchhi, arg, sel);
4140 rn = "WatchHi";
4141 break;
4142 default:
4143 goto die;
4145 break;
4146 case 20:
4147 switch (sel) {
4148 case 0:
4149 #if defined(TARGET_MIPS64)
4150 check_insn(env, ctx, ISA_MIPS3);
4151 gen_helper_mtc0_xcontext(arg);
4152 rn = "XContext";
4153 break;
4154 #endif
4155 default:
4156 goto die;
4158 break;
4159 case 21:
4160 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4161 switch (sel) {
4162 case 0:
4163 gen_helper_mtc0_framemask(arg);
4164 rn = "Framemask";
4165 break;
4166 default:
4167 goto die;
4169 break;
4170 case 22:
4171 /* ignored */
4172 rn = "Diagnostic"; /* implementation dependent */
4173 break;
4174 case 23:
4175 switch (sel) {
4176 case 0:
4177 gen_helper_mtc0_debug(arg); /* EJTAG support */
4178 /* BS_STOP isn't good enough here, hflags may have changed. */
4179 gen_save_pc(ctx->pc + 4);
4180 ctx->bstate = BS_EXCP;
4181 rn = "Debug";
4182 break;
4183 case 1:
4184 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
4185 rn = "TraceControl";
4186 /* Stop translation as we may have switched the execution mode */
4187 ctx->bstate = BS_STOP;
4188 // break;
4189 case 2:
4190 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
4191 rn = "TraceControl2";
4192 /* Stop translation as we may have switched the execution mode */
4193 ctx->bstate = BS_STOP;
4194 // break;
4195 case 3:
4196 /* Stop translation as we may have switched the execution mode */
4197 ctx->bstate = BS_STOP;
4198 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
4199 rn = "UserTraceData";
4200 /* Stop translation as we may have switched the execution mode */
4201 ctx->bstate = BS_STOP;
4202 // break;
4203 case 4:
4204 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
4205 /* Stop translation as we may have switched the execution mode */
4206 ctx->bstate = BS_STOP;
4207 rn = "TraceBPC";
4208 // break;
4209 default:
4210 goto die;
4212 break;
4213 case 24:
4214 switch (sel) {
4215 case 0:
4216 /* EJTAG support */
4217 gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
4218 rn = "DEPC";
4219 break;
4220 default:
4221 goto die;
4223 break;
4224 case 25:
4225 switch (sel) {
4226 case 0:
4227 gen_helper_mtc0_performance0(arg);
4228 rn = "Performance0";
4229 break;
4230 case 1:
4231 // gen_helper_mtc0_performance1(arg);
4232 rn = "Performance1";
4233 // break;
4234 case 2:
4235 // gen_helper_mtc0_performance2(arg);
4236 rn = "Performance2";
4237 // break;
4238 case 3:
4239 // gen_helper_mtc0_performance3(arg);
4240 rn = "Performance3";
4241 // break;
4242 case 4:
4243 // gen_helper_mtc0_performance4(arg);
4244 rn = "Performance4";
4245 // break;
4246 case 5:
4247 // gen_helper_mtc0_performance5(arg);
4248 rn = "Performance5";
4249 // break;
4250 case 6:
4251 // gen_helper_mtc0_performance6(arg);
4252 rn = "Performance6";
4253 // break;
4254 case 7:
4255 // gen_helper_mtc0_performance7(arg);
4256 rn = "Performance7";
4257 // break;
4258 default:
4259 goto die;
4261 break;
4262 case 26:
4263 /* ignored */
4264 rn = "ECC";
4265 break;
4266 case 27:
4267 switch (sel) {
4268 case 0 ... 3:
4269 /* ignored */
4270 rn = "CacheErr";
4271 break;
4272 default:
4273 goto die;
4275 break;
4276 case 28:
4277 switch (sel) {
4278 case 0:
4279 case 2:
4280 case 4:
4281 case 6:
4282 gen_helper_mtc0_taglo(arg);
4283 rn = "TagLo";
4284 break;
4285 case 1:
4286 case 3:
4287 case 5:
4288 case 7:
4289 gen_helper_mtc0_datalo(arg);
4290 rn = "DataLo";
4291 break;
4292 default:
4293 goto die;
4295 break;
4296 case 29:
4297 switch (sel) {
4298 case 0:
4299 case 2:
4300 case 4:
4301 case 6:
4302 gen_helper_mtc0_taghi(arg);
4303 rn = "TagHi";
4304 break;
4305 case 1:
4306 case 3:
4307 case 5:
4308 case 7:
4309 gen_helper_mtc0_datahi(arg);
4310 rn = "DataHi";
4311 break;
4312 default:
4313 rn = "invalid sel";
4314 goto die;
4316 break;
4317 case 30:
4318 switch (sel) {
4319 case 0:
4320 gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4321 rn = "ErrorEPC";
4322 break;
4323 default:
4324 goto die;
4326 break;
4327 case 31:
4328 switch (sel) {
4329 case 0:
4330 /* EJTAG support */
4331 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4332 rn = "DESAVE";
4333 break;
4334 default:
4335 goto die;
4337 /* Stop translation as we may have switched the execution mode */
4338 ctx->bstate = BS_STOP;
4339 break;
4340 default:
4341 goto die;
4343 (void)rn; /* avoid a compiler warning */
4344 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4345 /* For simplicity assume that all writes can cause interrupts. */
4346 if (use_icount) {
4347 gen_io_end();
4348 ctx->bstate = BS_STOP;
4350 return;
4352 die:
4353 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4354 generate_exception(ctx, EXCP_RI);
4357 #if defined(TARGET_MIPS64)
4358 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4360 const char *rn = "invalid";
4362 if (sel != 0)
4363 check_insn(env, ctx, ISA_MIPS64);
4365 switch (reg) {
4366 case 0:
4367 switch (sel) {
4368 case 0:
4369 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4370 rn = "Index";
4371 break;
4372 case 1:
4373 check_insn(env, ctx, ASE_MT);
4374 gen_helper_mfc0_mvpcontrol(arg);
4375 rn = "MVPControl";
4376 break;
4377 case 2:
4378 check_insn(env, ctx, ASE_MT);
4379 gen_helper_mfc0_mvpconf0(arg);
4380 rn = "MVPConf0";
4381 break;
4382 case 3:
4383 check_insn(env, ctx, ASE_MT);
4384 gen_helper_mfc0_mvpconf1(arg);
4385 rn = "MVPConf1";
4386 break;
4387 default:
4388 goto die;
4390 break;
4391 case 1:
4392 switch (sel) {
4393 case 0:
4394 gen_helper_mfc0_random(arg);
4395 rn = "Random";
4396 break;
4397 case 1:
4398 check_insn(env, ctx, ASE_MT);
4399 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4400 rn = "VPEControl";
4401 break;
4402 case 2:
4403 check_insn(env, ctx, ASE_MT);
4404 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4405 rn = "VPEConf0";
4406 break;
4407 case 3:
4408 check_insn(env, ctx, ASE_MT);
4409 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4410 rn = "VPEConf1";
4411 break;
4412 case 4:
4413 check_insn(env, ctx, ASE_MT);
4414 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4415 rn = "YQMask";
4416 break;
4417 case 5:
4418 check_insn(env, ctx, ASE_MT);
4419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4420 rn = "VPESchedule";
4421 break;
4422 case 6:
4423 check_insn(env, ctx, ASE_MT);
4424 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4425 rn = "VPEScheFBack";
4426 break;
4427 case 7:
4428 check_insn(env, ctx, ASE_MT);
4429 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4430 rn = "VPEOpt";
4431 break;
4432 default:
4433 goto die;
4435 break;
4436 case 2:
4437 switch (sel) {
4438 case 0:
4439 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4440 rn = "EntryLo0";
4441 break;
4442 case 1:
4443 check_insn(env, ctx, ASE_MT);
4444 gen_helper_mfc0_tcstatus(arg);
4445 rn = "TCStatus";
4446 break;
4447 case 2:
4448 check_insn(env, ctx, ASE_MT);
4449 gen_helper_mfc0_tcbind(arg);
4450 rn = "TCBind";
4451 break;
4452 case 3:
4453 check_insn(env, ctx, ASE_MT);
4454 gen_helper_dmfc0_tcrestart(arg);
4455 rn = "TCRestart";
4456 break;
4457 case 4:
4458 check_insn(env, ctx, ASE_MT);
4459 gen_helper_dmfc0_tchalt(arg);
4460 rn = "TCHalt";
4461 break;
4462 case 5:
4463 check_insn(env, ctx, ASE_MT);
4464 gen_helper_dmfc0_tccontext(arg);
4465 rn = "TCContext";
4466 break;
4467 case 6:
4468 check_insn(env, ctx, ASE_MT);
4469 gen_helper_dmfc0_tcschedule(arg);
4470 rn = "TCSchedule";
4471 break;
4472 case 7:
4473 check_insn(env, ctx, ASE_MT);
4474 gen_helper_dmfc0_tcschefback(arg);
4475 rn = "TCScheFBack";
4476 break;
4477 default:
4478 goto die;
4480 break;
4481 case 3:
4482 switch (sel) {
4483 case 0:
4484 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4485 rn = "EntryLo1";
4486 break;
4487 default:
4488 goto die;
4490 break;
4491 case 4:
4492 switch (sel) {
4493 case 0:
4494 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4495 rn = "Context";
4496 break;
4497 case 1:
4498 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4499 rn = "ContextConfig";
4500 // break;
4501 default:
4502 goto die;
4504 break;
4505 case 5:
4506 switch (sel) {
4507 case 0:
4508 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4509 rn = "PageMask";
4510 break;
4511 case 1:
4512 check_insn(env, ctx, ISA_MIPS32R2);
4513 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4514 rn = "PageGrain";
4515 break;
4516 default:
4517 goto die;
4519 break;
4520 case 6:
4521 switch (sel) {
4522 case 0:
4523 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4524 rn = "Wired";
4525 break;
4526 case 1:
4527 check_insn(env, ctx, ISA_MIPS32R2);
4528 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4529 rn = "SRSConf0";
4530 break;
4531 case 2:
4532 check_insn(env, ctx, ISA_MIPS32R2);
4533 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4534 rn = "SRSConf1";
4535 break;
4536 case 3:
4537 check_insn(env, ctx, ISA_MIPS32R2);
4538 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4539 rn = "SRSConf2";
4540 break;
4541 case 4:
4542 check_insn(env, ctx, ISA_MIPS32R2);
4543 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4544 rn = "SRSConf3";
4545 break;
4546 case 5:
4547 check_insn(env, ctx, ISA_MIPS32R2);
4548 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4549 rn = "SRSConf4";
4550 break;
4551 default:
4552 goto die;
4554 break;
4555 case 7:
4556 switch (sel) {
4557 case 0:
4558 check_insn(env, ctx, ISA_MIPS32R2);
4559 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4560 rn = "HWREna";
4561 break;
4562 default:
4563 goto die;
4565 break;
4566 case 8:
4567 switch (sel) {
4568 case 0:
4569 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4570 rn = "BadVAddr";
4571 break;
4572 default:
4573 goto die;
4575 break;
4576 case 9:
4577 switch (sel) {
4578 case 0:
4579 /* Mark as an IO operation because we read the time. */
4580 if (use_icount)
4581 gen_io_start();
4582 gen_helper_mfc0_count(arg);
4583 if (use_icount) {
4584 gen_io_end();
4586 /* Break the TB to be able to take timer interrupts immediately
4587 after reading count. */
4588 ctx->bstate = BS_STOP;
4589 rn = "Count";
4590 break;
4591 /* 6,7 are implementation dependent */
4592 default:
4593 goto die;
4595 break;
4596 case 10:
4597 switch (sel) {
4598 case 0:
4599 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4600 rn = "EntryHi";
4601 break;
4602 default:
4603 goto die;
4605 break;
4606 case 11:
4607 switch (sel) {
4608 case 0:
4609 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4610 rn = "Compare";
4611 break;
4612 /* 6,7 are implementation dependent */
4613 default:
4614 goto die;
4616 break;
4617 case 12:
4618 switch (sel) {
4619 case 0:
4620 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4621 rn = "Status";
4622 break;
4623 case 1:
4624 check_insn(env, ctx, ISA_MIPS32R2);
4625 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4626 rn = "IntCtl";
4627 break;
4628 case 2:
4629 check_insn(env, ctx, ISA_MIPS32R2);
4630 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4631 rn = "SRSCtl";
4632 break;
4633 case 3:
4634 check_insn(env, ctx, ISA_MIPS32R2);
4635 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4636 rn = "SRSMap";
4637 break;
4638 default:
4639 goto die;
4641 break;
4642 case 13:
4643 switch (sel) {
4644 case 0:
4645 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4646 rn = "Cause";
4647 break;
4648 default:
4649 goto die;
4651 break;
4652 case 14:
4653 switch (sel) {
4654 case 0:
4655 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4656 rn = "EPC";
4657 break;
4658 default:
4659 goto die;
4661 break;
4662 case 15:
4663 switch (sel) {
4664 case 0:
4665 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4666 rn = "PRid";
4667 break;
4668 case 1:
4669 check_insn(env, ctx, ISA_MIPS32R2);
4670 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4671 rn = "EBase";
4672 break;
4673 default:
4674 goto die;
4676 break;
4677 case 16:
4678 switch (sel) {
4679 case 0:
4680 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4681 rn = "Config";
4682 break;
4683 case 1:
4684 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4685 rn = "Config1";
4686 break;
4687 case 2:
4688 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4689 rn = "Config2";
4690 break;
4691 case 3:
4692 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4693 rn = "Config3";
4694 break;
4695 /* 6,7 are implementation dependent */
4696 case 6:
4697 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4698 rn = "Config6";
4699 break;
4700 case 7:
4701 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4702 rn = "Config7";
4703 break;
4704 default:
4705 goto die;
4707 break;
4708 case 17:
4709 switch (sel) {
4710 case 0:
4711 gen_helper_dmfc0_lladdr(arg);
4712 rn = "LLAddr";
4713 break;
4714 default:
4715 goto die;
4717 break;
4718 case 18:
4719 switch (sel) {
4720 case 0 ... 7:
4721 gen_helper_1i(dmfc0_watchlo, arg, sel);
4722 rn = "WatchLo";
4723 break;
4724 default:
4725 goto die;
4727 break;
4728 case 19:
4729 switch (sel) {
4730 case 0 ... 7:
4731 gen_helper_1i(mfc0_watchhi, arg, sel);
4732 rn = "WatchHi";
4733 break;
4734 default:
4735 goto die;
4737 break;
4738 case 20:
4739 switch (sel) {
4740 case 0:
4741 check_insn(env, ctx, ISA_MIPS3);
4742 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4743 rn = "XContext";
4744 break;
4745 default:
4746 goto die;
4748 break;
4749 case 21:
4750 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4751 switch (sel) {
4752 case 0:
4753 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4754 rn = "Framemask";
4755 break;
4756 default:
4757 goto die;
4759 break;
4760 case 22:
4761 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4762 rn = "'Diagnostic"; /* implementation dependent */
4763 break;
4764 case 23:
4765 switch (sel) {
4766 case 0:
4767 gen_helper_mfc0_debug(arg); /* EJTAG support */
4768 rn = "Debug";
4769 break;
4770 case 1:
4771 // gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4772 rn = "TraceControl";
4773 // break;
4774 case 2:
4775 // gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4776 rn = "TraceControl2";
4777 // break;
4778 case 3:
4779 // gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4780 rn = "UserTraceData";
4781 // break;
4782 case 4:
4783 // gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4784 rn = "TraceBPC";
4785 // break;
4786 default:
4787 goto die;
4789 break;
4790 case 24:
4791 switch (sel) {
4792 case 0:
4793 /* EJTAG support */
4794 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4795 rn = "DEPC";
4796 break;
4797 default:
4798 goto die;
4800 break;
4801 case 25:
4802 switch (sel) {
4803 case 0:
4804 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4805 rn = "Performance0";
4806 break;
4807 case 1:
4808 // gen_helper_dmfc0_performance1(arg);
4809 rn = "Performance1";
4810 // break;
4811 case 2:
4812 // gen_helper_dmfc0_performance2(arg);
4813 rn = "Performance2";
4814 // break;
4815 case 3:
4816 // gen_helper_dmfc0_performance3(arg);
4817 rn = "Performance3";
4818 // break;
4819 case 4:
4820 // gen_helper_dmfc0_performance4(arg);
4821 rn = "Performance4";
4822 // break;
4823 case 5:
4824 // gen_helper_dmfc0_performance5(arg);
4825 rn = "Performance5";
4826 // break;
4827 case 6:
4828 // gen_helper_dmfc0_performance6(arg);
4829 rn = "Performance6";
4830 // break;
4831 case 7:
4832 // gen_helper_dmfc0_performance7(arg);
4833 rn = "Performance7";
4834 // break;
4835 default:
4836 goto die;
4838 break;
4839 case 26:
4840 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4841 rn = "ECC";
4842 break;
4843 case 27:
4844 switch (sel) {
4845 /* ignored */
4846 case 0 ... 3:
4847 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4848 rn = "CacheErr";
4849 break;
4850 default:
4851 goto die;
4853 break;
4854 case 28:
4855 switch (sel) {
4856 case 0:
4857 case 2:
4858 case 4:
4859 case 6:
4860 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4861 rn = "TagLo";
4862 break;
4863 case 1:
4864 case 3:
4865 case 5:
4866 case 7:
4867 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4868 rn = "DataLo";
4869 break;
4870 default:
4871 goto die;
4873 break;
4874 case 29:
4875 switch (sel) {
4876 case 0:
4877 case 2:
4878 case 4:
4879 case 6:
4880 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4881 rn = "TagHi";
4882 break;
4883 case 1:
4884 case 3:
4885 case 5:
4886 case 7:
4887 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4888 rn = "DataHi";
4889 break;
4890 default:
4891 goto die;
4893 break;
4894 case 30:
4895 switch (sel) {
4896 case 0:
4897 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4898 rn = "ErrorEPC";
4899 break;
4900 default:
4901 goto die;
4903 break;
4904 case 31:
4905 switch (sel) {
4906 case 0:
4907 /* EJTAG support */
4908 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4909 rn = "DESAVE";
4910 break;
4911 default:
4912 goto die;
4914 break;
4915 default:
4916 goto die;
4918 (void)rn; /* avoid a compiler warning */
4919 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4920 return;
4922 die:
4923 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4924 generate_exception(ctx, EXCP_RI);
4927 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4929 const char *rn = "invalid";
4931 if (sel != 0)
4932 check_insn(env, ctx, ISA_MIPS64);
4934 if (use_icount)
4935 gen_io_start();
4937 switch (reg) {
4938 case 0:
4939 switch (sel) {
4940 case 0:
4941 gen_helper_mtc0_index(arg);
4942 rn = "Index";
4943 break;
4944 case 1:
4945 check_insn(env, ctx, ASE_MT);
4946 gen_helper_mtc0_mvpcontrol(arg);
4947 rn = "MVPControl";
4948 break;
4949 case 2:
4950 check_insn(env, ctx, ASE_MT);
4951 /* ignored */
4952 rn = "MVPConf0";
4953 break;
4954 case 3:
4955 check_insn(env, ctx, ASE_MT);
4956 /* ignored */
4957 rn = "MVPConf1";
4958 break;
4959 default:
4960 goto die;
4962 break;
4963 case 1:
4964 switch (sel) {
4965 case 0:
4966 /* ignored */
4967 rn = "Random";
4968 break;
4969 case 1:
4970 check_insn(env, ctx, ASE_MT);
4971 gen_helper_mtc0_vpecontrol(arg);
4972 rn = "VPEControl";
4973 break;
4974 case 2:
4975 check_insn(env, ctx, ASE_MT);
4976 gen_helper_mtc0_vpeconf0(arg);
4977 rn = "VPEConf0";
4978 break;
4979 case 3:
4980 check_insn(env, ctx, ASE_MT);
4981 gen_helper_mtc0_vpeconf1(arg);
4982 rn = "VPEConf1";
4983 break;
4984 case 4:
4985 check_insn(env, ctx, ASE_MT);
4986 gen_helper_mtc0_yqmask(arg);
4987 rn = "YQMask";
4988 break;
4989 case 5:
4990 check_insn(env, ctx, ASE_MT);
4991 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4992 rn = "VPESchedule";
4993 break;
4994 case 6:
4995 check_insn(env, ctx, ASE_MT);
4996 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4997 rn = "VPEScheFBack";
4998 break;
4999 case 7:
5000 check_insn(env, ctx, ASE_MT);
5001 gen_helper_mtc0_vpeopt(arg);
5002 rn = "VPEOpt";
5003 break;
5004 default:
5005 goto die;
5007 break;
5008 case 2:
5009 switch (sel) {
5010 case 0:
5011 gen_helper_mtc0_entrylo0(arg);
5012 rn = "EntryLo0";
5013 break;
5014 case 1:
5015 check_insn(env, ctx, ASE_MT);
5016 gen_helper_mtc0_tcstatus(arg);
5017 rn = "TCStatus";
5018 break;
5019 case 2:
5020 check_insn(env, ctx, ASE_MT);
5021 gen_helper_mtc0_tcbind(arg);
5022 rn = "TCBind";
5023 break;
5024 case 3:
5025 check_insn(env, ctx, ASE_MT);
5026 gen_helper_mtc0_tcrestart(arg);
5027 rn = "TCRestart";
5028 break;
5029 case 4:
5030 check_insn(env, ctx, ASE_MT);
5031 gen_helper_mtc0_tchalt(arg);
5032 rn = "TCHalt";
5033 break;
5034 case 5:
5035 check_insn(env, ctx, ASE_MT);
5036 gen_helper_mtc0_tccontext(arg);
5037 rn = "TCContext";
5038 break;
5039 case 6:
5040 check_insn(env, ctx, ASE_MT);
5041 gen_helper_mtc0_tcschedule(arg);
5042 rn = "TCSchedule";
5043 break;
5044 case 7:
5045 check_insn(env, ctx, ASE_MT);
5046 gen_helper_mtc0_tcschefback(arg);
5047 rn = "TCScheFBack";
5048 break;
5049 default:
5050 goto die;
5052 break;
5053 case 3:
5054 switch (sel) {
5055 case 0:
5056 gen_helper_mtc0_entrylo1(arg);
5057 rn = "EntryLo1";
5058 break;
5059 default:
5060 goto die;
5062 break;
5063 case 4:
5064 switch (sel) {
5065 case 0:
5066 gen_helper_mtc0_context(arg);
5067 rn = "Context";
5068 break;
5069 case 1:
5070 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
5071 rn = "ContextConfig";
5072 // break;
5073 default:
5074 goto die;
5076 break;
5077 case 5:
5078 switch (sel) {
5079 case 0:
5080 gen_helper_mtc0_pagemask(arg);
5081 rn = "PageMask";
5082 break;
5083 case 1:
5084 check_insn(env, ctx, ISA_MIPS32R2);
5085 gen_helper_mtc0_pagegrain(arg);
5086 rn = "PageGrain";
5087 break;
5088 default:
5089 goto die;
5091 break;
5092 case 6:
5093 switch (sel) {
5094 case 0:
5095 gen_helper_mtc0_wired(arg);
5096 rn = "Wired";
5097 break;
5098 case 1:
5099 check_insn(env, ctx, ISA_MIPS32R2);
5100 gen_helper_mtc0_srsconf0(arg);
5101 rn = "SRSConf0";
5102 break;
5103 case 2:
5104 check_insn(env, ctx, ISA_MIPS32R2);
5105 gen_helper_mtc0_srsconf1(arg);
5106 rn = "SRSConf1";
5107 break;
5108 case 3:
5109 check_insn(env, ctx, ISA_MIPS32R2);
5110 gen_helper_mtc0_srsconf2(arg);
5111 rn = "SRSConf2";
5112 break;
5113 case 4:
5114 check_insn(env, ctx, ISA_MIPS32R2);
5115 gen_helper_mtc0_srsconf3(arg);
5116 rn = "SRSConf3";
5117 break;
5118 case 5:
5119 check_insn(env, ctx, ISA_MIPS32R2);
5120 gen_helper_mtc0_srsconf4(arg);
5121 rn = "SRSConf4";
5122 break;
5123 default:
5124 goto die;
5126 break;
5127 case 7:
5128 switch (sel) {
5129 case 0:
5130 check_insn(env, ctx, ISA_MIPS32R2);
5131 gen_helper_mtc0_hwrena(arg);
5132 rn = "HWREna";
5133 break;
5134 default:
5135 goto die;
5137 break;
5138 case 8:
5139 /* ignored */
5140 rn = "BadVAddr";
5141 break;
5142 case 9:
5143 switch (sel) {
5144 case 0:
5145 gen_helper_mtc0_count(arg);
5146 rn = "Count";
5147 break;
5148 /* 6,7 are implementation dependent */
5149 default:
5150 goto die;
5152 /* Stop translation as we may have switched the execution mode */
5153 ctx->bstate = BS_STOP;
5154 break;
5155 case 10:
5156 switch (sel) {
5157 case 0:
5158 gen_helper_mtc0_entryhi(arg);
5159 rn = "EntryHi";
5160 break;
5161 default:
5162 goto die;
5164 break;
5165 case 11:
5166 switch (sel) {
5167 case 0:
5168 gen_helper_mtc0_compare(arg);
5169 rn = "Compare";
5170 break;
5171 /* 6,7 are implementation dependent */
5172 default:
5173 goto die;
5175 /* Stop translation as we may have switched the execution mode */
5176 ctx->bstate = BS_STOP;
5177 break;
5178 case 12:
5179 switch (sel) {
5180 case 0:
5181 save_cpu_state(ctx, 1);
5182 gen_helper_mtc0_status(arg);
5183 /* BS_STOP isn't good enough here, hflags may have changed. */
5184 gen_save_pc(ctx->pc + 4);
5185 ctx->bstate = BS_EXCP;
5186 rn = "Status";
5187 break;
5188 case 1:
5189 check_insn(env, ctx, ISA_MIPS32R2);
5190 gen_helper_mtc0_intctl(arg);
5191 /* Stop translation as we may have switched the execution mode */
5192 ctx->bstate = BS_STOP;
5193 rn = "IntCtl";
5194 break;
5195 case 2:
5196 check_insn(env, ctx, ISA_MIPS32R2);
5197 gen_helper_mtc0_srsctl(arg);
5198 /* Stop translation as we may have switched the execution mode */
5199 ctx->bstate = BS_STOP;
5200 rn = "SRSCtl";
5201 break;
5202 case 3:
5203 check_insn(env, ctx, ISA_MIPS32R2);
5204 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
5205 /* Stop translation as we may have switched the execution mode */
5206 ctx->bstate = BS_STOP;
5207 rn = "SRSMap";
5208 break;
5209 default:
5210 goto die;
5212 break;
5213 case 13:
5214 switch (sel) {
5215 case 0:
5216 save_cpu_state(ctx, 1);
5217 /* Mark as an IO operation because we may trigger a software
5218 interrupt. */
5219 if (use_icount) {
5220 gen_io_start();
5222 gen_helper_mtc0_cause(arg);
5223 if (use_icount) {
5224 gen_io_end();
5226 /* Stop translation as we may have triggered an intetrupt */
5227 ctx->bstate = BS_STOP;
5228 rn = "Cause";
5229 break;
5230 default:
5231 goto die;
5233 break;
5234 case 14:
5235 switch (sel) {
5236 case 0:
5237 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
5238 rn = "EPC";
5239 break;
5240 default:
5241 goto die;
5243 break;
5244 case 15:
5245 switch (sel) {
5246 case 0:
5247 /* ignored */
5248 rn = "PRid";
5249 break;
5250 case 1:
5251 check_insn(env, ctx, ISA_MIPS32R2);
5252 gen_helper_mtc0_ebase(arg);
5253 rn = "EBase";
5254 break;
5255 default:
5256 goto die;
5258 break;
5259 case 16:
5260 switch (sel) {
5261 case 0:
5262 gen_helper_mtc0_config0(arg);
5263 rn = "Config";
5264 /* Stop translation as we may have switched the execution mode */
5265 ctx->bstate = BS_STOP;
5266 break;
5267 case 1:
5268 /* ignored, read only */
5269 rn = "Config1";
5270 break;
5271 case 2:
5272 gen_helper_mtc0_config2(arg);
5273 rn = "Config2";
5274 /* Stop translation as we may have switched the execution mode */
5275 ctx->bstate = BS_STOP;
5276 break;
5277 case 3:
5278 /* ignored */
5279 rn = "Config3";
5280 break;
5281 /* 6,7 are implementation dependent */
5282 default:
5283 rn = "Invalid config selector";
5284 goto die;
5286 break;
5287 case 17:
5288 switch (sel) {
5289 case 0:
5290 gen_helper_mtc0_lladdr(arg);
5291 rn = "LLAddr";
5292 break;
5293 default:
5294 goto die;
5296 break;
5297 case 18:
5298 switch (sel) {
5299 case 0 ... 7:
5300 gen_helper_1i(mtc0_watchlo, arg, sel);
5301 rn = "WatchLo";
5302 break;
5303 default:
5304 goto die;
5306 break;
5307 case 19:
5308 switch (sel) {
5309 case 0 ... 7:
5310 gen_helper_1i(mtc0_watchhi, arg, sel);
5311 rn = "WatchHi";
5312 break;
5313 default:
5314 goto die;
5316 break;
5317 case 20:
5318 switch (sel) {
5319 case 0:
5320 check_insn(env, ctx, ISA_MIPS3);
5321 gen_helper_mtc0_xcontext(arg);
5322 rn = "XContext";
5323 break;
5324 default:
5325 goto die;
5327 break;
5328 case 21:
5329 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5330 switch (sel) {
5331 case 0:
5332 gen_helper_mtc0_framemask(arg);
5333 rn = "Framemask";
5334 break;
5335 default:
5336 goto die;
5338 break;
5339 case 22:
5340 /* ignored */
5341 rn = "Diagnostic"; /* implementation dependent */
5342 break;
5343 case 23:
5344 switch (sel) {
5345 case 0:
5346 gen_helper_mtc0_debug(arg); /* EJTAG support */
5347 /* BS_STOP isn't good enough here, hflags may have changed. */
5348 gen_save_pc(ctx->pc + 4);
5349 ctx->bstate = BS_EXCP;
5350 rn = "Debug";
5351 break;
5352 case 1:
5353 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5354 /* Stop translation as we may have switched the execution mode */
5355 ctx->bstate = BS_STOP;
5356 rn = "TraceControl";
5357 // break;
5358 case 2:
5359 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5360 /* Stop translation as we may have switched the execution mode */
5361 ctx->bstate = BS_STOP;
5362 rn = "TraceControl2";
5363 // break;
5364 case 3:
5365 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5366 /* Stop translation as we may have switched the execution mode */
5367 ctx->bstate = BS_STOP;
5368 rn = "UserTraceData";
5369 // break;
5370 case 4:
5371 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5372 /* Stop translation as we may have switched the execution mode */
5373 ctx->bstate = BS_STOP;
5374 rn = "TraceBPC";
5375 // break;
5376 default:
5377 goto die;
5379 break;
5380 case 24:
5381 switch (sel) {
5382 case 0:
5383 /* EJTAG support */
5384 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5385 rn = "DEPC";
5386 break;
5387 default:
5388 goto die;
5390 break;
5391 case 25:
5392 switch (sel) {
5393 case 0:
5394 gen_helper_mtc0_performance0(arg);
5395 rn = "Performance0";
5396 break;
5397 case 1:
5398 // gen_helper_mtc0_performance1(arg);
5399 rn = "Performance1";
5400 // break;
5401 case 2:
5402 // gen_helper_mtc0_performance2(arg);
5403 rn = "Performance2";
5404 // break;
5405 case 3:
5406 // gen_helper_mtc0_performance3(arg);
5407 rn = "Performance3";
5408 // break;
5409 case 4:
5410 // gen_helper_mtc0_performance4(arg);
5411 rn = "Performance4";
5412 // break;
5413 case 5:
5414 // gen_helper_mtc0_performance5(arg);
5415 rn = "Performance5";
5416 // break;
5417 case 6:
5418 // gen_helper_mtc0_performance6(arg);
5419 rn = "Performance6";
5420 // break;
5421 case 7:
5422 // gen_helper_mtc0_performance7(arg);
5423 rn = "Performance7";
5424 // break;
5425 default:
5426 goto die;
5428 break;
5429 case 26:
5430 /* ignored */
5431 rn = "ECC";
5432 break;
5433 case 27:
5434 switch (sel) {
5435 case 0 ... 3:
5436 /* ignored */
5437 rn = "CacheErr";
5438 break;
5439 default:
5440 goto die;
5442 break;
5443 case 28:
5444 switch (sel) {
5445 case 0:
5446 case 2:
5447 case 4:
5448 case 6:
5449 gen_helper_mtc0_taglo(arg);
5450 rn = "TagLo";
5451 break;
5452 case 1:
5453 case 3:
5454 case 5:
5455 case 7:
5456 gen_helper_mtc0_datalo(arg);
5457 rn = "DataLo";
5458 break;
5459 default:
5460 goto die;
5462 break;
5463 case 29:
5464 switch (sel) {
5465 case 0:
5466 case 2:
5467 case 4:
5468 case 6:
5469 gen_helper_mtc0_taghi(arg);
5470 rn = "TagHi";
5471 break;
5472 case 1:
5473 case 3:
5474 case 5:
5475 case 7:
5476 gen_helper_mtc0_datahi(arg);
5477 rn = "DataHi";
5478 break;
5479 default:
5480 rn = "invalid sel";
5481 goto die;
5483 break;
5484 case 30:
5485 switch (sel) {
5486 case 0:
5487 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5488 rn = "ErrorEPC";
5489 break;
5490 default:
5491 goto die;
5493 break;
5494 case 31:
5495 switch (sel) {
5496 case 0:
5497 /* EJTAG support */
5498 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5499 rn = "DESAVE";
5500 break;
5501 default:
5502 goto die;
5504 /* Stop translation as we may have switched the execution mode */
5505 ctx->bstate = BS_STOP;
5506 break;
5507 default:
5508 goto die;
5510 (void)rn; /* avoid a compiler warning */
5511 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5512 /* For simplicity assume that all writes can cause interrupts. */
5513 if (use_icount) {
5514 gen_io_end();
5515 ctx->bstate = BS_STOP;
5517 return;
5519 die:
5520 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5521 generate_exception(ctx, EXCP_RI);
5523 #endif /* TARGET_MIPS64 */
5525 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5526 int u, int sel, int h)
5528 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5529 TCGv t0 = tcg_temp_local_new();
5531 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5532 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5533 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5534 tcg_gen_movi_tl(t0, -1);
5535 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5536 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5537 tcg_gen_movi_tl(t0, -1);
5538 else if (u == 0) {
5539 switch (rt) {
5540 case 1:
5541 switch (sel) {
5542 case 1:
5543 gen_helper_mftc0_vpecontrol(t0);
5544 break;
5545 case 2:
5546 gen_helper_mftc0_vpeconf0(t0);
5547 break;
5548 default:
5549 goto die;
5550 break;
5552 break;
5553 case 2:
5554 switch (sel) {
5555 case 1:
5556 gen_helper_mftc0_tcstatus(t0);
5557 break;
5558 case 2:
5559 gen_helper_mftc0_tcbind(t0);
5560 break;
5561 case 3:
5562 gen_helper_mftc0_tcrestart(t0);
5563 break;
5564 case 4:
5565 gen_helper_mftc0_tchalt(t0);
5566 break;
5567 case 5:
5568 gen_helper_mftc0_tccontext(t0);
5569 break;
5570 case 6:
5571 gen_helper_mftc0_tcschedule(t0);
5572 break;
5573 case 7:
5574 gen_helper_mftc0_tcschefback(t0);
5575 break;
5576 default:
5577 gen_mfc0(env, ctx, t0, rt, sel);
5578 break;
5580 break;
5581 case 10:
5582 switch (sel) {
5583 case 0:
5584 gen_helper_mftc0_entryhi(t0);
5585 break;
5586 default:
5587 gen_mfc0(env, ctx, t0, rt, sel);
5588 break;
5590 case 12:
5591 switch (sel) {
5592 case 0:
5593 gen_helper_mftc0_status(t0);
5594 break;
5595 default:
5596 gen_mfc0(env, ctx, t0, rt, sel);
5597 break;
5599 case 13:
5600 switch (sel) {
5601 case 0:
5602 gen_helper_mftc0_cause(t0);
5603 break;
5604 default:
5605 goto die;
5606 break;
5608 break;
5609 case 14:
5610 switch (sel) {
5611 case 0:
5612 gen_helper_mftc0_epc(t0);
5613 break;
5614 default:
5615 goto die;
5616 break;
5618 break;
5619 case 15:
5620 switch (sel) {
5621 case 1:
5622 gen_helper_mftc0_ebase(t0);
5623 break;
5624 default:
5625 goto die;
5626 break;
5628 break;
5629 case 16:
5630 switch (sel) {
5631 case 0 ... 7:
5632 gen_helper_mftc0_configx(t0, tcg_const_tl(sel));
5633 break;
5634 default:
5635 goto die;
5636 break;
5638 break;
5639 case 23:
5640 switch (sel) {
5641 case 0:
5642 gen_helper_mftc0_debug(t0);
5643 break;
5644 default:
5645 gen_mfc0(env, ctx, t0, rt, sel);
5646 break;
5648 break;
5649 default:
5650 gen_mfc0(env, ctx, t0, rt, sel);
5652 } else switch (sel) {
5653 /* GPR registers. */
5654 case 0:
5655 gen_helper_1i(mftgpr, t0, rt);
5656 break;
5657 /* Auxiliary CPU registers */
5658 case 1:
5659 switch (rt) {
5660 case 0:
5661 gen_helper_1i(mftlo, t0, 0);
5662 break;
5663 case 1:
5664 gen_helper_1i(mfthi, t0, 0);
5665 break;
5666 case 2:
5667 gen_helper_1i(mftacx, t0, 0);
5668 break;
5669 case 4:
5670 gen_helper_1i(mftlo, t0, 1);
5671 break;
5672 case 5:
5673 gen_helper_1i(mfthi, t0, 1);
5674 break;
5675 case 6:
5676 gen_helper_1i(mftacx, t0, 1);
5677 break;
5678 case 8:
5679 gen_helper_1i(mftlo, t0, 2);
5680 break;
5681 case 9:
5682 gen_helper_1i(mfthi, t0, 2);
5683 break;
5684 case 10:
5685 gen_helper_1i(mftacx, t0, 2);
5686 break;
5687 case 12:
5688 gen_helper_1i(mftlo, t0, 3);
5689 break;
5690 case 13:
5691 gen_helper_1i(mfthi, t0, 3);
5692 break;
5693 case 14:
5694 gen_helper_1i(mftacx, t0, 3);
5695 break;
5696 case 16:
5697 gen_helper_mftdsp(t0);
5698 break;
5699 default:
5700 goto die;
5702 break;
5703 /* Floating point (COP1). */
5704 case 2:
5705 /* XXX: For now we support only a single FPU context. */
5706 if (h == 0) {
5707 TCGv_i32 fp0 = tcg_temp_new_i32();
5709 gen_load_fpr32(fp0, rt);
5710 tcg_gen_ext_i32_tl(t0, fp0);
5711 tcg_temp_free_i32(fp0);
5712 } else {
5713 TCGv_i32 fp0 = tcg_temp_new_i32();
5715 gen_load_fpr32h(fp0, rt);
5716 tcg_gen_ext_i32_tl(t0, fp0);
5717 tcg_temp_free_i32(fp0);
5719 break;
5720 case 3:
5721 /* XXX: For now we support only a single FPU context. */
5722 gen_helper_1i(cfc1, t0, rt);
5723 break;
5724 /* COP2: Not implemented. */
5725 case 4:
5726 case 5:
5727 /* fall through */
5728 default:
5729 goto die;
5731 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5732 gen_store_gpr(t0, rd);
5733 tcg_temp_free(t0);
5734 return;
5736 die:
5737 tcg_temp_free(t0);
5738 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5739 generate_exception(ctx, EXCP_RI);
5742 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5743 int u, int sel, int h)
5745 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5746 TCGv t0 = tcg_temp_local_new();
5748 gen_load_gpr(t0, rt);
5749 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5750 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5751 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5752 /* NOP */ ;
5753 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5754 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5755 /* NOP */ ;
5756 else if (u == 0) {
5757 switch (rd) {
5758 case 1:
5759 switch (sel) {
5760 case 1:
5761 gen_helper_mttc0_vpecontrol(t0);
5762 break;
5763 case 2:
5764 gen_helper_mttc0_vpeconf0(t0);
5765 break;
5766 default:
5767 goto die;
5768 break;
5770 break;
5771 case 2:
5772 switch (sel) {
5773 case 1:
5774 gen_helper_mttc0_tcstatus(t0);
5775 break;
5776 case 2:
5777 gen_helper_mttc0_tcbind(t0);
5778 break;
5779 case 3:
5780 gen_helper_mttc0_tcrestart(t0);
5781 break;
5782 case 4:
5783 gen_helper_mttc0_tchalt(t0);
5784 break;
5785 case 5:
5786 gen_helper_mttc0_tccontext(t0);
5787 break;
5788 case 6:
5789 gen_helper_mttc0_tcschedule(t0);
5790 break;
5791 case 7:
5792 gen_helper_mttc0_tcschefback(t0);
5793 break;
5794 default:
5795 gen_mtc0(env, ctx, t0, rd, sel);
5796 break;
5798 break;
5799 case 10:
5800 switch (sel) {
5801 case 0:
5802 gen_helper_mttc0_entryhi(t0);
5803 break;
5804 default:
5805 gen_mtc0(env, ctx, t0, rd, sel);
5806 break;
5808 case 12:
5809 switch (sel) {
5810 case 0:
5811 gen_helper_mttc0_status(t0);
5812 break;
5813 default:
5814 gen_mtc0(env, ctx, t0, rd, sel);
5815 break;
5817 case 13:
5818 switch (sel) {
5819 case 0:
5820 gen_helper_mttc0_cause(t0);
5821 break;
5822 default:
5823 goto die;
5824 break;
5826 break;
5827 case 15:
5828 switch (sel) {
5829 case 1:
5830 gen_helper_mttc0_ebase(t0);
5831 break;
5832 default:
5833 goto die;
5834 break;
5836 break;
5837 case 23:
5838 switch (sel) {
5839 case 0:
5840 gen_helper_mttc0_debug(t0);
5841 break;
5842 default:
5843 gen_mtc0(env, ctx, t0, rd, sel);
5844 break;
5846 break;
5847 default:
5848 gen_mtc0(env, ctx, t0, rd, sel);
5850 } else switch (sel) {
5851 /* GPR registers. */
5852 case 0:
5853 gen_helper_1i(mttgpr, t0, rd);
5854 break;
5855 /* Auxiliary CPU registers */
5856 case 1:
5857 switch (rd) {
5858 case 0:
5859 gen_helper_1i(mttlo, t0, 0);
5860 break;
5861 case 1:
5862 gen_helper_1i(mtthi, t0, 0);
5863 break;
5864 case 2:
5865 gen_helper_1i(mttacx, t0, 0);
5866 break;
5867 case 4:
5868 gen_helper_1i(mttlo, t0, 1);
5869 break;
5870 case 5:
5871 gen_helper_1i(mtthi, t0, 1);
5872 break;
5873 case 6:
5874 gen_helper_1i(mttacx, t0, 1);
5875 break;
5876 case 8:
5877 gen_helper_1i(mttlo, t0, 2);
5878 break;
5879 case 9:
5880 gen_helper_1i(mtthi, t0, 2);
5881 break;
5882 case 10:
5883 gen_helper_1i(mttacx, t0, 2);
5884 break;
5885 case 12:
5886 gen_helper_1i(mttlo, t0, 3);
5887 break;
5888 case 13:
5889 gen_helper_1i(mtthi, t0, 3);
5890 break;
5891 case 14:
5892 gen_helper_1i(mttacx, t0, 3);
5893 break;
5894 case 16:
5895 gen_helper_mttdsp(t0);
5896 break;
5897 default:
5898 goto die;
5900 break;
5901 /* Floating point (COP1). */
5902 case 2:
5903 /* XXX: For now we support only a single FPU context. */
5904 if (h == 0) {
5905 TCGv_i32 fp0 = tcg_temp_new_i32();
5907 tcg_gen_trunc_tl_i32(fp0, t0);
5908 gen_store_fpr32(fp0, rd);
5909 tcg_temp_free_i32(fp0);
5910 } else {
5911 TCGv_i32 fp0 = tcg_temp_new_i32();
5913 tcg_gen_trunc_tl_i32(fp0, t0);
5914 gen_store_fpr32h(fp0, rd);
5915 tcg_temp_free_i32(fp0);
5917 break;
5918 case 3:
5919 /* XXX: For now we support only a single FPU context. */
5920 gen_helper_1i(ctc1, t0, rd);
5921 break;
5922 /* COP2: Not implemented. */
5923 case 4:
5924 case 5:
5925 /* fall through */
5926 default:
5927 goto die;
5929 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5930 tcg_temp_free(t0);
5931 return;
5933 die:
5934 tcg_temp_free(t0);
5935 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5936 generate_exception(ctx, EXCP_RI);
5939 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5941 const char *opn = "ldst";
5943 switch (opc) {
5944 case OPC_MFC0:
5945 if (rt == 0) {
5946 /* Treat as NOP. */
5947 return;
5949 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5950 opn = "mfc0";
5951 break;
5952 case OPC_MTC0:
5954 TCGv t0 = tcg_temp_new();
5956 gen_load_gpr(t0, rt);
5957 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5958 tcg_temp_free(t0);
5960 opn = "mtc0";
5961 break;
5962 #if defined(TARGET_MIPS64)
5963 case OPC_DMFC0:
5964 check_insn(env, ctx, ISA_MIPS3);
5965 if (rt == 0) {
5966 /* Treat as NOP. */
5967 return;
5969 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5970 opn = "dmfc0";
5971 break;
5972 case OPC_DMTC0:
5973 check_insn(env, ctx, ISA_MIPS3);
5975 TCGv t0 = tcg_temp_new();
5977 gen_load_gpr(t0, rt);
5978 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5979 tcg_temp_free(t0);
5981 opn = "dmtc0";
5982 break;
5983 #endif
5984 case OPC_MFTR:
5985 check_insn(env, ctx, ASE_MT);
5986 if (rd == 0) {
5987 /* Treat as NOP. */
5988 return;
5990 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5991 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5992 opn = "mftr";
5993 break;
5994 case OPC_MTTR:
5995 check_insn(env, ctx, ASE_MT);
5996 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5997 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5998 opn = "mttr";
5999 break;
6000 case OPC_TLBWI:
6001 opn = "tlbwi";
6002 if (!env->tlb->helper_tlbwi)
6003 goto die;
6004 gen_helper_tlbwi();
6005 break;
6006 case OPC_TLBWR:
6007 opn = "tlbwr";
6008 if (!env->tlb->helper_tlbwr)
6009 goto die;
6010 gen_helper_tlbwr();
6011 break;
6012 case OPC_TLBP:
6013 opn = "tlbp";
6014 if (!env->tlb->helper_tlbp)
6015 goto die;
6016 gen_helper_tlbp();
6017 break;
6018 case OPC_TLBR:
6019 opn = "tlbr";
6020 if (!env->tlb->helper_tlbr)
6021 goto die;
6022 gen_helper_tlbr();
6023 break;
6024 case OPC_ERET:
6025 opn = "eret";
6026 check_insn(env, ctx, ISA_MIPS2);
6027 gen_helper_eret();
6028 ctx->bstate = BS_EXCP;
6029 break;
6030 case OPC_DERET:
6031 opn = "deret";
6032 check_insn(env, ctx, ISA_MIPS32);
6033 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6034 MIPS_INVAL(opn);
6035 generate_exception(ctx, EXCP_RI);
6036 } else {
6037 gen_helper_deret();
6038 ctx->bstate = BS_EXCP;
6040 break;
6041 case OPC_WAIT:
6042 opn = "wait";
6043 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6044 /* If we get an exception, we want to restart at next instruction */
6045 ctx->pc += 4;
6046 save_cpu_state(ctx, 1);
6047 ctx->pc -= 4;
6048 gen_helper_wait();
6049 ctx->bstate = BS_EXCP;
6050 break;
6051 default:
6052 die:
6053 MIPS_INVAL(opn);
6054 generate_exception(ctx, EXCP_RI);
6055 return;
6057 (void)opn; /* avoid a compiler warning */
6058 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6060 #endif /* !CONFIG_USER_ONLY */
6062 /* CP1 Branches (before delay slot) */
6063 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
6064 int32_t cc, int32_t offset)
6066 target_ulong btarget;
6067 const char *opn = "cp1 cond branch";
6068 TCGv_i32 t0 = tcg_temp_new_i32();
6070 if (cc != 0)
6071 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6073 btarget = ctx->pc + 4 + offset;
6075 switch (op) {
6076 case OPC_BC1F:
6077 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6078 tcg_gen_not_i32(t0, t0);
6079 tcg_gen_andi_i32(t0, t0, 1);
6080 tcg_gen_extu_i32_tl(bcond, t0);
6081 opn = "bc1f";
6082 goto not_likely;
6083 case OPC_BC1FL:
6084 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6085 tcg_gen_not_i32(t0, t0);
6086 tcg_gen_andi_i32(t0, t0, 1);
6087 tcg_gen_extu_i32_tl(bcond, t0);
6088 opn = "bc1fl";
6089 goto likely;
6090 case OPC_BC1T:
6091 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6092 tcg_gen_andi_i32(t0, t0, 1);
6093 tcg_gen_extu_i32_tl(bcond, t0);
6094 opn = "bc1t";
6095 goto not_likely;
6096 case OPC_BC1TL:
6097 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6098 tcg_gen_andi_i32(t0, t0, 1);
6099 tcg_gen_extu_i32_tl(bcond, t0);
6100 opn = "bc1tl";
6101 likely:
6102 ctx->hflags |= MIPS_HFLAG_BL;
6103 break;
6104 case OPC_BC1FANY2:
6106 TCGv_i32 t1 = tcg_temp_new_i32();
6107 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6108 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6109 tcg_gen_nor_i32(t0, t0, t1);
6110 tcg_temp_free_i32(t1);
6111 tcg_gen_andi_i32(t0, t0, 1);
6112 tcg_gen_extu_i32_tl(bcond, t0);
6114 opn = "bc1any2f";
6115 goto not_likely;
6116 case OPC_BC1TANY2:
6118 TCGv_i32 t1 = tcg_temp_new_i32();
6119 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6120 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6121 tcg_gen_or_i32(t0, t0, t1);
6122 tcg_temp_free_i32(t1);
6123 tcg_gen_andi_i32(t0, t0, 1);
6124 tcg_gen_extu_i32_tl(bcond, t0);
6126 opn = "bc1any2t";
6127 goto not_likely;
6128 case OPC_BC1FANY4:
6130 TCGv_i32 t1 = tcg_temp_new_i32();
6131 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6132 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6133 tcg_gen_or_i32(t0, t0, t1);
6134 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6135 tcg_gen_or_i32(t0, t0, t1);
6136 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6137 tcg_gen_nor_i32(t0, t0, t1);
6138 tcg_temp_free_i32(t1);
6139 tcg_gen_andi_i32(t0, t0, 1);
6140 tcg_gen_extu_i32_tl(bcond, t0);
6142 opn = "bc1any4f";
6143 goto not_likely;
6144 case OPC_BC1TANY4:
6146 TCGv_i32 t1 = tcg_temp_new_i32();
6147 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6148 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6149 tcg_gen_or_i32(t0, t0, t1);
6150 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6151 tcg_gen_or_i32(t0, t0, t1);
6152 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6153 tcg_gen_or_i32(t0, t0, t1);
6154 tcg_temp_free_i32(t1);
6155 tcg_gen_andi_i32(t0, t0, 1);
6156 tcg_gen_extu_i32_tl(bcond, t0);
6158 opn = "bc1any4t";
6159 not_likely:
6160 ctx->hflags |= MIPS_HFLAG_BC;
6161 break;
6162 default:
6163 MIPS_INVAL(opn);
6164 generate_exception (ctx, EXCP_RI);
6165 goto out;
6167 (void)opn; /* avoid a compiler warning */
6168 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6169 ctx->hflags, btarget);
6170 ctx->btarget = btarget;
6172 out:
6173 tcg_temp_free_i32(t0);
6176 /* Coprocessor 1 (FPU) */
6178 #define FOP(func, fmt) (((fmt) << 21) | (func))
6180 enum fopcode {
6181 OPC_ADD_S = FOP(0, FMT_S),
6182 OPC_SUB_S = FOP(1, FMT_S),
6183 OPC_MUL_S = FOP(2, FMT_S),
6184 OPC_DIV_S = FOP(3, FMT_S),
6185 OPC_SQRT_S = FOP(4, FMT_S),
6186 OPC_ABS_S = FOP(5, FMT_S),
6187 OPC_MOV_S = FOP(6, FMT_S),
6188 OPC_NEG_S = FOP(7, FMT_S),
6189 OPC_ROUND_L_S = FOP(8, FMT_S),
6190 OPC_TRUNC_L_S = FOP(9, FMT_S),
6191 OPC_CEIL_L_S = FOP(10, FMT_S),
6192 OPC_FLOOR_L_S = FOP(11, FMT_S),
6193 OPC_ROUND_W_S = FOP(12, FMT_S),
6194 OPC_TRUNC_W_S = FOP(13, FMT_S),
6195 OPC_CEIL_W_S = FOP(14, FMT_S),
6196 OPC_FLOOR_W_S = FOP(15, FMT_S),
6197 OPC_MOVCF_S = FOP(17, FMT_S),
6198 OPC_MOVZ_S = FOP(18, FMT_S),
6199 OPC_MOVN_S = FOP(19, FMT_S),
6200 OPC_RECIP_S = FOP(21, FMT_S),
6201 OPC_RSQRT_S = FOP(22, FMT_S),
6202 OPC_RECIP2_S = FOP(28, FMT_S),
6203 OPC_RECIP1_S = FOP(29, FMT_S),
6204 OPC_RSQRT1_S = FOP(30, FMT_S),
6205 OPC_RSQRT2_S = FOP(31, FMT_S),
6206 OPC_CVT_D_S = FOP(33, FMT_S),
6207 OPC_CVT_W_S = FOP(36, FMT_S),
6208 OPC_CVT_L_S = FOP(37, FMT_S),
6209 OPC_CVT_PS_S = FOP(38, FMT_S),
6210 OPC_CMP_F_S = FOP (48, FMT_S),
6211 OPC_CMP_UN_S = FOP (49, FMT_S),
6212 OPC_CMP_EQ_S = FOP (50, FMT_S),
6213 OPC_CMP_UEQ_S = FOP (51, FMT_S),
6214 OPC_CMP_OLT_S = FOP (52, FMT_S),
6215 OPC_CMP_ULT_S = FOP (53, FMT_S),
6216 OPC_CMP_OLE_S = FOP (54, FMT_S),
6217 OPC_CMP_ULE_S = FOP (55, FMT_S),
6218 OPC_CMP_SF_S = FOP (56, FMT_S),
6219 OPC_CMP_NGLE_S = FOP (57, FMT_S),
6220 OPC_CMP_SEQ_S = FOP (58, FMT_S),
6221 OPC_CMP_NGL_S = FOP (59, FMT_S),
6222 OPC_CMP_LT_S = FOP (60, FMT_S),
6223 OPC_CMP_NGE_S = FOP (61, FMT_S),
6224 OPC_CMP_LE_S = FOP (62, FMT_S),
6225 OPC_CMP_NGT_S = FOP (63, FMT_S),
6227 OPC_ADD_D = FOP(0, FMT_D),
6228 OPC_SUB_D = FOP(1, FMT_D),
6229 OPC_MUL_D = FOP(2, FMT_D),
6230 OPC_DIV_D = FOP(3, FMT_D),
6231 OPC_SQRT_D = FOP(4, FMT_D),
6232 OPC_ABS_D = FOP(5, FMT_D),
6233 OPC_MOV_D = FOP(6, FMT_D),
6234 OPC_NEG_D = FOP(7, FMT_D),
6235 OPC_ROUND_L_D = FOP(8, FMT_D),
6236 OPC_TRUNC_L_D = FOP(9, FMT_D),
6237 OPC_CEIL_L_D = FOP(10, FMT_D),
6238 OPC_FLOOR_L_D = FOP(11, FMT_D),
6239 OPC_ROUND_W_D = FOP(12, FMT_D),
6240 OPC_TRUNC_W_D = FOP(13, FMT_D),
6241 OPC_CEIL_W_D = FOP(14, FMT_D),
6242 OPC_FLOOR_W_D = FOP(15, FMT_D),
6243 OPC_MOVCF_D = FOP(17, FMT_D),
6244 OPC_MOVZ_D = FOP(18, FMT_D),
6245 OPC_MOVN_D = FOP(19, FMT_D),
6246 OPC_RECIP_D = FOP(21, FMT_D),
6247 OPC_RSQRT_D = FOP(22, FMT_D),
6248 OPC_RECIP2_D = FOP(28, FMT_D),
6249 OPC_RECIP1_D = FOP(29, FMT_D),
6250 OPC_RSQRT1_D = FOP(30, FMT_D),
6251 OPC_RSQRT2_D = FOP(31, FMT_D),
6252 OPC_CVT_S_D = FOP(32, FMT_D),
6253 OPC_CVT_W_D = FOP(36, FMT_D),
6254 OPC_CVT_L_D = FOP(37, FMT_D),
6255 OPC_CMP_F_D = FOP (48, FMT_D),
6256 OPC_CMP_UN_D = FOP (49, FMT_D),
6257 OPC_CMP_EQ_D = FOP (50, FMT_D),
6258 OPC_CMP_UEQ_D = FOP (51, FMT_D),
6259 OPC_CMP_OLT_D = FOP (52, FMT_D),
6260 OPC_CMP_ULT_D = FOP (53, FMT_D),
6261 OPC_CMP_OLE_D = FOP (54, FMT_D),
6262 OPC_CMP_ULE_D = FOP (55, FMT_D),
6263 OPC_CMP_SF_D = FOP (56, FMT_D),
6264 OPC_CMP_NGLE_D = FOP (57, FMT_D),
6265 OPC_CMP_SEQ_D = FOP (58, FMT_D),
6266 OPC_CMP_NGL_D = FOP (59, FMT_D),
6267 OPC_CMP_LT_D = FOP (60, FMT_D),
6268 OPC_CMP_NGE_D = FOP (61, FMT_D),
6269 OPC_CMP_LE_D = FOP (62, FMT_D),
6270 OPC_CMP_NGT_D = FOP (63, FMT_D),
6272 OPC_CVT_S_W = FOP(32, FMT_W),
6273 OPC_CVT_D_W = FOP(33, FMT_W),
6274 OPC_CVT_S_L = FOP(32, FMT_L),
6275 OPC_CVT_D_L = FOP(33, FMT_L),
6276 OPC_CVT_PS_PW = FOP(38, FMT_W),
6278 OPC_ADD_PS = FOP(0, FMT_PS),
6279 OPC_SUB_PS = FOP(1, FMT_PS),
6280 OPC_MUL_PS = FOP(2, FMT_PS),
6281 OPC_DIV_PS = FOP(3, FMT_PS),
6282 OPC_ABS_PS = FOP(5, FMT_PS),
6283 OPC_MOV_PS = FOP(6, FMT_PS),
6284 OPC_NEG_PS = FOP(7, FMT_PS),
6285 OPC_MOVCF_PS = FOP(17, FMT_PS),
6286 OPC_MOVZ_PS = FOP(18, FMT_PS),
6287 OPC_MOVN_PS = FOP(19, FMT_PS),
6288 OPC_ADDR_PS = FOP(24, FMT_PS),
6289 OPC_MULR_PS = FOP(26, FMT_PS),
6290 OPC_RECIP2_PS = FOP(28, FMT_PS),
6291 OPC_RECIP1_PS = FOP(29, FMT_PS),
6292 OPC_RSQRT1_PS = FOP(30, FMT_PS),
6293 OPC_RSQRT2_PS = FOP(31, FMT_PS),
6295 OPC_CVT_S_PU = FOP(32, FMT_PS),
6296 OPC_CVT_PW_PS = FOP(36, FMT_PS),
6297 OPC_CVT_S_PL = FOP(40, FMT_PS),
6298 OPC_PLL_PS = FOP(44, FMT_PS),
6299 OPC_PLU_PS = FOP(45, FMT_PS),
6300 OPC_PUL_PS = FOP(46, FMT_PS),
6301 OPC_PUU_PS = FOP(47, FMT_PS),
6302 OPC_CMP_F_PS = FOP (48, FMT_PS),
6303 OPC_CMP_UN_PS = FOP (49, FMT_PS),
6304 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
6305 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
6306 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
6307 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
6308 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
6309 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
6310 OPC_CMP_SF_PS = FOP (56, FMT_PS),
6311 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
6312 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
6313 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
6314 OPC_CMP_LT_PS = FOP (60, FMT_PS),
6315 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
6316 OPC_CMP_LE_PS = FOP (62, FMT_PS),
6317 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
6320 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6322 const char *opn = "cp1 move";
6323 TCGv t0 = tcg_temp_new();
6325 switch (opc) {
6326 case OPC_MFC1:
6328 TCGv_i32 fp0 = tcg_temp_new_i32();
6330 gen_load_fpr32(fp0, fs);
6331 tcg_gen_ext_i32_tl(t0, fp0);
6332 tcg_temp_free_i32(fp0);
6334 gen_store_gpr(t0, rt);
6335 opn = "mfc1";
6336 break;
6337 case OPC_MTC1:
6338 gen_load_gpr(t0, rt);
6340 TCGv_i32 fp0 = tcg_temp_new_i32();
6342 tcg_gen_trunc_tl_i32(fp0, t0);
6343 gen_store_fpr32(fp0, fs);
6344 tcg_temp_free_i32(fp0);
6346 opn = "mtc1";
6347 break;
6348 case OPC_CFC1:
6349 gen_helper_1i(cfc1, t0, fs);
6350 gen_store_gpr(t0, rt);
6351 opn = "cfc1";
6352 break;
6353 case OPC_CTC1:
6354 gen_load_gpr(t0, rt);
6355 gen_helper_1i(ctc1, t0, fs);
6356 opn = "ctc1";
6357 break;
6358 #if defined(TARGET_MIPS64)
6359 case OPC_DMFC1:
6360 gen_load_fpr64(ctx, t0, fs);
6361 gen_store_gpr(t0, rt);
6362 opn = "dmfc1";
6363 break;
6364 case OPC_DMTC1:
6365 gen_load_gpr(t0, rt);
6366 gen_store_fpr64(ctx, t0, fs);
6367 opn = "dmtc1";
6368 break;
6369 #endif
6370 case OPC_MFHC1:
6372 TCGv_i32 fp0 = tcg_temp_new_i32();
6374 gen_load_fpr32h(fp0, fs);
6375 tcg_gen_ext_i32_tl(t0, fp0);
6376 tcg_temp_free_i32(fp0);
6378 gen_store_gpr(t0, rt);
6379 opn = "mfhc1";
6380 break;
6381 case OPC_MTHC1:
6382 gen_load_gpr(t0, rt);
6384 TCGv_i32 fp0 = tcg_temp_new_i32();
6386 tcg_gen_trunc_tl_i32(fp0, t0);
6387 gen_store_fpr32h(fp0, fs);
6388 tcg_temp_free_i32(fp0);
6390 opn = "mthc1";
6391 break;
6392 default:
6393 MIPS_INVAL(opn);
6394 generate_exception (ctx, EXCP_RI);
6395 goto out;
6397 (void)opn; /* avoid a compiler warning */
6398 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6400 out:
6401 tcg_temp_free(t0);
6404 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6406 int l1;
6407 TCGCond cond;
6408 TCGv_i32 t0;
6410 if (rd == 0) {
6411 /* Treat as NOP. */
6412 return;
6415 if (tf)
6416 cond = TCG_COND_EQ;
6417 else
6418 cond = TCG_COND_NE;
6420 l1 = gen_new_label();
6421 t0 = tcg_temp_new_i32();
6422 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6423 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6424 tcg_temp_free_i32(t0);
6425 if (rs == 0) {
6426 tcg_gen_movi_tl(cpu_gpr[rd], 0);
6427 } else {
6428 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6430 gen_set_label(l1);
6433 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6435 int cond;
6436 TCGv_i32 t0 = tcg_temp_new_i32();
6437 int l1 = gen_new_label();
6439 if (tf)
6440 cond = TCG_COND_EQ;
6441 else
6442 cond = TCG_COND_NE;
6444 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6445 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6446 gen_load_fpr32(t0, fs);
6447 gen_store_fpr32(t0, fd);
6448 gen_set_label(l1);
6449 tcg_temp_free_i32(t0);
6452 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6454 int cond;
6455 TCGv_i32 t0 = tcg_temp_new_i32();
6456 TCGv_i64 fp0;
6457 int l1 = gen_new_label();
6459 if (tf)
6460 cond = TCG_COND_EQ;
6461 else
6462 cond = TCG_COND_NE;
6464 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6465 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6466 tcg_temp_free_i32(t0);
6467 fp0 = tcg_temp_new_i64();
6468 gen_load_fpr64(ctx, fp0, fs);
6469 gen_store_fpr64(ctx, fp0, fd);
6470 tcg_temp_free_i64(fp0);
6471 gen_set_label(l1);
6474 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6476 int cond;
6477 TCGv_i32 t0 = tcg_temp_new_i32();
6478 int l1 = gen_new_label();
6479 int l2 = gen_new_label();
6481 if (tf)
6482 cond = TCG_COND_EQ;
6483 else
6484 cond = TCG_COND_NE;
6486 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6487 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6488 gen_load_fpr32(t0, fs);
6489 gen_store_fpr32(t0, fd);
6490 gen_set_label(l1);
6492 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6493 tcg_gen_brcondi_i32(cond, t0, 0, l2);
6494 gen_load_fpr32h(t0, fs);
6495 gen_store_fpr32h(t0, fd);
6496 tcg_temp_free_i32(t0);
6497 gen_set_label(l2);
6501 static void gen_farith (DisasContext *ctx, enum fopcode op1,
6502 int ft, int fs, int fd, int cc)
6504 const char *opn = "farith";
6505 const char *condnames[] = {
6506 "c.f",
6507 "c.un",
6508 "c.eq",
6509 "c.ueq",
6510 "c.olt",
6511 "c.ult",
6512 "c.ole",
6513 "c.ule",
6514 "c.sf",
6515 "c.ngle",
6516 "c.seq",
6517 "c.ngl",
6518 "c.lt",
6519 "c.nge",
6520 "c.le",
6521 "c.ngt",
6523 const char *condnames_abs[] = {
6524 "cabs.f",
6525 "cabs.un",
6526 "cabs.eq",
6527 "cabs.ueq",
6528 "cabs.olt",
6529 "cabs.ult",
6530 "cabs.ole",
6531 "cabs.ule",
6532 "cabs.sf",
6533 "cabs.ngle",
6534 "cabs.seq",
6535 "cabs.ngl",
6536 "cabs.lt",
6537 "cabs.nge",
6538 "cabs.le",
6539 "cabs.ngt",
6541 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6542 uint32_t func = ctx->opcode & 0x3f;
6544 switch (op1) {
6545 case OPC_ADD_S:
6547 TCGv_i32 fp0 = tcg_temp_new_i32();
6548 TCGv_i32 fp1 = tcg_temp_new_i32();
6550 gen_load_fpr32(fp0, fs);
6551 gen_load_fpr32(fp1, ft);
6552 gen_helper_float_add_s(fp0, fp0, fp1);
6553 tcg_temp_free_i32(fp1);
6554 gen_store_fpr32(fp0, fd);
6555 tcg_temp_free_i32(fp0);
6557 opn = "add.s";
6558 optype = BINOP;
6559 break;
6560 case OPC_SUB_S:
6562 TCGv_i32 fp0 = tcg_temp_new_i32();
6563 TCGv_i32 fp1 = tcg_temp_new_i32();
6565 gen_load_fpr32(fp0, fs);
6566 gen_load_fpr32(fp1, ft);
6567 gen_helper_float_sub_s(fp0, fp0, fp1);
6568 tcg_temp_free_i32(fp1);
6569 gen_store_fpr32(fp0, fd);
6570 tcg_temp_free_i32(fp0);
6572 opn = "sub.s";
6573 optype = BINOP;
6574 break;
6575 case OPC_MUL_S:
6577 TCGv_i32 fp0 = tcg_temp_new_i32();
6578 TCGv_i32 fp1 = tcg_temp_new_i32();
6580 gen_load_fpr32(fp0, fs);
6581 gen_load_fpr32(fp1, ft);
6582 gen_helper_float_mul_s(fp0, fp0, fp1);
6583 tcg_temp_free_i32(fp1);
6584 gen_store_fpr32(fp0, fd);
6585 tcg_temp_free_i32(fp0);
6587 opn = "mul.s";
6588 optype = BINOP;
6589 break;
6590 case OPC_DIV_S:
6592 TCGv_i32 fp0 = tcg_temp_new_i32();
6593 TCGv_i32 fp1 = tcg_temp_new_i32();
6595 gen_load_fpr32(fp0, fs);
6596 gen_load_fpr32(fp1, ft);
6597 gen_helper_float_div_s(fp0, fp0, fp1);
6598 tcg_temp_free_i32(fp1);
6599 gen_store_fpr32(fp0, fd);
6600 tcg_temp_free_i32(fp0);
6602 opn = "div.s";
6603 optype = BINOP;
6604 break;
6605 case OPC_SQRT_S:
6607 TCGv_i32 fp0 = tcg_temp_new_i32();
6609 gen_load_fpr32(fp0, fs);
6610 gen_helper_float_sqrt_s(fp0, fp0);
6611 gen_store_fpr32(fp0, fd);
6612 tcg_temp_free_i32(fp0);
6614 opn = "sqrt.s";
6615 break;
6616 case OPC_ABS_S:
6618 TCGv_i32 fp0 = tcg_temp_new_i32();
6620 gen_load_fpr32(fp0, fs);
6621 gen_helper_float_abs_s(fp0, fp0);
6622 gen_store_fpr32(fp0, fd);
6623 tcg_temp_free_i32(fp0);
6625 opn = "abs.s";
6626 break;
6627 case OPC_MOV_S:
6629 TCGv_i32 fp0 = tcg_temp_new_i32();
6631 gen_load_fpr32(fp0, fs);
6632 gen_store_fpr32(fp0, fd);
6633 tcg_temp_free_i32(fp0);
6635 opn = "mov.s";
6636 break;
6637 case OPC_NEG_S:
6639 TCGv_i32 fp0 = tcg_temp_new_i32();
6641 gen_load_fpr32(fp0, fs);
6642 gen_helper_float_chs_s(fp0, fp0);
6643 gen_store_fpr32(fp0, fd);
6644 tcg_temp_free_i32(fp0);
6646 opn = "neg.s";
6647 break;
6648 case OPC_ROUND_L_S:
6649 check_cp1_64bitmode(ctx);
6651 TCGv_i32 fp32 = tcg_temp_new_i32();
6652 TCGv_i64 fp64 = tcg_temp_new_i64();
6654 gen_load_fpr32(fp32, fs);
6655 gen_helper_float_roundl_s(fp64, fp32);
6656 tcg_temp_free_i32(fp32);
6657 gen_store_fpr64(ctx, fp64, fd);
6658 tcg_temp_free_i64(fp64);
6660 opn = "round.l.s";
6661 break;
6662 case OPC_TRUNC_L_S:
6663 check_cp1_64bitmode(ctx);
6665 TCGv_i32 fp32 = tcg_temp_new_i32();
6666 TCGv_i64 fp64 = tcg_temp_new_i64();
6668 gen_load_fpr32(fp32, fs);
6669 gen_helper_float_truncl_s(fp64, fp32);
6670 tcg_temp_free_i32(fp32);
6671 gen_store_fpr64(ctx, fp64, fd);
6672 tcg_temp_free_i64(fp64);
6674 opn = "trunc.l.s";
6675 break;
6676 case OPC_CEIL_L_S:
6677 check_cp1_64bitmode(ctx);
6679 TCGv_i32 fp32 = tcg_temp_new_i32();
6680 TCGv_i64 fp64 = tcg_temp_new_i64();
6682 gen_load_fpr32(fp32, fs);
6683 gen_helper_float_ceill_s(fp64, fp32);
6684 tcg_temp_free_i32(fp32);
6685 gen_store_fpr64(ctx, fp64, fd);
6686 tcg_temp_free_i64(fp64);
6688 opn = "ceil.l.s";
6689 break;
6690 case OPC_FLOOR_L_S:
6691 check_cp1_64bitmode(ctx);
6693 TCGv_i32 fp32 = tcg_temp_new_i32();
6694 TCGv_i64 fp64 = tcg_temp_new_i64();
6696 gen_load_fpr32(fp32, fs);
6697 gen_helper_float_floorl_s(fp64, fp32);
6698 tcg_temp_free_i32(fp32);
6699 gen_store_fpr64(ctx, fp64, fd);
6700 tcg_temp_free_i64(fp64);
6702 opn = "floor.l.s";
6703 break;
6704 case OPC_ROUND_W_S:
6706 TCGv_i32 fp0 = tcg_temp_new_i32();
6708 gen_load_fpr32(fp0, fs);
6709 gen_helper_float_roundw_s(fp0, fp0);
6710 gen_store_fpr32(fp0, fd);
6711 tcg_temp_free_i32(fp0);
6713 opn = "round.w.s";
6714 break;
6715 case OPC_TRUNC_W_S:
6717 TCGv_i32 fp0 = tcg_temp_new_i32();
6719 gen_load_fpr32(fp0, fs);
6720 gen_helper_float_truncw_s(fp0, fp0);
6721 gen_store_fpr32(fp0, fd);
6722 tcg_temp_free_i32(fp0);
6724 opn = "trunc.w.s";
6725 break;
6726 case OPC_CEIL_W_S:
6728 TCGv_i32 fp0 = tcg_temp_new_i32();
6730 gen_load_fpr32(fp0, fs);
6731 gen_helper_float_ceilw_s(fp0, fp0);
6732 gen_store_fpr32(fp0, fd);
6733 tcg_temp_free_i32(fp0);
6735 opn = "ceil.w.s";
6736 break;
6737 case OPC_FLOOR_W_S:
6739 TCGv_i32 fp0 = tcg_temp_new_i32();
6741 gen_load_fpr32(fp0, fs);
6742 gen_helper_float_floorw_s(fp0, fp0);
6743 gen_store_fpr32(fp0, fd);
6744 tcg_temp_free_i32(fp0);
6746 opn = "floor.w.s";
6747 break;
6748 case OPC_MOVCF_S:
6749 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6750 opn = "movcf.s";
6751 break;
6752 case OPC_MOVZ_S:
6754 int l1 = gen_new_label();
6755 TCGv_i32 fp0;
6757 if (ft != 0) {
6758 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6760 fp0 = tcg_temp_new_i32();
6761 gen_load_fpr32(fp0, fs);
6762 gen_store_fpr32(fp0, fd);
6763 tcg_temp_free_i32(fp0);
6764 gen_set_label(l1);
6766 opn = "movz.s";
6767 break;
6768 case OPC_MOVN_S:
6770 int l1 = gen_new_label();
6771 TCGv_i32 fp0;
6773 if (ft != 0) {
6774 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6775 fp0 = tcg_temp_new_i32();
6776 gen_load_fpr32(fp0, fs);
6777 gen_store_fpr32(fp0, fd);
6778 tcg_temp_free_i32(fp0);
6779 gen_set_label(l1);
6782 opn = "movn.s";
6783 break;
6784 case OPC_RECIP_S:
6785 check_cop1x(ctx);
6787 TCGv_i32 fp0 = tcg_temp_new_i32();
6789 gen_load_fpr32(fp0, fs);
6790 gen_helper_float_recip_s(fp0, fp0);
6791 gen_store_fpr32(fp0, fd);
6792 tcg_temp_free_i32(fp0);
6794 opn = "recip.s";
6795 break;
6796 case OPC_RSQRT_S:
6797 check_cop1x(ctx);
6799 TCGv_i32 fp0 = tcg_temp_new_i32();
6801 gen_load_fpr32(fp0, fs);
6802 gen_helper_float_rsqrt_s(fp0, fp0);
6803 gen_store_fpr32(fp0, fd);
6804 tcg_temp_free_i32(fp0);
6806 opn = "rsqrt.s";
6807 break;
6808 case OPC_RECIP2_S:
6809 check_cp1_64bitmode(ctx);
6811 TCGv_i32 fp0 = tcg_temp_new_i32();
6812 TCGv_i32 fp1 = tcg_temp_new_i32();
6814 gen_load_fpr32(fp0, fs);
6815 gen_load_fpr32(fp1, fd);
6816 gen_helper_float_recip2_s(fp0, fp0, fp1);
6817 tcg_temp_free_i32(fp1);
6818 gen_store_fpr32(fp0, fd);
6819 tcg_temp_free_i32(fp0);
6821 opn = "recip2.s";
6822 break;
6823 case OPC_RECIP1_S:
6824 check_cp1_64bitmode(ctx);
6826 TCGv_i32 fp0 = tcg_temp_new_i32();
6828 gen_load_fpr32(fp0, fs);
6829 gen_helper_float_recip1_s(fp0, fp0);
6830 gen_store_fpr32(fp0, fd);
6831 tcg_temp_free_i32(fp0);
6833 opn = "recip1.s";
6834 break;
6835 case OPC_RSQRT1_S:
6836 check_cp1_64bitmode(ctx);
6838 TCGv_i32 fp0 = tcg_temp_new_i32();
6840 gen_load_fpr32(fp0, fs);
6841 gen_helper_float_rsqrt1_s(fp0, fp0);
6842 gen_store_fpr32(fp0, fd);
6843 tcg_temp_free_i32(fp0);
6845 opn = "rsqrt1.s";
6846 break;
6847 case OPC_RSQRT2_S:
6848 check_cp1_64bitmode(ctx);
6850 TCGv_i32 fp0 = tcg_temp_new_i32();
6851 TCGv_i32 fp1 = tcg_temp_new_i32();
6853 gen_load_fpr32(fp0, fs);
6854 gen_load_fpr32(fp1, ft);
6855 gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6856 tcg_temp_free_i32(fp1);
6857 gen_store_fpr32(fp0, fd);
6858 tcg_temp_free_i32(fp0);
6860 opn = "rsqrt2.s";
6861 break;
6862 case OPC_CVT_D_S:
6863 check_cp1_registers(ctx, fd);
6865 TCGv_i32 fp32 = tcg_temp_new_i32();
6866 TCGv_i64 fp64 = tcg_temp_new_i64();
6868 gen_load_fpr32(fp32, fs);
6869 gen_helper_float_cvtd_s(fp64, fp32);
6870 tcg_temp_free_i32(fp32);
6871 gen_store_fpr64(ctx, fp64, fd);
6872 tcg_temp_free_i64(fp64);
6874 opn = "cvt.d.s";
6875 break;
6876 case OPC_CVT_W_S:
6878 TCGv_i32 fp0 = tcg_temp_new_i32();
6880 gen_load_fpr32(fp0, fs);
6881 gen_helper_float_cvtw_s(fp0, fp0);
6882 gen_store_fpr32(fp0, fd);
6883 tcg_temp_free_i32(fp0);
6885 opn = "cvt.w.s";
6886 break;
6887 case OPC_CVT_L_S:
6888 check_cp1_64bitmode(ctx);
6890 TCGv_i32 fp32 = tcg_temp_new_i32();
6891 TCGv_i64 fp64 = tcg_temp_new_i64();
6893 gen_load_fpr32(fp32, fs);
6894 gen_helper_float_cvtl_s(fp64, fp32);
6895 tcg_temp_free_i32(fp32);
6896 gen_store_fpr64(ctx, fp64, fd);
6897 tcg_temp_free_i64(fp64);
6899 opn = "cvt.l.s";
6900 break;
6901 case OPC_CVT_PS_S:
6902 check_cp1_64bitmode(ctx);
6904 TCGv_i64 fp64 = tcg_temp_new_i64();
6905 TCGv_i32 fp32_0 = tcg_temp_new_i32();
6906 TCGv_i32 fp32_1 = tcg_temp_new_i32();
6908 gen_load_fpr32(fp32_0, fs);
6909 gen_load_fpr32(fp32_1, ft);
6910 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6911 tcg_temp_free_i32(fp32_1);
6912 tcg_temp_free_i32(fp32_0);
6913 gen_store_fpr64(ctx, fp64, fd);
6914 tcg_temp_free_i64(fp64);
6916 opn = "cvt.ps.s";
6917 break;
6918 case OPC_CMP_F_S:
6919 case OPC_CMP_UN_S:
6920 case OPC_CMP_EQ_S:
6921 case OPC_CMP_UEQ_S:
6922 case OPC_CMP_OLT_S:
6923 case OPC_CMP_ULT_S:
6924 case OPC_CMP_OLE_S:
6925 case OPC_CMP_ULE_S:
6926 case OPC_CMP_SF_S:
6927 case OPC_CMP_NGLE_S:
6928 case OPC_CMP_SEQ_S:
6929 case OPC_CMP_NGL_S:
6930 case OPC_CMP_LT_S:
6931 case OPC_CMP_NGE_S:
6932 case OPC_CMP_LE_S:
6933 case OPC_CMP_NGT_S:
6934 if (ctx->opcode & (1 << 6)) {
6935 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6936 opn = condnames_abs[func-48];
6937 } else {
6938 gen_cmp_s(ctx, func-48, ft, fs, cc);
6939 opn = condnames[func-48];
6941 break;
6942 case OPC_ADD_D:
6943 check_cp1_registers(ctx, fs | ft | fd);
6945 TCGv_i64 fp0 = tcg_temp_new_i64();
6946 TCGv_i64 fp1 = tcg_temp_new_i64();
6948 gen_load_fpr64(ctx, fp0, fs);
6949 gen_load_fpr64(ctx, fp1, ft);
6950 gen_helper_float_add_d(fp0, fp0, fp1);
6951 tcg_temp_free_i64(fp1);
6952 gen_store_fpr64(ctx, fp0, fd);
6953 tcg_temp_free_i64(fp0);
6955 opn = "add.d";
6956 optype = BINOP;
6957 break;
6958 case OPC_SUB_D:
6959 check_cp1_registers(ctx, fs | ft | fd);
6961 TCGv_i64 fp0 = tcg_temp_new_i64();
6962 TCGv_i64 fp1 = tcg_temp_new_i64();
6964 gen_load_fpr64(ctx, fp0, fs);
6965 gen_load_fpr64(ctx, fp1, ft);
6966 gen_helper_float_sub_d(fp0, fp0, fp1);
6967 tcg_temp_free_i64(fp1);
6968 gen_store_fpr64(ctx, fp0, fd);
6969 tcg_temp_free_i64(fp0);
6971 opn = "sub.d";
6972 optype = BINOP;
6973 break;
6974 case OPC_MUL_D:
6975 check_cp1_registers(ctx, fs | ft | fd);
6977 TCGv_i64 fp0 = tcg_temp_new_i64();
6978 TCGv_i64 fp1 = tcg_temp_new_i64();
6980 gen_load_fpr64(ctx, fp0, fs);
6981 gen_load_fpr64(ctx, fp1, ft);
6982 gen_helper_float_mul_d(fp0, fp0, fp1);
6983 tcg_temp_free_i64(fp1);
6984 gen_store_fpr64(ctx, fp0, fd);
6985 tcg_temp_free_i64(fp0);
6987 opn = "mul.d";
6988 optype = BINOP;
6989 break;
6990 case OPC_DIV_D:
6991 check_cp1_registers(ctx, fs | ft | fd);
6993 TCGv_i64 fp0 = tcg_temp_new_i64();
6994 TCGv_i64 fp1 = tcg_temp_new_i64();
6996 gen_load_fpr64(ctx, fp0, fs);
6997 gen_load_fpr64(ctx, fp1, ft);
6998 gen_helper_float_div_d(fp0, fp0, fp1);
6999 tcg_temp_free_i64(fp1);
7000 gen_store_fpr64(ctx, fp0, fd);
7001 tcg_temp_free_i64(fp0);
7003 opn = "div.d";
7004 optype = BINOP;
7005 break;
7006 case OPC_SQRT_D:
7007 check_cp1_registers(ctx, fs | fd);
7009 TCGv_i64 fp0 = tcg_temp_new_i64();
7011 gen_load_fpr64(ctx, fp0, fs);
7012 gen_helper_float_sqrt_d(fp0, fp0);
7013 gen_store_fpr64(ctx, fp0, fd);
7014 tcg_temp_free_i64(fp0);
7016 opn = "sqrt.d";
7017 break;
7018 case OPC_ABS_D:
7019 check_cp1_registers(ctx, fs | fd);
7021 TCGv_i64 fp0 = tcg_temp_new_i64();
7023 gen_load_fpr64(ctx, fp0, fs);
7024 gen_helper_float_abs_d(fp0, fp0);
7025 gen_store_fpr64(ctx, fp0, fd);
7026 tcg_temp_free_i64(fp0);
7028 opn = "abs.d";
7029 break;
7030 case OPC_MOV_D:
7031 check_cp1_registers(ctx, fs | fd);
7033 TCGv_i64 fp0 = tcg_temp_new_i64();
7035 gen_load_fpr64(ctx, fp0, fs);
7036 gen_store_fpr64(ctx, fp0, fd);
7037 tcg_temp_free_i64(fp0);
7039 opn = "mov.d";
7040 break;
7041 case OPC_NEG_D:
7042 check_cp1_registers(ctx, fs | fd);
7044 TCGv_i64 fp0 = tcg_temp_new_i64();
7046 gen_load_fpr64(ctx, fp0, fs);
7047 gen_helper_float_chs_d(fp0, fp0);
7048 gen_store_fpr64(ctx, fp0, fd);
7049 tcg_temp_free_i64(fp0);
7051 opn = "neg.d";
7052 break;
7053 case OPC_ROUND_L_D:
7054 check_cp1_64bitmode(ctx);
7056 TCGv_i64 fp0 = tcg_temp_new_i64();
7058 gen_load_fpr64(ctx, fp0, fs);
7059 gen_helper_float_roundl_d(fp0, fp0);
7060 gen_store_fpr64(ctx, fp0, fd);
7061 tcg_temp_free_i64(fp0);
7063 opn = "round.l.d";
7064 break;
7065 case OPC_TRUNC_L_D:
7066 check_cp1_64bitmode(ctx);
7068 TCGv_i64 fp0 = tcg_temp_new_i64();
7070 gen_load_fpr64(ctx, fp0, fs);
7071 gen_helper_float_truncl_d(fp0, fp0);
7072 gen_store_fpr64(ctx, fp0, fd);
7073 tcg_temp_free_i64(fp0);
7075 opn = "trunc.l.d";
7076 break;
7077 case OPC_CEIL_L_D:
7078 check_cp1_64bitmode(ctx);
7080 TCGv_i64 fp0 = tcg_temp_new_i64();
7082 gen_load_fpr64(ctx, fp0, fs);
7083 gen_helper_float_ceill_d(fp0, fp0);
7084 gen_store_fpr64(ctx, fp0, fd);
7085 tcg_temp_free_i64(fp0);
7087 opn = "ceil.l.d";
7088 break;
7089 case OPC_FLOOR_L_D:
7090 check_cp1_64bitmode(ctx);
7092 TCGv_i64 fp0 = tcg_temp_new_i64();
7094 gen_load_fpr64(ctx, fp0, fs);
7095 gen_helper_float_floorl_d(fp0, fp0);
7096 gen_store_fpr64(ctx, fp0, fd);
7097 tcg_temp_free_i64(fp0);
7099 opn = "floor.l.d";
7100 break;
7101 case OPC_ROUND_W_D:
7102 check_cp1_registers(ctx, fs);
7104 TCGv_i32 fp32 = tcg_temp_new_i32();
7105 TCGv_i64 fp64 = tcg_temp_new_i64();
7107 gen_load_fpr64(ctx, fp64, fs);
7108 gen_helper_float_roundw_d(fp32, fp64);
7109 tcg_temp_free_i64(fp64);
7110 gen_store_fpr32(fp32, fd);
7111 tcg_temp_free_i32(fp32);
7113 opn = "round.w.d";
7114 break;
7115 case OPC_TRUNC_W_D:
7116 check_cp1_registers(ctx, fs);
7118 TCGv_i32 fp32 = tcg_temp_new_i32();
7119 TCGv_i64 fp64 = tcg_temp_new_i64();
7121 gen_load_fpr64(ctx, fp64, fs);
7122 gen_helper_float_truncw_d(fp32, fp64);
7123 tcg_temp_free_i64(fp64);
7124 gen_store_fpr32(fp32, fd);
7125 tcg_temp_free_i32(fp32);
7127 opn = "trunc.w.d";
7128 break;
7129 case OPC_CEIL_W_D:
7130 check_cp1_registers(ctx, fs);
7132 TCGv_i32 fp32 = tcg_temp_new_i32();
7133 TCGv_i64 fp64 = tcg_temp_new_i64();
7135 gen_load_fpr64(ctx, fp64, fs);
7136 gen_helper_float_ceilw_d(fp32, fp64);
7137 tcg_temp_free_i64(fp64);
7138 gen_store_fpr32(fp32, fd);
7139 tcg_temp_free_i32(fp32);
7141 opn = "ceil.w.d";
7142 break;
7143 case OPC_FLOOR_W_D:
7144 check_cp1_registers(ctx, fs);
7146 TCGv_i32 fp32 = tcg_temp_new_i32();
7147 TCGv_i64 fp64 = tcg_temp_new_i64();
7149 gen_load_fpr64(ctx, fp64, fs);
7150 gen_helper_float_floorw_d(fp32, fp64);
7151 tcg_temp_free_i64(fp64);
7152 gen_store_fpr32(fp32, fd);
7153 tcg_temp_free_i32(fp32);
7155 opn = "floor.w.d";
7156 break;
7157 case OPC_MOVCF_D:
7158 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7159 opn = "movcf.d";
7160 break;
7161 case OPC_MOVZ_D:
7163 int l1 = gen_new_label();
7164 TCGv_i64 fp0;
7166 if (ft != 0) {
7167 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7169 fp0 = tcg_temp_new_i64();
7170 gen_load_fpr64(ctx, fp0, fs);
7171 gen_store_fpr64(ctx, fp0, fd);
7172 tcg_temp_free_i64(fp0);
7173 gen_set_label(l1);
7175 opn = "movz.d";
7176 break;
7177 case OPC_MOVN_D:
7179 int l1 = gen_new_label();
7180 TCGv_i64 fp0;
7182 if (ft != 0) {
7183 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7184 fp0 = tcg_temp_new_i64();
7185 gen_load_fpr64(ctx, fp0, fs);
7186 gen_store_fpr64(ctx, fp0, fd);
7187 tcg_temp_free_i64(fp0);
7188 gen_set_label(l1);
7191 opn = "movn.d";
7192 break;
7193 case OPC_RECIP_D:
7194 check_cp1_64bitmode(ctx);
7196 TCGv_i64 fp0 = tcg_temp_new_i64();
7198 gen_load_fpr64(ctx, fp0, fs);
7199 gen_helper_float_recip_d(fp0, fp0);
7200 gen_store_fpr64(ctx, fp0, fd);
7201 tcg_temp_free_i64(fp0);
7203 opn = "recip.d";
7204 break;
7205 case OPC_RSQRT_D:
7206 check_cp1_64bitmode(ctx);
7208 TCGv_i64 fp0 = tcg_temp_new_i64();
7210 gen_load_fpr64(ctx, fp0, fs);
7211 gen_helper_float_rsqrt_d(fp0, fp0);
7212 gen_store_fpr64(ctx, fp0, fd);
7213 tcg_temp_free_i64(fp0);
7215 opn = "rsqrt.d";
7216 break;
7217 case OPC_RECIP2_D:
7218 check_cp1_64bitmode(ctx);
7220 TCGv_i64 fp0 = tcg_temp_new_i64();
7221 TCGv_i64 fp1 = tcg_temp_new_i64();
7223 gen_load_fpr64(ctx, fp0, fs);
7224 gen_load_fpr64(ctx, fp1, ft);
7225 gen_helper_float_recip2_d(fp0, fp0, fp1);
7226 tcg_temp_free_i64(fp1);
7227 gen_store_fpr64(ctx, fp0, fd);
7228 tcg_temp_free_i64(fp0);
7230 opn = "recip2.d";
7231 break;
7232 case OPC_RECIP1_D:
7233 check_cp1_64bitmode(ctx);
7235 TCGv_i64 fp0 = tcg_temp_new_i64();
7237 gen_load_fpr64(ctx, fp0, fs);
7238 gen_helper_float_recip1_d(fp0, fp0);
7239 gen_store_fpr64(ctx, fp0, fd);
7240 tcg_temp_free_i64(fp0);
7242 opn = "recip1.d";
7243 break;
7244 case OPC_RSQRT1_D:
7245 check_cp1_64bitmode(ctx);
7247 TCGv_i64 fp0 = tcg_temp_new_i64();
7249 gen_load_fpr64(ctx, fp0, fs);
7250 gen_helper_float_rsqrt1_d(fp0, fp0);
7251 gen_store_fpr64(ctx, fp0, fd);
7252 tcg_temp_free_i64(fp0);
7254 opn = "rsqrt1.d";
7255 break;
7256 case OPC_RSQRT2_D:
7257 check_cp1_64bitmode(ctx);
7259 TCGv_i64 fp0 = tcg_temp_new_i64();
7260 TCGv_i64 fp1 = tcg_temp_new_i64();
7262 gen_load_fpr64(ctx, fp0, fs);
7263 gen_load_fpr64(ctx, fp1, ft);
7264 gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
7265 tcg_temp_free_i64(fp1);
7266 gen_store_fpr64(ctx, fp0, fd);
7267 tcg_temp_free_i64(fp0);
7269 opn = "rsqrt2.d";
7270 break;
7271 case OPC_CMP_F_D:
7272 case OPC_CMP_UN_D:
7273 case OPC_CMP_EQ_D:
7274 case OPC_CMP_UEQ_D:
7275 case OPC_CMP_OLT_D:
7276 case OPC_CMP_ULT_D:
7277 case OPC_CMP_OLE_D:
7278 case OPC_CMP_ULE_D:
7279 case OPC_CMP_SF_D:
7280 case OPC_CMP_NGLE_D:
7281 case OPC_CMP_SEQ_D:
7282 case OPC_CMP_NGL_D:
7283 case OPC_CMP_LT_D:
7284 case OPC_CMP_NGE_D:
7285 case OPC_CMP_LE_D:
7286 case OPC_CMP_NGT_D:
7287 if (ctx->opcode & (1 << 6)) {
7288 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7289 opn = condnames_abs[func-48];
7290 } else {
7291 gen_cmp_d(ctx, func-48, ft, fs, cc);
7292 opn = condnames[func-48];
7294 break;
7295 case OPC_CVT_S_D:
7296 check_cp1_registers(ctx, fs);
7298 TCGv_i32 fp32 = tcg_temp_new_i32();
7299 TCGv_i64 fp64 = tcg_temp_new_i64();
7301 gen_load_fpr64(ctx, fp64, fs);
7302 gen_helper_float_cvts_d(fp32, fp64);
7303 tcg_temp_free_i64(fp64);
7304 gen_store_fpr32(fp32, fd);
7305 tcg_temp_free_i32(fp32);
7307 opn = "cvt.s.d";
7308 break;
7309 case OPC_CVT_W_D:
7310 check_cp1_registers(ctx, fs);
7312 TCGv_i32 fp32 = tcg_temp_new_i32();
7313 TCGv_i64 fp64 = tcg_temp_new_i64();
7315 gen_load_fpr64(ctx, fp64, fs);
7316 gen_helper_float_cvtw_d(fp32, fp64);
7317 tcg_temp_free_i64(fp64);
7318 gen_store_fpr32(fp32, fd);
7319 tcg_temp_free_i32(fp32);
7321 opn = "cvt.w.d";
7322 break;
7323 case OPC_CVT_L_D:
7324 check_cp1_64bitmode(ctx);
7326 TCGv_i64 fp0 = tcg_temp_new_i64();
7328 gen_load_fpr64(ctx, fp0, fs);
7329 gen_helper_float_cvtl_d(fp0, fp0);
7330 gen_store_fpr64(ctx, fp0, fd);
7331 tcg_temp_free_i64(fp0);
7333 opn = "cvt.l.d";
7334 break;
7335 case OPC_CVT_S_W:
7337 TCGv_i32 fp0 = tcg_temp_new_i32();
7339 gen_load_fpr32(fp0, fs);
7340 gen_helper_float_cvts_w(fp0, fp0);
7341 gen_store_fpr32(fp0, fd);
7342 tcg_temp_free_i32(fp0);
7344 opn = "cvt.s.w";
7345 break;
7346 case OPC_CVT_D_W:
7347 check_cp1_registers(ctx, fd);
7349 TCGv_i32 fp32 = tcg_temp_new_i32();
7350 TCGv_i64 fp64 = tcg_temp_new_i64();
7352 gen_load_fpr32(fp32, fs);
7353 gen_helper_float_cvtd_w(fp64, fp32);
7354 tcg_temp_free_i32(fp32);
7355 gen_store_fpr64(ctx, fp64, fd);
7356 tcg_temp_free_i64(fp64);
7358 opn = "cvt.d.w";
7359 break;
7360 case OPC_CVT_S_L:
7361 check_cp1_64bitmode(ctx);
7363 TCGv_i32 fp32 = tcg_temp_new_i32();
7364 TCGv_i64 fp64 = tcg_temp_new_i64();
7366 gen_load_fpr64(ctx, fp64, fs);
7367 gen_helper_float_cvts_l(fp32, fp64);
7368 tcg_temp_free_i64(fp64);
7369 gen_store_fpr32(fp32, fd);
7370 tcg_temp_free_i32(fp32);
7372 opn = "cvt.s.l";
7373 break;
7374 case OPC_CVT_D_L:
7375 check_cp1_64bitmode(ctx);
7377 TCGv_i64 fp0 = tcg_temp_new_i64();
7379 gen_load_fpr64(ctx, fp0, fs);
7380 gen_helper_float_cvtd_l(fp0, fp0);
7381 gen_store_fpr64(ctx, fp0, fd);
7382 tcg_temp_free_i64(fp0);
7384 opn = "cvt.d.l";
7385 break;
7386 case OPC_CVT_PS_PW:
7387 check_cp1_64bitmode(ctx);
7389 TCGv_i64 fp0 = tcg_temp_new_i64();
7391 gen_load_fpr64(ctx, fp0, fs);
7392 gen_helper_float_cvtps_pw(fp0, fp0);
7393 gen_store_fpr64(ctx, fp0, fd);
7394 tcg_temp_free_i64(fp0);
7396 opn = "cvt.ps.pw";
7397 break;
7398 case OPC_ADD_PS:
7399 check_cp1_64bitmode(ctx);
7401 TCGv_i64 fp0 = tcg_temp_new_i64();
7402 TCGv_i64 fp1 = tcg_temp_new_i64();
7404 gen_load_fpr64(ctx, fp0, fs);
7405 gen_load_fpr64(ctx, fp1, ft);
7406 gen_helper_float_add_ps(fp0, fp0, fp1);
7407 tcg_temp_free_i64(fp1);
7408 gen_store_fpr64(ctx, fp0, fd);
7409 tcg_temp_free_i64(fp0);
7411 opn = "add.ps";
7412 break;
7413 case OPC_SUB_PS:
7414 check_cp1_64bitmode(ctx);
7416 TCGv_i64 fp0 = tcg_temp_new_i64();
7417 TCGv_i64 fp1 = tcg_temp_new_i64();
7419 gen_load_fpr64(ctx, fp0, fs);
7420 gen_load_fpr64(ctx, fp1, ft);
7421 gen_helper_float_sub_ps(fp0, fp0, fp1);
7422 tcg_temp_free_i64(fp1);
7423 gen_store_fpr64(ctx, fp0, fd);
7424 tcg_temp_free_i64(fp0);
7426 opn = "sub.ps";
7427 break;
7428 case OPC_MUL_PS:
7429 check_cp1_64bitmode(ctx);
7431 TCGv_i64 fp0 = tcg_temp_new_i64();
7432 TCGv_i64 fp1 = tcg_temp_new_i64();
7434 gen_load_fpr64(ctx, fp0, fs);
7435 gen_load_fpr64(ctx, fp1, ft);
7436 gen_helper_float_mul_ps(fp0, fp0, fp1);
7437 tcg_temp_free_i64(fp1);
7438 gen_store_fpr64(ctx, fp0, fd);
7439 tcg_temp_free_i64(fp0);
7441 opn = "mul.ps";
7442 break;
7443 case OPC_ABS_PS:
7444 check_cp1_64bitmode(ctx);
7446 TCGv_i64 fp0 = tcg_temp_new_i64();
7448 gen_load_fpr64(ctx, fp0, fs);
7449 gen_helper_float_abs_ps(fp0, fp0);
7450 gen_store_fpr64(ctx, fp0, fd);
7451 tcg_temp_free_i64(fp0);
7453 opn = "abs.ps";
7454 break;
7455 case OPC_MOV_PS:
7456 check_cp1_64bitmode(ctx);
7458 TCGv_i64 fp0 = tcg_temp_new_i64();
7460 gen_load_fpr64(ctx, fp0, fs);
7461 gen_store_fpr64(ctx, fp0, fd);
7462 tcg_temp_free_i64(fp0);
7464 opn = "mov.ps";
7465 break;
7466 case OPC_NEG_PS:
7467 check_cp1_64bitmode(ctx);
7469 TCGv_i64 fp0 = tcg_temp_new_i64();
7471 gen_load_fpr64(ctx, fp0, fs);
7472 gen_helper_float_chs_ps(fp0, fp0);
7473 gen_store_fpr64(ctx, fp0, fd);
7474 tcg_temp_free_i64(fp0);
7476 opn = "neg.ps";
7477 break;
7478 case OPC_MOVCF_PS:
7479 check_cp1_64bitmode(ctx);
7480 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7481 opn = "movcf.ps";
7482 break;
7483 case OPC_MOVZ_PS:
7484 check_cp1_64bitmode(ctx);
7486 int l1 = gen_new_label();
7487 TCGv_i64 fp0;
7489 if (ft != 0)
7490 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7491 fp0 = tcg_temp_new_i64();
7492 gen_load_fpr64(ctx, fp0, fs);
7493 gen_store_fpr64(ctx, fp0, fd);
7494 tcg_temp_free_i64(fp0);
7495 gen_set_label(l1);
7497 opn = "movz.ps";
7498 break;
7499 case OPC_MOVN_PS:
7500 check_cp1_64bitmode(ctx);
7502 int l1 = gen_new_label();
7503 TCGv_i64 fp0;
7505 if (ft != 0) {
7506 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7507 fp0 = tcg_temp_new_i64();
7508 gen_load_fpr64(ctx, fp0, fs);
7509 gen_store_fpr64(ctx, fp0, fd);
7510 tcg_temp_free_i64(fp0);
7511 gen_set_label(l1);
7514 opn = "movn.ps";
7515 break;
7516 case OPC_ADDR_PS:
7517 check_cp1_64bitmode(ctx);
7519 TCGv_i64 fp0 = tcg_temp_new_i64();
7520 TCGv_i64 fp1 = tcg_temp_new_i64();
7522 gen_load_fpr64(ctx, fp0, ft);
7523 gen_load_fpr64(ctx, fp1, fs);
7524 gen_helper_float_addr_ps(fp0, fp0, fp1);
7525 tcg_temp_free_i64(fp1);
7526 gen_store_fpr64(ctx, fp0, fd);
7527 tcg_temp_free_i64(fp0);
7529 opn = "addr.ps";
7530 break;
7531 case OPC_MULR_PS:
7532 check_cp1_64bitmode(ctx);
7534 TCGv_i64 fp0 = tcg_temp_new_i64();
7535 TCGv_i64 fp1 = tcg_temp_new_i64();
7537 gen_load_fpr64(ctx, fp0, ft);
7538 gen_load_fpr64(ctx, fp1, fs);
7539 gen_helper_float_mulr_ps(fp0, fp0, fp1);
7540 tcg_temp_free_i64(fp1);
7541 gen_store_fpr64(ctx, fp0, fd);
7542 tcg_temp_free_i64(fp0);
7544 opn = "mulr.ps";
7545 break;
7546 case OPC_RECIP2_PS:
7547 check_cp1_64bitmode(ctx);
7549 TCGv_i64 fp0 = tcg_temp_new_i64();
7550 TCGv_i64 fp1 = tcg_temp_new_i64();
7552 gen_load_fpr64(ctx, fp0, fs);
7553 gen_load_fpr64(ctx, fp1, fd);
7554 gen_helper_float_recip2_ps(fp0, fp0, fp1);
7555 tcg_temp_free_i64(fp1);
7556 gen_store_fpr64(ctx, fp0, fd);
7557 tcg_temp_free_i64(fp0);
7559 opn = "recip2.ps";
7560 break;
7561 case OPC_RECIP1_PS:
7562 check_cp1_64bitmode(ctx);
7564 TCGv_i64 fp0 = tcg_temp_new_i64();
7566 gen_load_fpr64(ctx, fp0, fs);
7567 gen_helper_float_recip1_ps(fp0, fp0);
7568 gen_store_fpr64(ctx, fp0, fd);
7569 tcg_temp_free_i64(fp0);
7571 opn = "recip1.ps";
7572 break;
7573 case OPC_RSQRT1_PS:
7574 check_cp1_64bitmode(ctx);
7576 TCGv_i64 fp0 = tcg_temp_new_i64();
7578 gen_load_fpr64(ctx, fp0, fs);
7579 gen_helper_float_rsqrt1_ps(fp0, fp0);
7580 gen_store_fpr64(ctx, fp0, fd);
7581 tcg_temp_free_i64(fp0);
7583 opn = "rsqrt1.ps";
7584 break;
7585 case OPC_RSQRT2_PS:
7586 check_cp1_64bitmode(ctx);
7588 TCGv_i64 fp0 = tcg_temp_new_i64();
7589 TCGv_i64 fp1 = tcg_temp_new_i64();
7591 gen_load_fpr64(ctx, fp0, fs);
7592 gen_load_fpr64(ctx, fp1, ft);
7593 gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7594 tcg_temp_free_i64(fp1);
7595 gen_store_fpr64(ctx, fp0, fd);
7596 tcg_temp_free_i64(fp0);
7598 opn = "rsqrt2.ps";
7599 break;
7600 case OPC_CVT_S_PU:
7601 check_cp1_64bitmode(ctx);
7603 TCGv_i32 fp0 = tcg_temp_new_i32();
7605 gen_load_fpr32h(fp0, fs);
7606 gen_helper_float_cvts_pu(fp0, fp0);
7607 gen_store_fpr32(fp0, fd);
7608 tcg_temp_free_i32(fp0);
7610 opn = "cvt.s.pu";
7611 break;
7612 case OPC_CVT_PW_PS:
7613 check_cp1_64bitmode(ctx);
7615 TCGv_i64 fp0 = tcg_temp_new_i64();
7617 gen_load_fpr64(ctx, fp0, fs);
7618 gen_helper_float_cvtpw_ps(fp0, fp0);
7619 gen_store_fpr64(ctx, fp0, fd);
7620 tcg_temp_free_i64(fp0);
7622 opn = "cvt.pw.ps";
7623 break;
7624 case OPC_CVT_S_PL:
7625 check_cp1_64bitmode(ctx);
7627 TCGv_i32 fp0 = tcg_temp_new_i32();
7629 gen_load_fpr32(fp0, fs);
7630 gen_helper_float_cvts_pl(fp0, fp0);
7631 gen_store_fpr32(fp0, fd);
7632 tcg_temp_free_i32(fp0);
7634 opn = "cvt.s.pl";
7635 break;
7636 case OPC_PLL_PS:
7637 check_cp1_64bitmode(ctx);
7639 TCGv_i32 fp0 = tcg_temp_new_i32();
7640 TCGv_i32 fp1 = tcg_temp_new_i32();
7642 gen_load_fpr32(fp0, fs);
7643 gen_load_fpr32(fp1, ft);
7644 gen_store_fpr32h(fp0, fd);
7645 gen_store_fpr32(fp1, fd);
7646 tcg_temp_free_i32(fp0);
7647 tcg_temp_free_i32(fp1);
7649 opn = "pll.ps";
7650 break;
7651 case OPC_PLU_PS:
7652 check_cp1_64bitmode(ctx);
7654 TCGv_i32 fp0 = tcg_temp_new_i32();
7655 TCGv_i32 fp1 = tcg_temp_new_i32();
7657 gen_load_fpr32(fp0, fs);
7658 gen_load_fpr32h(fp1, ft);
7659 gen_store_fpr32(fp1, fd);
7660 gen_store_fpr32h(fp0, fd);
7661 tcg_temp_free_i32(fp0);
7662 tcg_temp_free_i32(fp1);
7664 opn = "plu.ps";
7665 break;
7666 case OPC_PUL_PS:
7667 check_cp1_64bitmode(ctx);
7669 TCGv_i32 fp0 = tcg_temp_new_i32();
7670 TCGv_i32 fp1 = tcg_temp_new_i32();
7672 gen_load_fpr32h(fp0, fs);
7673 gen_load_fpr32(fp1, ft);
7674 gen_store_fpr32(fp1, fd);
7675 gen_store_fpr32h(fp0, fd);
7676 tcg_temp_free_i32(fp0);
7677 tcg_temp_free_i32(fp1);
7679 opn = "pul.ps";
7680 break;
7681 case OPC_PUU_PS:
7682 check_cp1_64bitmode(ctx);
7684 TCGv_i32 fp0 = tcg_temp_new_i32();
7685 TCGv_i32 fp1 = tcg_temp_new_i32();
7687 gen_load_fpr32h(fp0, fs);
7688 gen_load_fpr32h(fp1, ft);
7689 gen_store_fpr32(fp1, fd);
7690 gen_store_fpr32h(fp0, fd);
7691 tcg_temp_free_i32(fp0);
7692 tcg_temp_free_i32(fp1);
7694 opn = "puu.ps";
7695 break;
7696 case OPC_CMP_F_PS:
7697 case OPC_CMP_UN_PS:
7698 case OPC_CMP_EQ_PS:
7699 case OPC_CMP_UEQ_PS:
7700 case OPC_CMP_OLT_PS:
7701 case OPC_CMP_ULT_PS:
7702 case OPC_CMP_OLE_PS:
7703 case OPC_CMP_ULE_PS:
7704 case OPC_CMP_SF_PS:
7705 case OPC_CMP_NGLE_PS:
7706 case OPC_CMP_SEQ_PS:
7707 case OPC_CMP_NGL_PS:
7708 case OPC_CMP_LT_PS:
7709 case OPC_CMP_NGE_PS:
7710 case OPC_CMP_LE_PS:
7711 case OPC_CMP_NGT_PS:
7712 if (ctx->opcode & (1 << 6)) {
7713 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7714 opn = condnames_abs[func-48];
7715 } else {
7716 gen_cmp_ps(ctx, func-48, ft, fs, cc);
7717 opn = condnames[func-48];
7719 break;
7720 default:
7721 MIPS_INVAL(opn);
7722 generate_exception (ctx, EXCP_RI);
7723 return;
7725 (void)opn; /* avoid a compiler warning */
7726 switch (optype) {
7727 case BINOP:
7728 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7729 break;
7730 case CMPOP:
7731 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7732 break;
7733 default:
7734 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7735 break;
7739 /* Coprocessor 3 (FPU) */
7740 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7741 int fd, int fs, int base, int index)
7743 const char *opn = "extended float load/store";
7744 int store = 0;
7745 TCGv t0 = tcg_temp_new();
7747 if (base == 0) {
7748 gen_load_gpr(t0, index);
7749 } else if (index == 0) {
7750 gen_load_gpr(t0, base);
7751 } else {
7752 gen_load_gpr(t0, index);
7753 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7755 /* Don't do NOP if destination is zero: we must perform the actual
7756 memory access. */
7757 save_cpu_state(ctx, 0);
7758 switch (opc) {
7759 case OPC_LWXC1:
7760 check_cop1x(ctx);
7762 TCGv_i32 fp0 = tcg_temp_new_i32();
7764 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7765 tcg_gen_trunc_tl_i32(fp0, t0);
7766 gen_store_fpr32(fp0, fd);
7767 tcg_temp_free_i32(fp0);
7769 opn = "lwxc1";
7770 break;
7771 case OPC_LDXC1:
7772 check_cop1x(ctx);
7773 check_cp1_registers(ctx, fd);
7775 TCGv_i64 fp0 = tcg_temp_new_i64();
7777 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7778 gen_store_fpr64(ctx, fp0, fd);
7779 tcg_temp_free_i64(fp0);
7781 opn = "ldxc1";
7782 break;
7783 case OPC_LUXC1:
7784 check_cp1_64bitmode(ctx);
7785 tcg_gen_andi_tl(t0, t0, ~0x7);
7787 TCGv_i64 fp0 = tcg_temp_new_i64();
7789 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7790 gen_store_fpr64(ctx, fp0, fd);
7791 tcg_temp_free_i64(fp0);
7793 opn = "luxc1";
7794 break;
7795 case OPC_SWXC1:
7796 check_cop1x(ctx);
7798 TCGv_i32 fp0 = tcg_temp_new_i32();
7799 TCGv t1 = tcg_temp_new();
7801 gen_load_fpr32(fp0, fs);
7802 tcg_gen_extu_i32_tl(t1, fp0);
7803 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7804 tcg_temp_free_i32(fp0);
7805 tcg_temp_free(t1);
7807 opn = "swxc1";
7808 store = 1;
7809 break;
7810 case OPC_SDXC1:
7811 check_cop1x(ctx);
7812 check_cp1_registers(ctx, fs);
7814 TCGv_i64 fp0 = tcg_temp_new_i64();
7816 gen_load_fpr64(ctx, fp0, fs);
7817 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7818 tcg_temp_free_i64(fp0);
7820 opn = "sdxc1";
7821 store = 1;
7822 break;
7823 case OPC_SUXC1:
7824 check_cp1_64bitmode(ctx);
7825 tcg_gen_andi_tl(t0, t0, ~0x7);
7827 TCGv_i64 fp0 = tcg_temp_new_i64();
7829 gen_load_fpr64(ctx, fp0, fs);
7830 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7831 tcg_temp_free_i64(fp0);
7833 opn = "suxc1";
7834 store = 1;
7835 break;
7837 tcg_temp_free(t0);
7838 (void)opn; (void)store; /* avoid compiler warnings */
7839 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7840 regnames[index], regnames[base]);
7843 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7844 int fd, int fr, int fs, int ft)
7846 const char *opn = "flt3_arith";
7848 switch (opc) {
7849 case OPC_ALNV_PS:
7850 check_cp1_64bitmode(ctx);
7852 TCGv t0 = tcg_temp_local_new();
7853 TCGv_i32 fp = tcg_temp_new_i32();
7854 TCGv_i32 fph = tcg_temp_new_i32();
7855 int l1 = gen_new_label();
7856 int l2 = gen_new_label();
7858 gen_load_gpr(t0, fr);
7859 tcg_gen_andi_tl(t0, t0, 0x7);
7861 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7862 gen_load_fpr32(fp, fs);
7863 gen_load_fpr32h(fph, fs);
7864 gen_store_fpr32(fp, fd);
7865 gen_store_fpr32h(fph, fd);
7866 tcg_gen_br(l2);
7867 gen_set_label(l1);
7868 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7869 tcg_temp_free(t0);
7870 #ifdef TARGET_WORDS_BIGENDIAN
7871 gen_load_fpr32(fp, fs);
7872 gen_load_fpr32h(fph, ft);
7873 gen_store_fpr32h(fp, fd);
7874 gen_store_fpr32(fph, fd);
7875 #else
7876 gen_load_fpr32h(fph, fs);
7877 gen_load_fpr32(fp, ft);
7878 gen_store_fpr32(fph, fd);
7879 gen_store_fpr32h(fp, fd);
7880 #endif
7881 gen_set_label(l2);
7882 tcg_temp_free_i32(fp);
7883 tcg_temp_free_i32(fph);
7885 opn = "alnv.ps";
7886 break;
7887 case OPC_MADD_S:
7888 check_cop1x(ctx);
7890 TCGv_i32 fp0 = tcg_temp_new_i32();
7891 TCGv_i32 fp1 = tcg_temp_new_i32();
7892 TCGv_i32 fp2 = tcg_temp_new_i32();
7894 gen_load_fpr32(fp0, fs);
7895 gen_load_fpr32(fp1, ft);
7896 gen_load_fpr32(fp2, fr);
7897 gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7898 tcg_temp_free_i32(fp0);
7899 tcg_temp_free_i32(fp1);
7900 gen_store_fpr32(fp2, fd);
7901 tcg_temp_free_i32(fp2);
7903 opn = "madd.s";
7904 break;
7905 case OPC_MADD_D:
7906 check_cop1x(ctx);
7907 check_cp1_registers(ctx, fd | fs | ft | fr);
7909 TCGv_i64 fp0 = tcg_temp_new_i64();
7910 TCGv_i64 fp1 = tcg_temp_new_i64();
7911 TCGv_i64 fp2 = tcg_temp_new_i64();
7913 gen_load_fpr64(ctx, fp0, fs);
7914 gen_load_fpr64(ctx, fp1, ft);
7915 gen_load_fpr64(ctx, fp2, fr);
7916 gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7917 tcg_temp_free_i64(fp0);
7918 tcg_temp_free_i64(fp1);
7919 gen_store_fpr64(ctx, fp2, fd);
7920 tcg_temp_free_i64(fp2);
7922 opn = "madd.d";
7923 break;
7924 case OPC_MADD_PS:
7925 check_cp1_64bitmode(ctx);
7927 TCGv_i64 fp0 = tcg_temp_new_i64();
7928 TCGv_i64 fp1 = tcg_temp_new_i64();
7929 TCGv_i64 fp2 = tcg_temp_new_i64();
7931 gen_load_fpr64(ctx, fp0, fs);
7932 gen_load_fpr64(ctx, fp1, ft);
7933 gen_load_fpr64(ctx, fp2, fr);
7934 gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7935 tcg_temp_free_i64(fp0);
7936 tcg_temp_free_i64(fp1);
7937 gen_store_fpr64(ctx, fp2, fd);
7938 tcg_temp_free_i64(fp2);
7940 opn = "madd.ps";
7941 break;
7942 case OPC_MSUB_S:
7943 check_cop1x(ctx);
7945 TCGv_i32 fp0 = tcg_temp_new_i32();
7946 TCGv_i32 fp1 = tcg_temp_new_i32();
7947 TCGv_i32 fp2 = tcg_temp_new_i32();
7949 gen_load_fpr32(fp0, fs);
7950 gen_load_fpr32(fp1, ft);
7951 gen_load_fpr32(fp2, fr);
7952 gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7953 tcg_temp_free_i32(fp0);
7954 tcg_temp_free_i32(fp1);
7955 gen_store_fpr32(fp2, fd);
7956 tcg_temp_free_i32(fp2);
7958 opn = "msub.s";
7959 break;
7960 case OPC_MSUB_D:
7961 check_cop1x(ctx);
7962 check_cp1_registers(ctx, fd | fs | ft | fr);
7964 TCGv_i64 fp0 = tcg_temp_new_i64();
7965 TCGv_i64 fp1 = tcg_temp_new_i64();
7966 TCGv_i64 fp2 = tcg_temp_new_i64();
7968 gen_load_fpr64(ctx, fp0, fs);
7969 gen_load_fpr64(ctx, fp1, ft);
7970 gen_load_fpr64(ctx, fp2, fr);
7971 gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7972 tcg_temp_free_i64(fp0);
7973 tcg_temp_free_i64(fp1);
7974 gen_store_fpr64(ctx, fp2, fd);
7975 tcg_temp_free_i64(fp2);
7977 opn = "msub.d";
7978 break;
7979 case OPC_MSUB_PS:
7980 check_cp1_64bitmode(ctx);
7982 TCGv_i64 fp0 = tcg_temp_new_i64();
7983 TCGv_i64 fp1 = tcg_temp_new_i64();
7984 TCGv_i64 fp2 = tcg_temp_new_i64();
7986 gen_load_fpr64(ctx, fp0, fs);
7987 gen_load_fpr64(ctx, fp1, ft);
7988 gen_load_fpr64(ctx, fp2, fr);
7989 gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7990 tcg_temp_free_i64(fp0);
7991 tcg_temp_free_i64(fp1);
7992 gen_store_fpr64(ctx, fp2, fd);
7993 tcg_temp_free_i64(fp2);
7995 opn = "msub.ps";
7996 break;
7997 case OPC_NMADD_S:
7998 check_cop1x(ctx);
8000 TCGv_i32 fp0 = tcg_temp_new_i32();
8001 TCGv_i32 fp1 = tcg_temp_new_i32();
8002 TCGv_i32 fp2 = tcg_temp_new_i32();
8004 gen_load_fpr32(fp0, fs);
8005 gen_load_fpr32(fp1, ft);
8006 gen_load_fpr32(fp2, fr);
8007 gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
8008 tcg_temp_free_i32(fp0);
8009 tcg_temp_free_i32(fp1);
8010 gen_store_fpr32(fp2, fd);
8011 tcg_temp_free_i32(fp2);
8013 opn = "nmadd.s";
8014 break;
8015 case OPC_NMADD_D:
8016 check_cop1x(ctx);
8017 check_cp1_registers(ctx, fd | fs | ft | fr);
8019 TCGv_i64 fp0 = tcg_temp_new_i64();
8020 TCGv_i64 fp1 = tcg_temp_new_i64();
8021 TCGv_i64 fp2 = tcg_temp_new_i64();
8023 gen_load_fpr64(ctx, fp0, fs);
8024 gen_load_fpr64(ctx, fp1, ft);
8025 gen_load_fpr64(ctx, fp2, fr);
8026 gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
8027 tcg_temp_free_i64(fp0);
8028 tcg_temp_free_i64(fp1);
8029 gen_store_fpr64(ctx, fp2, fd);
8030 tcg_temp_free_i64(fp2);
8032 opn = "nmadd.d";
8033 break;
8034 case OPC_NMADD_PS:
8035 check_cp1_64bitmode(ctx);
8037 TCGv_i64 fp0 = tcg_temp_new_i64();
8038 TCGv_i64 fp1 = tcg_temp_new_i64();
8039 TCGv_i64 fp2 = tcg_temp_new_i64();
8041 gen_load_fpr64(ctx, fp0, fs);
8042 gen_load_fpr64(ctx, fp1, ft);
8043 gen_load_fpr64(ctx, fp2, fr);
8044 gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
8045 tcg_temp_free_i64(fp0);
8046 tcg_temp_free_i64(fp1);
8047 gen_store_fpr64(ctx, fp2, fd);
8048 tcg_temp_free_i64(fp2);
8050 opn = "nmadd.ps";
8051 break;
8052 case OPC_NMSUB_S:
8053 check_cop1x(ctx);
8055 TCGv_i32 fp0 = tcg_temp_new_i32();
8056 TCGv_i32 fp1 = tcg_temp_new_i32();
8057 TCGv_i32 fp2 = tcg_temp_new_i32();
8059 gen_load_fpr32(fp0, fs);
8060 gen_load_fpr32(fp1, ft);
8061 gen_load_fpr32(fp2, fr);
8062 gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
8063 tcg_temp_free_i32(fp0);
8064 tcg_temp_free_i32(fp1);
8065 gen_store_fpr32(fp2, fd);
8066 tcg_temp_free_i32(fp2);
8068 opn = "nmsub.s";
8069 break;
8070 case OPC_NMSUB_D:
8071 check_cop1x(ctx);
8072 check_cp1_registers(ctx, fd | fs | ft | fr);
8074 TCGv_i64 fp0 = tcg_temp_new_i64();
8075 TCGv_i64 fp1 = tcg_temp_new_i64();
8076 TCGv_i64 fp2 = tcg_temp_new_i64();
8078 gen_load_fpr64(ctx, fp0, fs);
8079 gen_load_fpr64(ctx, fp1, ft);
8080 gen_load_fpr64(ctx, fp2, fr);
8081 gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
8082 tcg_temp_free_i64(fp0);
8083 tcg_temp_free_i64(fp1);
8084 gen_store_fpr64(ctx, fp2, fd);
8085 tcg_temp_free_i64(fp2);
8087 opn = "nmsub.d";
8088 break;
8089 case OPC_NMSUB_PS:
8090 check_cp1_64bitmode(ctx);
8092 TCGv_i64 fp0 = tcg_temp_new_i64();
8093 TCGv_i64 fp1 = tcg_temp_new_i64();
8094 TCGv_i64 fp2 = tcg_temp_new_i64();
8096 gen_load_fpr64(ctx, fp0, fs);
8097 gen_load_fpr64(ctx, fp1, ft);
8098 gen_load_fpr64(ctx, fp2, fr);
8099 gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
8100 tcg_temp_free_i64(fp0);
8101 tcg_temp_free_i64(fp1);
8102 gen_store_fpr64(ctx, fp2, fd);
8103 tcg_temp_free_i64(fp2);
8105 opn = "nmsub.ps";
8106 break;
8107 default:
8108 MIPS_INVAL(opn);
8109 generate_exception (ctx, EXCP_RI);
8110 return;
8112 (void)opn; /* avoid a compiler warning */
8113 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
8114 fregnames[fs], fregnames[ft]);
8117 static void
8118 gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
8120 TCGv t0;
8122 check_insn(env, ctx, ISA_MIPS32R2);
8123 t0 = tcg_temp_new();
8125 switch (rd) {
8126 case 0:
8127 save_cpu_state(ctx, 1);
8128 gen_helper_rdhwr_cpunum(t0);
8129 gen_store_gpr(t0, rt);
8130 break;
8131 case 1:
8132 save_cpu_state(ctx, 1);
8133 gen_helper_rdhwr_synci_step(t0);
8134 gen_store_gpr(t0, rt);
8135 break;
8136 case 2:
8137 save_cpu_state(ctx, 1);
8138 gen_helper_rdhwr_cc(t0);
8139 gen_store_gpr(t0, rt);
8140 break;
8141 case 3:
8142 save_cpu_state(ctx, 1);
8143 gen_helper_rdhwr_ccres(t0);
8144 gen_store_gpr(t0, rt);
8145 break;
8146 case 29:
8147 #if defined(CONFIG_USER_ONLY)
8148 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
8149 gen_store_gpr(t0, rt);
8150 break;
8151 #else
8152 /* XXX: Some CPUs implement this in hardware.
8153 Not supported yet. */
8154 #endif
8155 default: /* Invalid */
8156 MIPS_INVAL("rdhwr");
8157 generate_exception(ctx, EXCP_RI);
8158 break;
8160 tcg_temp_free(t0);
8163 static void handle_delay_slot (CPUState *env, DisasContext *ctx,
8164 int insn_bytes)
8166 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8167 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8168 /* Branches completion */
8169 ctx->hflags &= ~MIPS_HFLAG_BMASK;
8170 ctx->bstate = BS_BRANCH;
8171 save_cpu_state(ctx, 0);
8172 /* FIXME: Need to clear can_do_io. */
8173 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
8174 case MIPS_HFLAG_B:
8175 /* unconditional branch */
8176 MIPS_DEBUG("unconditional branch");
8177 if (proc_hflags & MIPS_HFLAG_BX) {
8178 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
8180 gen_goto_tb(ctx, 0, ctx->btarget);
8181 break;
8182 case MIPS_HFLAG_BL:
8183 /* blikely taken case */
8184 MIPS_DEBUG("blikely branch taken");
8185 gen_goto_tb(ctx, 0, ctx->btarget);
8186 break;
8187 case MIPS_HFLAG_BC:
8188 /* Conditional branch */
8189 MIPS_DEBUG("conditional branch");
8191 int l1 = gen_new_label();
8193 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8194 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
8195 gen_set_label(l1);
8196 gen_goto_tb(ctx, 0, ctx->btarget);
8198 break;
8199 case MIPS_HFLAG_BR:
8200 /* unconditional branch to register */
8201 MIPS_DEBUG("branch to register");
8202 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
8203 TCGv t0 = tcg_temp_new();
8204 TCGv_i32 t1 = tcg_temp_new_i32();
8206 tcg_gen_andi_tl(t0, btarget, 0x1);
8207 tcg_gen_trunc_tl_i32(t1, t0);
8208 tcg_temp_free(t0);
8209 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
8210 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
8211 tcg_gen_or_i32(hflags, hflags, t1);
8212 tcg_temp_free_i32(t1);
8214 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
8215 } else {
8216 tcg_gen_mov_tl(cpu_PC, btarget);
8218 if (ctx->singlestep_enabled) {
8219 save_cpu_state(ctx, 0);
8220 gen_helper_0i(raise_exception, EXCP_DEBUG);
8222 tcg_gen_exit_tb(0);
8223 break;
8224 default:
8225 MIPS_DEBUG("unknown branch");
8226 break;
8231 /* ISA extensions (ASEs) */
8232 /* MIPS16 extension to MIPS32 */
8234 /* MIPS16 major opcodes */
8235 enum {
8236 M16_OPC_ADDIUSP = 0x00,
8237 M16_OPC_ADDIUPC = 0x01,
8238 M16_OPC_B = 0x02,
8239 M16_OPC_JAL = 0x03,
8240 M16_OPC_BEQZ = 0x04,
8241 M16_OPC_BNEQZ = 0x05,
8242 M16_OPC_SHIFT = 0x06,
8243 M16_OPC_LD = 0x07,
8244 M16_OPC_RRIA = 0x08,
8245 M16_OPC_ADDIU8 = 0x09,
8246 M16_OPC_SLTI = 0x0a,
8247 M16_OPC_SLTIU = 0x0b,
8248 M16_OPC_I8 = 0x0c,
8249 M16_OPC_LI = 0x0d,
8250 M16_OPC_CMPI = 0x0e,
8251 M16_OPC_SD = 0x0f,
8252 M16_OPC_LB = 0x10,
8253 M16_OPC_LH = 0x11,
8254 M16_OPC_LWSP = 0x12,
8255 M16_OPC_LW = 0x13,
8256 M16_OPC_LBU = 0x14,
8257 M16_OPC_LHU = 0x15,
8258 M16_OPC_LWPC = 0x16,
8259 M16_OPC_LWU = 0x17,
8260 M16_OPC_SB = 0x18,
8261 M16_OPC_SH = 0x19,
8262 M16_OPC_SWSP = 0x1a,
8263 M16_OPC_SW = 0x1b,
8264 M16_OPC_RRR = 0x1c,
8265 M16_OPC_RR = 0x1d,
8266 M16_OPC_EXTEND = 0x1e,
8267 M16_OPC_I64 = 0x1f
8270 /* I8 funct field */
8271 enum {
8272 I8_BTEQZ = 0x0,
8273 I8_BTNEZ = 0x1,
8274 I8_SWRASP = 0x2,
8275 I8_ADJSP = 0x3,
8276 I8_SVRS = 0x4,
8277 I8_MOV32R = 0x5,
8278 I8_MOVR32 = 0x7
8281 /* RRR f field */
8282 enum {
8283 RRR_DADDU = 0x0,
8284 RRR_ADDU = 0x1,
8285 RRR_DSUBU = 0x2,
8286 RRR_SUBU = 0x3
8289 /* RR funct field */
8290 enum {
8291 RR_JR = 0x00,
8292 RR_SDBBP = 0x01,
8293 RR_SLT = 0x02,
8294 RR_SLTU = 0x03,
8295 RR_SLLV = 0x04,
8296 RR_BREAK = 0x05,
8297 RR_SRLV = 0x06,
8298 RR_SRAV = 0x07,
8299 RR_DSRL = 0x08,
8300 RR_CMP = 0x0a,
8301 RR_NEG = 0x0b,
8302 RR_AND = 0x0c,
8303 RR_OR = 0x0d,
8304 RR_XOR = 0x0e,
8305 RR_NOT = 0x0f,
8306 RR_MFHI = 0x10,
8307 RR_CNVT = 0x11,
8308 RR_MFLO = 0x12,
8309 RR_DSRA = 0x13,
8310 RR_DSLLV = 0x14,
8311 RR_DSRLV = 0x16,
8312 RR_DSRAV = 0x17,
8313 RR_MULT = 0x18,
8314 RR_MULTU = 0x19,
8315 RR_DIV = 0x1a,
8316 RR_DIVU = 0x1b,
8317 RR_DMULT = 0x1c,
8318 RR_DMULTU = 0x1d,
8319 RR_DDIV = 0x1e,
8320 RR_DDIVU = 0x1f
8323 /* I64 funct field */
8324 enum {
8325 I64_LDSP = 0x0,
8326 I64_SDSP = 0x1,
8327 I64_SDRASP = 0x2,
8328 I64_DADJSP = 0x3,
8329 I64_LDPC = 0x4,
8330 I64_DADDIU5 = 0x5,
8331 I64_DADDIUPC = 0x6,
8332 I64_DADDIUSP = 0x7
8335 /* RR ry field for CNVT */
8336 enum {
8337 RR_RY_CNVT_ZEB = 0x0,
8338 RR_RY_CNVT_ZEH = 0x1,
8339 RR_RY_CNVT_ZEW = 0x2,
8340 RR_RY_CNVT_SEB = 0x4,
8341 RR_RY_CNVT_SEH = 0x5,
8342 RR_RY_CNVT_SEW = 0x6,
8345 static int xlat (int r)
8347 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8349 return map[r];
8352 static void gen_mips16_save (DisasContext *ctx,
8353 int xsregs, int aregs,
8354 int do_ra, int do_s0, int do_s1,
8355 int framesize)
8357 TCGv t0 = tcg_temp_new();
8358 TCGv t1 = tcg_temp_new();
8359 int args, astatic;
8361 switch (aregs) {
8362 case 0:
8363 case 1:
8364 case 2:
8365 case 3:
8366 case 11:
8367 args = 0;
8368 break;
8369 case 4:
8370 case 5:
8371 case 6:
8372 case 7:
8373 args = 1;
8374 break;
8375 case 8:
8376 case 9:
8377 case 10:
8378 args = 2;
8379 break;
8380 case 12:
8381 case 13:
8382 args = 3;
8383 break;
8384 case 14:
8385 args = 4;
8386 break;
8387 default:
8388 generate_exception(ctx, EXCP_RI);
8389 return;
8392 switch (args) {
8393 case 4:
8394 gen_base_offset_addr(ctx, t0, 29, 12);
8395 gen_load_gpr(t1, 7);
8396 op_st_sw(t1, t0, ctx);
8397 /* Fall through */
8398 case 3:
8399 gen_base_offset_addr(ctx, t0, 29, 8);
8400 gen_load_gpr(t1, 6);
8401 op_st_sw(t1, t0, ctx);
8402 /* Fall through */
8403 case 2:
8404 gen_base_offset_addr(ctx, t0, 29, 4);
8405 gen_load_gpr(t1, 5);
8406 op_st_sw(t1, t0, ctx);
8407 /* Fall through */
8408 case 1:
8409 gen_base_offset_addr(ctx, t0, 29, 0);
8410 gen_load_gpr(t1, 4);
8411 op_st_sw(t1, t0, ctx);
8414 gen_load_gpr(t0, 29);
8416 #define DECR_AND_STORE(reg) do { \
8417 tcg_gen_subi_tl(t0, t0, 4); \
8418 gen_load_gpr(t1, reg); \
8419 op_st_sw(t1, t0, ctx); \
8420 } while (0)
8422 if (do_ra) {
8423 DECR_AND_STORE(31);
8426 switch (xsregs) {
8427 case 7:
8428 DECR_AND_STORE(30);
8429 /* Fall through */
8430 case 6:
8431 DECR_AND_STORE(23);
8432 /* Fall through */
8433 case 5:
8434 DECR_AND_STORE(22);
8435 /* Fall through */
8436 case 4:
8437 DECR_AND_STORE(21);
8438 /* Fall through */
8439 case 3:
8440 DECR_AND_STORE(20);
8441 /* Fall through */
8442 case 2:
8443 DECR_AND_STORE(19);
8444 /* Fall through */
8445 case 1:
8446 DECR_AND_STORE(18);
8449 if (do_s1) {
8450 DECR_AND_STORE(17);
8452 if (do_s0) {
8453 DECR_AND_STORE(16);
8456 switch (aregs) {
8457 case 0:
8458 case 4:
8459 case 8:
8460 case 12:
8461 case 14:
8462 astatic = 0;
8463 break;
8464 case 1:
8465 case 5:
8466 case 9:
8467 case 13:
8468 astatic = 1;
8469 break;
8470 case 2:
8471 case 6:
8472 case 10:
8473 astatic = 2;
8474 break;
8475 case 3:
8476 case 7:
8477 astatic = 3;
8478 break;
8479 case 11:
8480 astatic = 4;
8481 break;
8482 default:
8483 generate_exception(ctx, EXCP_RI);
8484 return;
8487 if (astatic > 0) {
8488 DECR_AND_STORE(7);
8489 if (astatic > 1) {
8490 DECR_AND_STORE(6);
8491 if (astatic > 2) {
8492 DECR_AND_STORE(5);
8493 if (astatic > 3) {
8494 DECR_AND_STORE(4);
8499 #undef DECR_AND_STORE
8501 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8502 tcg_temp_free(t0);
8503 tcg_temp_free(t1);
8506 static void gen_mips16_restore (DisasContext *ctx,
8507 int xsregs, int aregs,
8508 int do_ra, int do_s0, int do_s1,
8509 int framesize)
8511 int astatic;
8512 TCGv t0 = tcg_temp_new();
8513 TCGv t1 = tcg_temp_new();
8515 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8517 #define DECR_AND_LOAD(reg) do { \
8518 tcg_gen_subi_tl(t0, t0, 4); \
8519 op_ld_lw(t1, t0, ctx); \
8520 gen_store_gpr(t1, reg); \
8521 } while (0)
8523 if (do_ra) {
8524 DECR_AND_LOAD(31);
8527 switch (xsregs) {
8528 case 7:
8529 DECR_AND_LOAD(30);
8530 /* Fall through */
8531 case 6:
8532 DECR_AND_LOAD(23);
8533 /* Fall through */
8534 case 5:
8535 DECR_AND_LOAD(22);
8536 /* Fall through */
8537 case 4:
8538 DECR_AND_LOAD(21);
8539 /* Fall through */
8540 case 3:
8541 DECR_AND_LOAD(20);
8542 /* Fall through */
8543 case 2:
8544 DECR_AND_LOAD(19);
8545 /* Fall through */
8546 case 1:
8547 DECR_AND_LOAD(18);
8550 if (do_s1) {
8551 DECR_AND_LOAD(17);
8553 if (do_s0) {
8554 DECR_AND_LOAD(16);
8557 switch (aregs) {
8558 case 0:
8559 case 4:
8560 case 8:
8561 case 12:
8562 case 14:
8563 astatic = 0;
8564 break;
8565 case 1:
8566 case 5:
8567 case 9:
8568 case 13:
8569 astatic = 1;
8570 break;
8571 case 2:
8572 case 6:
8573 case 10:
8574 astatic = 2;
8575 break;
8576 case 3:
8577 case 7:
8578 astatic = 3;
8579 break;
8580 case 11:
8581 astatic = 4;
8582 break;
8583 default:
8584 generate_exception(ctx, EXCP_RI);
8585 return;
8588 if (astatic > 0) {
8589 DECR_AND_LOAD(7);
8590 if (astatic > 1) {
8591 DECR_AND_LOAD(6);
8592 if (astatic > 2) {
8593 DECR_AND_LOAD(5);
8594 if (astatic > 3) {
8595 DECR_AND_LOAD(4);
8600 #undef DECR_AND_LOAD
8602 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8603 tcg_temp_free(t0);
8604 tcg_temp_free(t1);
8607 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8608 int is_64_bit, int extended)
8610 TCGv t0;
8612 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8613 generate_exception(ctx, EXCP_RI);
8614 return;
8617 t0 = tcg_temp_new();
8619 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8620 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8621 if (!is_64_bit) {
8622 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8625 tcg_temp_free(t0);
8628 #if defined(TARGET_MIPS64)
8629 static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8630 int ry, int funct, int16_t offset,
8631 int extended)
8633 switch (funct) {
8634 case I64_LDSP:
8635 check_mips_64(ctx);
8636 offset = extended ? offset : offset << 3;
8637 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
8638 break;
8639 case I64_SDSP:
8640 check_mips_64(ctx);
8641 offset = extended ? offset : offset << 3;
8642 gen_st(ctx, OPC_SD, ry, 29, offset);
8643 break;
8644 case I64_SDRASP:
8645 check_mips_64(ctx);
8646 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8647 gen_st(ctx, OPC_SD, 31, 29, offset);
8648 break;
8649 case I64_DADJSP:
8650 check_mips_64(ctx);
8651 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8652 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8653 break;
8654 case I64_LDPC:
8655 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8656 generate_exception(ctx, EXCP_RI);
8657 } else {
8658 offset = extended ? offset : offset << 3;
8659 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
8661 break;
8662 case I64_DADDIU5:
8663 check_mips_64(ctx);
8664 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8665 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8666 break;
8667 case I64_DADDIUPC:
8668 check_mips_64(ctx);
8669 offset = extended ? offset : offset << 2;
8670 gen_addiupc(ctx, ry, offset, 1, extended);
8671 break;
8672 case I64_DADDIUSP:
8673 check_mips_64(ctx);
8674 offset = extended ? offset : offset << 2;
8675 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8676 break;
8679 #endif
8681 static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8682 int *is_branch)
8684 int extend = lduw_code(ctx->pc + 2);
8685 int op, rx, ry, funct, sa;
8686 int16_t imm, offset;
8688 ctx->opcode = (ctx->opcode << 16) | extend;
8689 op = (ctx->opcode >> 11) & 0x1f;
8690 sa = (ctx->opcode >> 22) & 0x1f;
8691 funct = (ctx->opcode >> 8) & 0x7;
8692 rx = xlat((ctx->opcode >> 8) & 0x7);
8693 ry = xlat((ctx->opcode >> 5) & 0x7);
8694 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8695 | ((ctx->opcode >> 21) & 0x3f) << 5
8696 | (ctx->opcode & 0x1f));
8698 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8699 counterparts. */
8700 switch (op) {
8701 case M16_OPC_ADDIUSP:
8702 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8703 break;
8704 case M16_OPC_ADDIUPC:
8705 gen_addiupc(ctx, rx, imm, 0, 1);
8706 break;
8707 case M16_OPC_B:
8708 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8709 /* No delay slot, so just process as a normal instruction */
8710 break;
8711 case M16_OPC_BEQZ:
8712 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8713 /* No delay slot, so just process as a normal instruction */
8714 break;
8715 case M16_OPC_BNEQZ:
8716 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8717 /* No delay slot, so just process as a normal instruction */
8718 break;
8719 case M16_OPC_SHIFT:
8720 switch (ctx->opcode & 0x3) {
8721 case 0x0:
8722 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8723 break;
8724 case 0x1:
8725 #if defined(TARGET_MIPS64)
8726 check_mips_64(ctx);
8727 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8728 #else
8729 generate_exception(ctx, EXCP_RI);
8730 #endif
8731 break;
8732 case 0x2:
8733 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8734 break;
8735 case 0x3:
8736 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8737 break;
8739 break;
8740 #if defined(TARGET_MIPS64)
8741 case M16_OPC_LD:
8742 check_mips_64(ctx);
8743 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
8744 break;
8745 #endif
8746 case M16_OPC_RRIA:
8747 imm = ctx->opcode & 0xf;
8748 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8749 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8750 imm = (int16_t) (imm << 1) >> 1;
8751 if ((ctx->opcode >> 4) & 0x1) {
8752 #if defined(TARGET_MIPS64)
8753 check_mips_64(ctx);
8754 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8755 #else
8756 generate_exception(ctx, EXCP_RI);
8757 #endif
8758 } else {
8759 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8761 break;
8762 case M16_OPC_ADDIU8:
8763 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8764 break;
8765 case M16_OPC_SLTI:
8766 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8767 break;
8768 case M16_OPC_SLTIU:
8769 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8770 break;
8771 case M16_OPC_I8:
8772 switch (funct) {
8773 case I8_BTEQZ:
8774 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8775 break;
8776 case I8_BTNEZ:
8777 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8778 break;
8779 case I8_SWRASP:
8780 gen_st(ctx, OPC_SW, 31, 29, imm);
8781 break;
8782 case I8_ADJSP:
8783 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8784 break;
8785 case I8_SVRS:
8787 int xsregs = (ctx->opcode >> 24) & 0x7;
8788 int aregs = (ctx->opcode >> 16) & 0xf;
8789 int do_ra = (ctx->opcode >> 6) & 0x1;
8790 int do_s0 = (ctx->opcode >> 5) & 0x1;
8791 int do_s1 = (ctx->opcode >> 4) & 0x1;
8792 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8793 | (ctx->opcode & 0xf)) << 3;
8795 if (ctx->opcode & (1 << 7)) {
8796 gen_mips16_save(ctx, xsregs, aregs,
8797 do_ra, do_s0, do_s1,
8798 framesize);
8799 } else {
8800 gen_mips16_restore(ctx, xsregs, aregs,
8801 do_ra, do_s0, do_s1,
8802 framesize);
8805 break;
8806 default:
8807 generate_exception(ctx, EXCP_RI);
8808 break;
8810 break;
8811 case M16_OPC_LI:
8812 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8813 break;
8814 case M16_OPC_CMPI:
8815 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8816 break;
8817 #if defined(TARGET_MIPS64)
8818 case M16_OPC_SD:
8819 gen_st(ctx, OPC_SD, ry, rx, offset);
8820 break;
8821 #endif
8822 case M16_OPC_LB:
8823 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8824 break;
8825 case M16_OPC_LH:
8826 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
8827 break;
8828 case M16_OPC_LWSP:
8829 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
8830 break;
8831 case M16_OPC_LW:
8832 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
8833 break;
8834 case M16_OPC_LBU:
8835 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8836 break;
8837 case M16_OPC_LHU:
8838 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
8839 break;
8840 case M16_OPC_LWPC:
8841 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
8842 break;
8843 #if defined(TARGET_MIPS64)
8844 case M16_OPC_LWU:
8845 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
8846 break;
8847 #endif
8848 case M16_OPC_SB:
8849 gen_st(ctx, OPC_SB, ry, rx, offset);
8850 break;
8851 case M16_OPC_SH:
8852 gen_st(ctx, OPC_SH, ry, rx, offset);
8853 break;
8854 case M16_OPC_SWSP:
8855 gen_st(ctx, OPC_SW, rx, 29, offset);
8856 break;
8857 case M16_OPC_SW:
8858 gen_st(ctx, OPC_SW, ry, rx, offset);
8859 break;
8860 #if defined(TARGET_MIPS64)
8861 case M16_OPC_I64:
8862 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8863 break;
8864 #endif
8865 default:
8866 generate_exception(ctx, EXCP_RI);
8867 break;
8870 return 4;
8873 static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8874 int *is_branch)
8876 int rx, ry;
8877 int sa;
8878 int op, cnvt_op, op1, offset;
8879 int funct;
8880 int n_bytes;
8882 op = (ctx->opcode >> 11) & 0x1f;
8883 sa = (ctx->opcode >> 2) & 0x7;
8884 sa = sa == 0 ? 8 : sa;
8885 rx = xlat((ctx->opcode >> 8) & 0x7);
8886 cnvt_op = (ctx->opcode >> 5) & 0x7;
8887 ry = xlat((ctx->opcode >> 5) & 0x7);
8888 op1 = offset = ctx->opcode & 0x1f;
8890 n_bytes = 2;
8892 switch (op) {
8893 case M16_OPC_ADDIUSP:
8895 int16_t imm = ((uint8_t) ctx->opcode) << 2;
8897 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8899 break;
8900 case M16_OPC_ADDIUPC:
8901 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8902 break;
8903 case M16_OPC_B:
8904 offset = (ctx->opcode & 0x7ff) << 1;
8905 offset = (int16_t)(offset << 4) >> 4;
8906 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8907 /* No delay slot, so just process as a normal instruction */
8908 break;
8909 case M16_OPC_JAL:
8910 offset = lduw_code(ctx->pc + 2);
8911 offset = (((ctx->opcode & 0x1f) << 21)
8912 | ((ctx->opcode >> 5) & 0x1f) << 16
8913 | offset) << 2;
8914 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8915 gen_compute_branch(ctx, op, 4, rx, ry, offset);
8916 n_bytes = 4;
8917 *is_branch = 1;
8918 break;
8919 case M16_OPC_BEQZ:
8920 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8921 /* No delay slot, so just process as a normal instruction */
8922 break;
8923 case M16_OPC_BNEQZ:
8924 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8925 /* No delay slot, so just process as a normal instruction */
8926 break;
8927 case M16_OPC_SHIFT:
8928 switch (ctx->opcode & 0x3) {
8929 case 0x0:
8930 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8931 break;
8932 case 0x1:
8933 #if defined(TARGET_MIPS64)
8934 check_mips_64(ctx);
8935 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8936 #else
8937 generate_exception(ctx, EXCP_RI);
8938 #endif
8939 break;
8940 case 0x2:
8941 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8942 break;
8943 case 0x3:
8944 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8945 break;
8947 break;
8948 #if defined(TARGET_MIPS64)
8949 case M16_OPC_LD:
8950 check_mips_64(ctx);
8951 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
8952 break;
8953 #endif
8954 case M16_OPC_RRIA:
8956 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8958 if ((ctx->opcode >> 4) & 1) {
8959 #if defined(TARGET_MIPS64)
8960 check_mips_64(ctx);
8961 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8962 #else
8963 generate_exception(ctx, EXCP_RI);
8964 #endif
8965 } else {
8966 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8969 break;
8970 case M16_OPC_ADDIU8:
8972 int16_t imm = (int8_t) ctx->opcode;
8974 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8976 break;
8977 case M16_OPC_SLTI:
8979 int16_t imm = (uint8_t) ctx->opcode;
8981 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8983 break;
8984 case M16_OPC_SLTIU:
8986 int16_t imm = (uint8_t) ctx->opcode;
8988 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8990 break;
8991 case M16_OPC_I8:
8993 int reg32;
8995 funct = (ctx->opcode >> 8) & 0x7;
8996 switch (funct) {
8997 case I8_BTEQZ:
8998 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8999 ((int8_t)ctx->opcode) << 1);
9000 break;
9001 case I8_BTNEZ:
9002 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9003 ((int8_t)ctx->opcode) << 1);
9004 break;
9005 case I8_SWRASP:
9006 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9007 break;
9008 case I8_ADJSP:
9009 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9010 ((int8_t)ctx->opcode) << 3);
9011 break;
9012 case I8_SVRS:
9014 int do_ra = ctx->opcode & (1 << 6);
9015 int do_s0 = ctx->opcode & (1 << 5);
9016 int do_s1 = ctx->opcode & (1 << 4);
9017 int framesize = ctx->opcode & 0xf;
9019 if (framesize == 0) {
9020 framesize = 128;
9021 } else {
9022 framesize = framesize << 3;
9025 if (ctx->opcode & (1 << 7)) {
9026 gen_mips16_save(ctx, 0, 0,
9027 do_ra, do_s0, do_s1, framesize);
9028 } else {
9029 gen_mips16_restore(ctx, 0, 0,
9030 do_ra, do_s0, do_s1, framesize);
9033 break;
9034 case I8_MOV32R:
9036 int rz = xlat(ctx->opcode & 0x7);
9038 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9039 ((ctx->opcode >> 5) & 0x7);
9040 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9042 break;
9043 case I8_MOVR32:
9044 reg32 = ctx->opcode & 0x1f;
9045 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9046 break;
9047 default:
9048 generate_exception(ctx, EXCP_RI);
9049 break;
9052 break;
9053 case M16_OPC_LI:
9055 int16_t imm = (uint8_t) ctx->opcode;
9057 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9059 break;
9060 case M16_OPC_CMPI:
9062 int16_t imm = (uint8_t) ctx->opcode;
9064 gen_logic_imm(env, OPC_XORI, 24, rx, imm);
9066 break;
9067 #if defined(TARGET_MIPS64)
9068 case M16_OPC_SD:
9069 check_mips_64(ctx);
9070 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9071 break;
9072 #endif
9073 case M16_OPC_LB:
9074 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9075 break;
9076 case M16_OPC_LH:
9077 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9078 break;
9079 case M16_OPC_LWSP:
9080 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9081 break;
9082 case M16_OPC_LW:
9083 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9084 break;
9085 case M16_OPC_LBU:
9086 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9087 break;
9088 case M16_OPC_LHU:
9089 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9090 break;
9091 case M16_OPC_LWPC:
9092 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9093 break;
9094 #if defined (TARGET_MIPS64)
9095 case M16_OPC_LWU:
9096 check_mips_64(ctx);
9097 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9098 break;
9099 #endif
9100 case M16_OPC_SB:
9101 gen_st(ctx, OPC_SB, ry, rx, offset);
9102 break;
9103 case M16_OPC_SH:
9104 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9105 break;
9106 case M16_OPC_SWSP:
9107 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9108 break;
9109 case M16_OPC_SW:
9110 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9111 break;
9112 case M16_OPC_RRR:
9114 int rz = xlat((ctx->opcode >> 2) & 0x7);
9115 int mips32_op;
9117 switch (ctx->opcode & 0x3) {
9118 case RRR_ADDU:
9119 mips32_op = OPC_ADDU;
9120 break;
9121 case RRR_SUBU:
9122 mips32_op = OPC_SUBU;
9123 break;
9124 #if defined(TARGET_MIPS64)
9125 case RRR_DADDU:
9126 mips32_op = OPC_DADDU;
9127 check_mips_64(ctx);
9128 break;
9129 case RRR_DSUBU:
9130 mips32_op = OPC_DSUBU;
9131 check_mips_64(ctx);
9132 break;
9133 #endif
9134 default:
9135 generate_exception(ctx, EXCP_RI);
9136 goto done;
9139 gen_arith(env, ctx, mips32_op, rz, rx, ry);
9140 done:
9143 break;
9144 case M16_OPC_RR:
9145 switch (op1) {
9146 case RR_JR:
9148 int nd = (ctx->opcode >> 7) & 0x1;
9149 int link = (ctx->opcode >> 6) & 0x1;
9150 int ra = (ctx->opcode >> 5) & 0x1;
9152 if (link) {
9153 op = nd ? OPC_JALRC : OPC_JALRS;
9154 } else {
9155 op = OPC_JR;
9158 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9159 if (!nd) {
9160 *is_branch = 1;
9163 break;
9164 case RR_SDBBP:
9165 /* XXX: not clear which exception should be raised
9166 * when in debug mode...
9168 check_insn(env, ctx, ISA_MIPS32);
9169 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9170 generate_exception(ctx, EXCP_DBp);
9171 } else {
9172 generate_exception(ctx, EXCP_DBp);
9174 break;
9175 case RR_SLT:
9176 gen_slt(env, OPC_SLT, 24, rx, ry);
9177 break;
9178 case RR_SLTU:
9179 gen_slt(env, OPC_SLTU, 24, rx, ry);
9180 break;
9181 case RR_BREAK:
9182 generate_exception(ctx, EXCP_BREAK);
9183 break;
9184 case RR_SLLV:
9185 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9186 break;
9187 case RR_SRLV:
9188 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9189 break;
9190 case RR_SRAV:
9191 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9192 break;
9193 #if defined (TARGET_MIPS64)
9194 case RR_DSRL:
9195 check_mips_64(ctx);
9196 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9197 break;
9198 #endif
9199 case RR_CMP:
9200 gen_logic(env, OPC_XOR, 24, rx, ry);
9201 break;
9202 case RR_NEG:
9203 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9204 break;
9205 case RR_AND:
9206 gen_logic(env, OPC_AND, rx, rx, ry);
9207 break;
9208 case RR_OR:
9209 gen_logic(env, OPC_OR, rx, rx, ry);
9210 break;
9211 case RR_XOR:
9212 gen_logic(env, OPC_XOR, rx, rx, ry);
9213 break;
9214 case RR_NOT:
9215 gen_logic(env, OPC_NOR, rx, ry, 0);
9216 break;
9217 case RR_MFHI:
9218 gen_HILO(ctx, OPC_MFHI, rx);
9219 break;
9220 case RR_CNVT:
9221 switch (cnvt_op) {
9222 case RR_RY_CNVT_ZEB:
9223 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9224 break;
9225 case RR_RY_CNVT_ZEH:
9226 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9227 break;
9228 case RR_RY_CNVT_SEB:
9229 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9230 break;
9231 case RR_RY_CNVT_SEH:
9232 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9233 break;
9234 #if defined (TARGET_MIPS64)
9235 case RR_RY_CNVT_ZEW:
9236 check_mips_64(ctx);
9237 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9238 break;
9239 case RR_RY_CNVT_SEW:
9240 check_mips_64(ctx);
9241 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9242 break;
9243 #endif
9244 default:
9245 generate_exception(ctx, EXCP_RI);
9246 break;
9248 break;
9249 case RR_MFLO:
9250 gen_HILO(ctx, OPC_MFLO, rx);
9251 break;
9252 #if defined (TARGET_MIPS64)
9253 case RR_DSRA:
9254 check_mips_64(ctx);
9255 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9256 break;
9257 case RR_DSLLV:
9258 check_mips_64(ctx);
9259 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9260 break;
9261 case RR_DSRLV:
9262 check_mips_64(ctx);
9263 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9264 break;
9265 case RR_DSRAV:
9266 check_mips_64(ctx);
9267 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9268 break;
9269 #endif
9270 case RR_MULT:
9271 gen_muldiv(ctx, OPC_MULT, rx, ry);
9272 break;
9273 case RR_MULTU:
9274 gen_muldiv(ctx, OPC_MULTU, rx, ry);
9275 break;
9276 case RR_DIV:
9277 gen_muldiv(ctx, OPC_DIV, rx, ry);
9278 break;
9279 case RR_DIVU:
9280 gen_muldiv(ctx, OPC_DIVU, rx, ry);
9281 break;
9282 #if defined (TARGET_MIPS64)
9283 case RR_DMULT:
9284 check_mips_64(ctx);
9285 gen_muldiv(ctx, OPC_DMULT, rx, ry);
9286 break;
9287 case RR_DMULTU:
9288 check_mips_64(ctx);
9289 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9290 break;
9291 case RR_DDIV:
9292 check_mips_64(ctx);
9293 gen_muldiv(ctx, OPC_DDIV, rx, ry);
9294 break;
9295 case RR_DDIVU:
9296 check_mips_64(ctx);
9297 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9298 break;
9299 #endif
9300 default:
9301 generate_exception(ctx, EXCP_RI);
9302 break;
9304 break;
9305 case M16_OPC_EXTEND:
9306 decode_extended_mips16_opc(env, ctx, is_branch);
9307 n_bytes = 4;
9308 break;
9309 #if defined(TARGET_MIPS64)
9310 case M16_OPC_I64:
9311 funct = (ctx->opcode >> 8) & 0x7;
9312 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9313 break;
9314 #endif
9315 default:
9316 generate_exception(ctx, EXCP_RI);
9317 break;
9320 return n_bytes;
9323 /* microMIPS extension to MIPS32 */
9325 /* microMIPS32 major opcodes */
9327 enum {
9328 POOL32A = 0x00,
9329 POOL16A = 0x01,
9330 LBU16 = 0x02,
9331 MOVE16 = 0x03,
9332 ADDI32 = 0x04,
9333 LBU32 = 0x05,
9334 SB32 = 0x06,
9335 LB32 = 0x07,
9337 POOL32B = 0x08,
9338 POOL16B = 0x09,
9339 LHU16 = 0x0a,
9340 ANDI16 = 0x0b,
9341 ADDIU32 = 0x0c,
9342 LHU32 = 0x0d,
9343 SH32 = 0x0e,
9344 LH32 = 0x0f,
9346 POOL32I = 0x10,
9347 POOL16C = 0x11,
9348 LWSP16 = 0x12,
9349 POOL16D = 0x13,
9350 ORI32 = 0x14,
9351 POOL32F = 0x15,
9352 POOL32S = 0x16,
9353 DADDIU32 = 0x17,
9355 POOL32C = 0x18,
9356 LWGP16 = 0x19,
9357 LW16 = 0x1a,
9358 POOL16E = 0x1b,
9359 XORI32 = 0x1c,
9360 JALS32 = 0x1d,
9361 ADDIUPC = 0x1e,
9362 POOL48A = 0x1f,
9364 /* 0x20 is reserved */
9365 RES_20 = 0x20,
9366 POOL16F = 0x21,
9367 SB16 = 0x22,
9368 BEQZ16 = 0x23,
9369 SLTI32 = 0x24,
9370 BEQ32 = 0x25,
9371 SWC132 = 0x26,
9372 LWC132 = 0x27,
9374 /* 0x28 and 0x29 are reserved */
9375 RES_28 = 0x28,
9376 RES_29 = 0x29,
9377 SH16 = 0x2a,
9378 BNEZ16 = 0x2b,
9379 SLTIU32 = 0x2c,
9380 BNE32 = 0x2d,
9381 SDC132 = 0x2e,
9382 LDC132 = 0x2f,
9384 /* 0x30 and 0x31 are reserved */
9385 RES_30 = 0x30,
9386 RES_31 = 0x31,
9387 SWSP16 = 0x32,
9388 B16 = 0x33,
9389 ANDI32 = 0x34,
9390 J32 = 0x35,
9391 SD32 = 0x36,
9392 LD32 = 0x37,
9394 /* 0x38 and 0x39 are reserved */
9395 RES_38 = 0x38,
9396 RES_39 = 0x39,
9397 SW16 = 0x3a,
9398 LI16 = 0x3b,
9399 JALX32 = 0x3c,
9400 JAL32 = 0x3d,
9401 SW32 = 0x3e,
9402 LW32 = 0x3f
9405 /* POOL32A encoding of minor opcode field */
9407 enum {
9408 /* These opcodes are distinguished only by bits 9..6; those bits are
9409 * what are recorded below. */
9410 SLL32 = 0x0,
9411 SRL32 = 0x1,
9412 SRA = 0x2,
9413 ROTR = 0x3,
9415 SLLV = 0x0,
9416 SRLV = 0x1,
9417 SRAV = 0x2,
9418 ROTRV = 0x3,
9419 ADD = 0x4,
9420 ADDU32 = 0x5,
9421 SUB = 0x6,
9422 SUBU32 = 0x7,
9423 MUL = 0x8,
9424 AND = 0x9,
9425 OR32 = 0xa,
9426 NOR = 0xb,
9427 XOR32 = 0xc,
9428 SLT = 0xd,
9429 SLTU = 0xe,
9431 MOVN = 0x0,
9432 MOVZ = 0x1,
9433 LWXS = 0x4,
9435 /* The following can be distinguished by their lower 6 bits. */
9436 INS = 0x0c,
9437 EXT = 0x2c,
9438 POOL32AXF = 0x3c
9441 /* POOL32AXF encoding of minor opcode field extension */
9443 enum {
9444 /* bits 11..6 */
9445 TEQ = 0x00,
9446 TGE = 0x08,
9447 TGEU = 0x10,
9448 TLT = 0x20,
9449 TLTU = 0x28,
9450 TNE = 0x30,
9452 MFC0 = 0x03,
9453 MTC0 = 0x0b,
9455 /* bits 13..12 for 0x01 */
9456 MFHI_ACC = 0x0,
9457 MFLO_ACC = 0x1,
9458 MTHI_ACC = 0x2,
9459 MTLO_ACC = 0x3,
9461 /* bits 13..12 for 0x2a */
9462 MADD_ACC = 0x0,
9463 MADDU_ACC = 0x1,
9464 MSUB_ACC = 0x2,
9465 MSUBU_ACC = 0x3,
9467 /* bits 13..12 for 0x32 */
9468 MULT_ACC = 0x0,
9469 MULTU_ACC = 0x0,
9471 /* bits 15..12 for 0x2c */
9472 SEB = 0x2,
9473 SEH = 0x3,
9474 CLO = 0x4,
9475 CLZ = 0x5,
9476 RDHWR = 0x6,
9477 WSBH = 0x7,
9478 MULT = 0x8,
9479 MULTU = 0x9,
9480 DIV = 0xa,
9481 DIVU = 0xb,
9482 MADD = 0xc,
9483 MADDU = 0xd,
9484 MSUB = 0xe,
9485 MSUBU = 0xf,
9487 /* bits 15..12 for 0x34 */
9488 MFC2 = 0x4,
9489 MTC2 = 0x5,
9490 MFHC2 = 0x8,
9491 MTHC2 = 0x9,
9492 CFC2 = 0xc,
9493 CTC2 = 0xd,
9495 /* bits 15..12 for 0x3c */
9496 JALR = 0x0,
9497 JR = 0x0, /* alias */
9498 JALR_HB = 0x1,
9499 JALRS = 0x4,
9500 JALRS_HB = 0x5,
9502 /* bits 15..12 for 0x05 */
9503 RDPGPR = 0xe,
9504 WRPGPR = 0xf,
9506 /* bits 15..12 for 0x0d */
9507 TLBP = 0x0,
9508 TLBR = 0x1,
9509 TLBWI = 0x2,
9510 TLBWR = 0x3,
9511 WAIT = 0x9,
9512 IRET = 0xd,
9513 DERET = 0xe,
9514 ERET = 0xf,
9516 /* bits 15..12 for 0x15 */
9517 DMT = 0x0,
9518 DVPE = 0x1,
9519 EMT = 0x2,
9520 EVPE = 0x3,
9522 /* bits 15..12 for 0x1d */
9523 DI = 0x4,
9524 EI = 0x5,
9526 /* bits 15..12 for 0x2d */
9527 SYNC = 0x6,
9528 SYSCALL = 0x8,
9529 SDBBP = 0xd,
9531 /* bits 15..12 for 0x35 */
9532 MFHI32 = 0x0,
9533 MFLO32 = 0x1,
9534 MTHI32 = 0x2,
9535 MTLO32 = 0x3,
9538 /* POOL32B encoding of minor opcode field (bits 15..12) */
9540 enum {
9541 LWC2 = 0x0,
9542 LWP = 0x1,
9543 LDP = 0x4,
9544 LWM32 = 0x5,
9545 CACHE = 0x6,
9546 LDM = 0x7,
9547 SWC2 = 0x8,
9548 SWP = 0x9,
9549 SDP = 0xc,
9550 SWM32 = 0xd,
9551 SDM = 0xf
9554 /* POOL32C encoding of minor opcode field (bits 15..12) */
9556 enum {
9557 LWL = 0x0,
9558 SWL = 0x8,
9559 LWR = 0x1,
9560 SWR = 0x9,
9561 PREF = 0x2,
9562 /* 0xa is reserved */
9563 LL = 0x3,
9564 SC = 0xb,
9565 LDL = 0x4,
9566 SDL = 0xc,
9567 LDR = 0x5,
9568 SDR = 0xd,
9569 /* 0x6 is reserved */
9570 LWU = 0xe,
9571 LLD = 0x7,
9572 SCD = 0xf
9575 /* POOL32F encoding of minor opcode field (bits 5..0) */
9577 enum {
9578 /* These are the bit 7..6 values */
9579 ADD_FMT = 0x0,
9580 MOVN_FMT = 0x0,
9582 SUB_FMT = 0x1,
9583 MOVZ_FMT = 0x1,
9585 MUL_FMT = 0x2,
9587 DIV_FMT = 0x3,
9589 /* These are the bit 8..6 values */
9590 RSQRT2_FMT = 0x0,
9591 MOVF_FMT = 0x0,
9593 LWXC1 = 0x1,
9594 MOVT_FMT = 0x1,
9596 PLL_PS = 0x2,
9597 SWXC1 = 0x2,
9599 PLU_PS = 0x3,
9600 LDXC1 = 0x3,
9602 PUL_PS = 0x4,
9603 SDXC1 = 0x4,
9604 RECIP2_FMT = 0x4,
9606 PUU_PS = 0x5,
9607 LUXC1 = 0x5,
9609 CVT_PS_S = 0x6,
9610 SUXC1 = 0x6,
9611 ADDR_PS = 0x6,
9612 PREFX = 0x6,
9614 MULR_PS = 0x7,
9616 MADD_S = 0x01,
9617 MADD_D = 0x09,
9618 MADD_PS = 0x11,
9619 ALNV_PS = 0x19,
9620 MSUB_S = 0x21,
9621 MSUB_D = 0x29,
9622 MSUB_PS = 0x31,
9624 NMADD_S = 0x02,
9625 NMADD_D = 0x0a,
9626 NMADD_PS = 0x12,
9627 NMSUB_S = 0x22,
9628 NMSUB_D = 0x2a,
9629 NMSUB_PS = 0x32,
9631 POOL32FXF = 0x3b,
9633 CABS_COND_FMT = 0x1c, /* MIPS3D */
9634 C_COND_FMT = 0x3c
9637 /* POOL32Fxf encoding of minor opcode extension field */
9639 enum {
9640 CVT_L = 0x04,
9641 RSQRT_FMT = 0x08,
9642 FLOOR_L = 0x0c,
9643 CVT_PW_PS = 0x1c,
9644 CVT_W = 0x24,
9645 SQRT_FMT = 0x28,
9646 FLOOR_W = 0x2c,
9647 CVT_PS_PW = 0x3c,
9648 CFC1 = 0x40,
9649 RECIP_FMT = 0x48,
9650 CEIL_L = 0x4c,
9651 CTC1 = 0x60,
9652 CEIL_W = 0x6c,
9653 MFC1 = 0x80,
9654 CVT_S_PL = 0x84,
9655 TRUNC_L = 0x8c,
9656 MTC1 = 0xa0,
9657 CVT_S_PU = 0xa4,
9658 TRUNC_W = 0xac,
9659 MFHC1 = 0xc0,
9660 ROUND_L = 0xcc,
9661 MTHC1 = 0xe0,
9662 ROUND_W = 0xec,
9664 MOV_FMT = 0x01,
9665 MOVF = 0x05,
9666 ABS_FMT = 0x0d,
9667 RSQRT1_FMT = 0x1d,
9668 MOVT = 0x25,
9669 NEG_FMT = 0x2d,
9670 CVT_D = 0x4d,
9671 RECIP1_FMT = 0x5d,
9672 CVT_S = 0x6d
9675 /* POOL32I encoding of minor opcode field (bits 25..21) */
9677 enum {
9678 BLTZ = 0x00,
9679 BLTZAL = 0x01,
9680 BGEZ = 0x02,
9681 BGEZAL = 0x03,
9682 BLEZ = 0x04,
9683 BNEZC = 0x05,
9684 BGTZ = 0x06,
9685 BEQZC = 0x07,
9686 TLTI = 0x08,
9687 TGEI = 0x09,
9688 TLTIU = 0x0a,
9689 TGEIU = 0x0b,
9690 TNEI = 0x0c,
9691 LUI = 0x0d,
9692 TEQI = 0x0e,
9693 SYNCI = 0x10,
9694 BLTZALS = 0x11,
9695 BGEZALS = 0x13,
9696 BC2F = 0x14,
9697 BC2T = 0x15,
9698 BPOSGE64 = 0x1a,
9699 BPOSGE32 = 0x1b,
9700 /* These overlap and are distinguished by bit16 of the instruction */
9701 BC1F = 0x1c,
9702 BC1T = 0x1d,
9703 BC1ANY2F = 0x1c,
9704 BC1ANY2T = 0x1d,
9705 BC1ANY4F = 0x1e,
9706 BC1ANY4T = 0x1f
9709 /* POOL16A encoding of minor opcode field */
9711 enum {
9712 ADDU16 = 0x0,
9713 SUBU16 = 0x1
9716 /* POOL16B encoding of minor opcode field */
9718 enum {
9719 SLL16 = 0x0,
9720 SRL16 = 0x1
9723 /* POOL16C encoding of minor opcode field */
9725 enum {
9726 NOT16 = 0x00,
9727 XOR16 = 0x04,
9728 AND16 = 0x08,
9729 OR16 = 0x0c,
9730 LWM16 = 0x10,
9731 SWM16 = 0x14,
9732 JR16 = 0x18,
9733 JRC16 = 0x1a,
9734 JALR16 = 0x1c,
9735 JALR16S = 0x1e,
9736 MFHI16 = 0x20,
9737 MFLO16 = 0x24,
9738 BREAK16 = 0x28,
9739 SDBBP16 = 0x2c,
9740 JRADDIUSP = 0x30
9743 /* POOL16D encoding of minor opcode field */
9745 enum {
9746 ADDIUS5 = 0x0,
9747 ADDIUSP = 0x1
9750 /* POOL16E encoding of minor opcode field */
9752 enum {
9753 ADDIUR2 = 0x0,
9754 ADDIUR1SP = 0x1
9757 static int mmreg (int r)
9759 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9761 return map[r];
9764 /* Used for 16-bit store instructions. */
9765 static int mmreg2 (int r)
9767 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9769 return map[r];
9772 #define uMIPS_RD(op) ((op >> 7) & 0x7)
9773 #define uMIPS_RS(op) ((op >> 4) & 0x7)
9774 #define uMIPS_RS2(op) uMIPS_RS(op)
9775 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
9776 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9777 #define uMIPS_RS5(op) (op & 0x1f)
9779 /* Signed immediate */
9780 #define SIMM(op, start, width) \
9781 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
9782 << (32-width)) \
9783 >> (32-width))
9784 /* Zero-extended immediate */
9785 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9787 static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
9789 int rd = mmreg(uMIPS_RD(ctx->opcode));
9791 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9794 static void gen_addiur2 (CPUState *env, DisasContext *ctx)
9796 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9797 int rd = mmreg(uMIPS_RD(ctx->opcode));
9798 int rs = mmreg(uMIPS_RS(ctx->opcode));
9800 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9803 static void gen_addiusp (CPUState *env, DisasContext *ctx)
9805 int encoded = ZIMM(ctx->opcode, 1, 9);
9806 int decoded;
9808 if (encoded <= 1) {
9809 decoded = 256 + encoded;
9810 } else if (encoded <= 255) {
9811 decoded = encoded;
9812 } else if (encoded <= 509) {
9813 decoded = encoded - 512;
9814 } else {
9815 decoded = encoded - 768;
9818 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9821 static void gen_addius5 (CPUState *env, DisasContext *ctx)
9823 int imm = SIMM(ctx->opcode, 1, 4);
9824 int rd = (ctx->opcode >> 5) & 0x1f;
9826 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9829 static void gen_andi16 (CPUState *env, DisasContext *ctx)
9831 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9832 31, 32, 63, 64, 255, 32768, 65535 };
9833 int rd = mmreg(uMIPS_RD(ctx->opcode));
9834 int rs = mmreg(uMIPS_RS(ctx->opcode));
9835 int encoded = ZIMM(ctx->opcode, 0, 4);
9837 gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9840 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9841 int base, int16_t offset)
9843 TCGv t0, t1;
9844 TCGv_i32 t2;
9846 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9847 generate_exception(ctx, EXCP_RI);
9848 return;
9851 t0 = tcg_temp_new();
9853 gen_base_offset_addr(ctx, t0, base, offset);
9855 t1 = tcg_const_tl(reglist);
9856 t2 = tcg_const_i32(ctx->mem_idx);
9858 save_cpu_state(ctx, 1);
9859 switch (opc) {
9860 case LWM32:
9861 gen_helper_lwm(t0, t1, t2);
9862 break;
9863 case SWM32:
9864 gen_helper_swm(t0, t1, t2);
9865 break;
9866 #ifdef TARGET_MIPS64
9867 case LDM:
9868 gen_helper_ldm(t0, t1, t2);
9869 break;
9870 case SDM:
9871 gen_helper_sdm(t0, t1, t2);
9872 break;
9873 #endif
9875 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9876 tcg_temp_free(t0);
9877 tcg_temp_free(t1);
9878 tcg_temp_free_i32(t2);
9882 static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
9884 int rd = mmreg((ctx->opcode >> 3) & 0x7);
9885 int rs = mmreg(ctx->opcode & 0x7);
9886 int opc;
9888 switch (((ctx->opcode) >> 4) & 0x3f) {
9889 case NOT16 + 0:
9890 case NOT16 + 1:
9891 case NOT16 + 2:
9892 case NOT16 + 3:
9893 gen_logic(env, OPC_NOR, rd, rs, 0);
9894 break;
9895 case XOR16 + 0:
9896 case XOR16 + 1:
9897 case XOR16 + 2:
9898 case XOR16 + 3:
9899 gen_logic(env, OPC_XOR, rd, rd, rs);
9900 break;
9901 case AND16 + 0:
9902 case AND16 + 1:
9903 case AND16 + 2:
9904 case AND16 + 3:
9905 gen_logic(env, OPC_AND, rd, rd, rs);
9906 break;
9907 case OR16 + 0:
9908 case OR16 + 1:
9909 case OR16 + 2:
9910 case OR16 + 3:
9911 gen_logic(env, OPC_OR, rd, rd, rs);
9912 break;
9913 case LWM16 + 0:
9914 case LWM16 + 1:
9915 case LWM16 + 2:
9916 case LWM16 + 3:
9918 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9919 int offset = ZIMM(ctx->opcode, 0, 4);
9921 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9922 29, offset << 2);
9924 break;
9925 case SWM16 + 0:
9926 case SWM16 + 1:
9927 case SWM16 + 2:
9928 case SWM16 + 3:
9930 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9931 int offset = ZIMM(ctx->opcode, 0, 4);
9933 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9934 29, offset << 2);
9936 break;
9937 case JR16 + 0:
9938 case JR16 + 1:
9940 int reg = ctx->opcode & 0x1f;
9942 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9944 *is_branch = 1;
9945 break;
9946 case JRC16 + 0:
9947 case JRC16 + 1:
9949 int reg = ctx->opcode & 0x1f;
9951 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9952 /* Let normal delay slot handling in our caller take us
9953 to the branch target. */
9955 break;
9956 case JALR16 + 0:
9957 case JALR16 + 1:
9958 opc = OPC_JALR;
9959 goto do_jalr;
9960 case JALR16S + 0:
9961 case JALR16S + 1:
9962 opc = OPC_JALRS;
9963 do_jalr:
9965 int reg = ctx->opcode & 0x1f;
9967 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9969 *is_branch = 1;
9970 break;
9971 case MFHI16 + 0:
9972 case MFHI16 + 1:
9973 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9974 break;
9975 case MFLO16 + 0:
9976 case MFLO16 + 1:
9977 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9978 break;
9979 case BREAK16:
9980 generate_exception(ctx, EXCP_BREAK);
9981 break;
9982 case SDBBP16:
9983 /* XXX: not clear which exception should be raised
9984 * when in debug mode...
9986 check_insn(env, ctx, ISA_MIPS32);
9987 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9988 generate_exception(ctx, EXCP_DBp);
9989 } else {
9990 generate_exception(ctx, EXCP_DBp);
9992 break;
9993 case JRADDIUSP + 0:
9994 case JRADDIUSP + 1:
9996 int imm = ZIMM(ctx->opcode, 0, 5);
9998 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9999 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10000 /* Let normal delay slot handling in our caller take us
10001 to the branch target. */
10003 break;
10004 default:
10005 generate_exception(ctx, EXCP_RI);
10006 break;
10010 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10012 TCGv t0 = tcg_temp_new();
10013 TCGv t1 = tcg_temp_new();
10015 gen_load_gpr(t0, base);
10017 if (index != 0) {
10018 gen_load_gpr(t1, index);
10019 tcg_gen_shli_tl(t1, t1, 2);
10020 gen_op_addr_add(ctx, t0, t1, t0);
10023 save_cpu_state(ctx, 0);
10024 op_ld_lw(t1, t0, ctx);
10025 gen_store_gpr(t1, rd);
10027 tcg_temp_free(t0);
10028 tcg_temp_free(t1);
10031 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10032 int base, int16_t offset)
10034 const char *opn = "ldst_pair";
10035 TCGv t0, t1;
10037 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
10038 generate_exception(ctx, EXCP_RI);
10039 return;
10042 t0 = tcg_temp_new();
10043 t1 = tcg_temp_new();
10045 gen_base_offset_addr(ctx, t0, base, offset);
10047 switch (opc) {
10048 case LWP:
10049 save_cpu_state(ctx, 0);
10050 op_ld_lw(t1, t0, ctx);
10051 gen_store_gpr(t1, rd);
10052 tcg_gen_movi_tl(t1, 4);
10053 gen_op_addr_add(ctx, t0, t0, t1);
10054 op_ld_lw(t1, t0, ctx);
10055 gen_store_gpr(t1, rd+1);
10056 opn = "lwp";
10057 break;
10058 case SWP:
10059 save_cpu_state(ctx, 0);
10060 gen_load_gpr(t1, rd);
10061 op_st_sw(t1, t0, ctx);
10062 tcg_gen_movi_tl(t1, 4);
10063 gen_op_addr_add(ctx, t0, t0, t1);
10064 gen_load_gpr(t1, rd+1);
10065 op_st_sw(t1, t0, ctx);
10066 opn = "swp";
10067 break;
10068 #ifdef TARGET_MIPS64
10069 case LDP:
10070 save_cpu_state(ctx, 0);
10071 op_ld_ld(t1, t0, ctx);
10072 gen_store_gpr(t1, rd);
10073 tcg_gen_movi_tl(t1, 8);
10074 gen_op_addr_add(ctx, t0, t0, t1);
10075 op_ld_ld(t1, t0, ctx);
10076 gen_store_gpr(t1, rd+1);
10077 opn = "ldp";
10078 break;
10079 case SDP:
10080 save_cpu_state(ctx, 0);
10081 gen_load_gpr(t1, rd);
10082 op_st_sd(t1, t0, ctx);
10083 tcg_gen_movi_tl(t1, 8);
10084 gen_op_addr_add(ctx, t0, t0, t1);
10085 gen_load_gpr(t1, rd+1);
10086 op_st_sd(t1, t0, ctx);
10087 opn = "sdp";
10088 break;
10089 #endif
10091 (void)opn; /* avoid a compiler warning */
10092 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10093 tcg_temp_free(t0);
10094 tcg_temp_free(t1);
10097 static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
10098 int *is_branch)
10100 int extension = (ctx->opcode >> 6) & 0x3f;
10101 int minor = (ctx->opcode >> 12) & 0xf;
10102 uint32_t mips32_op;
10104 switch (extension) {
10105 case TEQ:
10106 mips32_op = OPC_TEQ;
10107 goto do_trap;
10108 case TGE:
10109 mips32_op = OPC_TGE;
10110 goto do_trap;
10111 case TGEU:
10112 mips32_op = OPC_TGEU;
10113 goto do_trap;
10114 case TLT:
10115 mips32_op = OPC_TLT;
10116 goto do_trap;
10117 case TLTU:
10118 mips32_op = OPC_TLTU;
10119 goto do_trap;
10120 case TNE:
10121 mips32_op = OPC_TNE;
10122 do_trap:
10123 gen_trap(ctx, mips32_op, rs, rt, -1);
10124 break;
10125 #ifndef CONFIG_USER_ONLY
10126 case MFC0:
10127 case MFC0 + 32:
10128 if (rt == 0) {
10129 /* Treat as NOP. */
10130 break;
10132 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10133 break;
10134 case MTC0:
10135 case MTC0 + 32:
10137 TCGv t0 = tcg_temp_new();
10139 gen_load_gpr(t0, rt);
10140 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
10141 tcg_temp_free(t0);
10143 break;
10144 #endif
10145 case 0x2c:
10146 switch (minor) {
10147 case SEB:
10148 gen_bshfl(ctx, OPC_SEB, rs, rt);
10149 break;
10150 case SEH:
10151 gen_bshfl(ctx, OPC_SEH, rs, rt);
10152 break;
10153 case CLO:
10154 mips32_op = OPC_CLO;
10155 goto do_cl;
10156 case CLZ:
10157 mips32_op = OPC_CLZ;
10158 do_cl:
10159 check_insn(env, ctx, ISA_MIPS32);
10160 gen_cl(ctx, mips32_op, rt, rs);
10161 break;
10162 case RDHWR:
10163 gen_rdhwr(env, ctx, rt, rs);
10164 break;
10165 case WSBH:
10166 gen_bshfl(ctx, OPC_WSBH, rs, rt);
10167 break;
10168 case MULT:
10169 mips32_op = OPC_MULT;
10170 goto do_muldiv;
10171 case MULTU:
10172 mips32_op = OPC_MULTU;
10173 goto do_muldiv;
10174 case DIV:
10175 mips32_op = OPC_DIV;
10176 goto do_muldiv;
10177 case DIVU:
10178 mips32_op = OPC_DIVU;
10179 goto do_muldiv;
10180 case MADD:
10181 mips32_op = OPC_MADD;
10182 goto do_muldiv;
10183 case MADDU:
10184 mips32_op = OPC_MADDU;
10185 goto do_muldiv;
10186 case MSUB:
10187 mips32_op = OPC_MSUB;
10188 goto do_muldiv;
10189 case MSUBU:
10190 mips32_op = OPC_MSUBU;
10191 do_muldiv:
10192 check_insn(env, ctx, ISA_MIPS32);
10193 gen_muldiv(ctx, mips32_op, rs, rt);
10194 break;
10195 default:
10196 goto pool32axf_invalid;
10198 break;
10199 case 0x34:
10200 switch (minor) {
10201 case MFC2:
10202 case MTC2:
10203 case MFHC2:
10204 case MTHC2:
10205 case CFC2:
10206 case CTC2:
10207 generate_exception_err(ctx, EXCP_CpU, 2);
10208 break;
10209 default:
10210 goto pool32axf_invalid;
10212 break;
10213 case 0x3c:
10214 switch (minor) {
10215 case JALR:
10216 case JALR_HB:
10217 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10218 *is_branch = 1;
10219 break;
10220 case JALRS:
10221 case JALRS_HB:
10222 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10223 *is_branch = 1;
10224 break;
10225 default:
10226 goto pool32axf_invalid;
10228 break;
10229 case 0x05:
10230 switch (minor) {
10231 case RDPGPR:
10232 check_insn(env, ctx, ISA_MIPS32R2);
10233 gen_load_srsgpr(rt, rs);
10234 break;
10235 case WRPGPR:
10236 check_insn(env, ctx, ISA_MIPS32R2);
10237 gen_store_srsgpr(rt, rs);
10238 break;
10239 default:
10240 goto pool32axf_invalid;
10242 break;
10243 #ifndef CONFIG_USER_ONLY
10244 case 0x0d:
10245 switch (minor) {
10246 case TLBP:
10247 mips32_op = OPC_TLBP;
10248 goto do_cp0;
10249 case TLBR:
10250 mips32_op = OPC_TLBR;
10251 goto do_cp0;
10252 case TLBWI:
10253 mips32_op = OPC_TLBWI;
10254 goto do_cp0;
10255 case TLBWR:
10256 mips32_op = OPC_TLBWR;
10257 goto do_cp0;
10258 case WAIT:
10259 mips32_op = OPC_WAIT;
10260 goto do_cp0;
10261 case DERET:
10262 mips32_op = OPC_DERET;
10263 goto do_cp0;
10264 case ERET:
10265 mips32_op = OPC_ERET;
10266 do_cp0:
10267 gen_cp0(env, ctx, mips32_op, rt, rs);
10268 break;
10269 default:
10270 goto pool32axf_invalid;
10272 break;
10273 case 0x1d:
10274 switch (minor) {
10275 case DI:
10277 TCGv t0 = tcg_temp_new();
10279 save_cpu_state(ctx, 1);
10280 gen_helper_di(t0);
10281 gen_store_gpr(t0, rs);
10282 /* Stop translation as we may have switched the execution mode */
10283 ctx->bstate = BS_STOP;
10284 tcg_temp_free(t0);
10286 break;
10287 case EI:
10289 TCGv t0 = tcg_temp_new();
10291 save_cpu_state(ctx, 1);
10292 gen_helper_ei(t0);
10293 gen_store_gpr(t0, rs);
10294 /* Stop translation as we may have switched the execution mode */
10295 ctx->bstate = BS_STOP;
10296 tcg_temp_free(t0);
10298 break;
10299 default:
10300 goto pool32axf_invalid;
10302 break;
10303 #endif
10304 case 0x2d:
10305 switch (minor) {
10306 case SYNC:
10307 /* NOP */
10308 break;
10309 case SYSCALL:
10310 generate_exception(ctx, EXCP_SYSCALL);
10311 ctx->bstate = BS_STOP;
10312 break;
10313 case SDBBP:
10314 check_insn(env, ctx, ISA_MIPS32);
10315 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10316 generate_exception(ctx, EXCP_DBp);
10317 } else {
10318 generate_exception(ctx, EXCP_DBp);
10320 break;
10321 default:
10322 goto pool32axf_invalid;
10324 break;
10325 case 0x35:
10326 switch (minor) {
10327 case MFHI32:
10328 gen_HILO(ctx, OPC_MFHI, rs);
10329 break;
10330 case MFLO32:
10331 gen_HILO(ctx, OPC_MFLO, rs);
10332 break;
10333 case MTHI32:
10334 gen_HILO(ctx, OPC_MTHI, rs);
10335 break;
10336 case MTLO32:
10337 gen_HILO(ctx, OPC_MTLO, rs);
10338 break;
10339 default:
10340 goto pool32axf_invalid;
10342 break;
10343 default:
10344 pool32axf_invalid:
10345 MIPS_INVAL("pool32axf");
10346 generate_exception(ctx, EXCP_RI);
10347 break;
10351 /* Values for microMIPS fmt field. Variable-width, depending on which
10352 formats the instruction supports. */
10354 enum {
10355 FMT_SD_S = 0,
10356 FMT_SD_D = 1,
10358 FMT_SDPS_S = 0,
10359 FMT_SDPS_D = 1,
10360 FMT_SDPS_PS = 2,
10362 FMT_SWL_S = 0,
10363 FMT_SWL_W = 1,
10364 FMT_SWL_L = 2,
10366 FMT_DWL_D = 0,
10367 FMT_DWL_W = 1,
10368 FMT_DWL_L = 2
10371 static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
10373 int extension = (ctx->opcode >> 6) & 0x3ff;
10374 uint32_t mips32_op;
10376 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10377 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10378 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10380 switch (extension) {
10381 case FLOAT_1BIT_FMT(CFC1, 0):
10382 mips32_op = OPC_CFC1;
10383 goto do_cp1;
10384 case FLOAT_1BIT_FMT(CTC1, 0):
10385 mips32_op = OPC_CTC1;
10386 goto do_cp1;
10387 case FLOAT_1BIT_FMT(MFC1, 0):
10388 mips32_op = OPC_MFC1;
10389 goto do_cp1;
10390 case FLOAT_1BIT_FMT(MTC1, 0):
10391 mips32_op = OPC_MTC1;
10392 goto do_cp1;
10393 case FLOAT_1BIT_FMT(MFHC1, 0):
10394 mips32_op = OPC_MFHC1;
10395 goto do_cp1;
10396 case FLOAT_1BIT_FMT(MTHC1, 0):
10397 mips32_op = OPC_MTHC1;
10398 do_cp1:
10399 gen_cp1(ctx, mips32_op, rt, rs);
10400 break;
10402 /* Reciprocal square root */
10403 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10404 mips32_op = OPC_RSQRT_S;
10405 goto do_unaryfp;
10406 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10407 mips32_op = OPC_RSQRT_D;
10408 goto do_unaryfp;
10410 /* Square root */
10411 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10412 mips32_op = OPC_SQRT_S;
10413 goto do_unaryfp;
10414 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10415 mips32_op = OPC_SQRT_D;
10416 goto do_unaryfp;
10418 /* Reciprocal */
10419 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10420 mips32_op = OPC_RECIP_S;
10421 goto do_unaryfp;
10422 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10423 mips32_op = OPC_RECIP_D;
10424 goto do_unaryfp;
10426 /* Floor */
10427 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10428 mips32_op = OPC_FLOOR_L_S;
10429 goto do_unaryfp;
10430 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10431 mips32_op = OPC_FLOOR_L_D;
10432 goto do_unaryfp;
10433 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10434 mips32_op = OPC_FLOOR_W_S;
10435 goto do_unaryfp;
10436 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10437 mips32_op = OPC_FLOOR_W_D;
10438 goto do_unaryfp;
10440 /* Ceiling */
10441 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10442 mips32_op = OPC_CEIL_L_S;
10443 goto do_unaryfp;
10444 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10445 mips32_op = OPC_CEIL_L_D;
10446 goto do_unaryfp;
10447 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10448 mips32_op = OPC_CEIL_W_S;
10449 goto do_unaryfp;
10450 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10451 mips32_op = OPC_CEIL_W_D;
10452 goto do_unaryfp;
10454 /* Truncation */
10455 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10456 mips32_op = OPC_TRUNC_L_S;
10457 goto do_unaryfp;
10458 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10459 mips32_op = OPC_TRUNC_L_D;
10460 goto do_unaryfp;
10461 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10462 mips32_op = OPC_TRUNC_W_S;
10463 goto do_unaryfp;
10464 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10465 mips32_op = OPC_TRUNC_W_D;
10466 goto do_unaryfp;
10468 /* Round */
10469 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10470 mips32_op = OPC_ROUND_L_S;
10471 goto do_unaryfp;
10472 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10473 mips32_op = OPC_ROUND_L_D;
10474 goto do_unaryfp;
10475 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10476 mips32_op = OPC_ROUND_W_S;
10477 goto do_unaryfp;
10478 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10479 mips32_op = OPC_ROUND_W_D;
10480 goto do_unaryfp;
10482 /* Integer to floating-point conversion */
10483 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10484 mips32_op = OPC_CVT_L_S;
10485 goto do_unaryfp;
10486 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10487 mips32_op = OPC_CVT_L_D;
10488 goto do_unaryfp;
10489 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10490 mips32_op = OPC_CVT_W_S;
10491 goto do_unaryfp;
10492 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10493 mips32_op = OPC_CVT_W_D;
10494 goto do_unaryfp;
10496 /* Paired-foo conversions */
10497 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10498 mips32_op = OPC_CVT_S_PL;
10499 goto do_unaryfp;
10500 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10501 mips32_op = OPC_CVT_S_PU;
10502 goto do_unaryfp;
10503 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10504 mips32_op = OPC_CVT_PW_PS;
10505 goto do_unaryfp;
10506 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10507 mips32_op = OPC_CVT_PS_PW;
10508 goto do_unaryfp;
10510 /* Floating-point moves */
10511 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10512 mips32_op = OPC_MOV_S;
10513 goto do_unaryfp;
10514 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10515 mips32_op = OPC_MOV_D;
10516 goto do_unaryfp;
10517 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10518 mips32_op = OPC_MOV_PS;
10519 goto do_unaryfp;
10521 /* Absolute value */
10522 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10523 mips32_op = OPC_ABS_S;
10524 goto do_unaryfp;
10525 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10526 mips32_op = OPC_ABS_D;
10527 goto do_unaryfp;
10528 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10529 mips32_op = OPC_ABS_PS;
10530 goto do_unaryfp;
10532 /* Negation */
10533 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10534 mips32_op = OPC_NEG_S;
10535 goto do_unaryfp;
10536 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10537 mips32_op = OPC_NEG_D;
10538 goto do_unaryfp;
10539 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10540 mips32_op = OPC_NEG_PS;
10541 goto do_unaryfp;
10543 /* Reciprocal square root step */
10544 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10545 mips32_op = OPC_RSQRT1_S;
10546 goto do_unaryfp;
10547 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10548 mips32_op = OPC_RSQRT1_D;
10549 goto do_unaryfp;
10550 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10551 mips32_op = OPC_RSQRT1_PS;
10552 goto do_unaryfp;
10554 /* Reciprocal step */
10555 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10556 mips32_op = OPC_RECIP1_S;
10557 goto do_unaryfp;
10558 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10559 mips32_op = OPC_RECIP1_S;
10560 goto do_unaryfp;
10561 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10562 mips32_op = OPC_RECIP1_PS;
10563 goto do_unaryfp;
10565 /* Conversions from double */
10566 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10567 mips32_op = OPC_CVT_D_S;
10568 goto do_unaryfp;
10569 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10570 mips32_op = OPC_CVT_D_W;
10571 goto do_unaryfp;
10572 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10573 mips32_op = OPC_CVT_D_L;
10574 goto do_unaryfp;
10576 /* Conversions from single */
10577 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10578 mips32_op = OPC_CVT_S_D;
10579 goto do_unaryfp;
10580 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10581 mips32_op = OPC_CVT_S_W;
10582 goto do_unaryfp;
10583 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10584 mips32_op = OPC_CVT_S_L;
10585 do_unaryfp:
10586 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10587 break;
10589 /* Conditional moves on floating-point codes */
10590 case COND_FLOAT_MOV(MOVT, 0):
10591 case COND_FLOAT_MOV(MOVT, 1):
10592 case COND_FLOAT_MOV(MOVT, 2):
10593 case COND_FLOAT_MOV(MOVT, 3):
10594 case COND_FLOAT_MOV(MOVT, 4):
10595 case COND_FLOAT_MOV(MOVT, 5):
10596 case COND_FLOAT_MOV(MOVT, 6):
10597 case COND_FLOAT_MOV(MOVT, 7):
10598 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10599 break;
10600 case COND_FLOAT_MOV(MOVF, 0):
10601 case COND_FLOAT_MOV(MOVF, 1):
10602 case COND_FLOAT_MOV(MOVF, 2):
10603 case COND_FLOAT_MOV(MOVF, 3):
10604 case COND_FLOAT_MOV(MOVF, 4):
10605 case COND_FLOAT_MOV(MOVF, 5):
10606 case COND_FLOAT_MOV(MOVF, 6):
10607 case COND_FLOAT_MOV(MOVF, 7):
10608 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10609 break;
10610 default:
10611 MIPS_INVAL("pool32fxf");
10612 generate_exception(ctx, EXCP_RI);
10613 break;
10617 static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
10618 uint16_t insn_hw1, int *is_branch)
10620 int32_t offset;
10621 uint16_t insn;
10622 int rt, rs, rd, rr;
10623 int16_t imm;
10624 uint32_t op, minor, mips32_op;
10625 uint32_t cond, fmt, cc;
10627 insn = lduw_code(ctx->pc + 2);
10628 ctx->opcode = (ctx->opcode << 16) | insn;
10630 rt = (ctx->opcode >> 21) & 0x1f;
10631 rs = (ctx->opcode >> 16) & 0x1f;
10632 rd = (ctx->opcode >> 11) & 0x1f;
10633 rr = (ctx->opcode >> 6) & 0x1f;
10634 imm = (int16_t) ctx->opcode;
10636 op = (ctx->opcode >> 26) & 0x3f;
10637 switch (op) {
10638 case POOL32A:
10639 minor = ctx->opcode & 0x3f;
10640 switch (minor) {
10641 case 0x00:
10642 minor = (ctx->opcode >> 6) & 0xf;
10643 switch (minor) {
10644 case SLL32:
10645 mips32_op = OPC_SLL;
10646 goto do_shifti;
10647 case SRA:
10648 mips32_op = OPC_SRA;
10649 goto do_shifti;
10650 case SRL32:
10651 mips32_op = OPC_SRL;
10652 goto do_shifti;
10653 case ROTR:
10654 mips32_op = OPC_ROTR;
10655 do_shifti:
10656 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10657 break;
10658 default:
10659 goto pool32a_invalid;
10661 break;
10662 case 0x10:
10663 minor = (ctx->opcode >> 6) & 0xf;
10664 switch (minor) {
10665 /* Arithmetic */
10666 case ADD:
10667 mips32_op = OPC_ADD;
10668 goto do_arith;
10669 case ADDU32:
10670 mips32_op = OPC_ADDU;
10671 goto do_arith;
10672 case SUB:
10673 mips32_op = OPC_SUB;
10674 goto do_arith;
10675 case SUBU32:
10676 mips32_op = OPC_SUBU;
10677 goto do_arith;
10678 case MUL:
10679 mips32_op = OPC_MUL;
10680 do_arith:
10681 gen_arith(env, ctx, mips32_op, rd, rs, rt);
10682 break;
10683 /* Shifts */
10684 case SLLV:
10685 mips32_op = OPC_SLLV;
10686 goto do_shift;
10687 case SRLV:
10688 mips32_op = OPC_SRLV;
10689 goto do_shift;
10690 case SRAV:
10691 mips32_op = OPC_SRAV;
10692 goto do_shift;
10693 case ROTRV:
10694 mips32_op = OPC_ROTRV;
10695 do_shift:
10696 gen_shift(env, ctx, mips32_op, rd, rs, rt);
10697 break;
10698 /* Logical operations */
10699 case AND:
10700 mips32_op = OPC_AND;
10701 goto do_logic;
10702 case OR32:
10703 mips32_op = OPC_OR;
10704 goto do_logic;
10705 case NOR:
10706 mips32_op = OPC_NOR;
10707 goto do_logic;
10708 case XOR32:
10709 mips32_op = OPC_XOR;
10710 do_logic:
10711 gen_logic(env, mips32_op, rd, rs, rt);
10712 break;
10713 /* Set less than */
10714 case SLT:
10715 mips32_op = OPC_SLT;
10716 goto do_slt;
10717 case SLTU:
10718 mips32_op = OPC_SLTU;
10719 do_slt:
10720 gen_slt(env, mips32_op, rd, rs, rt);
10721 break;
10722 default:
10723 goto pool32a_invalid;
10725 break;
10726 case 0x18:
10727 minor = (ctx->opcode >> 6) & 0xf;
10728 switch (minor) {
10729 /* Conditional moves */
10730 case MOVN:
10731 mips32_op = OPC_MOVN;
10732 goto do_cmov;
10733 case MOVZ:
10734 mips32_op = OPC_MOVZ;
10735 do_cmov:
10736 gen_cond_move(env, mips32_op, rd, rs, rt);
10737 break;
10738 case LWXS:
10739 gen_ldxs(ctx, rs, rt, rd);
10740 break;
10741 default:
10742 goto pool32a_invalid;
10744 break;
10745 case INS:
10746 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10747 return;
10748 case EXT:
10749 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10750 return;
10751 case POOL32AXF:
10752 gen_pool32axf(env, ctx, rt, rs, is_branch);
10753 break;
10754 case 0x07:
10755 generate_exception(ctx, EXCP_BREAK);
10756 break;
10757 default:
10758 pool32a_invalid:
10759 MIPS_INVAL("pool32a");
10760 generate_exception(ctx, EXCP_RI);
10761 break;
10763 break;
10764 case POOL32B:
10765 minor = (ctx->opcode >> 12) & 0xf;
10766 switch (minor) {
10767 case CACHE:
10768 /* Treat as no-op. */
10769 break;
10770 case LWC2:
10771 case SWC2:
10772 /* COP2: Not implemented. */
10773 generate_exception_err(ctx, EXCP_CpU, 2);
10774 break;
10775 case LWP:
10776 case SWP:
10777 #ifdef TARGET_MIPS64
10778 case LDP:
10779 case SDP:
10780 #endif
10781 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10782 break;
10783 case LWM32:
10784 case SWM32:
10785 #ifdef TARGET_MIPS64
10786 case LDM:
10787 case SDM:
10788 #endif
10789 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10790 break;
10791 default:
10792 MIPS_INVAL("pool32b");
10793 generate_exception(ctx, EXCP_RI);
10794 break;
10796 break;
10797 case POOL32F:
10798 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10799 minor = ctx->opcode & 0x3f;
10800 check_cp1_enabled(ctx);
10801 switch (minor) {
10802 case ALNV_PS:
10803 mips32_op = OPC_ALNV_PS;
10804 goto do_madd;
10805 case MADD_S:
10806 mips32_op = OPC_MADD_S;
10807 goto do_madd;
10808 case MADD_D:
10809 mips32_op = OPC_MADD_D;
10810 goto do_madd;
10811 case MADD_PS:
10812 mips32_op = OPC_MADD_PS;
10813 goto do_madd;
10814 case MSUB_S:
10815 mips32_op = OPC_MSUB_S;
10816 goto do_madd;
10817 case MSUB_D:
10818 mips32_op = OPC_MSUB_D;
10819 goto do_madd;
10820 case MSUB_PS:
10821 mips32_op = OPC_MSUB_PS;
10822 goto do_madd;
10823 case NMADD_S:
10824 mips32_op = OPC_NMADD_S;
10825 goto do_madd;
10826 case NMADD_D:
10827 mips32_op = OPC_NMADD_D;
10828 goto do_madd;
10829 case NMADD_PS:
10830 mips32_op = OPC_NMADD_PS;
10831 goto do_madd;
10832 case NMSUB_S:
10833 mips32_op = OPC_NMSUB_S;
10834 goto do_madd;
10835 case NMSUB_D:
10836 mips32_op = OPC_NMSUB_D;
10837 goto do_madd;
10838 case NMSUB_PS:
10839 mips32_op = OPC_NMSUB_PS;
10840 do_madd:
10841 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10842 break;
10843 case CABS_COND_FMT:
10844 cond = (ctx->opcode >> 6) & 0xf;
10845 cc = (ctx->opcode >> 13) & 0x7;
10846 fmt = (ctx->opcode >> 10) & 0x3;
10847 switch (fmt) {
10848 case 0x0:
10849 gen_cmpabs_s(ctx, cond, rt, rs, cc);
10850 break;
10851 case 0x1:
10852 gen_cmpabs_d(ctx, cond, rt, rs, cc);
10853 break;
10854 case 0x2:
10855 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10856 break;
10857 default:
10858 goto pool32f_invalid;
10860 break;
10861 case C_COND_FMT:
10862 cond = (ctx->opcode >> 6) & 0xf;
10863 cc = (ctx->opcode >> 13) & 0x7;
10864 fmt = (ctx->opcode >> 10) & 0x3;
10865 switch (fmt) {
10866 case 0x0:
10867 gen_cmp_s(ctx, cond, rt, rs, cc);
10868 break;
10869 case 0x1:
10870 gen_cmp_d(ctx, cond, rt, rs, cc);
10871 break;
10872 case 0x2:
10873 gen_cmp_ps(ctx, cond, rt, rs, cc);
10874 break;
10875 default:
10876 goto pool32f_invalid;
10878 break;
10879 case POOL32FXF:
10880 gen_pool32fxf(env, ctx, rt, rs);
10881 break;
10882 case 0x00:
10883 /* PLL foo */
10884 switch ((ctx->opcode >> 6) & 0x7) {
10885 case PLL_PS:
10886 mips32_op = OPC_PLL_PS;
10887 goto do_ps;
10888 case PLU_PS:
10889 mips32_op = OPC_PLU_PS;
10890 goto do_ps;
10891 case PUL_PS:
10892 mips32_op = OPC_PUL_PS;
10893 goto do_ps;
10894 case PUU_PS:
10895 mips32_op = OPC_PUU_PS;
10896 goto do_ps;
10897 case CVT_PS_S:
10898 mips32_op = OPC_CVT_PS_S;
10899 do_ps:
10900 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10901 break;
10902 default:
10903 goto pool32f_invalid;
10905 break;
10906 case 0x08:
10907 /* [LS][WDU]XC1 */
10908 switch ((ctx->opcode >> 6) & 0x7) {
10909 case LWXC1:
10910 mips32_op = OPC_LWXC1;
10911 goto do_ldst_cp1;
10912 case SWXC1:
10913 mips32_op = OPC_SWXC1;
10914 goto do_ldst_cp1;
10915 case LDXC1:
10916 mips32_op = OPC_LDXC1;
10917 goto do_ldst_cp1;
10918 case SDXC1:
10919 mips32_op = OPC_SDXC1;
10920 goto do_ldst_cp1;
10921 case LUXC1:
10922 mips32_op = OPC_LUXC1;
10923 goto do_ldst_cp1;
10924 case SUXC1:
10925 mips32_op = OPC_SUXC1;
10926 do_ldst_cp1:
10927 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10928 break;
10929 default:
10930 goto pool32f_invalid;
10932 break;
10933 case 0x18:
10934 /* 3D insns */
10935 fmt = (ctx->opcode >> 9) & 0x3;
10936 switch ((ctx->opcode >> 6) & 0x7) {
10937 case RSQRT2_FMT:
10938 switch (fmt) {
10939 case FMT_SDPS_S:
10940 mips32_op = OPC_RSQRT2_S;
10941 goto do_3d;
10942 case FMT_SDPS_D:
10943 mips32_op = OPC_RSQRT2_D;
10944 goto do_3d;
10945 case FMT_SDPS_PS:
10946 mips32_op = OPC_RSQRT2_PS;
10947 goto do_3d;
10948 default:
10949 goto pool32f_invalid;
10951 break;
10952 case RECIP2_FMT:
10953 switch (fmt) {
10954 case FMT_SDPS_S:
10955 mips32_op = OPC_RECIP2_S;
10956 goto do_3d;
10957 case FMT_SDPS_D:
10958 mips32_op = OPC_RECIP2_D;
10959 goto do_3d;
10960 case FMT_SDPS_PS:
10961 mips32_op = OPC_RECIP2_PS;
10962 goto do_3d;
10963 default:
10964 goto pool32f_invalid;
10966 break;
10967 case ADDR_PS:
10968 mips32_op = OPC_ADDR_PS;
10969 goto do_3d;
10970 case MULR_PS:
10971 mips32_op = OPC_MULR_PS;
10972 do_3d:
10973 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10974 break;
10975 default:
10976 goto pool32f_invalid;
10978 break;
10979 case 0x20:
10980 /* MOV[FT].fmt and PREFX */
10981 cc = (ctx->opcode >> 13) & 0x7;
10982 fmt = (ctx->opcode >> 9) & 0x3;
10983 switch ((ctx->opcode >> 6) & 0x7) {
10984 case MOVF_FMT:
10985 switch (fmt) {
10986 case FMT_SDPS_S:
10987 gen_movcf_s(rs, rt, cc, 0);
10988 break;
10989 case FMT_SDPS_D:
10990 gen_movcf_d(ctx, rs, rt, cc, 0);
10991 break;
10992 case FMT_SDPS_PS:
10993 gen_movcf_ps(rs, rt, cc, 0);
10994 break;
10995 default:
10996 goto pool32f_invalid;
10998 break;
10999 case MOVT_FMT:
11000 switch (fmt) {
11001 case FMT_SDPS_S:
11002 gen_movcf_s(rs, rt, cc, 1);
11003 break;
11004 case FMT_SDPS_D:
11005 gen_movcf_d(ctx, rs, rt, cc, 1);
11006 break;
11007 case FMT_SDPS_PS:
11008 gen_movcf_ps(rs, rt, cc, 1);
11009 break;
11010 default:
11011 goto pool32f_invalid;
11013 break;
11014 case PREFX:
11015 break;
11016 default:
11017 goto pool32f_invalid;
11019 break;
11020 #define FINSN_3ARG_SDPS(prfx) \
11021 switch ((ctx->opcode >> 8) & 0x3) { \
11022 case FMT_SDPS_S: \
11023 mips32_op = OPC_##prfx##_S; \
11024 goto do_fpop; \
11025 case FMT_SDPS_D: \
11026 mips32_op = OPC_##prfx##_D; \
11027 goto do_fpop; \
11028 case FMT_SDPS_PS: \
11029 mips32_op = OPC_##prfx##_PS; \
11030 goto do_fpop; \
11031 default: \
11032 goto pool32f_invalid; \
11034 case 0x30:
11035 /* regular FP ops */
11036 switch ((ctx->opcode >> 6) & 0x3) {
11037 case ADD_FMT:
11038 FINSN_3ARG_SDPS(ADD);
11039 break;
11040 case SUB_FMT:
11041 FINSN_3ARG_SDPS(SUB);
11042 break;
11043 case MUL_FMT:
11044 FINSN_3ARG_SDPS(MUL);
11045 break;
11046 case DIV_FMT:
11047 fmt = (ctx->opcode >> 8) & 0x3;
11048 if (fmt == 1) {
11049 mips32_op = OPC_DIV_D;
11050 } else if (fmt == 0) {
11051 mips32_op = OPC_DIV_S;
11052 } else {
11053 goto pool32f_invalid;
11055 goto do_fpop;
11056 default:
11057 goto pool32f_invalid;
11059 break;
11060 case 0x38:
11061 /* cmovs */
11062 switch ((ctx->opcode >> 6) & 0x3) {
11063 case MOVN_FMT:
11064 FINSN_3ARG_SDPS(MOVN);
11065 break;
11066 case MOVZ_FMT:
11067 FINSN_3ARG_SDPS(MOVZ);
11068 break;
11069 default:
11070 goto pool32f_invalid;
11072 break;
11073 do_fpop:
11074 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11075 break;
11076 default:
11077 pool32f_invalid:
11078 MIPS_INVAL("pool32f");
11079 generate_exception(ctx, EXCP_RI);
11080 break;
11082 } else {
11083 generate_exception_err(ctx, EXCP_CpU, 1);
11085 break;
11086 case POOL32I:
11087 minor = (ctx->opcode >> 21) & 0x1f;
11088 switch (minor) {
11089 case BLTZ:
11090 mips32_op = OPC_BLTZ;
11091 goto do_branch;
11092 case BLTZAL:
11093 mips32_op = OPC_BLTZAL;
11094 goto do_branch;
11095 case BLTZALS:
11096 mips32_op = OPC_BLTZALS;
11097 goto do_branch;
11098 case BGEZ:
11099 mips32_op = OPC_BGEZ;
11100 goto do_branch;
11101 case BGEZAL:
11102 mips32_op = OPC_BGEZAL;
11103 goto do_branch;
11104 case BGEZALS:
11105 mips32_op = OPC_BGEZALS;
11106 goto do_branch;
11107 case BLEZ:
11108 mips32_op = OPC_BLEZ;
11109 goto do_branch;
11110 case BGTZ:
11111 mips32_op = OPC_BGTZ;
11112 do_branch:
11113 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
11114 *is_branch = 1;
11115 break;
11117 /* Traps */
11118 case TLTI:
11119 mips32_op = OPC_TLTI;
11120 goto do_trapi;
11121 case TGEI:
11122 mips32_op = OPC_TGEI;
11123 goto do_trapi;
11124 case TLTIU:
11125 mips32_op = OPC_TLTIU;
11126 goto do_trapi;
11127 case TGEIU:
11128 mips32_op = OPC_TGEIU;
11129 goto do_trapi;
11130 case TNEI:
11131 mips32_op = OPC_TNEI;
11132 goto do_trapi;
11133 case TEQI:
11134 mips32_op = OPC_TEQI;
11135 do_trapi:
11136 gen_trap(ctx, mips32_op, rs, -1, imm);
11137 break;
11139 case BNEZC:
11140 case BEQZC:
11141 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
11142 4, rs, 0, imm << 1);
11143 /* Compact branches don't have a delay slot, so just let
11144 the normal delay slot handling take us to the branch
11145 target. */
11146 break;
11147 case LUI:
11148 gen_logic_imm(env, OPC_LUI, rs, -1, imm);
11149 break;
11150 case SYNCI:
11151 break;
11152 case BC2F:
11153 case BC2T:
11154 /* COP2: Not implemented. */
11155 generate_exception_err(ctx, EXCP_CpU, 2);
11156 break;
11157 case BC1F:
11158 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11159 goto do_cp1branch;
11160 case BC1T:
11161 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11162 goto do_cp1branch;
11163 case BC1ANY4F:
11164 mips32_op = OPC_BC1FANY4;
11165 goto do_cp1mips3d;
11166 case BC1ANY4T:
11167 mips32_op = OPC_BC1TANY4;
11168 do_cp1mips3d:
11169 check_cop1x(ctx);
11170 check_insn(env, ctx, ASE_MIPS3D);
11171 /* Fall through */
11172 do_cp1branch:
11173 gen_compute_branch1(env, ctx, mips32_op,
11174 (ctx->opcode >> 18) & 0x7, imm << 1);
11175 *is_branch = 1;
11176 break;
11177 case BPOSGE64:
11178 case BPOSGE32:
11179 /* MIPS DSP: not implemented */
11180 /* Fall through */
11181 default:
11182 MIPS_INVAL("pool32i");
11183 generate_exception(ctx, EXCP_RI);
11184 break;
11186 break;
11187 case POOL32C:
11188 minor = (ctx->opcode >> 12) & 0xf;
11189 switch (minor) {
11190 case LWL:
11191 mips32_op = OPC_LWL;
11192 goto do_ld_lr;
11193 case SWL:
11194 mips32_op = OPC_SWL;
11195 goto do_st_lr;
11196 case LWR:
11197 mips32_op = OPC_LWR;
11198 goto do_ld_lr;
11199 case SWR:
11200 mips32_op = OPC_SWR;
11201 goto do_st_lr;
11202 #if defined(TARGET_MIPS64)
11203 case LDL:
11204 mips32_op = OPC_LDL;
11205 goto do_ld_lr;
11206 case SDL:
11207 mips32_op = OPC_SDL;
11208 goto do_st_lr;
11209 case LDR:
11210 mips32_op = OPC_LDR;
11211 goto do_ld_lr;
11212 case SDR:
11213 mips32_op = OPC_SDR;
11214 goto do_st_lr;
11215 case LWU:
11216 mips32_op = OPC_LWU;
11217 goto do_ld_lr;
11218 case LLD:
11219 mips32_op = OPC_LLD;
11220 goto do_ld_lr;
11221 #endif
11222 case LL:
11223 mips32_op = OPC_LL;
11224 goto do_ld_lr;
11225 do_ld_lr:
11226 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11227 break;
11228 do_st_lr:
11229 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11230 break;
11231 case SC:
11232 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11233 break;
11234 #if defined(TARGET_MIPS64)
11235 case SCD:
11236 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11237 break;
11238 #endif
11239 case PREF:
11240 /* Treat as no-op */
11241 break;
11242 default:
11243 MIPS_INVAL("pool32c");
11244 generate_exception(ctx, EXCP_RI);
11245 break;
11247 break;
11248 case ADDI32:
11249 mips32_op = OPC_ADDI;
11250 goto do_addi;
11251 case ADDIU32:
11252 mips32_op = OPC_ADDIU;
11253 do_addi:
11254 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11255 break;
11257 /* Logical operations */
11258 case ORI32:
11259 mips32_op = OPC_ORI;
11260 goto do_logici;
11261 case XORI32:
11262 mips32_op = OPC_XORI;
11263 goto do_logici;
11264 case ANDI32:
11265 mips32_op = OPC_ANDI;
11266 do_logici:
11267 gen_logic_imm(env, mips32_op, rt, rs, imm);
11268 break;
11270 /* Set less than immediate */
11271 case SLTI32:
11272 mips32_op = OPC_SLTI;
11273 goto do_slti;
11274 case SLTIU32:
11275 mips32_op = OPC_SLTIU;
11276 do_slti:
11277 gen_slt_imm(env, mips32_op, rt, rs, imm);
11278 break;
11279 case JALX32:
11280 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11281 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11282 *is_branch = 1;
11283 break;
11284 case JALS32:
11285 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11286 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11287 *is_branch = 1;
11288 break;
11289 case BEQ32:
11290 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11291 *is_branch = 1;
11292 break;
11293 case BNE32:
11294 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11295 *is_branch = 1;
11296 break;
11297 case J32:
11298 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11299 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11300 *is_branch = 1;
11301 break;
11302 case JAL32:
11303 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11304 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11305 *is_branch = 1;
11306 break;
11307 /* Floating point (COP1) */
11308 case LWC132:
11309 mips32_op = OPC_LWC1;
11310 goto do_cop1;
11311 case LDC132:
11312 mips32_op = OPC_LDC1;
11313 goto do_cop1;
11314 case SWC132:
11315 mips32_op = OPC_SWC1;
11316 goto do_cop1;
11317 case SDC132:
11318 mips32_op = OPC_SDC1;
11319 do_cop1:
11320 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11321 break;
11322 case ADDIUPC:
11324 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
11325 int offset = SIMM(ctx->opcode, 0, 23) << 2;
11327 gen_addiupc(ctx, reg, offset, 0, 0);
11329 break;
11330 /* Loads and stores */
11331 case LB32:
11332 mips32_op = OPC_LB;
11333 goto do_ld;
11334 case LBU32:
11335 mips32_op = OPC_LBU;
11336 goto do_ld;
11337 case LH32:
11338 mips32_op = OPC_LH;
11339 goto do_ld;
11340 case LHU32:
11341 mips32_op = OPC_LHU;
11342 goto do_ld;
11343 case LW32:
11344 mips32_op = OPC_LW;
11345 goto do_ld;
11346 #ifdef TARGET_MIPS64
11347 case LD32:
11348 mips32_op = OPC_LD;
11349 goto do_ld;
11350 case SD32:
11351 mips32_op = OPC_SD;
11352 goto do_st;
11353 #endif
11354 case SB32:
11355 mips32_op = OPC_SB;
11356 goto do_st;
11357 case SH32:
11358 mips32_op = OPC_SH;
11359 goto do_st;
11360 case SW32:
11361 mips32_op = OPC_SW;
11362 goto do_st;
11363 do_ld:
11364 gen_ld(env, ctx, mips32_op, rt, rs, imm);
11365 break;
11366 do_st:
11367 gen_st(ctx, mips32_op, rt, rs, imm);
11368 break;
11369 default:
11370 generate_exception(ctx, EXCP_RI);
11371 break;
11375 static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11377 uint32_t op;
11379 /* make sure instructions are on a halfword boundary */
11380 if (ctx->pc & 0x1) {
11381 env->CP0_BadVAddr = ctx->pc;
11382 generate_exception(ctx, EXCP_AdEL);
11383 ctx->bstate = BS_STOP;
11384 return 2;
11387 op = (ctx->opcode >> 10) & 0x3f;
11388 /* Enforce properly-sized instructions in a delay slot */
11389 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11390 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11392 switch (op) {
11393 case POOL32A:
11394 case POOL32B:
11395 case POOL32I:
11396 case POOL32C:
11397 case ADDI32:
11398 case ADDIU32:
11399 case ORI32:
11400 case XORI32:
11401 case SLTI32:
11402 case SLTIU32:
11403 case ANDI32:
11404 case JALX32:
11405 case LBU32:
11406 case LHU32:
11407 case POOL32F:
11408 case JALS32:
11409 case BEQ32:
11410 case BNE32:
11411 case J32:
11412 case JAL32:
11413 case SB32:
11414 case SH32:
11415 case POOL32S:
11416 case ADDIUPC:
11417 case SWC132:
11418 case SDC132:
11419 case SD32:
11420 case SW32:
11421 case LB32:
11422 case LH32:
11423 case DADDIU32:
11424 case POOL48A: /* ??? */
11425 case LWC132:
11426 case LDC132:
11427 case LD32:
11428 case LW32:
11429 if (bits & MIPS_HFLAG_BDS16) {
11430 generate_exception(ctx, EXCP_RI);
11431 /* Just stop translation; the user is confused. */
11432 ctx->bstate = BS_STOP;
11433 return 2;
11435 break;
11436 case POOL16A:
11437 case POOL16B:
11438 case POOL16C:
11439 case LWGP16:
11440 case POOL16F:
11441 case LBU16:
11442 case LHU16:
11443 case LWSP16:
11444 case LW16:
11445 case SB16:
11446 case SH16:
11447 case SWSP16:
11448 case SW16:
11449 case MOVE16:
11450 case ANDI16:
11451 case POOL16D:
11452 case POOL16E:
11453 case BEQZ16:
11454 case BNEZ16:
11455 case B16:
11456 case LI16:
11457 if (bits & MIPS_HFLAG_BDS32) {
11458 generate_exception(ctx, EXCP_RI);
11459 /* Just stop translation; the user is confused. */
11460 ctx->bstate = BS_STOP;
11461 return 2;
11463 break;
11464 default:
11465 break;
11468 switch (op) {
11469 case POOL16A:
11471 int rd = mmreg(uMIPS_RD(ctx->opcode));
11472 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11473 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11474 uint32_t opc = 0;
11476 switch (ctx->opcode & 0x1) {
11477 case ADDU16:
11478 opc = OPC_ADDU;
11479 break;
11480 case SUBU16:
11481 opc = OPC_SUBU;
11482 break;
11485 gen_arith(env, ctx, opc, rd, rs1, rs2);
11487 break;
11488 case POOL16B:
11490 int rd = mmreg(uMIPS_RD(ctx->opcode));
11491 int rs = mmreg(uMIPS_RS(ctx->opcode));
11492 int amount = (ctx->opcode >> 1) & 0x7;
11493 uint32_t opc = 0;
11494 amount = amount == 0 ? 8 : amount;
11496 switch (ctx->opcode & 0x1) {
11497 case SLL16:
11498 opc = OPC_SLL;
11499 break;
11500 case SRL16:
11501 opc = OPC_SRL;
11502 break;
11505 gen_shift_imm(env, ctx, opc, rd, rs, amount);
11507 break;
11508 case POOL16C:
11509 gen_pool16c_insn(env, ctx, is_branch);
11510 break;
11511 case LWGP16:
11513 int rd = mmreg(uMIPS_RD(ctx->opcode));
11514 int rb = 28; /* GP */
11515 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11517 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11519 break;
11520 case POOL16F:
11521 if (ctx->opcode & 1) {
11522 generate_exception(ctx, EXCP_RI);
11523 } else {
11524 /* MOVEP */
11525 int enc_dest = uMIPS_RD(ctx->opcode);
11526 int enc_rt = uMIPS_RS2(ctx->opcode);
11527 int enc_rs = uMIPS_RS1(ctx->opcode);
11528 int rd, rs, re, rt;
11529 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11530 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11531 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11533 rd = rd_enc[enc_dest];
11534 re = re_enc[enc_dest];
11535 rs = rs_rt_enc[enc_rs];
11536 rt = rs_rt_enc[enc_rt];
11538 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11539 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11541 break;
11542 case LBU16:
11544 int rd = mmreg(uMIPS_RD(ctx->opcode));
11545 int rb = mmreg(uMIPS_RS(ctx->opcode));
11546 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11547 offset = (offset == 0xf ? -1 : offset);
11549 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
11551 break;
11552 case LHU16:
11554 int rd = mmreg(uMIPS_RD(ctx->opcode));
11555 int rb = mmreg(uMIPS_RS(ctx->opcode));
11556 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11558 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
11560 break;
11561 case LWSP16:
11563 int rd = (ctx->opcode >> 5) & 0x1f;
11564 int rb = 29; /* SP */
11565 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11567 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11569 break;
11570 case LW16:
11572 int rd = mmreg(uMIPS_RD(ctx->opcode));
11573 int rb = mmreg(uMIPS_RS(ctx->opcode));
11574 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11576 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11578 break;
11579 case SB16:
11581 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11582 int rb = mmreg(uMIPS_RS(ctx->opcode));
11583 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11585 gen_st(ctx, OPC_SB, rd, rb, offset);
11587 break;
11588 case SH16:
11590 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11591 int rb = mmreg(uMIPS_RS(ctx->opcode));
11592 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11594 gen_st(ctx, OPC_SH, rd, rb, offset);
11596 break;
11597 case SWSP16:
11599 int rd = (ctx->opcode >> 5) & 0x1f;
11600 int rb = 29; /* SP */
11601 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11603 gen_st(ctx, OPC_SW, rd, rb, offset);
11605 break;
11606 case SW16:
11608 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11609 int rb = mmreg(uMIPS_RS(ctx->opcode));
11610 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11612 gen_st(ctx, OPC_SW, rd, rb, offset);
11614 break;
11615 case MOVE16:
11617 int rd = uMIPS_RD5(ctx->opcode);
11618 int rs = uMIPS_RS5(ctx->opcode);
11620 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11622 break;
11623 case ANDI16:
11624 gen_andi16(env, ctx);
11625 break;
11626 case POOL16D:
11627 switch (ctx->opcode & 0x1) {
11628 case ADDIUS5:
11629 gen_addius5(env, ctx);
11630 break;
11631 case ADDIUSP:
11632 gen_addiusp(env, ctx);
11633 break;
11635 break;
11636 case POOL16E:
11637 switch (ctx->opcode & 0x1) {
11638 case ADDIUR2:
11639 gen_addiur2(env, ctx);
11640 break;
11641 case ADDIUR1SP:
11642 gen_addiur1sp(env, ctx);
11643 break;
11645 break;
11646 case B16:
11647 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11648 SIMM(ctx->opcode, 0, 10) << 1);
11649 *is_branch = 1;
11650 break;
11651 case BNEZ16:
11652 case BEQZ16:
11653 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11654 mmreg(uMIPS_RD(ctx->opcode)),
11655 0, SIMM(ctx->opcode, 0, 7) << 1);
11656 *is_branch = 1;
11657 break;
11658 case LI16:
11660 int reg = mmreg(uMIPS_RD(ctx->opcode));
11661 int imm = ZIMM(ctx->opcode, 0, 7);
11663 imm = (imm == 0x7f ? -1 : imm);
11664 tcg_gen_movi_tl(cpu_gpr[reg], imm);
11666 break;
11667 case RES_20:
11668 case RES_28:
11669 case RES_29:
11670 case RES_30:
11671 case RES_31:
11672 case RES_38:
11673 case RES_39:
11674 generate_exception(ctx, EXCP_RI);
11675 break;
11676 default:
11677 decode_micromips32_opc (env, ctx, op, is_branch);
11678 return 4;
11681 return 2;
11684 /* SmartMIPS extension to MIPS32 */
11686 #if defined(TARGET_MIPS64)
11688 /* MDMX extension to MIPS64 */
11690 #endif
11692 static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11694 int32_t offset;
11695 int rs, rt, rd, sa;
11696 uint32_t op, op1, op2;
11697 int16_t imm;
11699 /* make sure instructions are on a word boundary */
11700 if (ctx->pc & 0x3) {
11701 env->CP0_BadVAddr = ctx->pc;
11702 generate_exception(ctx, EXCP_AdEL);
11703 return;
11706 /* Handle blikely not taken case */
11707 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11708 int l1 = gen_new_label();
11710 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11711 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11712 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11713 gen_goto_tb(ctx, 1, ctx->pc + 4);
11714 gen_set_label(l1);
11717 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11718 tcg_gen_debug_insn_start(ctx->pc);
11720 op = MASK_OP_MAJOR(ctx->opcode);
11721 rs = (ctx->opcode >> 21) & 0x1f;
11722 rt = (ctx->opcode >> 16) & 0x1f;
11723 rd = (ctx->opcode >> 11) & 0x1f;
11724 sa = (ctx->opcode >> 6) & 0x1f;
11725 imm = (int16_t)ctx->opcode;
11726 switch (op) {
11727 case OPC_SPECIAL:
11728 op1 = MASK_SPECIAL(ctx->opcode);
11729 switch (op1) {
11730 case OPC_SLL: /* Shift with immediate */
11731 case OPC_SRA:
11732 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11733 break;
11734 case OPC_SRL:
11735 switch ((ctx->opcode >> 21) & 0x1f) {
11736 case 1:
11737 /* rotr is decoded as srl on non-R2 CPUs */
11738 if (env->insn_flags & ISA_MIPS32R2) {
11739 op1 = OPC_ROTR;
11741 /* Fallthrough */
11742 case 0:
11743 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11744 break;
11745 default:
11746 generate_exception(ctx, EXCP_RI);
11747 break;
11749 break;
11750 case OPC_MOVN: /* Conditional move */
11751 case OPC_MOVZ:
11752 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11753 INSN_LOONGSON2E | INSN_LOONGSON2F);
11754 gen_cond_move(env, op1, rd, rs, rt);
11755 break;
11756 case OPC_ADD ... OPC_SUBU:
11757 gen_arith(env, ctx, op1, rd, rs, rt);
11758 break;
11759 case OPC_SLLV: /* Shifts */
11760 case OPC_SRAV:
11761 gen_shift(env, ctx, op1, rd, rs, rt);
11762 break;
11763 case OPC_SRLV:
11764 switch ((ctx->opcode >> 6) & 0x1f) {
11765 case 1:
11766 /* rotrv is decoded as srlv on non-R2 CPUs */
11767 if (env->insn_flags & ISA_MIPS32R2) {
11768 op1 = OPC_ROTRV;
11770 /* Fallthrough */
11771 case 0:
11772 gen_shift(env, ctx, op1, rd, rs, rt);
11773 break;
11774 default:
11775 generate_exception(ctx, EXCP_RI);
11776 break;
11778 break;
11779 case OPC_SLT: /* Set on less than */
11780 case OPC_SLTU:
11781 gen_slt(env, op1, rd, rs, rt);
11782 break;
11783 case OPC_AND: /* Logic*/
11784 case OPC_OR:
11785 case OPC_NOR:
11786 case OPC_XOR:
11787 gen_logic(env, op1, rd, rs, rt);
11788 break;
11789 case OPC_MULT ... OPC_DIVU:
11790 if (sa) {
11791 check_insn(env, ctx, INSN_VR54XX);
11792 op1 = MASK_MUL_VR54XX(ctx->opcode);
11793 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11794 } else
11795 gen_muldiv(ctx, op1, rs, rt);
11796 break;
11797 case OPC_JR ... OPC_JALR:
11798 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11799 *is_branch = 1;
11800 break;
11801 case OPC_TGE ... OPC_TEQ: /* Traps */
11802 case OPC_TNE:
11803 gen_trap(ctx, op1, rs, rt, -1);
11804 break;
11805 case OPC_MFHI: /* Move from HI/LO */
11806 case OPC_MFLO:
11807 gen_HILO(ctx, op1, rd);
11808 break;
11809 case OPC_MTHI:
11810 case OPC_MTLO: /* Move to HI/LO */
11811 gen_HILO(ctx, op1, rs);
11812 break;
11813 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
11814 #ifdef MIPS_STRICT_STANDARD
11815 MIPS_INVAL("PMON / selsl");
11816 generate_exception(ctx, EXCP_RI);
11817 #else
11818 gen_helper_0i(pmon, sa);
11819 #endif
11820 break;
11821 case OPC_SYSCALL:
11822 generate_exception(ctx, EXCP_SYSCALL);
11823 ctx->bstate = BS_STOP;
11824 break;
11825 case OPC_BREAK:
11826 generate_exception(ctx, EXCP_BREAK);
11827 break;
11828 case OPC_SPIM:
11829 #ifdef MIPS_STRICT_STANDARD
11830 MIPS_INVAL("SPIM");
11831 generate_exception(ctx, EXCP_RI);
11832 #else
11833 /* Implemented as RI exception for now. */
11834 MIPS_INVAL("spim (unofficial)");
11835 generate_exception(ctx, EXCP_RI);
11836 #endif
11837 break;
11838 case OPC_SYNC:
11839 /* Treat as NOP. */
11840 break;
11842 case OPC_MOVCI:
11843 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11844 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11845 check_cp1_enabled(ctx);
11846 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11847 (ctx->opcode >> 16) & 1);
11848 } else {
11849 generate_exception_err(ctx, EXCP_CpU, 1);
11851 break;
11853 #if defined(TARGET_MIPS64)
11854 /* MIPS64 specific opcodes */
11855 case OPC_DSLL:
11856 case OPC_DSRA:
11857 case OPC_DSLL32:
11858 case OPC_DSRA32:
11859 check_insn(env, ctx, ISA_MIPS3);
11860 check_mips_64(ctx);
11861 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11862 break;
11863 case OPC_DSRL:
11864 switch ((ctx->opcode >> 21) & 0x1f) {
11865 case 1:
11866 /* drotr is decoded as dsrl on non-R2 CPUs */
11867 if (env->insn_flags & ISA_MIPS32R2) {
11868 op1 = OPC_DROTR;
11870 /* Fallthrough */
11871 case 0:
11872 check_insn(env, ctx, ISA_MIPS3);
11873 check_mips_64(ctx);
11874 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11875 break;
11876 default:
11877 generate_exception(ctx, EXCP_RI);
11878 break;
11880 break;
11881 case OPC_DSRL32:
11882 switch ((ctx->opcode >> 21) & 0x1f) {
11883 case 1:
11884 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11885 if (env->insn_flags & ISA_MIPS32R2) {
11886 op1 = OPC_DROTR32;
11888 /* Fallthrough */
11889 case 0:
11890 check_insn(env, ctx, ISA_MIPS3);
11891 check_mips_64(ctx);
11892 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11893 break;
11894 default:
11895 generate_exception(ctx, EXCP_RI);
11896 break;
11898 break;
11899 case OPC_DADD ... OPC_DSUBU:
11900 check_insn(env, ctx, ISA_MIPS3);
11901 check_mips_64(ctx);
11902 gen_arith(env, ctx, op1, rd, rs, rt);
11903 break;
11904 case OPC_DSLLV:
11905 case OPC_DSRAV:
11906 check_insn(env, ctx, ISA_MIPS3);
11907 check_mips_64(ctx);
11908 gen_shift(env, ctx, op1, rd, rs, rt);
11909 break;
11910 case OPC_DSRLV:
11911 switch ((ctx->opcode >> 6) & 0x1f) {
11912 case 1:
11913 /* drotrv is decoded as dsrlv on non-R2 CPUs */
11914 if (env->insn_flags & ISA_MIPS32R2) {
11915 op1 = OPC_DROTRV;
11917 /* Fallthrough */
11918 case 0:
11919 check_insn(env, ctx, ISA_MIPS3);
11920 check_mips_64(ctx);
11921 gen_shift(env, ctx, op1, rd, rs, rt);
11922 break;
11923 default:
11924 generate_exception(ctx, EXCP_RI);
11925 break;
11927 break;
11928 case OPC_DMULT ... OPC_DDIVU:
11929 check_insn(env, ctx, ISA_MIPS3);
11930 check_mips_64(ctx);
11931 gen_muldiv(ctx, op1, rs, rt);
11932 break;
11933 #endif
11934 default: /* Invalid */
11935 MIPS_INVAL("special");
11936 generate_exception(ctx, EXCP_RI);
11937 break;
11939 break;
11940 case OPC_SPECIAL2:
11941 op1 = MASK_SPECIAL2(ctx->opcode);
11942 switch (op1) {
11943 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11944 case OPC_MSUB ... OPC_MSUBU:
11945 check_insn(env, ctx, ISA_MIPS32);
11946 gen_muldiv(ctx, op1, rs, rt);
11947 break;
11948 case OPC_MUL:
11949 gen_arith(env, ctx, op1, rd, rs, rt);
11950 break;
11951 case OPC_CLO:
11952 case OPC_CLZ:
11953 check_insn(env, ctx, ISA_MIPS32);
11954 gen_cl(ctx, op1, rd, rs);
11955 break;
11956 case OPC_SDBBP:
11957 /* XXX: not clear which exception should be raised
11958 * when in debug mode...
11960 check_insn(env, ctx, ISA_MIPS32);
11961 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11962 generate_exception(ctx, EXCP_DBp);
11963 } else {
11964 generate_exception(ctx, EXCP_DBp);
11966 /* Treat as NOP. */
11967 break;
11968 case OPC_DIV_G_2F:
11969 case OPC_DIVU_G_2F:
11970 case OPC_MULT_G_2F:
11971 case OPC_MULTU_G_2F:
11972 case OPC_MOD_G_2F:
11973 case OPC_MODU_G_2F:
11974 check_insn(env, ctx, INSN_LOONGSON2F);
11975 gen_loongson_integer(ctx, op1, rd, rs, rt);
11976 break;
11977 #if defined(TARGET_MIPS64)
11978 case OPC_DCLO:
11979 case OPC_DCLZ:
11980 check_insn(env, ctx, ISA_MIPS64);
11981 check_mips_64(ctx);
11982 gen_cl(ctx, op1, rd, rs);
11983 break;
11984 case OPC_DMULT_G_2F:
11985 case OPC_DMULTU_G_2F:
11986 case OPC_DDIV_G_2F:
11987 case OPC_DDIVU_G_2F:
11988 case OPC_DMOD_G_2F:
11989 case OPC_DMODU_G_2F:
11990 check_insn(env, ctx, INSN_LOONGSON2F);
11991 gen_loongson_integer(ctx, op1, rd, rs, rt);
11992 break;
11993 #endif
11994 default: /* Invalid */
11995 MIPS_INVAL("special2");
11996 generate_exception(ctx, EXCP_RI);
11997 break;
11999 break;
12000 case OPC_SPECIAL3:
12001 op1 = MASK_SPECIAL3(ctx->opcode);
12002 switch (op1) {
12003 case OPC_EXT:
12004 case OPC_INS:
12005 check_insn(env, ctx, ISA_MIPS32R2);
12006 gen_bitops(ctx, op1, rt, rs, sa, rd);
12007 break;
12008 case OPC_BSHFL:
12009 check_insn(env, ctx, ISA_MIPS32R2);
12010 op2 = MASK_BSHFL(ctx->opcode);
12011 gen_bshfl(ctx, op2, rt, rd);
12012 break;
12013 case OPC_RDHWR:
12014 gen_rdhwr(env, ctx, rt, rd);
12015 break;
12016 case OPC_FORK:
12017 check_insn(env, ctx, ASE_MT);
12019 TCGv t0 = tcg_temp_new();
12020 TCGv t1 = tcg_temp_new();
12022 gen_load_gpr(t0, rt);
12023 gen_load_gpr(t1, rs);
12024 gen_helper_fork(t0, t1);
12025 tcg_temp_free(t0);
12026 tcg_temp_free(t1);
12028 break;
12029 case OPC_YIELD:
12030 check_insn(env, ctx, ASE_MT);
12032 TCGv t0 = tcg_temp_new();
12034 save_cpu_state(ctx, 1);
12035 gen_load_gpr(t0, rs);
12036 gen_helper_yield(t0, t0);
12037 gen_store_gpr(t0, rd);
12038 tcg_temp_free(t0);
12040 break;
12041 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
12042 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
12043 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
12044 check_insn(env, ctx, INSN_LOONGSON2E);
12045 gen_loongson_integer(ctx, op1, rd, rs, rt);
12046 break;
12047 #if defined(TARGET_MIPS64)
12048 case OPC_DEXTM ... OPC_DEXT:
12049 case OPC_DINSM ... OPC_DINS:
12050 check_insn(env, ctx, ISA_MIPS64R2);
12051 check_mips_64(ctx);
12052 gen_bitops(ctx, op1, rt, rs, sa, rd);
12053 break;
12054 case OPC_DBSHFL:
12055 check_insn(env, ctx, ISA_MIPS64R2);
12056 check_mips_64(ctx);
12057 op2 = MASK_DBSHFL(ctx->opcode);
12058 gen_bshfl(ctx, op2, rt, rd);
12059 break;
12060 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
12061 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
12062 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
12063 check_insn(env, ctx, INSN_LOONGSON2E);
12064 gen_loongson_integer(ctx, op1, rd, rs, rt);
12065 break;
12066 #endif
12067 default: /* Invalid */
12068 MIPS_INVAL("special3");
12069 generate_exception(ctx, EXCP_RI);
12070 break;
12072 break;
12073 case OPC_REGIMM:
12074 op1 = MASK_REGIMM(ctx->opcode);
12075 switch (op1) {
12076 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
12077 case OPC_BLTZAL ... OPC_BGEZALL:
12078 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
12079 *is_branch = 1;
12080 break;
12081 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
12082 case OPC_TNEI:
12083 gen_trap(ctx, op1, rs, -1, imm);
12084 break;
12085 case OPC_SYNCI:
12086 check_insn(env, ctx, ISA_MIPS32R2);
12087 /* Treat as NOP. */
12088 break;
12089 default: /* Invalid */
12090 MIPS_INVAL("regimm");
12091 generate_exception(ctx, EXCP_RI);
12092 break;
12094 break;
12095 case OPC_CP0:
12096 check_cp0_enabled(ctx);
12097 op1 = MASK_CP0(ctx->opcode);
12098 switch (op1) {
12099 case OPC_MFC0:
12100 case OPC_MTC0:
12101 case OPC_MFTR:
12102 case OPC_MTTR:
12103 #if defined(TARGET_MIPS64)
12104 case OPC_DMFC0:
12105 case OPC_DMTC0:
12106 #endif
12107 #ifndef CONFIG_USER_ONLY
12108 gen_cp0(env, ctx, op1, rt, rd);
12109 #endif /* !CONFIG_USER_ONLY */
12110 break;
12111 case OPC_C0_FIRST ... OPC_C0_LAST:
12112 #ifndef CONFIG_USER_ONLY
12113 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
12114 #endif /* !CONFIG_USER_ONLY */
12115 break;
12116 case OPC_MFMC0:
12117 #ifndef CONFIG_USER_ONLY
12119 TCGv t0 = tcg_temp_new();
12121 op2 = MASK_MFMC0(ctx->opcode);
12122 switch (op2) {
12123 case OPC_DMT:
12124 check_insn(env, ctx, ASE_MT);
12125 gen_helper_dmt(t0);
12126 gen_store_gpr(t0, rt);
12127 break;
12128 case OPC_EMT:
12129 check_insn(env, ctx, ASE_MT);
12130 gen_helper_emt(t0);
12131 gen_store_gpr(t0, rt);
12132 break;
12133 case OPC_DVPE:
12134 check_insn(env, ctx, ASE_MT);
12135 gen_helper_dvpe(t0);
12136 gen_store_gpr(t0, rt);
12137 break;
12138 case OPC_EVPE:
12139 check_insn(env, ctx, ASE_MT);
12140 gen_helper_evpe(t0);
12141 gen_store_gpr(t0, rt);
12142 break;
12143 case OPC_DI:
12144 check_insn(env, ctx, ISA_MIPS32R2);
12145 save_cpu_state(ctx, 1);
12146 gen_helper_di(t0);
12147 gen_store_gpr(t0, rt);
12148 /* Stop translation as we may have switched the execution mode */
12149 ctx->bstate = BS_STOP;
12150 break;
12151 case OPC_EI:
12152 check_insn(env, ctx, ISA_MIPS32R2);
12153 save_cpu_state(ctx, 1);
12154 gen_helper_ei(t0);
12155 gen_store_gpr(t0, rt);
12156 /* Stop translation as we may have switched the execution mode */
12157 ctx->bstate = BS_STOP;
12158 break;
12159 default: /* Invalid */
12160 MIPS_INVAL("mfmc0");
12161 generate_exception(ctx, EXCP_RI);
12162 break;
12164 tcg_temp_free(t0);
12166 #endif /* !CONFIG_USER_ONLY */
12167 break;
12168 case OPC_RDPGPR:
12169 check_insn(env, ctx, ISA_MIPS32R2);
12170 gen_load_srsgpr(rt, rd);
12171 break;
12172 case OPC_WRPGPR:
12173 check_insn(env, ctx, ISA_MIPS32R2);
12174 gen_store_srsgpr(rt, rd);
12175 break;
12176 default:
12177 MIPS_INVAL("cp0");
12178 generate_exception(ctx, EXCP_RI);
12179 break;
12181 break;
12182 case OPC_ADDI: /* Arithmetic with immediate opcode */
12183 case OPC_ADDIU:
12184 gen_arith_imm(env, ctx, op, rt, rs, imm);
12185 break;
12186 case OPC_SLTI: /* Set on less than with immediate opcode */
12187 case OPC_SLTIU:
12188 gen_slt_imm(env, op, rt, rs, imm);
12189 break;
12190 case OPC_ANDI: /* Arithmetic with immediate opcode */
12191 case OPC_LUI:
12192 case OPC_ORI:
12193 case OPC_XORI:
12194 gen_logic_imm(env, op, rt, rs, imm);
12195 break;
12196 case OPC_J ... OPC_JAL: /* Jump */
12197 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12198 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12199 *is_branch = 1;
12200 break;
12201 case OPC_BEQ ... OPC_BGTZ: /* Branch */
12202 case OPC_BEQL ... OPC_BGTZL:
12203 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12204 *is_branch = 1;
12205 break;
12206 case OPC_LB ... OPC_LWR: /* Load and stores */
12207 case OPC_LL:
12208 gen_ld(env, ctx, op, rt, rs, imm);
12209 break;
12210 case OPC_SB ... OPC_SW:
12211 case OPC_SWR:
12212 gen_st(ctx, op, rt, rs, imm);
12213 break;
12214 case OPC_SC:
12215 gen_st_cond(ctx, op, rt, rs, imm);
12216 break;
12217 case OPC_CACHE:
12218 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12219 /* Treat as NOP. */
12220 break;
12221 case OPC_PREF:
12222 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12223 /* Treat as NOP. */
12224 break;
12226 /* Floating point (COP1). */
12227 case OPC_LWC1:
12228 case OPC_LDC1:
12229 case OPC_SWC1:
12230 case OPC_SDC1:
12231 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12232 break;
12234 case OPC_CP1:
12235 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12236 check_cp1_enabled(ctx);
12237 op1 = MASK_CP1(ctx->opcode);
12238 switch (op1) {
12239 case OPC_MFHC1:
12240 case OPC_MTHC1:
12241 check_insn(env, ctx, ISA_MIPS32R2);
12242 case OPC_MFC1:
12243 case OPC_CFC1:
12244 case OPC_MTC1:
12245 case OPC_CTC1:
12246 gen_cp1(ctx, op1, rt, rd);
12247 break;
12248 #if defined(TARGET_MIPS64)
12249 case OPC_DMFC1:
12250 case OPC_DMTC1:
12251 check_insn(env, ctx, ISA_MIPS3);
12252 gen_cp1(ctx, op1, rt, rd);
12253 break;
12254 #endif
12255 case OPC_BC1ANY2:
12256 case OPC_BC1ANY4:
12257 check_cop1x(ctx);
12258 check_insn(env, ctx, ASE_MIPS3D);
12259 /* fall through */
12260 case OPC_BC1:
12261 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12262 (rt >> 2) & 0x7, imm << 2);
12263 *is_branch = 1;
12264 break;
12265 case OPC_S_FMT:
12266 case OPC_D_FMT:
12267 case OPC_W_FMT:
12268 case OPC_L_FMT:
12269 case OPC_PS_FMT:
12270 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12271 (imm >> 8) & 0x7);
12272 break;
12273 default:
12274 MIPS_INVAL("cp1");
12275 generate_exception (ctx, EXCP_RI);
12276 break;
12278 } else {
12279 generate_exception_err(ctx, EXCP_CpU, 1);
12281 break;
12283 /* COP2. */
12284 case OPC_LWC2:
12285 case OPC_LDC2:
12286 case OPC_SWC2:
12287 case OPC_SDC2:
12288 case OPC_CP2:
12289 /* COP2: Not implemented. */
12290 generate_exception_err(ctx, EXCP_CpU, 2);
12291 break;
12293 case OPC_CP3:
12294 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12295 check_cp1_enabled(ctx);
12296 op1 = MASK_CP3(ctx->opcode);
12297 switch (op1) {
12298 case OPC_LWXC1:
12299 case OPC_LDXC1:
12300 case OPC_LUXC1:
12301 case OPC_SWXC1:
12302 case OPC_SDXC1:
12303 case OPC_SUXC1:
12304 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12305 break;
12306 case OPC_PREFX:
12307 /* Treat as NOP. */
12308 break;
12309 case OPC_ALNV_PS:
12310 case OPC_MADD_S:
12311 case OPC_MADD_D:
12312 case OPC_MADD_PS:
12313 case OPC_MSUB_S:
12314 case OPC_MSUB_D:
12315 case OPC_MSUB_PS:
12316 case OPC_NMADD_S:
12317 case OPC_NMADD_D:
12318 case OPC_NMADD_PS:
12319 case OPC_NMSUB_S:
12320 case OPC_NMSUB_D:
12321 case OPC_NMSUB_PS:
12322 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12323 break;
12324 default:
12325 MIPS_INVAL("cp3");
12326 generate_exception (ctx, EXCP_RI);
12327 break;
12329 } else {
12330 generate_exception_err(ctx, EXCP_CpU, 1);
12332 break;
12334 #if defined(TARGET_MIPS64)
12335 /* MIPS64 opcodes */
12336 case OPC_LWU:
12337 case OPC_LDL ... OPC_LDR:
12338 case OPC_LLD:
12339 case OPC_LD:
12340 check_insn(env, ctx, ISA_MIPS3);
12341 check_mips_64(ctx);
12342 gen_ld(env, ctx, op, rt, rs, imm);
12343 break;
12344 case OPC_SDL ... OPC_SDR:
12345 case OPC_SD:
12346 check_insn(env, ctx, ISA_MIPS3);
12347 check_mips_64(ctx);
12348 gen_st(ctx, op, rt, rs, imm);
12349 break;
12350 case OPC_SCD:
12351 check_insn(env, ctx, ISA_MIPS3);
12352 check_mips_64(ctx);
12353 gen_st_cond(ctx, op, rt, rs, imm);
12354 break;
12355 case OPC_DADDI:
12356 case OPC_DADDIU:
12357 check_insn(env, ctx, ISA_MIPS3);
12358 check_mips_64(ctx);
12359 gen_arith_imm(env, ctx, op, rt, rs, imm);
12360 break;
12361 #endif
12362 case OPC_JALX:
12363 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
12364 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12365 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12366 *is_branch = 1;
12367 break;
12368 case OPC_MDMX:
12369 check_insn(env, ctx, ASE_MDMX);
12370 /* MDMX: Not implemented. */
12371 default: /* Invalid */
12372 MIPS_INVAL("major opcode");
12373 generate_exception(ctx, EXCP_RI);
12374 break;
12378 static inline void
12379 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
12380 int search_pc)
12382 DisasContext ctx;
12383 target_ulong pc_start;
12384 uint16_t *gen_opc_end;
12385 CPUBreakpoint *bp;
12386 int j, lj = -1;
12387 int num_insns;
12388 int max_insns;
12389 int insn_bytes;
12390 int is_branch;
12392 if (search_pc)
12393 qemu_log("search pc %d\n", search_pc);
12395 pc_start = tb->pc;
12396 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12397 ctx.pc = pc_start;
12398 ctx.saved_pc = -1;
12399 ctx.singlestep_enabled = env->singlestep_enabled;
12400 ctx.tb = tb;
12401 ctx.bstate = BS_NONE;
12402 /* Restore delay slot state from the tb context. */
12403 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
12404 restore_cpu_state(env, &ctx);
12405 #ifdef CONFIG_USER_ONLY
12406 ctx.mem_idx = MIPS_HFLAG_UM;
12407 #else
12408 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12409 #endif
12410 num_insns = 0;
12411 max_insns = tb->cflags & CF_COUNT_MASK;
12412 if (max_insns == 0)
12413 max_insns = CF_COUNT_MASK;
12414 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
12415 gen_icount_start();
12416 while (ctx.bstate == BS_NONE) {
12417 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
12418 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
12419 if (bp->pc == ctx.pc) {
12420 save_cpu_state(&ctx, 1);
12421 ctx.bstate = BS_BRANCH;
12422 gen_helper_0i(raise_exception, EXCP_DEBUG);
12423 /* Include the breakpoint location or the tb won't
12424 * be flushed when it must be. */
12425 ctx.pc += 4;
12426 goto done_generating;
12431 if (search_pc) {
12432 j = gen_opc_ptr - gen_opc_buf;
12433 if (lj < j) {
12434 lj++;
12435 while (lj < j)
12436 gen_opc_instr_start[lj++] = 0;
12438 gen_opc_pc[lj] = ctx.pc;
12439 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12440 gen_opc_instr_start[lj] = 1;
12441 gen_opc_icount[lj] = num_insns;
12443 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12444 gen_io_start();
12446 is_branch = 0;
12447 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12448 ctx.opcode = ldl_code(ctx.pc);
12449 insn_bytes = 4;
12450 decode_opc(env, &ctx, &is_branch);
12451 } else if (env->insn_flags & ASE_MICROMIPS) {
12452 ctx.opcode = lduw_code(ctx.pc);
12453 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12454 } else if (env->insn_flags & ASE_MIPS16) {
12455 ctx.opcode = lduw_code(ctx.pc);
12456 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12457 } else {
12458 generate_exception(&ctx, EXCP_RI);
12459 ctx.bstate = BS_STOP;
12460 break;
12462 if (!is_branch) {
12463 handle_delay_slot(env, &ctx, insn_bytes);
12465 ctx.pc += insn_bytes;
12467 num_insns++;
12469 /* Execute a branch and its delay slot as a single instruction.
12470 This is what GDB expects and is consistent with what the
12471 hardware does (e.g. if a delay slot instruction faults, the
12472 reported PC is the PC of the branch). */
12473 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12474 break;
12476 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12477 break;
12479 if (gen_opc_ptr >= gen_opc_end)
12480 break;
12482 if (num_insns >= max_insns)
12483 break;
12485 if (singlestep)
12486 break;
12488 if (tb->cflags & CF_LAST_IO)
12489 gen_io_end();
12490 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12491 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12492 gen_helper_0i(raise_exception, EXCP_DEBUG);
12493 } else {
12494 switch (ctx.bstate) {
12495 case BS_STOP:
12496 gen_goto_tb(&ctx, 0, ctx.pc);
12497 break;
12498 case BS_NONE:
12499 save_cpu_state(&ctx, 0);
12500 gen_goto_tb(&ctx, 0, ctx.pc);
12501 break;
12502 case BS_EXCP:
12503 tcg_gen_exit_tb(0);
12504 break;
12505 case BS_BRANCH:
12506 default:
12507 break;
12510 done_generating:
12511 gen_icount_end(tb, num_insns);
12512 *gen_opc_ptr = INDEX_op_end;
12513 if (search_pc) {
12514 j = gen_opc_ptr - gen_opc_buf;
12515 lj++;
12516 while (lj <= j)
12517 gen_opc_instr_start[lj++] = 0;
12518 } else {
12519 tb->size = ctx.pc - pc_start;
12520 tb->icount = num_insns;
12522 #ifdef DEBUG_DISAS
12523 LOG_DISAS("\n");
12524 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12525 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12526 log_target_disas(pc_start, ctx.pc - pc_start, 0);
12527 qemu_log("\n");
12529 #endif
12532 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
12534 gen_intermediate_code_internal(env, tb, 0);
12537 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
12539 gen_intermediate_code_internal(env, tb, 1);
12542 static void fpu_dump_state(CPUState *env, FILE *f, fprintf_function fpu_fprintf,
12543 int flags)
12545 int i;
12546 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12548 #define printfpr(fp) \
12549 do { \
12550 if (is_fpu64) \
12551 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12552 " fd:%13g fs:%13g psu: %13g\n", \
12553 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
12554 (double)(fp)->fd, \
12555 (double)(fp)->fs[FP_ENDIAN_IDX], \
12556 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
12557 else { \
12558 fpr_t tmp; \
12559 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
12560 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
12561 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12562 " fd:%13g fs:%13g psu:%13g\n", \
12563 tmp.w[FP_ENDIAN_IDX], tmp.d, \
12564 (double)tmp.fd, \
12565 (double)tmp.fs[FP_ENDIAN_IDX], \
12566 (double)tmp.fs[!FP_ENDIAN_IDX]); \
12568 } while(0)
12571 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
12572 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
12573 get_float_exception_flags(&env->active_fpu.fp_status));
12574 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12575 fpu_fprintf(f, "%3s: ", fregnames[i]);
12576 printfpr(&env->active_fpu.fpr[i]);
12579 #undef printfpr
12582 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12583 /* Debug help: The architecture requires 32bit code to maintain proper
12584 sign-extended values on 64bit machines. */
12586 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12588 static void
12589 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
12590 fprintf_function cpu_fprintf,
12591 int flags)
12593 int i;
12595 if (!SIGN_EXT_P(env->active_tc.PC))
12596 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12597 if (!SIGN_EXT_P(env->active_tc.HI[0]))
12598 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12599 if (!SIGN_EXT_P(env->active_tc.LO[0]))
12600 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12601 if (!SIGN_EXT_P(env->btarget))
12602 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12604 for (i = 0; i < 32; i++) {
12605 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12606 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12609 if (!SIGN_EXT_P(env->CP0_EPC))
12610 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12611 if (!SIGN_EXT_P(env->lladdr))
12612 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12614 #endif
12616 void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
12617 int flags)
12619 int i;
12621 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12622 " LO=0x" TARGET_FMT_lx " ds %04x "
12623 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12624 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12625 env->hflags, env->btarget, env->bcond);
12626 for (i = 0; i < 32; i++) {
12627 if ((i & 3) == 0)
12628 cpu_fprintf(f, "GPR%02d:", i);
12629 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12630 if ((i & 3) == 3)
12631 cpu_fprintf(f, "\n");
12634 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
12635 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12636 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12637 env->CP0_Config0, env->CP0_Config1, env->lladdr);
12638 if (env->hflags & MIPS_HFLAG_FPU)
12639 fpu_dump_state(env, f, cpu_fprintf, flags);
12640 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12641 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12642 #endif
12645 static void mips_tcg_init(void)
12647 int i;
12648 static int inited;
12650 /* Initialize various static tables. */
12651 if (inited)
12652 return;
12654 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12655 TCGV_UNUSED(cpu_gpr[0]);
12656 for (i = 1; i < 32; i++)
12657 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12658 offsetof(CPUState, active_tc.gpr[i]),
12659 regnames[i]);
12660 cpu_PC = tcg_global_mem_new(TCG_AREG0,
12661 offsetof(CPUState, active_tc.PC), "PC");
12662 for (i = 0; i < MIPS_DSP_ACC; i++) {
12663 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12664 offsetof(CPUState, active_tc.HI[i]),
12665 regnames_HI[i]);
12666 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12667 offsetof(CPUState, active_tc.LO[i]),
12668 regnames_LO[i]);
12669 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12670 offsetof(CPUState, active_tc.ACX[i]),
12671 regnames_ACX[i]);
12673 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12674 offsetof(CPUState, active_tc.DSPControl),
12675 "DSPControl");
12676 bcond = tcg_global_mem_new(TCG_AREG0,
12677 offsetof(CPUState, bcond), "bcond");
12678 btarget = tcg_global_mem_new(TCG_AREG0,
12679 offsetof(CPUState, btarget), "btarget");
12680 hflags = tcg_global_mem_new_i32(TCG_AREG0,
12681 offsetof(CPUState, hflags), "hflags");
12683 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12684 offsetof(CPUState, active_fpu.fcr0),
12685 "fcr0");
12686 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12687 offsetof(CPUState, active_fpu.fcr31),
12688 "fcr31");
12690 /* register helpers */
12691 #define GEN_HELPER 2
12692 #include "helper.h"
12694 inited = 1;
12697 #include "translate_init.c"
12699 CPUMIPSState *cpu_mips_init (const char *cpu_model)
12701 CPUMIPSState *env;
12702 const mips_def_t *def;
12704 def = cpu_mips_find_by_name(cpu_model);
12705 if (!def)
12706 return NULL;
12707 env = g_malloc0(sizeof(CPUMIPSState));
12708 env->cpu_model = def;
12709 env->cpu_model_str = cpu_model;
12711 cpu_exec_init(env);
12712 #ifndef CONFIG_USER_ONLY
12713 mmu_init(env, def);
12714 #endif
12715 fpu_init(env, def);
12716 mvp_init(env, def);
12717 mips_tcg_init();
12718 cpu_reset(env);
12719 qemu_init_vcpu(env);
12720 return env;
12723 void cpu_reset (CPUMIPSState *env)
12725 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12726 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12727 log_cpu_state(env, 0);
12730 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12731 tlb_flush(env, 1);
12733 /* Reset registers to their default values */
12734 env->CP0_PRid = env->cpu_model->CP0_PRid;
12735 env->CP0_Config0 = env->cpu_model->CP0_Config0;
12736 #ifdef TARGET_WORDS_BIGENDIAN
12737 env->CP0_Config0 |= (1 << CP0C0_BE);
12738 #endif
12739 env->CP0_Config1 = env->cpu_model->CP0_Config1;
12740 env->CP0_Config2 = env->cpu_model->CP0_Config2;
12741 env->CP0_Config3 = env->cpu_model->CP0_Config3;
12742 env->CP0_Config6 = env->cpu_model->CP0_Config6;
12743 env->CP0_Config7 = env->cpu_model->CP0_Config7;
12744 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12745 << env->cpu_model->CP0_LLAddr_shift;
12746 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12747 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12748 env->CCRes = env->cpu_model->CCRes;
12749 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12750 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12751 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12752 env->current_tc = 0;
12753 env->SEGBITS = env->cpu_model->SEGBITS;
12754 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12755 #if defined(TARGET_MIPS64)
12756 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12757 env->SEGMask |= 3ULL << 62;
12759 #endif
12760 env->PABITS = env->cpu_model->PABITS;
12761 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12762 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12763 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12764 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12765 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12766 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12767 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12768 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12769 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12770 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12771 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12772 env->insn_flags = env->cpu_model->insn_flags;
12774 #if defined(CONFIG_USER_ONLY)
12775 env->hflags = MIPS_HFLAG_UM;
12776 /* Enable access to the SYNCI_Step register. */
12777 env->CP0_HWREna |= (1 << 1);
12778 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12779 env->hflags |= MIPS_HFLAG_FPU;
12781 #ifdef TARGET_MIPS64
12782 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12783 env->hflags |= MIPS_HFLAG_F64;
12785 #endif
12786 #else
12787 if (env->hflags & MIPS_HFLAG_BMASK) {
12788 /* If the exception was raised from a delay slot,
12789 come back to the jump. */
12790 env->CP0_ErrorEPC = env->active_tc.PC - 4;
12791 } else {
12792 env->CP0_ErrorEPC = env->active_tc.PC;
12794 env->active_tc.PC = (int32_t)0xBFC00000;
12795 env->CP0_Random = env->tlb->nb_tlb - 1;
12796 env->tlb->tlb_in_use = env->tlb->nb_tlb;
12797 env->CP0_Wired = 0;
12798 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
12799 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12800 /* vectored interrupts not implemented, timer on int 7,
12801 no performance counters. */
12802 env->CP0_IntCtl = 0xe0000000;
12804 int i;
12806 for (i = 0; i < 7; i++) {
12807 env->CP0_WatchLo[i] = 0;
12808 env->CP0_WatchHi[i] = 0x80000000;
12810 env->CP0_WatchLo[7] = 0;
12811 env->CP0_WatchHi[7] = 0;
12813 /* Count register increments in debug mode, EJTAG version 1 */
12814 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12815 env->hflags = MIPS_HFLAG_CP0;
12817 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
12818 int i;
12820 /* Only TC0 on VPE 0 starts as active. */
12821 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
12822 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
12823 env->tcs[i].CP0_TCHalt = 1;
12825 env->active_tc.CP0_TCHalt = 1;
12826 env->halted = 1;
12828 if (!env->cpu_index) {
12829 /* VPE0 starts up enabled. */
12830 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
12831 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
12833 /* TC0 starts up unhalted. */
12834 env->halted = 0;
12835 env->active_tc.CP0_TCHalt = 0;
12836 env->tcs[0].CP0_TCHalt = 0;
12837 /* With thread 0 active. */
12838 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
12839 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
12842 #endif
12843 #if defined(TARGET_MIPS64)
12844 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12845 env->hflags |= MIPS_HFLAG_64;
12847 #endif
12848 env->exception_index = EXCP_NONE;
12851 void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
12853 env->active_tc.PC = gen_opc_pc[pc_pos];
12854 env->hflags &= ~MIPS_HFLAG_BMASK;
12855 env->hflags |= gen_opc_hflags[pc_pos];