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