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