]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
target-mips: fix call to check_*() functions
[mirror_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 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
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_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
72 OPC_BEQL = (0x14 << 26),
73 OPC_BNE = (0x05 << 26),
74 OPC_BNEL = (0x15 << 26),
75 OPC_BLEZ = (0x06 << 26),
76 OPC_BLEZL = (0x16 << 26),
77 OPC_BGTZ = (0x07 << 26),
78 OPC_BGTZL = (0x17 << 26),
79 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
80 /* Load and stores */
81 OPC_LDL = (0x1A << 26),
82 OPC_LDR = (0x1B << 26),
83 OPC_LB = (0x20 << 26),
84 OPC_LH = (0x21 << 26),
85 OPC_LWL = (0x22 << 26),
86 OPC_LW = (0x23 << 26),
87 OPC_LBU = (0x24 << 26),
88 OPC_LHU = (0x25 << 26),
89 OPC_LWR = (0x26 << 26),
90 OPC_LWU = (0x27 << 26),
91 OPC_SB = (0x28 << 26),
92 OPC_SH = (0x29 << 26),
93 OPC_SWL = (0x2A << 26),
94 OPC_SW = (0x2B << 26),
95 OPC_SDL = (0x2C << 26),
96 OPC_SDR = (0x2D << 26),
97 OPC_SWR = (0x2E << 26),
98 OPC_LL = (0x30 << 26),
99 OPC_LLD = (0x34 << 26),
100 OPC_LD = (0x37 << 26),
101 OPC_SC = (0x38 << 26),
102 OPC_SCD = (0x3C << 26),
103 OPC_SD = (0x3F << 26),
104 /* Floating point load/store */
105 OPC_LWC1 = (0x31 << 26),
106 OPC_LWC2 = (0x32 << 26),
107 OPC_LDC1 = (0x35 << 26),
108 OPC_LDC2 = (0x36 << 26),
109 OPC_SWC1 = (0x39 << 26),
110 OPC_SWC2 = (0x3A << 26),
111 OPC_SDC1 = (0x3D << 26),
112 OPC_SDC2 = (0x3E << 26),
113 /* MDMX ASE specific */
114 OPC_MDMX = (0x1E << 26),
115 /* Cache and prefetch */
116 OPC_CACHE = (0x2F << 26),
117 OPC_PREF = (0x33 << 26),
118 /* Reserved major opcode */
119 OPC_MAJOR3B_RESERVED = (0x3B << 26),
120 };
121
122 /* MIPS special opcodes */
123 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124
125 enum {
126 /* Shifts */
127 OPC_SLL = 0x00 | OPC_SPECIAL,
128 /* NOP is SLL r0, r0, 0 */
129 /* SSNOP is SLL r0, r0, 1 */
130 /* EHB is SLL r0, r0, 3 */
131 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
132 OPC_SRA = 0x03 | OPC_SPECIAL,
133 OPC_SLLV = 0x04 | OPC_SPECIAL,
134 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
135 OPC_SRAV = 0x07 | OPC_SPECIAL,
136 OPC_DSLLV = 0x14 | OPC_SPECIAL,
137 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DSRA = 0x3B | OPC_SPECIAL,
142 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
143 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
144 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
145 /* Multiplication / division */
146 OPC_MULT = 0x18 | OPC_SPECIAL,
147 OPC_MULTU = 0x19 | OPC_SPECIAL,
148 OPC_DIV = 0x1A | OPC_SPECIAL,
149 OPC_DIVU = 0x1B | OPC_SPECIAL,
150 OPC_DMULT = 0x1C | OPC_SPECIAL,
151 OPC_DMULTU = 0x1D | OPC_SPECIAL,
152 OPC_DDIV = 0x1E | OPC_SPECIAL,
153 OPC_DDIVU = 0x1F | OPC_SPECIAL,
154 /* 2 registers arithmetic / logic */
155 OPC_ADD = 0x20 | OPC_SPECIAL,
156 OPC_ADDU = 0x21 | OPC_SPECIAL,
157 OPC_SUB = 0x22 | OPC_SPECIAL,
158 OPC_SUBU = 0x23 | OPC_SPECIAL,
159 OPC_AND = 0x24 | OPC_SPECIAL,
160 OPC_OR = 0x25 | OPC_SPECIAL,
161 OPC_XOR = 0x26 | OPC_SPECIAL,
162 OPC_NOR = 0x27 | OPC_SPECIAL,
163 OPC_SLT = 0x2A | OPC_SPECIAL,
164 OPC_SLTU = 0x2B | OPC_SPECIAL,
165 OPC_DADD = 0x2C | OPC_SPECIAL,
166 OPC_DADDU = 0x2D | OPC_SPECIAL,
167 OPC_DSUB = 0x2E | OPC_SPECIAL,
168 OPC_DSUBU = 0x2F | OPC_SPECIAL,
169 /* Jumps */
170 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
171 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
172 /* Traps */
173 OPC_TGE = 0x30 | OPC_SPECIAL,
174 OPC_TGEU = 0x31 | OPC_SPECIAL,
175 OPC_TLT = 0x32 | OPC_SPECIAL,
176 OPC_TLTU = 0x33 | OPC_SPECIAL,
177 OPC_TEQ = 0x34 | OPC_SPECIAL,
178 OPC_TNE = 0x36 | OPC_SPECIAL,
179 /* HI / LO registers load & stores */
180 OPC_MFHI = 0x10 | OPC_SPECIAL,
181 OPC_MTHI = 0x11 | OPC_SPECIAL,
182 OPC_MFLO = 0x12 | OPC_SPECIAL,
183 OPC_MTLO = 0x13 | OPC_SPECIAL,
184 /* Conditional moves */
185 OPC_MOVZ = 0x0A | OPC_SPECIAL,
186 OPC_MOVN = 0x0B | OPC_SPECIAL,
187
188 OPC_MOVCI = 0x01 | OPC_SPECIAL,
189
190 /* Special */
191 OPC_PMON = 0x05 | OPC_SPECIAL, /* inofficial */
192 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
193 OPC_BREAK = 0x0D | OPC_SPECIAL,
194 OPC_SPIM = 0x0E | OPC_SPECIAL, /* inofficial */
195 OPC_SYNC = 0x0F | OPC_SPECIAL,
196
197 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
198 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
199 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
200 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
201 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
202 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
203 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
204 };
205
206 /* Multiplication variants of the vr54xx. */
207 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
208
209 enum {
210 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
211 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
212 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
213 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
214 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
215 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
216 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
217 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
218 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
219 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
220 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
221 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
222 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
223 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
224 };
225
226 /* REGIMM (rt field) opcodes */
227 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
228
229 enum {
230 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
231 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
232 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
233 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
234 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
235 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
236 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
237 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
238 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
239 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
240 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
241 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
242 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
243 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
244 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
245 };
246
247 /* Special2 opcodes */
248 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
249
250 enum {
251 /* Multiply & xxx operations */
252 OPC_MADD = 0x00 | OPC_SPECIAL2,
253 OPC_MADDU = 0x01 | OPC_SPECIAL2,
254 OPC_MUL = 0x02 | OPC_SPECIAL2,
255 OPC_MSUB = 0x04 | OPC_SPECIAL2,
256 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
257 /* Misc */
258 OPC_CLZ = 0x20 | OPC_SPECIAL2,
259 OPC_CLO = 0x21 | OPC_SPECIAL2,
260 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
261 OPC_DCLO = 0x25 | OPC_SPECIAL2,
262 /* Special */
263 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
264 };
265
266 /* Special3 opcodes */
267 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
268
269 enum {
270 OPC_EXT = 0x00 | OPC_SPECIAL3,
271 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
272 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
273 OPC_DEXT = 0x03 | OPC_SPECIAL3,
274 OPC_INS = 0x04 | OPC_SPECIAL3,
275 OPC_DINSM = 0x05 | OPC_SPECIAL3,
276 OPC_DINSU = 0x06 | OPC_SPECIAL3,
277 OPC_DINS = 0x07 | OPC_SPECIAL3,
278 OPC_FORK = 0x08 | OPC_SPECIAL3,
279 OPC_YIELD = 0x09 | OPC_SPECIAL3,
280 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
281 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
282 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
283 };
284
285 /* BSHFL opcodes */
286 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
287
288 enum {
289 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
290 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
291 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
292 };
293
294 /* DBSHFL opcodes */
295 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
296
297 enum {
298 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
299 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
300 };
301
302 /* Coprocessor 0 (rs field) */
303 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
304
305 enum {
306 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
307 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
308 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
309 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
310 OPC_MFTR = (0x08 << 21) | OPC_CP0,
311 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
312 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
313 OPC_MTTR = (0x0C << 21) | OPC_CP0,
314 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
315 OPC_C0 = (0x10 << 21) | OPC_CP0,
316 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
317 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
318 };
319
320 /* MFMC0 opcodes */
321 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
322
323 enum {
324 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
325 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
326 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
327 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
328 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
329 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
330 };
331
332 /* Coprocessor 0 (with rs == C0) */
333 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
334
335 enum {
336 OPC_TLBR = 0x01 | OPC_C0,
337 OPC_TLBWI = 0x02 | OPC_C0,
338 OPC_TLBWR = 0x06 | OPC_C0,
339 OPC_TLBP = 0x08 | OPC_C0,
340 OPC_RFE = 0x10 | OPC_C0,
341 OPC_ERET = 0x18 | OPC_C0,
342 OPC_DERET = 0x1F | OPC_C0,
343 OPC_WAIT = 0x20 | OPC_C0,
344 };
345
346 /* Coprocessor 1 (rs field) */
347 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
348
349 enum {
350 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
351 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
352 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
353 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
354 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
355 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
356 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
357 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
358 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
359 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
360 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
361 OPC_S_FMT = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
362 OPC_D_FMT = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
363 OPC_E_FMT = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
364 OPC_Q_FMT = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
365 OPC_W_FMT = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
366 OPC_L_FMT = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
367 OPC_PS_FMT = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
368 };
369
370 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
371 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
372
373 enum {
374 OPC_BC1F = (0x00 << 16) | OPC_BC1,
375 OPC_BC1T = (0x01 << 16) | OPC_BC1,
376 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
377 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
378 };
379
380 enum {
381 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
382 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
383 };
384
385 enum {
386 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
387 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
388 };
389
390 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
391
392 enum {
393 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
394 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
395 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
396 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
397 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
398 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
399 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
400 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
401 OPC_BC2 = (0x08 << 21) | OPC_CP2,
402 };
403
404 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
405
406 enum {
407 OPC_LWXC1 = 0x00 | OPC_CP3,
408 OPC_LDXC1 = 0x01 | OPC_CP3,
409 OPC_LUXC1 = 0x05 | OPC_CP3,
410 OPC_SWXC1 = 0x08 | OPC_CP3,
411 OPC_SDXC1 = 0x09 | OPC_CP3,
412 OPC_SUXC1 = 0x0D | OPC_CP3,
413 OPC_PREFX = 0x0F | OPC_CP3,
414 OPC_ALNV_PS = 0x1E | OPC_CP3,
415 OPC_MADD_S = 0x20 | OPC_CP3,
416 OPC_MADD_D = 0x21 | OPC_CP3,
417 OPC_MADD_PS = 0x26 | OPC_CP3,
418 OPC_MSUB_S = 0x28 | OPC_CP3,
419 OPC_MSUB_D = 0x29 | OPC_CP3,
420 OPC_MSUB_PS = 0x2E | OPC_CP3,
421 OPC_NMADD_S = 0x30 | OPC_CP3,
422 OPC_NMADD_D = 0x31 | OPC_CP3,
423 OPC_NMADD_PS= 0x36 | OPC_CP3,
424 OPC_NMSUB_S = 0x38 | OPC_CP3,
425 OPC_NMSUB_D = 0x39 | OPC_CP3,
426 OPC_NMSUB_PS= 0x3E | OPC_CP3,
427 };
428
429 /* global register indices */
430 static TCGv_ptr cpu_env;
431 static TCGv cpu_gpr[32], cpu_PC;
432 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
433 static TCGv cpu_dspctrl, btarget, bcond;
434 static TCGv_i32 hflags;
435 static TCGv_i32 fpu_fcr0, fpu_fcr31;
436
437 #include "gen-icount.h"
438
439 #define gen_helper_0i(name, arg) do { \
440 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
441 gen_helper_##name(helper_tmp); \
442 tcg_temp_free_i32(helper_tmp); \
443 } while(0)
444
445 #define gen_helper_1i(name, arg1, arg2) do { \
446 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
447 gen_helper_##name(arg1, helper_tmp); \
448 tcg_temp_free_i32(helper_tmp); \
449 } while(0)
450
451 #define gen_helper_2i(name, arg1, arg2, arg3) do { \
452 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
453 gen_helper_##name(arg1, arg2, helper_tmp); \
454 tcg_temp_free_i32(helper_tmp); \
455 } while(0)
456
457 #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do { \
458 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
459 gen_helper_##name(arg1, arg2, arg3, helper_tmp); \
460 tcg_temp_free_i32(helper_tmp); \
461 } while(0)
462
463 typedef struct DisasContext {
464 struct TranslationBlock *tb;
465 target_ulong pc, saved_pc;
466 uint32_t opcode;
467 /* Routine used to access memory */
468 int mem_idx;
469 uint32_t hflags, saved_hflags;
470 int bstate;
471 target_ulong btarget;
472 } DisasContext;
473
474 enum {
475 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
476 * exception condition */
477 BS_STOP = 1, /* We want to stop translation for any reason */
478 BS_BRANCH = 2, /* We reached a branch condition */
479 BS_EXCP = 3, /* We reached an exception condition */
480 };
481
482 static const char *regnames[] =
483 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
484 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
485 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
486 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
487
488 static const char *regnames_HI[] =
489 { "HI0", "HI1", "HI2", "HI3", };
490
491 static const char *regnames_LO[] =
492 { "LO0", "LO1", "LO2", "LO3", };
493
494 static const char *regnames_ACX[] =
495 { "ACX0", "ACX1", "ACX2", "ACX3", };
496
497 static const char *fregnames[] =
498 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
499 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
500 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
501 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
502
503 #ifdef MIPS_DEBUG_DISAS
504 #define MIPS_DEBUG(fmt, args...) \
505 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
506 TARGET_FMT_lx ": %08x " fmt "\n", \
507 ctx->pc, ctx->opcode , ##args)
508 #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
509 #else
510 #define MIPS_DEBUG(fmt, args...) do { } while(0)
511 #define LOG_DISAS(...) do { } while (0)
512 #endif
513
514 #define MIPS_INVAL(op) \
515 do { \
516 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
517 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
518 } while (0)
519
520 /* General purpose registers moves. */
521 static inline void gen_load_gpr (TCGv t, int reg)
522 {
523 if (reg == 0)
524 tcg_gen_movi_tl(t, 0);
525 else
526 tcg_gen_mov_tl(t, cpu_gpr[reg]);
527 }
528
529 static inline void gen_store_gpr (TCGv t, int reg)
530 {
531 if (reg != 0)
532 tcg_gen_mov_tl(cpu_gpr[reg], t);
533 }
534
535 /* Moves to/from ACX register. */
536 static inline void gen_load_ACX (TCGv t, int reg)
537 {
538 tcg_gen_mov_tl(t, cpu_ACX[reg]);
539 }
540
541 static inline void gen_store_ACX (TCGv t, int reg)
542 {
543 tcg_gen_mov_tl(cpu_ACX[reg], t);
544 }
545
546 /* Moves to/from shadow registers. */
547 static inline void gen_load_srsgpr (int from, int to)
548 {
549 TCGv t0 = tcg_temp_new();
550
551 if (from == 0)
552 tcg_gen_movi_tl(t0, 0);
553 else {
554 TCGv_i32 t2 = tcg_temp_new_i32();
555 TCGv_ptr addr = tcg_temp_new_ptr();
556
557 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
558 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
559 tcg_gen_andi_i32(t2, t2, 0xf);
560 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
561 tcg_gen_ext_i32_ptr(addr, t2);
562 tcg_gen_add_ptr(addr, cpu_env, addr);
563
564 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
565 tcg_temp_free_ptr(addr);
566 tcg_temp_free_i32(t2);
567 }
568 gen_store_gpr(t0, to);
569 tcg_temp_free(t0);
570 }
571
572 static inline void gen_store_srsgpr (int from, int to)
573 {
574 if (to != 0) {
575 TCGv t0 = tcg_temp_new();
576 TCGv_i32 t2 = tcg_temp_new_i32();
577 TCGv_ptr addr = tcg_temp_new_ptr();
578
579 gen_load_gpr(t0, from);
580 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
581 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
582 tcg_gen_andi_i32(t2, t2, 0xf);
583 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
584 tcg_gen_ext_i32_ptr(addr, t2);
585 tcg_gen_add_ptr(addr, cpu_env, addr);
586
587 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
588 tcg_temp_free_ptr(addr);
589 tcg_temp_free_i32(t2);
590 tcg_temp_free(t0);
591 }
592 }
593
594 /* Floating point register moves. */
595 static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
596 {
597 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
598 }
599
600 static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
601 {
602 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
603 }
604
605 static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
606 {
607 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
608 }
609
610 static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
611 {
612 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
613 }
614
615 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
616 {
617 if (ctx->hflags & MIPS_HFLAG_F64) {
618 tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
619 } else {
620 TCGv_i32 t0 = tcg_temp_new_i32();
621 TCGv_i32 t1 = tcg_temp_new_i32();
622 gen_load_fpr32(t0, reg & ~1);
623 gen_load_fpr32(t1, reg | 1);
624 tcg_gen_concat_i32_i64(t, t0, t1);
625 tcg_temp_free_i32(t0);
626 tcg_temp_free_i32(t1);
627 }
628 }
629
630 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
631 {
632 if (ctx->hflags & MIPS_HFLAG_F64) {
633 tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
634 } else {
635 TCGv_i64 t0 = tcg_temp_new_i64();
636 TCGv_i32 t1 = tcg_temp_new_i32();
637 tcg_gen_trunc_i64_i32(t1, t);
638 gen_store_fpr32(t1, reg & ~1);
639 tcg_gen_shri_i64(t0, t, 32);
640 tcg_gen_trunc_i64_i32(t1, t0);
641 gen_store_fpr32(t1, reg | 1);
642 tcg_temp_free_i32(t1);
643 tcg_temp_free_i64(t0);
644 }
645 }
646
647 static inline int get_fp_bit (int cc)
648 {
649 if (cc)
650 return 24 + cc;
651 else
652 return 23;
653 }
654
655 #define FOP_CONDS(type, fmt, bits) \
656 static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a, \
657 TCGv_i##bits b, int cc) \
658 { \
659 switch (n) { \
660 case 0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc); break;\
661 case 1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc); break;\
662 case 2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc); break;\
663 case 3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc); break;\
664 case 4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc); break;\
665 case 5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc); break;\
666 case 6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc); break;\
667 case 7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc); break;\
668 case 8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc); break;\
669 case 9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
670 case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc); break;\
671 case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc); break;\
672 case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc); break;\
673 case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc); break;\
674 case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc); break;\
675 case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc); break;\
676 default: abort(); \
677 } \
678 }
679
680 FOP_CONDS(, d, 64)
681 FOP_CONDS(abs, d, 64)
682 FOP_CONDS(, s, 32)
683 FOP_CONDS(abs, s, 32)
684 FOP_CONDS(, ps, 64)
685 FOP_CONDS(abs, ps, 64)
686 #undef FOP_CONDS
687
688 /* Tests */
689 #define OP_COND(name, cond) \
690 static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \
691 { \
692 int l1 = gen_new_label(); \
693 int l2 = gen_new_label(); \
694 \
695 tcg_gen_brcond_tl(cond, t0, t1, l1); \
696 tcg_gen_movi_tl(ret, 0); \
697 tcg_gen_br(l2); \
698 gen_set_label(l1); \
699 tcg_gen_movi_tl(ret, 1); \
700 gen_set_label(l2); \
701 }
702 OP_COND(eq, TCG_COND_EQ);
703 OP_COND(ne, TCG_COND_NE);
704 OP_COND(ge, TCG_COND_GE);
705 OP_COND(geu, TCG_COND_GEU);
706 OP_COND(lt, TCG_COND_LT);
707 OP_COND(ltu, TCG_COND_LTU);
708 #undef OP_COND
709
710 #define OP_CONDI(name, cond) \
711 static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \
712 { \
713 int l1 = gen_new_label(); \
714 int l2 = gen_new_label(); \
715 \
716 tcg_gen_brcondi_tl(cond, t0, val, l1); \
717 tcg_gen_movi_tl(ret, 0); \
718 tcg_gen_br(l2); \
719 gen_set_label(l1); \
720 tcg_gen_movi_tl(ret, 1); \
721 gen_set_label(l2); \
722 }
723 OP_CONDI(lti, TCG_COND_LT);
724 OP_CONDI(ltiu, TCG_COND_LTU);
725 #undef OP_CONDI
726
727 #define OP_CONDZ(name, cond) \
728 static inline void glue(gen_op_, name) (TCGv ret, TCGv t0) \
729 { \
730 int l1 = gen_new_label(); \
731 int l2 = gen_new_label(); \
732 \
733 tcg_gen_brcondi_tl(cond, t0, 0, l1); \
734 tcg_gen_movi_tl(ret, 0); \
735 tcg_gen_br(l2); \
736 gen_set_label(l1); \
737 tcg_gen_movi_tl(ret, 1); \
738 gen_set_label(l2); \
739 }
740 OP_CONDZ(gez, TCG_COND_GE);
741 OP_CONDZ(gtz, TCG_COND_GT);
742 OP_CONDZ(lez, TCG_COND_LE);
743 OP_CONDZ(ltz, TCG_COND_LT);
744 #undef OP_CONDZ
745
746 static inline void gen_save_pc(target_ulong pc)
747 {
748 tcg_gen_movi_tl(cpu_PC, pc);
749 }
750
751 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
752 {
753 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
754 if (do_save_pc && ctx->pc != ctx->saved_pc) {
755 gen_save_pc(ctx->pc);
756 ctx->saved_pc = ctx->pc;
757 }
758 if (ctx->hflags != ctx->saved_hflags) {
759 tcg_gen_movi_i32(hflags, ctx->hflags);
760 ctx->saved_hflags = ctx->hflags;
761 switch (ctx->hflags & MIPS_HFLAG_BMASK) {
762 case MIPS_HFLAG_BR:
763 break;
764 case MIPS_HFLAG_BC:
765 case MIPS_HFLAG_BL:
766 case MIPS_HFLAG_B:
767 tcg_gen_movi_tl(btarget, ctx->btarget);
768 break;
769 }
770 }
771 }
772
773 static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
774 {
775 ctx->saved_hflags = ctx->hflags;
776 switch (ctx->hflags & MIPS_HFLAG_BMASK) {
777 case MIPS_HFLAG_BR:
778 break;
779 case MIPS_HFLAG_BC:
780 case MIPS_HFLAG_BL:
781 case MIPS_HFLAG_B:
782 ctx->btarget = env->btarget;
783 break;
784 }
785 }
786
787 static inline void
788 generate_exception_err (DisasContext *ctx, int excp, int err)
789 {
790 TCGv_i32 texcp = tcg_const_i32(excp);
791 TCGv_i32 terr = tcg_const_i32(err);
792 save_cpu_state(ctx, 1);
793 gen_helper_raise_exception_err(texcp, terr);
794 tcg_temp_free_i32(terr);
795 tcg_temp_free_i32(texcp);
796 gen_helper_interrupt_restart();
797 tcg_gen_exit_tb(0);
798 }
799
800 static inline void
801 generate_exception (DisasContext *ctx, int excp)
802 {
803 save_cpu_state(ctx, 1);
804 gen_helper_0i(raise_exception, excp);
805 gen_helper_interrupt_restart();
806 tcg_gen_exit_tb(0);
807 }
808
809 /* Addresses computation */
810 static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
811 {
812 tcg_gen_add_tl(t0, t0, t1);
813
814 #if defined(TARGET_MIPS64)
815 /* For compatibility with 32-bit code, data reference in user mode
816 with Status_UX = 0 should be casted to 32-bit and sign extended.
817 See the MIPS64 PRA manual, section 4.10. */
818 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
819 !(ctx->hflags & MIPS_HFLAG_UX)) {
820 tcg_gen_ext32s_i64(t0, t0);
821 }
822 #endif
823 }
824
825 static inline void check_cp0_enabled(DisasContext *ctx)
826 {
827 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
828 generate_exception_err(ctx, EXCP_CpU, 1);
829 }
830
831 static inline void check_cp1_enabled(DisasContext *ctx)
832 {
833 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
834 generate_exception_err(ctx, EXCP_CpU, 1);
835 }
836
837 /* Verify that the processor is running with COP1X instructions enabled.
838 This is associated with the nabla symbol in the MIPS32 and MIPS64
839 opcode tables. */
840
841 static inline void check_cop1x(DisasContext *ctx)
842 {
843 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
844 generate_exception(ctx, EXCP_RI);
845 }
846
847 /* Verify that the processor is running with 64-bit floating-point
848 operations enabled. */
849
850 static inline void check_cp1_64bitmode(DisasContext *ctx)
851 {
852 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
853 generate_exception(ctx, EXCP_RI);
854 }
855
856 /*
857 * Verify if floating point register is valid; an operation is not defined
858 * if bit 0 of any register specification is set and the FR bit in the
859 * Status register equals zero, since the register numbers specify an
860 * even-odd pair of adjacent coprocessor general registers. When the FR bit
861 * in the Status register equals one, both even and odd register numbers
862 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
863 *
864 * Multiple 64 bit wide registers can be checked by calling
865 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
866 */
867 static inline void check_cp1_registers(DisasContext *ctx, int regs)
868 {
869 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
870 generate_exception(ctx, EXCP_RI);
871 }
872
873 /* This code generates a "reserved instruction" exception if the
874 CPU does not support the instruction set corresponding to flags. */
875 static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
876 {
877 if (unlikely(!(env->insn_flags & flags)))
878 generate_exception(ctx, EXCP_RI);
879 }
880
881 /* This code generates a "reserved instruction" exception if 64-bit
882 instructions are not enabled. */
883 static inline void check_mips_64(DisasContext *ctx)
884 {
885 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
886 generate_exception(ctx, EXCP_RI);
887 }
888
889 /* load/store instructions. */
890 #define OP_LD(insn,fname) \
891 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
892 { \
893 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
894 }
895 OP_LD(lb,ld8s);
896 OP_LD(lbu,ld8u);
897 OP_LD(lh,ld16s);
898 OP_LD(lhu,ld16u);
899 OP_LD(lw,ld32s);
900 #if defined(TARGET_MIPS64)
901 OP_LD(lwu,ld32u);
902 OP_LD(ld,ld64);
903 #endif
904 #undef OP_LD
905
906 #define OP_ST(insn,fname) \
907 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
908 { \
909 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
910 }
911 OP_ST(sb,st8);
912 OP_ST(sh,st16);
913 OP_ST(sw,st32);
914 #if defined(TARGET_MIPS64)
915 OP_ST(sd,st64);
916 #endif
917 #undef OP_ST
918
919 #define OP_LD_ATOMIC(insn,fname) \
920 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
921 { \
922 TCGv t0 = tcg_temp_new(); \
923 tcg_gen_mov_tl(t0, arg1); \
924 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
925 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr)); \
926 tcg_temp_free(t0); \
927 }
928 OP_LD_ATOMIC(ll,ld32s);
929 #if defined(TARGET_MIPS64)
930 OP_LD_ATOMIC(lld,ld64);
931 #endif
932 #undef OP_LD_ATOMIC
933
934 #define OP_ST_ATOMIC(insn,fname,almask) \
935 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, TCGv arg2, DisasContext *ctx) \
936 { \
937 TCGv t0 = tcg_temp_new(); \
938 int l1 = gen_new_label(); \
939 int l2 = gen_new_label(); \
940 int l3 = gen_new_label(); \
941 \
942 tcg_gen_andi_tl(t0, arg2, almask); \
943 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
944 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
945 generate_exception(ctx, EXCP_AdES); \
946 gen_set_label(l1); \
947 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr)); \
948 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
949 tcg_temp_free(t0); \
950 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
951 tcg_gen_movi_tl(ret, 1); \
952 tcg_gen_br(l3); \
953 gen_set_label(l2); \
954 tcg_gen_movi_tl(ret, 0); \
955 gen_set_label(l3); \
956 }
957 OP_ST_ATOMIC(sc,st32,0x3);
958 #if defined(TARGET_MIPS64)
959 OP_ST_ATOMIC(scd,st64,0x7);
960 #endif
961 #undef OP_ST_ATOMIC
962
963 /* Load and store */
964 static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
965 int base, int16_t offset)
966 {
967 const char *opn = "ldst";
968 TCGv t0 = tcg_temp_new();
969 TCGv t1 = tcg_temp_new();
970
971 if (base == 0) {
972 tcg_gen_movi_tl(t0, offset);
973 } else if (offset == 0) {
974 gen_load_gpr(t0, base);
975 } else {
976 tcg_gen_movi_tl(t0, offset);
977 gen_op_addr_add(ctx, t0, cpu_gpr[base]);
978 }
979 /* Don't do NOP if destination is zero: we must perform the actual
980 memory access. */
981 switch (opc) {
982 #if defined(TARGET_MIPS64)
983 case OPC_LWU:
984 save_cpu_state(ctx, 0);
985 op_ldst_lwu(t0, t0, ctx);
986 gen_store_gpr(t0, rt);
987 opn = "lwu";
988 break;
989 case OPC_LD:
990 save_cpu_state(ctx, 0);
991 op_ldst_ld(t0, t0, ctx);
992 gen_store_gpr(t0, rt);
993 opn = "ld";
994 break;
995 case OPC_LLD:
996 save_cpu_state(ctx, 0);
997 op_ldst_lld(t0, t0, ctx);
998 gen_store_gpr(t0, rt);
999 opn = "lld";
1000 break;
1001 case OPC_SD:
1002 save_cpu_state(ctx, 0);
1003 gen_load_gpr(t1, rt);
1004 op_ldst_sd(t1, t0, ctx);
1005 opn = "sd";
1006 break;
1007 case OPC_LDL:
1008 save_cpu_state(ctx, 1);
1009 gen_load_gpr(t1, rt);
1010 gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1011 gen_store_gpr(t1, rt);
1012 opn = "ldl";
1013 break;
1014 case OPC_SDL:
1015 save_cpu_state(ctx, 1);
1016 gen_load_gpr(t1, rt);
1017 gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1018 opn = "sdl";
1019 break;
1020 case OPC_LDR:
1021 save_cpu_state(ctx, 1);
1022 gen_load_gpr(t1, rt);
1023 gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1024 gen_store_gpr(t1, rt);
1025 opn = "ldr";
1026 break;
1027 case OPC_SDR:
1028 save_cpu_state(ctx, 1);
1029 gen_load_gpr(t1, rt);
1030 gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1031 opn = "sdr";
1032 break;
1033 #endif
1034 case OPC_LW:
1035 save_cpu_state(ctx, 0);
1036 op_ldst_lw(t0, t0, ctx);
1037 gen_store_gpr(t0, rt);
1038 opn = "lw";
1039 break;
1040 case OPC_SW:
1041 save_cpu_state(ctx, 0);
1042 gen_load_gpr(t1, rt);
1043 op_ldst_sw(t1, t0, ctx);
1044 opn = "sw";
1045 break;
1046 case OPC_LH:
1047 save_cpu_state(ctx, 0);
1048 op_ldst_lh(t0, t0, ctx);
1049 gen_store_gpr(t0, rt);
1050 opn = "lh";
1051 break;
1052 case OPC_SH:
1053 save_cpu_state(ctx, 0);
1054 gen_load_gpr(t1, rt);
1055 op_ldst_sh(t1, t0, ctx);
1056 opn = "sh";
1057 break;
1058 case OPC_LHU:
1059 save_cpu_state(ctx, 0);
1060 op_ldst_lhu(t0, t0, ctx);
1061 gen_store_gpr(t0, rt);
1062 opn = "lhu";
1063 break;
1064 case OPC_LB:
1065 save_cpu_state(ctx, 0);
1066 op_ldst_lb(t0, t0, ctx);
1067 gen_store_gpr(t0, rt);
1068 opn = "lb";
1069 break;
1070 case OPC_SB:
1071 save_cpu_state(ctx, 0);
1072 gen_load_gpr(t1, rt);
1073 op_ldst_sb(t1, t0, ctx);
1074 opn = "sb";
1075 break;
1076 case OPC_LBU:
1077 save_cpu_state(ctx, 0);
1078 op_ldst_lbu(t0, t0, ctx);
1079 gen_store_gpr(t0, rt);
1080 opn = "lbu";
1081 break;
1082 case OPC_LWL:
1083 save_cpu_state(ctx, 1);
1084 gen_load_gpr(t1, rt);
1085 gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1086 gen_store_gpr(t1, rt);
1087 opn = "lwl";
1088 break;
1089 case OPC_SWL:
1090 save_cpu_state(ctx, 1);
1091 gen_load_gpr(t1, rt);
1092 gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1093 opn = "swr";
1094 break;
1095 case OPC_LWR:
1096 save_cpu_state(ctx, 1);
1097 gen_load_gpr(t1, rt);
1098 gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1099 gen_store_gpr(t1, rt);
1100 opn = "lwr";
1101 break;
1102 case OPC_SWR:
1103 save_cpu_state(ctx, 1);
1104 gen_load_gpr(t1, rt);
1105 gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1106 opn = "swr";
1107 break;
1108 case OPC_LL:
1109 save_cpu_state(ctx, 0);
1110 op_ldst_ll(t0, t0, ctx);
1111 gen_store_gpr(t0, rt);
1112 opn = "ll";
1113 break;
1114 }
1115 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1116 tcg_temp_free(t0);
1117 tcg_temp_free(t1);
1118 }
1119
1120 /* Store conditional */
1121 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1122 int base, int16_t offset)
1123 {
1124 const char *opn = "st_cond";
1125 TCGv t0, t1;
1126
1127 t0 = tcg_temp_local_new();
1128
1129 if (base == 0) {
1130 tcg_gen_movi_tl(t0, offset);
1131 } else if (offset == 0) {
1132 gen_load_gpr(t0, base);
1133 } else {
1134 tcg_gen_movi_tl(t0, offset);
1135 gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1136 }
1137 /* Don't do NOP if destination is zero: we must perform the actual
1138 memory access. */
1139
1140 t1 = tcg_temp_local_new();
1141 gen_load_gpr(t1, rt);
1142 switch (opc) {
1143 #if defined(TARGET_MIPS64)
1144 case OPC_SCD:
1145 save_cpu_state(ctx, 0);
1146 op_ldst_scd(t0, t1, t0, ctx);
1147 opn = "scd";
1148 break;
1149 #endif
1150 case OPC_SC:
1151 save_cpu_state(ctx, 0);
1152 op_ldst_sc(t0, t1, t0, ctx);
1153 opn = "sc";
1154 break;
1155 }
1156 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1157 tcg_temp_free(t1);
1158 gen_store_gpr(t0, rt);
1159 tcg_temp_free(t0);
1160 }
1161
1162 /* Load and store */
1163 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1164 int base, int16_t offset)
1165 {
1166 const char *opn = "flt_ldst";
1167 TCGv t0 = tcg_temp_new();
1168
1169 if (base == 0) {
1170 tcg_gen_movi_tl(t0, offset);
1171 } else if (offset == 0) {
1172 gen_load_gpr(t0, base);
1173 } else {
1174 tcg_gen_movi_tl(t0, offset);
1175 gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1176 }
1177 /* Don't do NOP if destination is zero: we must perform the actual
1178 memory access. */
1179 switch (opc) {
1180 case OPC_LWC1:
1181 {
1182 TCGv_i32 fp0 = tcg_temp_new_i32();
1183
1184 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1185 tcg_gen_trunc_tl_i32(fp0, t0);
1186 gen_store_fpr32(fp0, ft);
1187 tcg_temp_free_i32(fp0);
1188 }
1189 opn = "lwc1";
1190 break;
1191 case OPC_SWC1:
1192 {
1193 TCGv_i32 fp0 = tcg_temp_new_i32();
1194 TCGv t1 = tcg_temp_new();
1195
1196 gen_load_fpr32(fp0, ft);
1197 tcg_gen_extu_i32_tl(t1, fp0);
1198 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1199 tcg_temp_free(t1);
1200 tcg_temp_free_i32(fp0);
1201 }
1202 opn = "swc1";
1203 break;
1204 case OPC_LDC1:
1205 {
1206 TCGv_i64 fp0 = tcg_temp_new_i64();
1207
1208 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1209 gen_store_fpr64(ctx, fp0, ft);
1210 tcg_temp_free_i64(fp0);
1211 }
1212 opn = "ldc1";
1213 break;
1214 case OPC_SDC1:
1215 {
1216 TCGv_i64 fp0 = tcg_temp_new_i64();
1217
1218 gen_load_fpr64(ctx, fp0, ft);
1219 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1220 tcg_temp_free_i64(fp0);
1221 }
1222 opn = "sdc1";
1223 break;
1224 default:
1225 MIPS_INVAL(opn);
1226 generate_exception(ctx, EXCP_RI);
1227 goto out;
1228 }
1229 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1230 out:
1231 tcg_temp_free(t0);
1232 }
1233
1234 /* Arithmetic with immediate operand */
1235 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1236 int rt, int rs, int16_t imm)
1237 {
1238 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1239 const char *opn = "imm arith";
1240
1241 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1242 /* If no destination, treat it as a NOP.
1243 For addi, we must generate the overflow exception when needed. */
1244 MIPS_DEBUG("NOP");
1245 return;
1246 }
1247 switch (opc) {
1248 case OPC_ADDI:
1249 {
1250 TCGv t0 = tcg_temp_local_new();
1251 TCGv t1 = tcg_temp_new();
1252 TCGv t2 = tcg_temp_new();
1253 int l1 = gen_new_label();
1254
1255 gen_load_gpr(t1, rs);
1256 tcg_gen_addi_tl(t0, t1, uimm);
1257 tcg_gen_ext32s_tl(t0, t0);
1258
1259 tcg_gen_xori_tl(t1, t1, ~uimm);
1260 tcg_gen_xori_tl(t2, t0, uimm);
1261 tcg_gen_and_tl(t1, t1, t2);
1262 tcg_temp_free(t2);
1263 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1264 tcg_temp_free(t1);
1265 /* operands of same sign, result different sign */
1266 generate_exception(ctx, EXCP_OVERFLOW);
1267 gen_set_label(l1);
1268 tcg_gen_ext32s_tl(t0, t0);
1269 gen_store_gpr(t0, rt);
1270 tcg_temp_free(t0);
1271 }
1272 opn = "addi";
1273 break;
1274 case OPC_ADDIU:
1275 if (rs != 0) {
1276 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1277 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1278 } else {
1279 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1280 }
1281 opn = "addiu";
1282 break;
1283 #if defined(TARGET_MIPS64)
1284 case OPC_DADDI:
1285 {
1286 TCGv t0 = tcg_temp_local_new();
1287 TCGv t1 = tcg_temp_new();
1288 TCGv t2 = tcg_temp_new();
1289 int l1 = gen_new_label();
1290
1291 gen_load_gpr(t1, rs);
1292 tcg_gen_addi_tl(t0, t1, uimm);
1293
1294 tcg_gen_xori_tl(t1, t1, ~uimm);
1295 tcg_gen_xori_tl(t2, t0, uimm);
1296 tcg_gen_and_tl(t1, t1, t2);
1297 tcg_temp_free(t2);
1298 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1299 tcg_temp_free(t1);
1300 /* operands of same sign, result different sign */
1301 generate_exception(ctx, EXCP_OVERFLOW);
1302 gen_set_label(l1);
1303 gen_store_gpr(t0, rt);
1304 tcg_temp_free(t0);
1305 }
1306 opn = "daddi";
1307 break;
1308 case OPC_DADDIU:
1309 if (rs != 0) {
1310 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1311 } else {
1312 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1313 }
1314 opn = "daddiu";
1315 break;
1316 #endif
1317 }
1318 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1319 }
1320
1321 /* Logic with immediate operand */
1322 static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1323 {
1324 target_ulong uimm;
1325 const char *opn = "imm logic";
1326
1327 if (rt == 0) {
1328 /* If no destination, treat it as a NOP. */
1329 MIPS_DEBUG("NOP");
1330 return;
1331 }
1332 uimm = (uint16_t)imm;
1333 switch (opc) {
1334 case OPC_ANDI:
1335 if (likely(rs != 0))
1336 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1337 else
1338 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1339 opn = "andi";
1340 break;
1341 case OPC_ORI:
1342 if (rs != 0)
1343 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1344 else
1345 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1346 opn = "ori";
1347 break;
1348 case OPC_XORI:
1349 if (likely(rs != 0))
1350 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1351 else
1352 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1353 opn = "xori";
1354 break;
1355 case OPC_LUI:
1356 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1357 opn = "lui";
1358 break;
1359 }
1360 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1361 }
1362
1363 /* Set on less than with immediate operand */
1364 static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1365 {
1366 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1367 const char *opn = "imm arith";
1368 TCGv t0;
1369
1370 if (rt == 0) {
1371 /* If no destination, treat it as a NOP. */
1372 MIPS_DEBUG("NOP");
1373 return;
1374 }
1375 t0 = tcg_temp_new();
1376 gen_load_gpr(t0, rs);
1377 switch (opc) {
1378 case OPC_SLTI:
1379 gen_op_lti(cpu_gpr[rt], t0, uimm);
1380 opn = "slti";
1381 break;
1382 case OPC_SLTIU:
1383 gen_op_ltiu(cpu_gpr[rt], t0, uimm);
1384 opn = "sltiu";
1385 break;
1386 }
1387 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1388 tcg_temp_free(t0);
1389 }
1390
1391 /* Shifts with immediate operand */
1392 static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1393 int rt, int rs, int16_t imm)
1394 {
1395 target_ulong uimm = ((uint16_t)imm) & 0x1f;
1396 const char *opn = "imm shift";
1397 TCGv t0;
1398
1399 if (rt == 0) {
1400 /* If no destination, treat it as a NOP. */
1401 MIPS_DEBUG("NOP");
1402 return;
1403 }
1404
1405 t0 = tcg_temp_new();
1406 gen_load_gpr(t0, rs);
1407 switch (opc) {
1408 case OPC_SLL:
1409 tcg_gen_shli_tl(t0, t0, uimm);
1410 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1411 opn = "sll";
1412 break;
1413 case OPC_SRA:
1414 tcg_gen_ext32s_tl(t0, t0);
1415 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1416 opn = "sra";
1417 break;
1418 case OPC_SRL:
1419 switch ((ctx->opcode >> 21) & 0x1f) {
1420 case 0:
1421 if (uimm != 0) {
1422 tcg_gen_ext32u_tl(t0, t0);
1423 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1424 } else {
1425 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1426 }
1427 opn = "srl";
1428 break;
1429 case 1:
1430 /* rotr is decoded as srl on non-R2 CPUs */
1431 if (env->insn_flags & ISA_MIPS32R2) {
1432 if (uimm != 0) {
1433 TCGv_i32 t1 = tcg_temp_new_i32();
1434
1435 tcg_gen_trunc_tl_i32(t1, t0);
1436 tcg_gen_rotri_i32(t1, t1, uimm);
1437 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1438 tcg_temp_free_i32(t1);
1439 }
1440 opn = "rotr";
1441 } else {
1442 if (uimm != 0) {
1443 tcg_gen_ext32u_tl(t0, t0);
1444 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1445 } else {
1446 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1447 }
1448 opn = "srl";
1449 }
1450 break;
1451 default:
1452 MIPS_INVAL("invalid srl flag");
1453 generate_exception(ctx, EXCP_RI);
1454 break;
1455 }
1456 break;
1457 #if defined(TARGET_MIPS64)
1458 case OPC_DSLL:
1459 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1460 opn = "dsll";
1461 break;
1462 case OPC_DSRA:
1463 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1464 opn = "dsra";
1465 break;
1466 case OPC_DSRL:
1467 switch ((ctx->opcode >> 21) & 0x1f) {
1468 case 0:
1469 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1470 opn = "dsrl";
1471 break;
1472 case 1:
1473 /* drotr is decoded as dsrl on non-R2 CPUs */
1474 if (env->insn_flags & ISA_MIPS32R2) {
1475 if (uimm != 0) {
1476 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1477 }
1478 opn = "drotr";
1479 } else {
1480 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1481 opn = "dsrl";
1482 }
1483 break;
1484 default:
1485 MIPS_INVAL("invalid dsrl flag");
1486 generate_exception(ctx, EXCP_RI);
1487 break;
1488 }
1489 break;
1490 case OPC_DSLL32:
1491 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1492 opn = "dsll32";
1493 break;
1494 case OPC_DSRA32:
1495 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1496 opn = "dsra32";
1497 break;
1498 case OPC_DSRL32:
1499 switch ((ctx->opcode >> 21) & 0x1f) {
1500 case 0:
1501 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1502 opn = "dsrl32";
1503 break;
1504 case 1:
1505 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1506 if (env->insn_flags & ISA_MIPS32R2) {
1507 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1508 opn = "drotr32";
1509 } else {
1510 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1511 opn = "dsrl32";
1512 }
1513 break;
1514 default:
1515 MIPS_INVAL("invalid dsrl32 flag");
1516 generate_exception(ctx, EXCP_RI);
1517 break;
1518 }
1519 break;
1520 #endif
1521 }
1522 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1523 tcg_temp_free(t0);
1524 }
1525
1526 /* Arithmetic */
1527 static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1528 int rd, int rs, int rt)
1529 {
1530 const char *opn = "arith";
1531
1532 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1533 && opc != OPC_DADD && opc != OPC_DSUB) {
1534 /* If no destination, treat it as a NOP.
1535 For add & sub, we must generate the overflow exception when needed. */
1536 MIPS_DEBUG("NOP");
1537 return;
1538 }
1539
1540 switch (opc) {
1541 case OPC_ADD:
1542 {
1543 TCGv t0 = tcg_temp_local_new();
1544 TCGv t1 = tcg_temp_new();
1545 TCGv t2 = tcg_temp_new();
1546 int l1 = gen_new_label();
1547
1548 gen_load_gpr(t1, rs);
1549 gen_load_gpr(t2, rt);
1550 tcg_gen_add_tl(t0, t1, t2);
1551 tcg_gen_ext32s_tl(t0, t0);
1552 tcg_gen_xor_tl(t1, t1, t2);
1553 tcg_gen_not_tl(t1, t1);
1554 tcg_gen_xor_tl(t2, t0, t2);
1555 tcg_gen_and_tl(t1, t1, t2);
1556 tcg_temp_free(t2);
1557 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1558 tcg_temp_free(t1);
1559 /* operands of same sign, result different sign */
1560 generate_exception(ctx, EXCP_OVERFLOW);
1561 gen_set_label(l1);
1562 gen_store_gpr(t0, rd);
1563 tcg_temp_free(t0);
1564 }
1565 opn = "add";
1566 break;
1567 case OPC_ADDU:
1568 if (rs != 0 && rt != 0) {
1569 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1570 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1571 } else if (rs == 0 && rt != 0) {
1572 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1573 } else if (rs != 0 && rt == 0) {
1574 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1575 } else {
1576 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1577 }
1578 opn = "addu";
1579 break;
1580 case OPC_SUB:
1581 {
1582 TCGv t0 = tcg_temp_local_new();
1583 TCGv t1 = tcg_temp_new();
1584 TCGv t2 = tcg_temp_new();
1585 int l1 = gen_new_label();
1586
1587 gen_load_gpr(t1, rs);
1588 gen_load_gpr(t2, rt);
1589 tcg_gen_sub_tl(t0, t1, t2);
1590 tcg_gen_ext32s_tl(t0, t0);
1591 tcg_gen_xor_tl(t2, t1, t2);
1592 tcg_gen_xor_tl(t1, t0, t1);
1593 tcg_gen_and_tl(t1, t1, t2);
1594 tcg_temp_free(t2);
1595 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1596 tcg_temp_free(t1);
1597 /* operands of same sign, result different sign */
1598 generate_exception(ctx, EXCP_OVERFLOW);
1599 gen_set_label(l1);
1600 gen_store_gpr(t0, rd);
1601 tcg_temp_free(t0);
1602 }
1603 opn = "sub";
1604 break;
1605 case OPC_SUBU:
1606 if (rs != 0 && rt != 0) {
1607 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1608 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1609 } else if (rs == 0 && rt != 0) {
1610 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1611 } else if (rs != 0 && rt == 0) {
1612 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1613 } else {
1614 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1615 }
1616 opn = "subu";
1617 break;
1618 #if defined(TARGET_MIPS64)
1619 case OPC_DADD:
1620 {
1621 TCGv t0 = tcg_temp_local_new();
1622 TCGv t1 = tcg_temp_new();
1623 TCGv t2 = tcg_temp_new();
1624 int l1 = gen_new_label();
1625
1626 gen_load_gpr(t1, rs);
1627 gen_load_gpr(t2, rt);
1628 tcg_gen_add_tl(t0, t1, t2);
1629 tcg_gen_xor_tl(t1, t1, t2);
1630 tcg_gen_not_tl(t1, t1);
1631 tcg_gen_xor_tl(t2, t0, t2);
1632 tcg_gen_and_tl(t1, t1, t2);
1633 tcg_temp_free(t2);
1634 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1635 tcg_temp_free(t1);
1636 /* operands of same sign, result different sign */
1637 generate_exception(ctx, EXCP_OVERFLOW);
1638 gen_set_label(l1);
1639 gen_store_gpr(t0, rd);
1640 tcg_temp_free(t0);
1641 }
1642 opn = "dadd";
1643 break;
1644 case OPC_DADDU:
1645 if (rs != 0 && rt != 0) {
1646 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1647 } else if (rs == 0 && rt != 0) {
1648 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1649 } else if (rs != 0 && rt == 0) {
1650 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1651 } else {
1652 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1653 }
1654 opn = "daddu";
1655 break;
1656 case OPC_DSUB:
1657 {
1658 TCGv t0 = tcg_temp_local_new();
1659 TCGv t1 = tcg_temp_new();
1660 TCGv t2 = tcg_temp_new();
1661 int l1 = gen_new_label();
1662
1663 gen_load_gpr(t1, rs);
1664 gen_load_gpr(t2, rt);
1665 tcg_gen_sub_tl(t0, t1, t2);
1666 tcg_gen_xor_tl(t2, t1, t2);
1667 tcg_gen_xor_tl(t1, t0, t1);
1668 tcg_gen_and_tl(t1, t1, t2);
1669 tcg_temp_free(t2);
1670 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1671 tcg_temp_free(t1);
1672 /* operands of same sign, result different sign */
1673 generate_exception(ctx, EXCP_OVERFLOW);
1674 gen_set_label(l1);
1675 gen_store_gpr(t0, rd);
1676 tcg_temp_free(t0);
1677 }
1678 opn = "dsub";
1679 break;
1680 case OPC_DSUBU:
1681 if (rs != 0 && rt != 0) {
1682 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1683 } else if (rs == 0 && rt != 0) {
1684 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1685 } else if (rs != 0 && rt == 0) {
1686 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1687 } else {
1688 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1689 }
1690 opn = "dsubu";
1691 break;
1692 #endif
1693 case OPC_MUL:
1694 if (likely(rs != 0 && rt != 0)) {
1695 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1696 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1697 } else {
1698 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1699 }
1700 opn = "mul";
1701 break;
1702 }
1703 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1704 }
1705
1706 /* Conditional move */
1707 static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1708 {
1709 const char *opn = "cond move";
1710 int l1;
1711
1712 if (rd == 0) {
1713 /* If no destination, treat it as a NOP.
1714 For add & sub, we must generate the overflow exception when needed. */
1715 MIPS_DEBUG("NOP");
1716 return;
1717 }
1718
1719 l1 = gen_new_label();
1720 switch (opc) {
1721 case OPC_MOVN:
1722 if (likely(rt != 0))
1723 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1724 else
1725 tcg_gen_br(l1);
1726 opn = "movn";
1727 break;
1728 case OPC_MOVZ:
1729 if (likely(rt != 0))
1730 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1731 opn = "movz";
1732 break;
1733 }
1734 if (rs != 0)
1735 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1736 else
1737 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1738 gen_set_label(l1);
1739
1740 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1741 }
1742
1743 /* Logic */
1744 static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1745 {
1746 const char *opn = "logic";
1747
1748 if (rd == 0) {
1749 /* If no destination, treat it as a NOP. */
1750 MIPS_DEBUG("NOP");
1751 return;
1752 }
1753
1754 switch (opc) {
1755 case OPC_AND:
1756 if (likely(rs != 0 && rt != 0)) {
1757 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1758 } else {
1759 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1760 }
1761 opn = "and";
1762 break;
1763 case OPC_NOR:
1764 if (rs != 0 && rt != 0) {
1765 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1766 } else if (rs == 0 && rt != 0) {
1767 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1768 } else if (rs != 0 && rt == 0) {
1769 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1770 } else {
1771 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1772 }
1773 opn = "nor";
1774 break;
1775 case OPC_OR:
1776 if (likely(rs != 0 && rt != 0)) {
1777 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1778 } else if (rs == 0 && rt != 0) {
1779 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1780 } else if (rs != 0 && rt == 0) {
1781 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1782 } else {
1783 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1784 }
1785 opn = "or";
1786 break;
1787 case OPC_XOR:
1788 if (likely(rs != 0 && rt != 0)) {
1789 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1790 } else if (rs == 0 && rt != 0) {
1791 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1792 } else if (rs != 0 && rt == 0) {
1793 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1794 } else {
1795 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1796 }
1797 opn = "xor";
1798 break;
1799 }
1800 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1801 }
1802
1803 /* Set on lower than */
1804 static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1805 {
1806 const char *opn = "slt";
1807 TCGv t0, t1;
1808
1809 if (rd == 0) {
1810 /* If no destination, treat it as a NOP. */
1811 MIPS_DEBUG("NOP");
1812 return;
1813 }
1814
1815 t0 = tcg_temp_new();
1816 t1 = tcg_temp_new();
1817 gen_load_gpr(t0, rs);
1818 gen_load_gpr(t1, rt);
1819 switch (opc) {
1820 case OPC_SLT:
1821 gen_op_lt(cpu_gpr[rd], t0, t1);
1822 opn = "slt";
1823 break;
1824 case OPC_SLTU:
1825 gen_op_ltu(cpu_gpr[rd], t0, t1);
1826 opn = "sltu";
1827 break;
1828 }
1829 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1830 tcg_temp_free(t0);
1831 tcg_temp_free(t1);
1832 }
1833
1834 /* Shifts */
1835 static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1836 int rd, int rs, int rt)
1837 {
1838 const char *opn = "shifts";
1839 TCGv t0, t1;
1840
1841 if (rd == 0) {
1842 /* If no destination, treat it as a NOP.
1843 For add & sub, we must generate the overflow exception when needed. */
1844 MIPS_DEBUG("NOP");
1845 return;
1846 }
1847
1848 t0 = tcg_temp_new();
1849 t1 = tcg_temp_new();
1850 gen_load_gpr(t0, rs);
1851 gen_load_gpr(t1, rt);
1852 switch (opc) {
1853 case OPC_SLLV:
1854 tcg_gen_andi_tl(t0, t0, 0x1f);
1855 tcg_gen_shl_tl(t0, t1, t0);
1856 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1857 opn = "sllv";
1858 break;
1859 case OPC_SRAV:
1860 tcg_gen_ext32s_tl(t1, t1);
1861 tcg_gen_andi_tl(t0, t0, 0x1f);
1862 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1863 opn = "srav";
1864 break;
1865 case OPC_SRLV:
1866 switch ((ctx->opcode >> 6) & 0x1f) {
1867 case 0:
1868 tcg_gen_ext32u_tl(t1, t1);
1869 tcg_gen_andi_tl(t0, t0, 0x1f);
1870 tcg_gen_shr_tl(t0, t1, t0);
1871 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1872 opn = "srlv";
1873 break;
1874 case 1:
1875 /* rotrv is decoded as srlv on non-R2 CPUs */
1876 if (env->insn_flags & ISA_MIPS32R2) {
1877 TCGv_i32 t2 = tcg_temp_new_i32();
1878 TCGv_i32 t3 = tcg_temp_new_i32();
1879
1880 tcg_gen_trunc_tl_i32(t2, t0);
1881 tcg_gen_trunc_tl_i32(t3, t1);
1882 tcg_gen_andi_i32(t2, t2, 0x1f);
1883 tcg_gen_rotr_i32(t2, t3, t2);
1884 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1885 tcg_temp_free_i32(t2);
1886 tcg_temp_free_i32(t3);
1887 opn = "rotrv";
1888 } else {
1889 tcg_gen_ext32u_tl(t1, t1);
1890 tcg_gen_andi_tl(t0, t0, 0x1f);
1891 tcg_gen_shr_tl(t0, t1, t0);
1892 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1893 opn = "srlv";
1894 }
1895 break;
1896 default:
1897 MIPS_INVAL("invalid srlv flag");
1898 generate_exception(ctx, EXCP_RI);
1899 break;
1900 }
1901 break;
1902 #if defined(TARGET_MIPS64)
1903 case OPC_DSLLV:
1904 tcg_gen_andi_tl(t0, t0, 0x3f);
1905 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1906 opn = "dsllv";
1907 break;
1908 case OPC_DSRAV:
1909 tcg_gen_andi_tl(t0, t0, 0x3f);
1910 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1911 opn = "dsrav";
1912 break;
1913 case OPC_DSRLV:
1914 switch ((ctx->opcode >> 6) & 0x1f) {
1915 case 0:
1916 tcg_gen_andi_tl(t0, t0, 0x3f);
1917 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1918 opn = "dsrlv";
1919 break;
1920 case 1:
1921 /* drotrv is decoded as dsrlv on non-R2 CPUs */
1922 if (env->insn_flags & ISA_MIPS32R2) {
1923 tcg_gen_andi_tl(t0, t0, 0x3f);
1924 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1925 opn = "drotrv";
1926 } else {
1927 tcg_gen_andi_tl(t0, t0, 0x3f);
1928 tcg_gen_shr_tl(t0, t1, t0);
1929 opn = "dsrlv";
1930 }
1931 break;
1932 default:
1933 MIPS_INVAL("invalid dsrlv flag");
1934 generate_exception(ctx, EXCP_RI);
1935 break;
1936 }
1937 break;
1938 #endif
1939 }
1940 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1941 tcg_temp_free(t0);
1942 tcg_temp_free(t1);
1943 }
1944
1945 /* Arithmetic on HI/LO registers */
1946 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1947 {
1948 const char *opn = "hilo";
1949
1950 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1951 /* Treat as NOP. */
1952 MIPS_DEBUG("NOP");
1953 return;
1954 }
1955 switch (opc) {
1956 case OPC_MFHI:
1957 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1958 opn = "mfhi";
1959 break;
1960 case OPC_MFLO:
1961 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1962 opn = "mflo";
1963 break;
1964 case OPC_MTHI:
1965 if (reg != 0)
1966 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1967 else
1968 tcg_gen_movi_tl(cpu_HI[0], 0);
1969 opn = "mthi";
1970 break;
1971 case OPC_MTLO:
1972 if (reg != 0)
1973 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1974 else
1975 tcg_gen_movi_tl(cpu_LO[0], 0);
1976 opn = "mtlo";
1977 break;
1978 }
1979 MIPS_DEBUG("%s %s", opn, regnames[reg]);
1980 }
1981
1982 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1983 int rs, int rt)
1984 {
1985 const char *opn = "mul/div";
1986 TCGv t0, t1;
1987
1988 switch (opc) {
1989 case OPC_DIV:
1990 case OPC_DIVU:
1991 #if defined(TARGET_MIPS64)
1992 case OPC_DDIV:
1993 case OPC_DDIVU:
1994 #endif
1995 t0 = tcg_temp_local_new();
1996 t1 = tcg_temp_local_new();
1997 break;
1998 default:
1999 t0 = tcg_temp_new();
2000 t1 = tcg_temp_new();
2001 break;
2002 }
2003
2004 gen_load_gpr(t0, rs);
2005 gen_load_gpr(t1, rt);
2006 switch (opc) {
2007 case OPC_DIV:
2008 {
2009 int l1 = gen_new_label();
2010 int l2 = gen_new_label();
2011
2012 tcg_gen_ext32s_tl(t0, t0);
2013 tcg_gen_ext32s_tl(t1, t1);
2014 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2015 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2016 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2017
2018 tcg_gen_mov_tl(cpu_LO[0], t0);
2019 tcg_gen_movi_tl(cpu_HI[0], 0);
2020 tcg_gen_br(l1);
2021 gen_set_label(l2);
2022 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2023 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2024 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2025 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2026 gen_set_label(l1);
2027 }
2028 opn = "div";
2029 break;
2030 case OPC_DIVU:
2031 {
2032 int l1 = gen_new_label();
2033
2034 tcg_gen_ext32u_tl(t0, t0);
2035 tcg_gen_ext32u_tl(t1, t1);
2036 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2037 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2038 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2039 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2040 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2041 gen_set_label(l1);
2042 }
2043 opn = "divu";
2044 break;
2045 case OPC_MULT:
2046 {
2047 TCGv_i64 t2 = tcg_temp_new_i64();
2048 TCGv_i64 t3 = tcg_temp_new_i64();
2049
2050 tcg_gen_ext_tl_i64(t2, t0);
2051 tcg_gen_ext_tl_i64(t3, t1);
2052 tcg_gen_mul_i64(t2, t2, t3);
2053 tcg_temp_free_i64(t3);
2054 tcg_gen_trunc_i64_tl(t0, t2);
2055 tcg_gen_shri_i64(t2, t2, 32);
2056 tcg_gen_trunc_i64_tl(t1, t2);
2057 tcg_temp_free_i64(t2);
2058 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2059 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2060 }
2061 opn = "mult";
2062 break;
2063 case OPC_MULTU:
2064 {
2065 TCGv_i64 t2 = tcg_temp_new_i64();
2066 TCGv_i64 t3 = tcg_temp_new_i64();
2067
2068 tcg_gen_ext32u_tl(t0, t0);
2069 tcg_gen_ext32u_tl(t1, t1);
2070 tcg_gen_extu_tl_i64(t2, t0);
2071 tcg_gen_extu_tl_i64(t3, t1);
2072 tcg_gen_mul_i64(t2, t2, t3);
2073 tcg_temp_free_i64(t3);
2074 tcg_gen_trunc_i64_tl(t0, t2);
2075 tcg_gen_shri_i64(t2, t2, 32);
2076 tcg_gen_trunc_i64_tl(t1, t2);
2077 tcg_temp_free_i64(t2);
2078 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2079 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2080 }
2081 opn = "multu";
2082 break;
2083 #if defined(TARGET_MIPS64)
2084 case OPC_DDIV:
2085 {
2086 int l1 = gen_new_label();
2087 int l2 = gen_new_label();
2088
2089 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2090 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2091 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2092 tcg_gen_mov_tl(cpu_LO[0], t0);
2093 tcg_gen_movi_tl(cpu_HI[0], 0);
2094 tcg_gen_br(l1);
2095 gen_set_label(l2);
2096 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2097 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2098 gen_set_label(l1);
2099 }
2100 opn = "ddiv";
2101 break;
2102 case OPC_DDIVU:
2103 {
2104 int l1 = gen_new_label();
2105
2106 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2107 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2108 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2109 gen_set_label(l1);
2110 }
2111 opn = "ddivu";
2112 break;
2113 case OPC_DMULT:
2114 gen_helper_dmult(t0, t1);
2115 opn = "dmult";
2116 break;
2117 case OPC_DMULTU:
2118 gen_helper_dmultu(t0, t1);
2119 opn = "dmultu";
2120 break;
2121 #endif
2122 case OPC_MADD:
2123 {
2124 TCGv_i64 t2 = tcg_temp_new_i64();
2125 TCGv_i64 t3 = tcg_temp_new_i64();
2126
2127 tcg_gen_ext_tl_i64(t2, t0);
2128 tcg_gen_ext_tl_i64(t3, t1);
2129 tcg_gen_mul_i64(t2, t2, t3);
2130 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2131 tcg_gen_add_i64(t2, t2, t3);
2132 tcg_temp_free_i64(t3);
2133 tcg_gen_trunc_i64_tl(t0, t2);
2134 tcg_gen_shri_i64(t2, t2, 32);
2135 tcg_gen_trunc_i64_tl(t1, t2);
2136 tcg_temp_free_i64(t2);
2137 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2138 tcg_gen_ext32s_tl(cpu_LO[1], t1);
2139 }
2140 opn = "madd";
2141 break;
2142 case OPC_MADDU:
2143 {
2144 TCGv_i64 t2 = tcg_temp_new_i64();
2145 TCGv_i64 t3 = tcg_temp_new_i64();
2146
2147 tcg_gen_ext32u_tl(t0, t0);
2148 tcg_gen_ext32u_tl(t1, t1);
2149 tcg_gen_extu_tl_i64(t2, t0);
2150 tcg_gen_extu_tl_i64(t3, t1);
2151 tcg_gen_mul_i64(t2, t2, t3);
2152 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2153 tcg_gen_add_i64(t2, t2, t3);
2154 tcg_temp_free_i64(t3);
2155 tcg_gen_trunc_i64_tl(t0, t2);
2156 tcg_gen_shri_i64(t2, t2, 32);
2157 tcg_gen_trunc_i64_tl(t1, t2);
2158 tcg_temp_free_i64(t2);
2159 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2160 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2161 }
2162 opn = "maddu";
2163 break;
2164 case OPC_MSUB:
2165 {
2166 TCGv_i64 t2 = tcg_temp_new_i64();
2167 TCGv_i64 t3 = tcg_temp_new_i64();
2168
2169 tcg_gen_ext_tl_i64(t2, t0);
2170 tcg_gen_ext_tl_i64(t3, t1);
2171 tcg_gen_mul_i64(t2, t2, t3);
2172 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2173 tcg_gen_sub_i64(t2, t2, t3);
2174 tcg_temp_free_i64(t3);
2175 tcg_gen_trunc_i64_tl(t0, t2);
2176 tcg_gen_shri_i64(t2, t2, 32);
2177 tcg_gen_trunc_i64_tl(t1, t2);
2178 tcg_temp_free_i64(t2);
2179 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2180 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2181 }
2182 opn = "msub";
2183 break;
2184 case OPC_MSUBU:
2185 {
2186 TCGv_i64 t2 = tcg_temp_new_i64();
2187 TCGv_i64 t3 = tcg_temp_new_i64();
2188
2189 tcg_gen_ext32u_tl(t0, t0);
2190 tcg_gen_ext32u_tl(t1, t1);
2191 tcg_gen_extu_tl_i64(t2, t0);
2192 tcg_gen_extu_tl_i64(t3, t1);
2193 tcg_gen_mul_i64(t2, t2, t3);
2194 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2195 tcg_gen_sub_i64(t2, t2, t3);
2196 tcg_temp_free_i64(t3);
2197 tcg_gen_trunc_i64_tl(t0, t2);
2198 tcg_gen_shri_i64(t2, t2, 32);
2199 tcg_gen_trunc_i64_tl(t1, t2);
2200 tcg_temp_free_i64(t2);
2201 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2202 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2203 }
2204 opn = "msubu";
2205 break;
2206 default:
2207 MIPS_INVAL(opn);
2208 generate_exception(ctx, EXCP_RI);
2209 goto out;
2210 }
2211 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2212 out:
2213 tcg_temp_free(t0);
2214 tcg_temp_free(t1);
2215 }
2216
2217 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2218 int rd, int rs, int rt)
2219 {
2220 const char *opn = "mul vr54xx";
2221 TCGv t0 = tcg_temp_new();
2222 TCGv t1 = tcg_temp_new();
2223
2224 gen_load_gpr(t0, rs);
2225 gen_load_gpr(t1, rt);
2226
2227 switch (opc) {
2228 case OPC_VR54XX_MULS:
2229 gen_helper_muls(t0, t0, t1);
2230 opn = "muls";
2231 break;
2232 case OPC_VR54XX_MULSU:
2233 gen_helper_mulsu(t0, t0, t1);
2234 opn = "mulsu";
2235 break;
2236 case OPC_VR54XX_MACC:
2237 gen_helper_macc(t0, t0, t1);
2238 opn = "macc";
2239 break;
2240 case OPC_VR54XX_MACCU:
2241 gen_helper_maccu(t0, t0, t1);
2242 opn = "maccu";
2243 break;
2244 case OPC_VR54XX_MSAC:
2245 gen_helper_msac(t0, t0, t1);
2246 opn = "msac";
2247 break;
2248 case OPC_VR54XX_MSACU:
2249 gen_helper_msacu(t0, t0, t1);
2250 opn = "msacu";
2251 break;
2252 case OPC_VR54XX_MULHI:
2253 gen_helper_mulhi(t0, t0, t1);
2254 opn = "mulhi";
2255 break;
2256 case OPC_VR54XX_MULHIU:
2257 gen_helper_mulhiu(t0, t0, t1);
2258 opn = "mulhiu";
2259 break;
2260 case OPC_VR54XX_MULSHI:
2261 gen_helper_mulshi(t0, t0, t1);
2262 opn = "mulshi";
2263 break;
2264 case OPC_VR54XX_MULSHIU:
2265 gen_helper_mulshiu(t0, t0, t1);
2266 opn = "mulshiu";
2267 break;
2268 case OPC_VR54XX_MACCHI:
2269 gen_helper_macchi(t0, t0, t1);
2270 opn = "macchi";
2271 break;
2272 case OPC_VR54XX_MACCHIU:
2273 gen_helper_macchiu(t0, t0, t1);
2274 opn = "macchiu";
2275 break;
2276 case OPC_VR54XX_MSACHI:
2277 gen_helper_msachi(t0, t0, t1);
2278 opn = "msachi";
2279 break;
2280 case OPC_VR54XX_MSACHIU:
2281 gen_helper_msachiu(t0, t0, t1);
2282 opn = "msachiu";
2283 break;
2284 default:
2285 MIPS_INVAL("mul vr54xx");
2286 generate_exception(ctx, EXCP_RI);
2287 goto out;
2288 }
2289 gen_store_gpr(t0, rd);
2290 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2291
2292 out:
2293 tcg_temp_free(t0);
2294 tcg_temp_free(t1);
2295 }
2296
2297 static void gen_cl (DisasContext *ctx, uint32_t opc,
2298 int rd, int rs)
2299 {
2300 const char *opn = "CLx";
2301 TCGv t0;
2302
2303 if (rd == 0) {
2304 /* Treat as NOP. */
2305 MIPS_DEBUG("NOP");
2306 return;
2307 }
2308 t0 = tcg_temp_new();
2309 gen_load_gpr(t0, rs);
2310 switch (opc) {
2311 case OPC_CLO:
2312 gen_helper_clo(cpu_gpr[rd], t0);
2313 opn = "clo";
2314 break;
2315 case OPC_CLZ:
2316 gen_helper_clz(cpu_gpr[rd], t0);
2317 opn = "clz";
2318 break;
2319 #if defined(TARGET_MIPS64)
2320 case OPC_DCLO:
2321 gen_helper_dclo(cpu_gpr[rd], t0);
2322 opn = "dclo";
2323 break;
2324 case OPC_DCLZ:
2325 gen_helper_dclz(cpu_gpr[rd], t0);
2326 opn = "dclz";
2327 break;
2328 #endif
2329 }
2330 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2331 tcg_temp_free(t0);
2332 }
2333
2334 /* Traps */
2335 static void gen_trap (DisasContext *ctx, uint32_t opc,
2336 int rs, int rt, int16_t imm)
2337 {
2338 int cond;
2339 TCGv t0 = tcg_temp_new();
2340 TCGv t1 = tcg_temp_new();
2341
2342 cond = 0;
2343 /* Load needed operands */
2344 switch (opc) {
2345 case OPC_TEQ:
2346 case OPC_TGE:
2347 case OPC_TGEU:
2348 case OPC_TLT:
2349 case OPC_TLTU:
2350 case OPC_TNE:
2351 /* Compare two registers */
2352 if (rs != rt) {
2353 gen_load_gpr(t0, rs);
2354 gen_load_gpr(t1, rt);
2355 cond = 1;
2356 }
2357 break;
2358 case OPC_TEQI:
2359 case OPC_TGEI:
2360 case OPC_TGEIU:
2361 case OPC_TLTI:
2362 case OPC_TLTIU:
2363 case OPC_TNEI:
2364 /* Compare register to immediate */
2365 if (rs != 0 || imm != 0) {
2366 gen_load_gpr(t0, rs);
2367 tcg_gen_movi_tl(t1, (int32_t)imm);
2368 cond = 1;
2369 }
2370 break;
2371 }
2372 if (cond == 0) {
2373 switch (opc) {
2374 case OPC_TEQ: /* rs == rs */
2375 case OPC_TEQI: /* r0 == 0 */
2376 case OPC_TGE: /* rs >= rs */
2377 case OPC_TGEI: /* r0 >= 0 */
2378 case OPC_TGEU: /* rs >= rs unsigned */
2379 case OPC_TGEIU: /* r0 >= 0 unsigned */
2380 /* Always trap */
2381 generate_exception(ctx, EXCP_TRAP);
2382 break;
2383 case OPC_TLT: /* rs < rs */
2384 case OPC_TLTI: /* r0 < 0 */
2385 case OPC_TLTU: /* rs < rs unsigned */
2386 case OPC_TLTIU: /* r0 < 0 unsigned */
2387 case OPC_TNE: /* rs != rs */
2388 case OPC_TNEI: /* r0 != 0 */
2389 /* Never trap: treat as NOP. */
2390 break;
2391 }
2392 } else {
2393 int l1 = gen_new_label();
2394
2395 switch (opc) {
2396 case OPC_TEQ:
2397 case OPC_TEQI:
2398 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2399 break;
2400 case OPC_TGE:
2401 case OPC_TGEI:
2402 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2403 break;
2404 case OPC_TGEU:
2405 case OPC_TGEIU:
2406 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2407 break;
2408 case OPC_TLT:
2409 case OPC_TLTI:
2410 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2411 break;
2412 case OPC_TLTU:
2413 case OPC_TLTIU:
2414 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2415 break;
2416 case OPC_TNE:
2417 case OPC_TNEI:
2418 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2419 break;
2420 }
2421 generate_exception(ctx, EXCP_TRAP);
2422 gen_set_label(l1);
2423 }
2424 tcg_temp_free(t0);
2425 tcg_temp_free(t1);
2426 }
2427
2428 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2429 {
2430 TranslationBlock *tb;
2431 tb = ctx->tb;
2432 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2433 tcg_gen_goto_tb(n);
2434 gen_save_pc(dest);
2435 tcg_gen_exit_tb((long)tb + n);
2436 } else {
2437 gen_save_pc(dest);
2438 tcg_gen_exit_tb(0);
2439 }
2440 }
2441
2442 /* Branches (before delay slot) */
2443 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
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 + 4 + offset;
2473 break;
2474 case OPC_BGEZ:
2475 case OPC_BGEZAL:
2476 case OPC_BGEZALL:
2477 case OPC_BGEZL:
2478 case OPC_BGTZ:
2479 case OPC_BGTZL:
2480 case OPC_BLEZ:
2481 case OPC_BLEZL:
2482 case OPC_BLTZ:
2483 case OPC_BLTZAL:
2484 case OPC_BLTZALL:
2485 case OPC_BLTZL:
2486 /* Compare to zero */
2487 if (rs != 0) {
2488 gen_load_gpr(t0, rs);
2489 bcond_compute = 1;
2490 }
2491 btgt = ctx->pc + 4 + offset;
2492 break;
2493 case OPC_J:
2494 case OPC_JAL:
2495 /* Jump to immediate */
2496 btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2497 break;
2498 case OPC_JR:
2499 case OPC_JALR:
2500 /* Jump to register */
2501 if (offset != 0 && offset != 16) {
2502 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2503 others are reserved. */
2504 MIPS_INVAL("jump hint");
2505 generate_exception(ctx, EXCP_RI);
2506 goto out;
2507 }
2508 gen_load_gpr(btarget, rs);
2509 break;
2510 default:
2511 MIPS_INVAL("branch/jump");
2512 generate_exception(ctx, EXCP_RI);
2513 goto out;
2514 }
2515 if (bcond_compute == 0) {
2516 /* No condition to be computed */
2517 switch (opc) {
2518 case OPC_BEQ: /* rx == rx */
2519 case OPC_BEQL: /* rx == rx likely */
2520 case OPC_BGEZ: /* 0 >= 0 */
2521 case OPC_BGEZL: /* 0 >= 0 likely */
2522 case OPC_BLEZ: /* 0 <= 0 */
2523 case OPC_BLEZL: /* 0 <= 0 likely */
2524 /* Always take */
2525 ctx->hflags |= MIPS_HFLAG_B;
2526 MIPS_DEBUG("balways");
2527 break;
2528 case OPC_BGEZAL: /* 0 >= 0 */
2529 case OPC_BGEZALL: /* 0 >= 0 likely */
2530 /* Always take and link */
2531 blink = 31;
2532 ctx->hflags |= MIPS_HFLAG_B;
2533 MIPS_DEBUG("balways and link");
2534 break;
2535 case OPC_BNE: /* rx != rx */
2536 case OPC_BGTZ: /* 0 > 0 */
2537 case OPC_BLTZ: /* 0 < 0 */
2538 /* Treat as NOP. */
2539 MIPS_DEBUG("bnever (NOP)");
2540 goto out;
2541 case OPC_BLTZAL: /* 0 < 0 */
2542 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2543 MIPS_DEBUG("bnever and link");
2544 goto out;
2545 case OPC_BLTZALL: /* 0 < 0 likely */
2546 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2547 /* Skip the instruction in the delay slot */
2548 MIPS_DEBUG("bnever, link and skip");
2549 ctx->pc += 4;
2550 goto out;
2551 case OPC_BNEL: /* rx != rx likely */
2552 case OPC_BGTZL: /* 0 > 0 likely */
2553 case OPC_BLTZL: /* 0 < 0 likely */
2554 /* Skip the instruction in the delay slot */
2555 MIPS_DEBUG("bnever and skip");
2556 ctx->pc += 4;
2557 goto out;
2558 case OPC_J:
2559 ctx->hflags |= MIPS_HFLAG_B;
2560 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2561 break;
2562 case OPC_JAL:
2563 blink = 31;
2564 ctx->hflags |= MIPS_HFLAG_B;
2565 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2566 break;
2567 case OPC_JR:
2568 ctx->hflags |= MIPS_HFLAG_BR;
2569 MIPS_DEBUG("jr %s", regnames[rs]);
2570 break;
2571 case OPC_JALR:
2572 blink = rt;
2573 ctx->hflags |= MIPS_HFLAG_BR;
2574 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2575 break;
2576 default:
2577 MIPS_INVAL("branch/jump");
2578 generate_exception(ctx, EXCP_RI);
2579 goto out;
2580 }
2581 } else {
2582 switch (opc) {
2583 case OPC_BEQ:
2584 gen_op_eq(bcond, t0, t1);
2585 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2586 regnames[rs], regnames[rt], btgt);
2587 goto not_likely;
2588 case OPC_BEQL:
2589 gen_op_eq(bcond, t0, t1);
2590 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2591 regnames[rs], regnames[rt], btgt);
2592 goto likely;
2593 case OPC_BNE:
2594 gen_op_ne(bcond, t0, t1);
2595 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2596 regnames[rs], regnames[rt], btgt);
2597 goto not_likely;
2598 case OPC_BNEL:
2599 gen_op_ne(bcond, t0, t1);
2600 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2601 regnames[rs], regnames[rt], btgt);
2602 goto likely;
2603 case OPC_BGEZ:
2604 gen_op_gez(bcond, t0);
2605 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2606 goto not_likely;
2607 case OPC_BGEZL:
2608 gen_op_gez(bcond, t0);
2609 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2610 goto likely;
2611 case OPC_BGEZAL:
2612 gen_op_gez(bcond, t0);
2613 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2614 blink = 31;
2615 goto not_likely;
2616 case OPC_BGEZALL:
2617 gen_op_gez(bcond, t0);
2618 blink = 31;
2619 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2620 goto likely;
2621 case OPC_BGTZ:
2622 gen_op_gtz(bcond, t0);
2623 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2624 goto not_likely;
2625 case OPC_BGTZL:
2626 gen_op_gtz(bcond, t0);
2627 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2628 goto likely;
2629 case OPC_BLEZ:
2630 gen_op_lez(bcond, t0);
2631 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2632 goto not_likely;
2633 case OPC_BLEZL:
2634 gen_op_lez(bcond, t0);
2635 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2636 goto likely;
2637 case OPC_BLTZ:
2638 gen_op_ltz(bcond, t0);
2639 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2640 goto not_likely;
2641 case OPC_BLTZL:
2642 gen_op_ltz(bcond, t0);
2643 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2644 goto likely;
2645 case OPC_BLTZAL:
2646 gen_op_ltz(bcond, t0);
2647 blink = 31;
2648 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2649 not_likely:
2650 ctx->hflags |= MIPS_HFLAG_BC;
2651 break;
2652 case OPC_BLTZALL:
2653 gen_op_ltz(bcond, t0);
2654 blink = 31;
2655 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2656 likely:
2657 ctx->hflags |= MIPS_HFLAG_BL;
2658 break;
2659 default:
2660 MIPS_INVAL("conditional branch/jump");
2661 generate_exception(ctx, EXCP_RI);
2662 goto out;
2663 }
2664 }
2665 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2666 blink, ctx->hflags, btgt);
2667
2668 ctx->btarget = btgt;
2669 if (blink > 0) {
2670 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2671 }
2672
2673 out:
2674 tcg_temp_free(t0);
2675 tcg_temp_free(t1);
2676 }
2677
2678 /* special3 bitfield operations */
2679 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2680 int rs, int lsb, int msb)
2681 {
2682 TCGv t0 = tcg_temp_new();
2683 TCGv t1 = tcg_temp_new();
2684 target_ulong mask;
2685
2686 gen_load_gpr(t1, rs);
2687 switch (opc) {
2688 case OPC_EXT:
2689 if (lsb + msb > 31)
2690 goto fail;
2691 tcg_gen_shri_tl(t0, t1, lsb);
2692 if (msb != 31) {
2693 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2694 } else {
2695 tcg_gen_ext32s_tl(t0, t0);
2696 }
2697 break;
2698 #if defined(TARGET_MIPS64)
2699 case OPC_DEXTM:
2700 tcg_gen_shri_tl(t0, t1, lsb);
2701 if (msb != 31) {
2702 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2703 }
2704 break;
2705 case OPC_DEXTU:
2706 tcg_gen_shri_tl(t0, t1, lsb + 32);
2707 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2708 break;
2709 case OPC_DEXT:
2710 tcg_gen_shri_tl(t0, t1, lsb);
2711 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2712 break;
2713 #endif
2714 case OPC_INS:
2715 if (lsb > msb)
2716 goto fail;
2717 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2718 gen_load_gpr(t0, rt);
2719 tcg_gen_andi_tl(t0, t0, ~mask);
2720 tcg_gen_shli_tl(t1, t1, lsb);
2721 tcg_gen_andi_tl(t1, t1, mask);
2722 tcg_gen_or_tl(t0, t0, t1);
2723 tcg_gen_ext32s_tl(t0, t0);
2724 break;
2725 #if defined(TARGET_MIPS64)
2726 case OPC_DINSM:
2727 if (lsb > msb)
2728 goto fail;
2729 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2730 gen_load_gpr(t0, rt);
2731 tcg_gen_andi_tl(t0, t0, ~mask);
2732 tcg_gen_shli_tl(t1, t1, lsb);
2733 tcg_gen_andi_tl(t1, t1, mask);
2734 tcg_gen_or_tl(t0, t0, t1);
2735 break;
2736 case OPC_DINSU:
2737 if (lsb > msb)
2738 goto fail;
2739 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2740 gen_load_gpr(t0, rt);
2741 tcg_gen_andi_tl(t0, t0, ~mask);
2742 tcg_gen_shli_tl(t1, t1, lsb + 32);
2743 tcg_gen_andi_tl(t1, t1, mask);
2744 tcg_gen_or_tl(t0, t0, t1);
2745 break;
2746 case OPC_DINS:
2747 if (lsb > msb)
2748 goto fail;
2749 gen_load_gpr(t0, rt);
2750 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2751 gen_load_gpr(t0, rt);
2752 tcg_gen_andi_tl(t0, t0, ~mask);
2753 tcg_gen_shli_tl(t1, t1, lsb);
2754 tcg_gen_andi_tl(t1, t1, mask);
2755 tcg_gen_or_tl(t0, t0, t1);
2756 break;
2757 #endif
2758 default:
2759 fail:
2760 MIPS_INVAL("bitops");
2761 generate_exception(ctx, EXCP_RI);
2762 tcg_temp_free(t0);
2763 tcg_temp_free(t1);
2764 return;
2765 }
2766 gen_store_gpr(t0, rt);
2767 tcg_temp_free(t0);
2768 tcg_temp_free(t1);
2769 }
2770
2771 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2772 {
2773 TCGv t0;
2774
2775 if (rd == 0) {
2776 /* If no destination, treat it as a NOP. */
2777 MIPS_DEBUG("NOP");
2778 return;
2779 }
2780
2781 t0 = tcg_temp_new();
2782 gen_load_gpr(t0, rt);
2783 switch (op2) {
2784 case OPC_WSBH:
2785 {
2786 TCGv t1 = tcg_temp_new();
2787
2788 tcg_gen_shri_tl(t1, t0, 8);
2789 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2790 tcg_gen_shli_tl(t0, t0, 8);
2791 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2792 tcg_gen_or_tl(t0, t0, t1);
2793 tcg_temp_free(t1);
2794 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2795 }
2796 break;
2797 case OPC_SEB:
2798 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2799 break;
2800 case OPC_SEH:
2801 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2802 break;
2803 #if defined(TARGET_MIPS64)
2804 case OPC_DSBH:
2805 {
2806 TCGv t1 = tcg_temp_new();
2807
2808 tcg_gen_shri_tl(t1, t0, 8);
2809 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2810 tcg_gen_shli_tl(t0, t0, 8);
2811 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2812 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2813 tcg_temp_free(t1);
2814 }
2815 break;
2816 case OPC_DSHD:
2817 {
2818 TCGv t1 = tcg_temp_new();
2819
2820 tcg_gen_shri_tl(t1, t0, 16);
2821 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2822 tcg_gen_shli_tl(t0, t0, 16);
2823 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2824 tcg_gen_or_tl(t0, t0, t1);
2825 tcg_gen_shri_tl(t1, t0, 32);
2826 tcg_gen_shli_tl(t0, t0, 32);
2827 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2828 tcg_temp_free(t1);
2829 }
2830 break;
2831 #endif
2832 default:
2833 MIPS_INVAL("bsfhl");
2834 generate_exception(ctx, EXCP_RI);
2835 tcg_temp_free(t0);
2836 return;
2837 }
2838 tcg_temp_free(t0);
2839 }
2840
2841 #ifndef CONFIG_USER_ONLY
2842 /* CP0 (MMU and control) */
2843 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2844 {
2845 TCGv_i32 t0 = tcg_temp_new_i32();
2846
2847 tcg_gen_ld_i32(t0, cpu_env, off);
2848 tcg_gen_ext_i32_tl(arg, t0);
2849 tcg_temp_free_i32(t0);
2850 }
2851
2852 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2853 {
2854 tcg_gen_ld_tl(arg, cpu_env, off);
2855 tcg_gen_ext32s_tl(arg, arg);
2856 }
2857
2858 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2859 {
2860 TCGv_i32 t0 = tcg_temp_new_i32();
2861
2862 tcg_gen_trunc_tl_i32(t0, arg);
2863 tcg_gen_st_i32(t0, cpu_env, off);
2864 tcg_temp_free_i32(t0);
2865 }
2866
2867 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2868 {
2869 tcg_gen_ext32s_tl(arg, arg);
2870 tcg_gen_st_tl(arg, cpu_env, off);
2871 }
2872
2873 static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2874 {
2875 const char *rn = "invalid";
2876
2877 if (sel != 0)
2878 check_insn(env, ctx, ISA_MIPS32);
2879
2880 switch (reg) {
2881 case 0:
2882 switch (sel) {
2883 case 0:
2884 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
2885 rn = "Index";
2886 break;
2887 case 1:
2888 check_insn(env, ctx, ASE_MT);
2889 gen_helper_mfc0_mvpcontrol(arg);
2890 rn = "MVPControl";
2891 break;
2892 case 2:
2893 check_insn(env, ctx, ASE_MT);
2894 gen_helper_mfc0_mvpconf0(arg);
2895 rn = "MVPConf0";
2896 break;
2897 case 3:
2898 check_insn(env, ctx, ASE_MT);
2899 gen_helper_mfc0_mvpconf1(arg);
2900 rn = "MVPConf1";
2901 break;
2902 default:
2903 goto die;
2904 }
2905 break;
2906 case 1:
2907 switch (sel) {
2908 case 0:
2909 gen_helper_mfc0_random(arg);
2910 rn = "Random";
2911 break;
2912 case 1:
2913 check_insn(env, ctx, ASE_MT);
2914 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
2915 rn = "VPEControl";
2916 break;
2917 case 2:
2918 check_insn(env, ctx, ASE_MT);
2919 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
2920 rn = "VPEConf0";
2921 break;
2922 case 3:
2923 check_insn(env, ctx, ASE_MT);
2924 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
2925 rn = "VPEConf1";
2926 break;
2927 case 4:
2928 check_insn(env, ctx, ASE_MT);
2929 gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
2930 rn = "YQMask";
2931 break;
2932 case 5:
2933 check_insn(env, ctx, ASE_MT);
2934 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
2935 rn = "VPESchedule";
2936 break;
2937 case 6:
2938 check_insn(env, ctx, ASE_MT);
2939 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
2940 rn = "VPEScheFBack";
2941 break;
2942 case 7:
2943 check_insn(env, ctx, ASE_MT);
2944 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
2945 rn = "VPEOpt";
2946 break;
2947 default:
2948 goto die;
2949 }
2950 break;
2951 case 2:
2952 switch (sel) {
2953 case 0:
2954 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2955 tcg_gen_ext32s_tl(arg, arg);
2956 rn = "EntryLo0";
2957 break;
2958 case 1:
2959 check_insn(env, ctx, ASE_MT);
2960 gen_helper_mfc0_tcstatus(arg);
2961 rn = "TCStatus";
2962 break;
2963 case 2:
2964 check_insn(env, ctx, ASE_MT);
2965 gen_helper_mfc0_tcbind(arg);
2966 rn = "TCBind";
2967 break;
2968 case 3:
2969 check_insn(env, ctx, ASE_MT);
2970 gen_helper_mfc0_tcrestart(arg);
2971 rn = "TCRestart";
2972 break;
2973 case 4:
2974 check_insn(env, ctx, ASE_MT);
2975 gen_helper_mfc0_tchalt(arg);
2976 rn = "TCHalt";
2977 break;
2978 case 5:
2979 check_insn(env, ctx, ASE_MT);
2980 gen_helper_mfc0_tccontext(arg);
2981 rn = "TCContext";
2982 break;
2983 case 6:
2984 check_insn(env, ctx, ASE_MT);
2985 gen_helper_mfc0_tcschedule(arg);
2986 rn = "TCSchedule";
2987 break;
2988 case 7:
2989 check_insn(env, ctx, ASE_MT);
2990 gen_helper_mfc0_tcschefback(arg);
2991 rn = "TCScheFBack";
2992 break;
2993 default:
2994 goto die;
2995 }
2996 break;
2997 case 3:
2998 switch (sel) {
2999 case 0:
3000 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3001 tcg_gen_ext32s_tl(arg, arg);
3002 rn = "EntryLo1";
3003 break;
3004 default:
3005 goto die;
3006 }
3007 break;
3008 case 4:
3009 switch (sel) {
3010 case 0:
3011 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3012 tcg_gen_ext32s_tl(arg, arg);
3013 rn = "Context";
3014 break;
3015 case 1:
3016 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3017 rn = "ContextConfig";
3018 // break;
3019 default:
3020 goto die;
3021 }
3022 break;
3023 case 5:
3024 switch (sel) {
3025 case 0:
3026 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3027 rn = "PageMask";
3028 break;
3029 case 1:
3030 check_insn(env, ctx, ISA_MIPS32R2);
3031 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3032 rn = "PageGrain";
3033 break;
3034 default:
3035 goto die;
3036 }
3037 break;
3038 case 6:
3039 switch (sel) {
3040 case 0:
3041 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3042 rn = "Wired";
3043 break;
3044 case 1:
3045 check_insn(env, ctx, ISA_MIPS32R2);
3046 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3047 rn = "SRSConf0";
3048 break;
3049 case 2:
3050 check_insn(env, ctx, ISA_MIPS32R2);
3051 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3052 rn = "SRSConf1";
3053 break;
3054 case 3:
3055 check_insn(env, ctx, ISA_MIPS32R2);
3056 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3057 rn = "SRSConf2";
3058 break;
3059 case 4:
3060 check_insn(env, ctx, ISA_MIPS32R2);
3061 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3062 rn = "SRSConf3";
3063 break;
3064 case 5:
3065 check_insn(env, ctx, ISA_MIPS32R2);
3066 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3067 rn = "SRSConf4";
3068 break;
3069 default:
3070 goto die;
3071 }
3072 break;
3073 case 7:
3074 switch (sel) {
3075 case 0:
3076 check_insn(env, ctx, ISA_MIPS32R2);
3077 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3078 rn = "HWREna";
3079 break;
3080 default:
3081 goto die;
3082 }
3083 break;
3084 case 8:
3085 switch (sel) {
3086 case 0:
3087 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3088 tcg_gen_ext32s_tl(arg, arg);
3089 rn = "BadVAddr";
3090 break;
3091 default:
3092 goto die;
3093 }
3094 break;
3095 case 9:
3096 switch (sel) {
3097 case 0:
3098 /* Mark as an IO operation because we read the time. */
3099 if (use_icount)
3100 gen_io_start();
3101 gen_helper_mfc0_count(arg);
3102 if (use_icount) {
3103 gen_io_end();
3104 ctx->bstate = BS_STOP;
3105 }
3106 rn = "Count";
3107 break;
3108 /* 6,7 are implementation dependent */
3109 default:
3110 goto die;
3111 }
3112 break;
3113 case 10:
3114 switch (sel) {
3115 case 0:
3116 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3117 tcg_gen_ext32s_tl(arg, arg);
3118 rn = "EntryHi";
3119 break;
3120 default:
3121 goto die;
3122 }
3123 break;
3124 case 11:
3125 switch (sel) {
3126 case 0:
3127 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3128 rn = "Compare";
3129 break;
3130 /* 6,7 are implementation dependent */
3131 default:
3132 goto die;
3133 }
3134 break;
3135 case 12:
3136 switch (sel) {
3137 case 0:
3138 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3139 rn = "Status";
3140 break;
3141 case 1:
3142 check_insn(env, ctx, ISA_MIPS32R2);
3143 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3144 rn = "IntCtl";
3145 break;
3146 case 2:
3147 check_insn(env, ctx, ISA_MIPS32R2);
3148 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3149 rn = "SRSCtl";
3150 break;
3151 case 3:
3152 check_insn(env, ctx, ISA_MIPS32R2);
3153 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3154 rn = "SRSMap";
3155 break;
3156 default:
3157 goto die;
3158 }
3159 break;
3160 case 13:
3161 switch (sel) {
3162 case 0:
3163 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3164 rn = "Cause";
3165 break;
3166 default:
3167 goto die;
3168 }
3169 break;
3170 case 14:
3171 switch (sel) {
3172 case 0:
3173 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3174 tcg_gen_ext32s_tl(arg, arg);
3175 rn = "EPC";
3176 break;
3177 default:
3178 goto die;
3179 }
3180 break;
3181 case 15:
3182 switch (sel) {
3183 case 0:
3184 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3185 rn = "PRid";
3186 break;
3187 case 1:
3188 check_insn(env, ctx, ISA_MIPS32R2);
3189 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3190 rn = "EBase";
3191 break;
3192 default:
3193 goto die;
3194 }
3195 break;
3196 case 16:
3197 switch (sel) {
3198 case 0:
3199 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3200 rn = "Config";
3201 break;
3202 case 1:
3203 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3204 rn = "Config1";
3205 break;
3206 case 2:
3207 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3208 rn = "Config2";
3209 break;
3210 case 3:
3211 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3212 rn = "Config3";
3213 break;
3214 /* 4,5 are reserved */
3215 /* 6,7 are implementation dependent */
3216 case 6:
3217 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3218 rn = "Config6";
3219 break;
3220 case 7:
3221 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3222 rn = "Config7";
3223 break;
3224 default:
3225 goto die;
3226 }
3227 break;
3228 case 17:
3229 switch (sel) {
3230 case 0:
3231 gen_helper_mfc0_lladdr(arg);
3232 rn = "LLAddr";
3233 break;
3234 default:
3235 goto die;
3236 }
3237 break;
3238 case 18:
3239 switch (sel) {
3240 case 0 ... 7:
3241 gen_helper_1i(mfc0_watchlo, arg, sel);
3242 rn = "WatchLo";
3243 break;
3244 default:
3245 goto die;
3246 }
3247 break;
3248 case 19:
3249 switch (sel) {
3250 case 0 ...7:
3251 gen_helper_1i(mfc0_watchhi, arg, sel);
3252 rn = "WatchHi";
3253 break;
3254 default:
3255 goto die;
3256 }
3257 break;
3258 case 20:
3259 switch (sel) {
3260 case 0:
3261 #if defined(TARGET_MIPS64)
3262 check_insn(env, ctx, ISA_MIPS3);
3263 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3264 tcg_gen_ext32s_tl(arg, arg);
3265 rn = "XContext";
3266 break;
3267 #endif
3268 default:
3269 goto die;
3270 }
3271 break;
3272 case 21:
3273 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3274 switch (sel) {
3275 case 0:
3276 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3277 rn = "Framemask";
3278 break;
3279 default:
3280 goto die;
3281 }
3282 break;
3283 case 22:
3284 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3285 rn = "'Diagnostic"; /* implementation dependent */
3286 break;
3287 case 23:
3288 switch (sel) {
3289 case 0:
3290 gen_helper_mfc0_debug(arg); /* EJTAG support */
3291 rn = "Debug";
3292 break;
3293 case 1:
3294 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3295 rn = "TraceControl";
3296 // break;
3297 case 2:
3298 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3299 rn = "TraceControl2";
3300 // break;
3301 case 3:
3302 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3303 rn = "UserTraceData";
3304 // break;
3305 case 4:
3306 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3307 rn = "TraceBPC";
3308 // break;
3309 default:
3310 goto die;
3311 }
3312 break;
3313 case 24:
3314 switch (sel) {
3315 case 0:
3316 /* EJTAG support */
3317 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3318 tcg_gen_ext32s_tl(arg, arg);
3319 rn = "DEPC";
3320 break;
3321 default:
3322 goto die;
3323 }
3324 break;
3325 case 25:
3326 switch (sel) {
3327 case 0:
3328 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3329 rn = "Performance0";
3330 break;
3331 case 1:
3332 // gen_helper_mfc0_performance1(arg);
3333 rn = "Performance1";
3334 // break;
3335 case 2:
3336 // gen_helper_mfc0_performance2(arg);
3337 rn = "Performance2";
3338 // break;
3339 case 3:
3340 // gen_helper_mfc0_performance3(arg);
3341 rn = "Performance3";
3342 // break;
3343 case 4:
3344 // gen_helper_mfc0_performance4(arg);
3345 rn = "Performance4";
3346 // break;
3347 case 5:
3348 // gen_helper_mfc0_performance5(arg);
3349 rn = "Performance5";
3350 // break;
3351 case 6:
3352 // gen_helper_mfc0_performance6(arg);
3353 rn = "Performance6";
3354 // break;
3355 case 7:
3356 // gen_helper_mfc0_performance7(arg);
3357 rn = "Performance7";
3358 // break;
3359 default:
3360 goto die;
3361 }
3362 break;
3363 case 26:
3364 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3365 rn = "ECC";
3366 break;
3367 case 27:
3368 switch (sel) {
3369 case 0 ... 3:
3370 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3371 rn = "CacheErr";
3372 break;
3373 default:
3374 goto die;
3375 }
3376 break;
3377 case 28:
3378 switch (sel) {
3379 case 0:
3380 case 2:
3381 case 4:
3382 case 6:
3383 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3384 rn = "TagLo";
3385 break;
3386 case 1:
3387 case 3:
3388 case 5:
3389 case 7:
3390 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3391 rn = "DataLo";
3392 break;
3393 default:
3394 goto die;
3395 }
3396 break;
3397 case 29:
3398 switch (sel) {
3399 case 0:
3400 case 2:
3401 case 4:
3402 case 6:
3403 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3404 rn = "TagHi";
3405 break;
3406 case 1:
3407 case 3:
3408 case 5:
3409 case 7:
3410 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3411 rn = "DataHi";
3412 break;
3413 default:
3414 goto die;
3415 }
3416 break;
3417 case 30:
3418 switch (sel) {
3419 case 0:
3420 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3421 tcg_gen_ext32s_tl(arg, arg);
3422 rn = "ErrorEPC";
3423 break;
3424 default:
3425 goto die;
3426 }
3427 break;
3428 case 31:
3429 switch (sel) {
3430 case 0:
3431 /* EJTAG support */
3432 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3433 rn = "DESAVE";
3434 break;
3435 default:
3436 goto die;
3437 }
3438 break;
3439 default:
3440 goto die;
3441 }
3442 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3443 return;
3444
3445 die:
3446 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3447 generate_exception(ctx, EXCP_RI);
3448 }
3449
3450 static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3451 {
3452 const char *rn = "invalid";
3453
3454 if (sel != 0)
3455 check_insn(env, ctx, ISA_MIPS32);
3456
3457 if (use_icount)
3458 gen_io_start();
3459
3460 switch (reg) {
3461 case 0:
3462 switch (sel) {
3463 case 0:
3464 gen_helper_mtc0_index(arg);
3465 rn = "Index";
3466 break;
3467 case 1:
3468 check_insn(env, ctx, ASE_MT);
3469 gen_helper_mtc0_mvpcontrol(arg);
3470 rn = "MVPControl";
3471 break;
3472 case 2:
3473 check_insn(env, ctx, ASE_MT);
3474 /* ignored */
3475 rn = "MVPConf0";
3476 break;
3477 case 3:
3478 check_insn(env, ctx, ASE_MT);
3479 /* ignored */
3480 rn = "MVPConf1";
3481 break;
3482 default:
3483 goto die;
3484 }
3485 break;
3486 case 1:
3487 switch (sel) {
3488 case 0:
3489 /* ignored */
3490 rn = "Random";
3491 break;
3492 case 1:
3493 check_insn(env, ctx, ASE_MT);
3494 gen_helper_mtc0_vpecontrol(arg);
3495 rn = "VPEControl";
3496 break;
3497 case 2:
3498 check_insn(env, ctx, ASE_MT);
3499 gen_helper_mtc0_vpeconf0(arg);
3500 rn = "VPEConf0";
3501 break;
3502 case 3:
3503 check_insn(env, ctx, ASE_MT);
3504 gen_helper_mtc0_vpeconf1(arg);
3505 rn = "VPEConf1";
3506 break;
3507 case 4:
3508 check_insn(env, ctx, ASE_MT);
3509 gen_helper_mtc0_yqmask(arg);
3510 rn = "YQMask";
3511 break;
3512 case 5:
3513 check_insn(env, ctx, ASE_MT);
3514 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3515 rn = "VPESchedule";
3516 break;
3517 case 6:
3518 check_insn(env, ctx, ASE_MT);
3519 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3520 rn = "VPEScheFBack";
3521 break;
3522 case 7:
3523 check_insn(env, ctx, ASE_MT);
3524 gen_helper_mtc0_vpeopt(arg);
3525 rn = "VPEOpt";
3526 break;
3527 default:
3528 goto die;
3529 }
3530 break;
3531 case 2:
3532 switch (sel) {
3533 case 0:
3534 gen_helper_mtc0_entrylo0(arg);
3535 rn = "EntryLo0";
3536 break;
3537 case 1:
3538 check_insn(env, ctx, ASE_MT);
3539 gen_helper_mtc0_tcstatus(arg);
3540 rn = "TCStatus";
3541 break;
3542 case 2:
3543 check_insn(env, ctx, ASE_MT);
3544 gen_helper_mtc0_tcbind(arg);
3545 rn = "TCBind";
3546 break;
3547 case 3:
3548 check_insn(env, ctx, ASE_MT);
3549 gen_helper_mtc0_tcrestart(arg);
3550 rn = "TCRestart";
3551 break;
3552 case 4:
3553 check_insn(env, ctx, ASE_MT);
3554 gen_helper_mtc0_tchalt(arg);
3555 rn = "TCHalt";
3556 break;
3557 case 5:
3558 check_insn(env, ctx, ASE_MT);
3559 gen_helper_mtc0_tccontext(arg);
3560 rn = "TCContext";
3561 break;
3562 case 6:
3563 check_insn(env, ctx, ASE_MT);
3564 gen_helper_mtc0_tcschedule(arg);
3565 rn = "TCSchedule";
3566 break;
3567 case 7:
3568 check_insn(env, ctx, ASE_MT);
3569 gen_helper_mtc0_tcschefback(arg);
3570 rn = "TCScheFBack";
3571 break;
3572 default:
3573 goto die;
3574 }
3575 break;
3576 case 3:
3577 switch (sel) {
3578 case 0:
3579 gen_helper_mtc0_entrylo1(arg);
3580 rn = "EntryLo1";
3581 break;
3582 default:
3583 goto die;
3584 }
3585 break;
3586 case 4:
3587 switch (sel) {
3588 case 0:
3589 gen_helper_mtc0_context(arg);
3590 rn = "Context";
3591 break;
3592 case 1:
3593 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3594 rn = "ContextConfig";
3595 // break;
3596 default:
3597 goto die;
3598 }
3599 break;
3600 case 5:
3601 switch (sel) {
3602 case 0:
3603 gen_helper_mtc0_pagemask(arg);
3604 rn = "PageMask";
3605 break;
3606 case 1:
3607 check_insn(env, ctx, ISA_MIPS32R2);
3608 gen_helper_mtc0_pagegrain(arg);
3609 rn = "PageGrain";
3610 break;
3611 default:
3612 goto die;
3613 }
3614 break;
3615 case 6:
3616 switch (sel) {
3617 case 0:
3618 gen_helper_mtc0_wired(arg);
3619 rn = "Wired";
3620 break;
3621 case 1:
3622 check_insn(env, ctx, ISA_MIPS32R2);
3623 gen_helper_mtc0_srsconf0(arg);
3624 rn = "SRSConf0";
3625 break;
3626 case 2:
3627 check_insn(env, ctx, ISA_MIPS32R2);
3628 gen_helper_mtc0_srsconf1(arg);
3629 rn = "SRSConf1";
3630 break;
3631 case 3:
3632 check_insn(env, ctx, ISA_MIPS32R2);
3633 gen_helper_mtc0_srsconf2(arg);
3634 rn = "SRSConf2";
3635 break;
3636 case 4:
3637 check_insn(env, ctx, ISA_MIPS32R2);
3638 gen_helper_mtc0_srsconf3(arg);
3639 rn = "SRSConf3";
3640 break;
3641 case 5:
3642 check_insn(env, ctx, ISA_MIPS32R2);
3643 gen_helper_mtc0_srsconf4(arg);
3644 rn = "SRSConf4";
3645 break;
3646 default:
3647 goto die;
3648 }
3649 break;
3650 case 7:
3651 switch (sel) {
3652 case 0:
3653 check_insn(env, ctx, ISA_MIPS32R2);
3654 gen_helper_mtc0_hwrena(arg);
3655 rn = "HWREna";
3656 break;
3657 default:
3658 goto die;
3659 }
3660 break;
3661 case 8:
3662 /* ignored */
3663 rn = "BadVAddr";
3664 break;
3665 case 9:
3666 switch (sel) {
3667 case 0:
3668 gen_helper_mtc0_count(arg);
3669 rn = "Count";
3670 break;
3671 /* 6,7 are implementation dependent */
3672 default:
3673 goto die;
3674 }
3675 break;
3676 case 10:
3677 switch (sel) {
3678 case 0:
3679 gen_helper_mtc0_entryhi(arg);
3680 rn = "EntryHi";
3681 break;
3682 default:
3683 goto die;
3684 }
3685 break;
3686 case 11:
3687 switch (sel) {
3688 case 0:
3689 gen_helper_mtc0_compare(arg);
3690 rn = "Compare";
3691 break;
3692 /* 6,7 are implementation dependent */
3693 default:
3694 goto die;
3695 }
3696 break;
3697 case 12:
3698 switch (sel) {
3699 case 0:
3700 save_cpu_state(ctx, 1);
3701 gen_helper_mtc0_status(arg);
3702 /* BS_STOP isn't good enough here, hflags may have changed. */
3703 gen_save_pc(ctx->pc + 4);
3704 ctx->bstate = BS_EXCP;
3705 rn = "Status";
3706 break;
3707 case 1:
3708 check_insn(env, ctx, ISA_MIPS32R2);
3709 gen_helper_mtc0_intctl(arg);
3710 /* Stop translation as we may have switched the execution mode */
3711 ctx->bstate = BS_STOP;
3712 rn = "IntCtl";
3713 break;
3714 case 2:
3715 check_insn(env, ctx, ISA_MIPS32R2);
3716 gen_helper_mtc0_srsctl(arg);
3717 /* Stop translation as we may have switched the execution mode */
3718 ctx->bstate = BS_STOP;
3719 rn = "SRSCtl";
3720 break;
3721 case 3:
3722 check_insn(env, ctx, ISA_MIPS32R2);
3723 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
3724 /* Stop translation as we may have switched the execution mode */
3725 ctx->bstate = BS_STOP;
3726 rn = "SRSMap";
3727 break;
3728 default:
3729 goto die;
3730 }
3731 break;
3732 case 13:
3733 switch (sel) {
3734 case 0:
3735 save_cpu_state(ctx, 1);
3736 gen_helper_mtc0_cause(arg);
3737 rn = "Cause";
3738 break;
3739 default:
3740 goto die;
3741 }
3742 break;
3743 case 14:
3744 switch (sel) {
3745 case 0:
3746 gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
3747 rn = "EPC";
3748 break;
3749 default:
3750 goto die;
3751 }
3752 break;
3753 case 15:
3754 switch (sel) {
3755 case 0:
3756 /* ignored */
3757 rn = "PRid";
3758 break;
3759 case 1:
3760 check_insn(env, ctx, ISA_MIPS32R2);
3761 gen_helper_mtc0_ebase(arg);
3762 rn = "EBase";
3763 break;
3764 default:
3765 goto die;
3766 }
3767 break;
3768 case 16:
3769 switch (sel) {
3770 case 0:
3771 gen_helper_mtc0_config0(arg);
3772 rn = "Config";
3773 /* Stop translation as we may have switched the execution mode */
3774 ctx->bstate = BS_STOP;
3775 break;
3776 case 1:
3777 /* ignored, read only */
3778 rn = "Config1";
3779 break;
3780 case 2:
3781 gen_helper_mtc0_config2(arg);
3782 rn = "Config2";
3783 /* Stop translation as we may have switched the execution mode */
3784 ctx->bstate = BS_STOP;
3785 break;
3786 case 3:
3787 /* ignored, read only */
3788 rn = "Config3";
3789 break;
3790 /* 4,5 are reserved */
3791 /* 6,7 are implementation dependent */
3792 case 6:
3793 /* ignored */
3794 rn = "Config6";
3795 break;
3796 case 7:
3797 /* ignored */
3798 rn = "Config7";
3799 break;
3800 default:
3801 rn = "Invalid config selector";
3802 goto die;
3803 }
3804 break;
3805 case 17:
3806 switch (sel) {
3807 case 0:
3808 /* ignored */
3809 rn = "LLAddr";
3810 break;
3811 default:
3812 goto die;
3813 }
3814 break;
3815 case 18:
3816 switch (sel) {
3817 case 0 ... 7:
3818 gen_helper_1i(mtc0_watchlo, arg, sel);
3819 rn = "WatchLo";
3820 break;
3821 default:
3822 goto die;
3823 }
3824 break;
3825 case 19:
3826 switch (sel) {
3827 case 0 ... 7:
3828 gen_helper_1i(mtc0_watchhi, arg, sel);
3829 rn = "WatchHi";
3830 break;
3831 default:
3832 goto die;
3833 }
3834 break;
3835 case 20:
3836 switch (sel) {
3837 case 0:
3838 #if defined(TARGET_MIPS64)
3839 check_insn(env, ctx, ISA_MIPS3);
3840 gen_helper_mtc0_xcontext(arg);
3841 rn = "XContext";
3842 break;
3843 #endif
3844 default:
3845 goto die;
3846 }
3847 break;
3848 case 21:
3849 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3850 switch (sel) {
3851 case 0:
3852 gen_helper_mtc0_framemask(arg);
3853 rn = "Framemask";
3854 break;
3855 default:
3856 goto die;
3857 }
3858 break;
3859 case 22:
3860 /* ignored */
3861 rn = "Diagnostic"; /* implementation dependent */
3862 break;
3863 case 23:
3864 switch (sel) {
3865 case 0:
3866 gen_helper_mtc0_debug(arg); /* EJTAG support */
3867 /* BS_STOP isn't good enough here, hflags may have changed. */
3868 gen_save_pc(ctx->pc + 4);
3869 ctx->bstate = BS_EXCP;
3870 rn = "Debug";
3871 break;
3872 case 1:
3873 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
3874 rn = "TraceControl";
3875 /* Stop translation as we may have switched the execution mode */
3876 ctx->bstate = BS_STOP;
3877 // break;
3878 case 2:
3879 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
3880 rn = "TraceControl2";
3881 /* Stop translation as we may have switched the execution mode */
3882 ctx->bstate = BS_STOP;
3883 // break;
3884 case 3:
3885 /* Stop translation as we may have switched the execution mode */
3886 ctx->bstate = BS_STOP;
3887 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
3888 rn = "UserTraceData";
3889 /* Stop translation as we may have switched the execution mode */
3890 ctx->bstate = BS_STOP;
3891 // break;
3892 case 4:
3893 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
3894 /* Stop translation as we may have switched the execution mode */
3895 ctx->bstate = BS_STOP;
3896 rn = "TraceBPC";
3897 // break;
3898 default:
3899 goto die;
3900 }
3901 break;
3902 case 24:
3903 switch (sel) {
3904 case 0:
3905 /* EJTAG support */
3906 gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
3907 rn = "DEPC";
3908 break;
3909 default:
3910 goto die;
3911 }
3912 break;
3913 case 25:
3914 switch (sel) {
3915 case 0:
3916 gen_helper_mtc0_performance0(arg);
3917 rn = "Performance0";
3918 break;
3919 case 1:
3920 // gen_helper_mtc0_performance1(arg);
3921 rn = "Performance1";
3922 // break;
3923 case 2:
3924 // gen_helper_mtc0_performance2(arg);
3925 rn = "Performance2";
3926 // break;
3927 case 3:
3928 // gen_helper_mtc0_performance3(arg);
3929 rn = "Performance3";
3930 // break;
3931 case 4:
3932 // gen_helper_mtc0_performance4(arg);
3933 rn = "Performance4";
3934 // break;
3935 case 5:
3936 // gen_helper_mtc0_performance5(arg);
3937 rn = "Performance5";
3938 // break;
3939 case 6:
3940 // gen_helper_mtc0_performance6(arg);
3941 rn = "Performance6";
3942 // break;
3943 case 7:
3944 // gen_helper_mtc0_performance7(arg);
3945 rn = "Performance7";
3946 // break;
3947 default:
3948 goto die;
3949 }
3950 break;
3951 case 26:
3952 /* ignored */
3953 rn = "ECC";
3954 break;
3955 case 27:
3956 switch (sel) {
3957 case 0 ... 3:
3958 /* ignored */
3959 rn = "CacheErr";
3960 break;
3961 default:
3962 goto die;
3963 }
3964 break;
3965 case 28:
3966 switch (sel) {
3967 case 0:
3968 case 2:
3969 case 4:
3970 case 6:
3971 gen_helper_mtc0_taglo(arg);
3972 rn = "TagLo";
3973 break;
3974 case 1:
3975 case 3:
3976 case 5:
3977 case 7:
3978 gen_helper_mtc0_datalo(arg);
3979 rn = "DataLo";
3980 break;
3981 default:
3982 goto die;
3983 }
3984 break;
3985 case 29:
3986 switch (sel) {
3987 case 0:
3988 case 2:
3989 case 4:
3990 case 6:
3991 gen_helper_mtc0_taghi(arg);
3992 rn = "TagHi";
3993 break;
3994 case 1:
3995 case 3:
3996 case 5:
3997 case 7:
3998 gen_helper_mtc0_datahi(arg);
3999 rn = "DataHi";
4000 break;
4001 default:
4002 rn = "invalid sel";
4003 goto die;
4004 }
4005 break;
4006 case 30:
4007 switch (sel) {
4008 case 0:
4009 gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4010 rn = "ErrorEPC";
4011 break;
4012 default:
4013 goto die;
4014 }
4015 break;
4016 case 31:
4017 switch (sel) {
4018 case 0:
4019 /* EJTAG support */
4020 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4021 rn = "DESAVE";
4022 break;
4023 default:
4024 goto die;
4025 }
4026 /* Stop translation as we may have switched the execution mode */
4027 ctx->bstate = BS_STOP;
4028 break;
4029 default:
4030 goto die;
4031 }
4032 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4033 /* For simplicity assume that all writes can cause interrupts. */
4034 if (use_icount) {
4035 gen_io_end();
4036 ctx->bstate = BS_STOP;
4037 }
4038 return;
4039
4040 die:
4041 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4042 generate_exception(ctx, EXCP_RI);
4043 }
4044
4045 #if defined(TARGET_MIPS64)
4046 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4047 {
4048 const char *rn = "invalid";
4049
4050 if (sel != 0)
4051 check_insn(env, ctx, ISA_MIPS64);
4052
4053 switch (reg) {
4054 case 0:
4055 switch (sel) {
4056 case 0:
4057 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4058 rn = "Index";
4059 break;
4060 case 1:
4061 check_insn(env, ctx, ASE_MT);
4062 gen_helper_mfc0_mvpcontrol(arg);
4063 rn = "MVPControl";
4064 break;
4065 case 2:
4066 check_insn(env, ctx, ASE_MT);
4067 gen_helper_mfc0_mvpconf0(arg);
4068 rn = "MVPConf0";
4069 break;
4070 case 3:
4071 check_insn(env, ctx, ASE_MT);
4072 gen_helper_mfc0_mvpconf1(arg);
4073 rn = "MVPConf1";
4074 break;
4075 default:
4076 goto die;
4077 }
4078 break;
4079 case 1:
4080 switch (sel) {
4081 case 0:
4082 gen_helper_mfc0_random(arg);
4083 rn = "Random";
4084 break;
4085 case 1:
4086 check_insn(env, ctx, ASE_MT);
4087 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4088 rn = "VPEControl";
4089 break;
4090 case 2:
4091 check_insn(env, ctx, ASE_MT);
4092 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4093 rn = "VPEConf0";
4094 break;
4095 case 3:
4096 check_insn(env, ctx, ASE_MT);
4097 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4098 rn = "VPEConf1";
4099 break;
4100 case 4:
4101 check_insn(env, ctx, ASE_MT);
4102 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4103 rn = "YQMask";
4104 break;
4105 case 5:
4106 check_insn(env, ctx, ASE_MT);
4107 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4108 rn = "VPESchedule";
4109 break;
4110 case 6:
4111 check_insn(env, ctx, ASE_MT);
4112 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4113 rn = "VPEScheFBack";
4114 break;
4115 case 7:
4116 check_insn(env, ctx, ASE_MT);
4117 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4118 rn = "VPEOpt";
4119 break;
4120 default:
4121 goto die;
4122 }
4123 break;
4124 case 2:
4125 switch (sel) {
4126 case 0:
4127 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4128 rn = "EntryLo0";
4129 break;
4130 case 1:
4131 check_insn(env, ctx, ASE_MT);
4132 gen_helper_mfc0_tcstatus(arg);
4133 rn = "TCStatus";
4134 break;
4135 case 2:
4136 check_insn(env, ctx, ASE_MT);
4137 gen_helper_mfc0_tcbind(arg);
4138 rn = "TCBind";
4139 break;
4140 case 3:
4141 check_insn(env, ctx, ASE_MT);
4142 gen_helper_dmfc0_tcrestart(arg);
4143 rn = "TCRestart";
4144 break;
4145 case 4:
4146 check_insn(env, ctx, ASE_MT);
4147 gen_helper_dmfc0_tchalt(arg);
4148 rn = "TCHalt";
4149 break;
4150 case 5:
4151 check_insn(env, ctx, ASE_MT);
4152 gen_helper_dmfc0_tccontext(arg);
4153 rn = "TCContext";
4154 break;
4155 case 6:
4156 check_insn(env, ctx, ASE_MT);
4157 gen_helper_dmfc0_tcschedule(arg);
4158 rn = "TCSchedule";
4159 break;
4160 case 7:
4161 check_insn(env, ctx, ASE_MT);
4162 gen_helper_dmfc0_tcschefback(arg);
4163 rn = "TCScheFBack";
4164 break;
4165 default:
4166 goto die;
4167 }
4168 break;
4169 case 3:
4170 switch (sel) {
4171 case 0:
4172 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4173 rn = "EntryLo1";
4174 break;
4175 default:
4176 goto die;
4177 }
4178 break;
4179 case 4:
4180 switch (sel) {
4181 case 0:
4182 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4183 rn = "Context";
4184 break;
4185 case 1:
4186 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4187 rn = "ContextConfig";
4188 // break;
4189 default:
4190 goto die;
4191 }
4192 break;
4193 case 5:
4194 switch (sel) {
4195 case 0:
4196 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4197 rn = "PageMask";
4198 break;
4199 case 1:
4200 check_insn(env, ctx, ISA_MIPS32R2);
4201 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4202 rn = "PageGrain";
4203 break;
4204 default:
4205 goto die;
4206 }
4207 break;
4208 case 6:
4209 switch (sel) {
4210 case 0:
4211 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4212 rn = "Wired";
4213 break;
4214 case 1:
4215 check_insn(env, ctx, ISA_MIPS32R2);
4216 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4217 rn = "SRSConf0";
4218 break;
4219 case 2:
4220 check_insn(env, ctx, ISA_MIPS32R2);
4221 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4222 rn = "SRSConf1";
4223 break;
4224 case 3:
4225 check_insn(env, ctx, ISA_MIPS32R2);
4226 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4227 rn = "SRSConf2";
4228 break;
4229 case 4:
4230 check_insn(env, ctx, ISA_MIPS32R2);
4231 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4232 rn = "SRSConf3";
4233 break;
4234 case 5:
4235 check_insn(env, ctx, ISA_MIPS32R2);
4236 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4237 rn = "SRSConf4";
4238 break;
4239 default:
4240 goto die;
4241 }
4242 break;
4243 case 7:
4244 switch (sel) {
4245 case 0:
4246 check_insn(env, ctx, ISA_MIPS32R2);
4247 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4248 rn = "HWREna";
4249 break;
4250 default:
4251 goto die;
4252 }
4253 break;
4254 case 8:
4255 switch (sel) {
4256 case 0:
4257 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4258 rn = "BadVAddr";
4259 break;
4260 default:
4261 goto die;
4262 }
4263 break;
4264 case 9:
4265 switch (sel) {
4266 case 0:
4267 /* Mark as an IO operation because we read the time. */
4268 if (use_icount)
4269 gen_io_start();
4270 gen_helper_mfc0_count(arg);
4271 if (use_icount) {
4272 gen_io_end();
4273 ctx->bstate = BS_STOP;
4274 }
4275 rn = "Count";
4276 break;
4277 /* 6,7 are implementation dependent */
4278 default:
4279 goto die;
4280 }
4281 break;
4282 case 10:
4283 switch (sel) {
4284 case 0:
4285 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4286 rn = "EntryHi";
4287 break;
4288 default:
4289 goto die;
4290 }
4291 break;
4292 case 11:
4293 switch (sel) {
4294 case 0:
4295 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4296 rn = "Compare";
4297 break;
4298 /* 6,7 are implementation dependent */
4299 default:
4300 goto die;
4301 }
4302 break;
4303 case 12:
4304 switch (sel) {
4305 case 0:
4306 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4307 rn = "Status";
4308 break;
4309 case 1:
4310 check_insn(env, ctx, ISA_MIPS32R2);
4311 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4312 rn = "IntCtl";
4313 break;
4314 case 2:
4315 check_insn(env, ctx, ISA_MIPS32R2);
4316 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4317 rn = "SRSCtl";
4318 break;
4319 case 3:
4320 check_insn(env, ctx, ISA_MIPS32R2);
4321 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4322 rn = "SRSMap";
4323 break;
4324 default:
4325 goto die;
4326 }
4327 break;
4328 case 13:
4329 switch (sel) {
4330 case 0:
4331 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4332 rn = "Cause";
4333 break;
4334 default:
4335 goto die;
4336 }
4337 break;
4338 case 14:
4339 switch (sel) {
4340 case 0:
4341 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4342 rn = "EPC";
4343 break;
4344 default:
4345 goto die;
4346 }
4347 break;
4348 case 15:
4349 switch (sel) {
4350 case 0:
4351 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4352 rn = "PRid";
4353 break;
4354 case 1:
4355 check_insn(env, ctx, ISA_MIPS32R2);
4356 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4357 rn = "EBase";
4358 break;
4359 default:
4360 goto die;
4361 }
4362 break;
4363 case 16:
4364 switch (sel) {
4365 case 0:
4366 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4367 rn = "Config";
4368 break;
4369 case 1:
4370 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4371 rn = "Config1";
4372 break;
4373 case 2:
4374 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4375 rn = "Config2";
4376 break;
4377 case 3:
4378 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4379 rn = "Config3";
4380 break;
4381 /* 6,7 are implementation dependent */
4382 case 6:
4383 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4384 rn = "Config6";
4385 break;
4386 case 7:
4387 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4388 rn = "Config7";
4389 break;
4390 default:
4391 goto die;
4392 }
4393 break;
4394 case 17:
4395 switch (sel) {
4396 case 0:
4397 gen_helper_dmfc0_lladdr(arg);
4398 rn = "LLAddr";
4399 break;
4400 default:
4401 goto die;
4402 }
4403 break;
4404 case 18:
4405 switch (sel) {
4406 case 0 ... 7:
4407 gen_helper_1i(dmfc0_watchlo, arg, sel);
4408 rn = "WatchLo";
4409 break;
4410 default:
4411 goto die;
4412 }
4413 break;
4414 case 19:
4415 switch (sel) {
4416 case 0 ... 7:
4417 gen_helper_1i(mfc0_watchhi, arg, sel);
4418 rn = "WatchHi";
4419 break;
4420 default:
4421 goto die;
4422 }
4423 break;
4424 case 20:
4425 switch (sel) {
4426 case 0:
4427 check_insn(env, ctx, ISA_MIPS3);
4428 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4429 rn = "XContext";
4430 break;
4431 default:
4432 goto die;
4433 }
4434 break;
4435 case 21:
4436 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4437 switch (sel) {
4438 case 0:
4439 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4440 rn = "Framemask";
4441 break;
4442 default:
4443 goto die;
4444 }
4445 break;
4446 case 22:
4447 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4448 rn = "'Diagnostic"; /* implementation dependent */
4449 break;
4450 case 23:
4451 switch (sel) {
4452 case 0:
4453 gen_helper_mfc0_debug(arg); /* EJTAG support */
4454 rn = "Debug";
4455 break;
4456 case 1:
4457 // gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4458 rn = "TraceControl";
4459 // break;
4460 case 2:
4461 // gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4462 rn = "TraceControl2";
4463 // break;
4464 case 3:
4465 // gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4466 rn = "UserTraceData";
4467 // break;
4468 case 4:
4469 // gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4470 rn = "TraceBPC";
4471 // break;
4472 default:
4473 goto die;
4474 }
4475 break;
4476 case 24:
4477 switch (sel) {
4478 case 0:
4479 /* EJTAG support */
4480 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4481 rn = "DEPC";
4482 break;
4483 default:
4484 goto die;
4485 }
4486 break;
4487 case 25:
4488 switch (sel) {
4489 case 0:
4490 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4491 rn = "Performance0";
4492 break;
4493 case 1:
4494 // gen_helper_dmfc0_performance1(arg);
4495 rn = "Performance1";
4496 // break;
4497 case 2:
4498 // gen_helper_dmfc0_performance2(arg);
4499 rn = "Performance2";
4500 // break;
4501 case 3:
4502 // gen_helper_dmfc0_performance3(arg);
4503 rn = "Performance3";
4504 // break;
4505 case 4:
4506 // gen_helper_dmfc0_performance4(arg);
4507 rn = "Performance4";
4508 // break;
4509 case 5:
4510 // gen_helper_dmfc0_performance5(arg);
4511 rn = "Performance5";
4512 // break;
4513 case 6:
4514 // gen_helper_dmfc0_performance6(arg);
4515 rn = "Performance6";
4516 // break;
4517 case 7:
4518 // gen_helper_dmfc0_performance7(arg);
4519 rn = "Performance7";
4520 // break;
4521 default:
4522 goto die;
4523 }
4524 break;
4525 case 26:
4526 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4527 rn = "ECC";
4528 break;
4529 case 27:
4530 switch (sel) {
4531 /* ignored */
4532 case 0 ... 3:
4533 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4534 rn = "CacheErr";
4535 break;
4536 default:
4537 goto die;
4538 }
4539 break;
4540 case 28:
4541 switch (sel) {
4542 case 0:
4543 case 2:
4544 case 4:
4545 case 6:
4546 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4547 rn = "TagLo";
4548 break;
4549 case 1:
4550 case 3:
4551 case 5:
4552 case 7:
4553 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4554 rn = "DataLo";
4555 break;
4556 default:
4557 goto die;
4558 }
4559 break;
4560 case 29:
4561 switch (sel) {
4562 case 0:
4563 case 2:
4564 case 4:
4565 case 6:
4566 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4567 rn = "TagHi";
4568 break;
4569 case 1:
4570 case 3:
4571 case 5:
4572 case 7:
4573 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4574 rn = "DataHi";
4575 break;
4576 default:
4577 goto die;
4578 }
4579 break;
4580 case 30:
4581 switch (sel) {
4582 case 0:
4583 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4584 rn = "ErrorEPC";
4585 break;
4586 default:
4587 goto die;
4588 }
4589 break;
4590 case 31:
4591 switch (sel) {
4592 case 0:
4593 /* EJTAG support */
4594 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4595 rn = "DESAVE";
4596 break;
4597 default:
4598 goto die;
4599 }
4600 break;
4601 default:
4602 goto die;
4603 }
4604 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4605 return;
4606
4607 die:
4608 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4609 generate_exception(ctx, EXCP_RI);
4610 }
4611
4612 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4613 {
4614 const char *rn = "invalid";
4615
4616 if (sel != 0)
4617 check_insn(env, ctx, ISA_MIPS64);
4618
4619 if (use_icount)
4620 gen_io_start();
4621
4622 switch (reg) {
4623 case 0:
4624 switch (sel) {
4625 case 0:
4626 gen_helper_mtc0_index(arg);
4627 rn = "Index";
4628 break;
4629 case 1:
4630 check_insn(env, ctx, ASE_MT);
4631 gen_helper_mtc0_mvpcontrol(arg);
4632 rn = "MVPControl";
4633 break;
4634 case 2:
4635 check_insn(env, ctx, ASE_MT);
4636 /* ignored */
4637 rn = "MVPConf0";
4638 break;
4639 case 3:
4640 check_insn(env, ctx, ASE_MT);
4641 /* ignored */
4642 rn = "MVPConf1";
4643 break;
4644 default:
4645 goto die;
4646 }
4647 break;
4648 case 1:
4649 switch (sel) {
4650 case 0:
4651 /* ignored */
4652 rn = "Random";
4653 break;
4654 case 1:
4655 check_insn(env, ctx, ASE_MT);
4656 gen_helper_mtc0_vpecontrol(arg);
4657 rn = "VPEControl";
4658 break;
4659 case 2:
4660 check_insn(env, ctx, ASE_MT);
4661 gen_helper_mtc0_vpeconf0(arg);
4662 rn = "VPEConf0";
4663 break;
4664 case 3:
4665 check_insn(env, ctx, ASE_MT);
4666 gen_helper_mtc0_vpeconf1(arg);
4667 rn = "VPEConf1";
4668 break;
4669 case 4:
4670 check_insn(env, ctx, ASE_MT);
4671 gen_helper_mtc0_yqmask(arg);
4672 rn = "YQMask";
4673 break;
4674 case 5:
4675 check_insn(env, ctx, ASE_MT);
4676 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4677 rn = "VPESchedule";
4678 break;
4679 case 6:
4680 check_insn(env, ctx, ASE_MT);
4681 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4682 rn = "VPEScheFBack";
4683 break;
4684 case 7:
4685 check_insn(env, ctx, ASE_MT);
4686 gen_helper_mtc0_vpeopt(arg);
4687 rn = "VPEOpt";
4688 break;
4689 default:
4690 goto die;
4691 }
4692 break;
4693 case 2:
4694 switch (sel) {
4695 case 0:
4696 gen_helper_mtc0_entrylo0(arg);
4697 rn = "EntryLo0";
4698 break;
4699 case 1:
4700 check_insn(env, ctx, ASE_MT);
4701 gen_helper_mtc0_tcstatus(arg);
4702 rn = "TCStatus";
4703 break;
4704 case 2:
4705 check_insn(env, ctx, ASE_MT);
4706 gen_helper_mtc0_tcbind(arg);
4707 rn = "TCBind";
4708 break;
4709 case 3:
4710 check_insn(env, ctx, ASE_MT);
4711 gen_helper_mtc0_tcrestart(arg);
4712 rn = "TCRestart";
4713 break;
4714 case 4:
4715 check_insn(env, ctx, ASE_MT);
4716 gen_helper_mtc0_tchalt(arg);
4717 rn = "TCHalt";
4718 break;
4719 case 5:
4720 check_insn(env, ctx, ASE_MT);
4721 gen_helper_mtc0_tccontext(arg);
4722 rn = "TCContext";
4723 break;
4724 case 6:
4725 check_insn(env, ctx, ASE_MT);
4726 gen_helper_mtc0_tcschedule(arg);
4727 rn = "TCSchedule";
4728 break;
4729 case 7:
4730 check_insn(env, ctx, ASE_MT);
4731 gen_helper_mtc0_tcschefback(arg);
4732 rn = "TCScheFBack";
4733 break;
4734 default:
4735 goto die;
4736 }
4737 break;
4738 case 3:
4739 switch (sel) {
4740 case 0:
4741 gen_helper_mtc0_entrylo1(arg);
4742 rn = "EntryLo1";
4743 break;
4744 default:
4745 goto die;
4746 }
4747 break;
4748 case 4:
4749 switch (sel) {
4750 case 0:
4751 gen_helper_mtc0_context(arg);
4752 rn = "Context";
4753 break;
4754 case 1:
4755 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
4756 rn = "ContextConfig";
4757 // break;
4758 default:
4759 goto die;
4760 }
4761 break;
4762 case 5:
4763 switch (sel) {
4764 case 0:
4765 gen_helper_mtc0_pagemask(arg);
4766 rn = "PageMask";
4767 break;
4768 case 1:
4769 check_insn(env, ctx, ISA_MIPS32R2);
4770 gen_helper_mtc0_pagegrain(arg);
4771 rn = "PageGrain";
4772 break;
4773 default:
4774 goto die;
4775 }
4776 break;
4777 case 6:
4778 switch (sel) {
4779 case 0:
4780 gen_helper_mtc0_wired(arg);
4781 rn = "Wired";
4782 break;
4783 case 1:
4784 check_insn(env, ctx, ISA_MIPS32R2);
4785 gen_helper_mtc0_srsconf0(arg);
4786 rn = "SRSConf0";
4787 break;
4788 case 2:
4789 check_insn(env, ctx, ISA_MIPS32R2);
4790 gen_helper_mtc0_srsconf1(arg);
4791 rn = "SRSConf1";
4792 break;
4793 case 3:
4794 check_insn(env, ctx, ISA_MIPS32R2);
4795 gen_helper_mtc0_srsconf2(arg);
4796 rn = "SRSConf2";
4797 break;
4798 case 4:
4799 check_insn(env, ctx, ISA_MIPS32R2);
4800 gen_helper_mtc0_srsconf3(arg);
4801 rn = "SRSConf3";
4802 break;
4803 case 5:
4804 check_insn(env, ctx, ISA_MIPS32R2);
4805 gen_helper_mtc0_srsconf4(arg);
4806 rn = "SRSConf4";
4807 break;
4808 default:
4809 goto die;
4810 }
4811 break;
4812 case 7:
4813 switch (sel) {
4814 case 0:
4815 check_insn(env, ctx, ISA_MIPS32R2);
4816 gen_helper_mtc0_hwrena(arg);
4817 rn = "HWREna";
4818 break;
4819 default:
4820 goto die;
4821 }
4822 break;
4823 case 8:
4824 /* ignored */
4825 rn = "BadVAddr";
4826 break;
4827 case 9:
4828 switch (sel) {
4829 case 0:
4830 gen_helper_mtc0_count(arg);
4831 rn = "Count";
4832 break;
4833 /* 6,7 are implementation dependent */
4834 default:
4835 goto die;
4836 }
4837 /* Stop translation as we may have switched the execution mode */
4838 ctx->bstate = BS_STOP;
4839 break;
4840 case 10:
4841 switch (sel) {
4842 case 0:
4843 gen_helper_mtc0_entryhi(arg);
4844 rn = "EntryHi";
4845 break;
4846 default:
4847 goto die;
4848 }
4849 break;
4850 case 11:
4851 switch (sel) {
4852 case 0:
4853 gen_helper_mtc0_compare(arg);
4854 rn = "Compare";
4855 break;
4856 /* 6,7 are implementation dependent */
4857 default:
4858 goto die;
4859 }
4860 /* Stop translation as we may have switched the execution mode */
4861 ctx->bstate = BS_STOP;
4862 break;
4863 case 12:
4864 switch (sel) {
4865 case 0:
4866 save_cpu_state(ctx, 1);
4867 gen_helper_mtc0_status(arg);
4868 /* BS_STOP isn't good enough here, hflags may have changed. */
4869 gen_save_pc(ctx->pc + 4);
4870 ctx->bstate = BS_EXCP;
4871 rn = "Status";
4872 break;
4873 case 1:
4874 check_insn(env, ctx, ISA_MIPS32R2);
4875 gen_helper_mtc0_intctl(arg);
4876 /* Stop translation as we may have switched the execution mode */
4877 ctx->bstate = BS_STOP;
4878 rn = "IntCtl";
4879 break;
4880 case 2:
4881 check_insn(env, ctx, ISA_MIPS32R2);
4882 gen_helper_mtc0_srsctl(arg);
4883 /* Stop translation as we may have switched the execution mode */
4884 ctx->bstate = BS_STOP;
4885 rn = "SRSCtl";
4886 break;
4887 case 3:
4888 check_insn(env, ctx, ISA_MIPS32R2);
4889 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4890 /* Stop translation as we may have switched the execution mode */
4891 ctx->bstate = BS_STOP;
4892 rn = "SRSMap";
4893 break;
4894 default:
4895 goto die;
4896 }
4897 break;
4898 case 13:
4899 switch (sel) {
4900 case 0:
4901 save_cpu_state(ctx, 1);
4902 gen_helper_mtc0_cause(arg);
4903 rn = "Cause";
4904 break;
4905 default:
4906 goto die;
4907 }
4908 break;
4909 case 14:
4910 switch (sel) {
4911 case 0:
4912 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4913 rn = "EPC";
4914 break;
4915 default:
4916 goto die;
4917 }
4918 break;
4919 case 15:
4920 switch (sel) {
4921 case 0:
4922 /* ignored */
4923 rn = "PRid";
4924 break;
4925 case 1:
4926 check_insn(env, ctx, ISA_MIPS32R2);
4927 gen_helper_mtc0_ebase(arg);
4928 rn = "EBase";
4929 break;
4930 default:
4931 goto die;
4932 }
4933 break;
4934 case 16:
4935 switch (sel) {
4936 case 0:
4937 gen_helper_mtc0_config0(arg);
4938 rn = "Config";
4939 /* Stop translation as we may have switched the execution mode */
4940 ctx->bstate = BS_STOP;
4941 break;
4942 case 1:
4943 /* ignored, read only */
4944 rn = "Config1";
4945 break;
4946 case 2:
4947 gen_helper_mtc0_config2(arg);
4948 rn = "Config2";
4949 /* Stop translation as we may have switched the execution mode */
4950 ctx->bstate = BS_STOP;
4951 break;
4952 case 3:
4953 /* ignored */
4954 rn = "Config3";
4955 break;
4956 /* 6,7 are implementation dependent */
4957 default:
4958 rn = "Invalid config selector";
4959 goto die;
4960 }
4961 break;
4962 case 17:
4963 switch (sel) {
4964 case 0:
4965 /* ignored */
4966 rn = "LLAddr";
4967 break;
4968 default:
4969 goto die;
4970 }
4971 break;
4972 case 18:
4973 switch (sel) {
4974 case 0 ... 7:
4975 gen_helper_1i(mtc0_watchlo, arg, sel);
4976 rn = "WatchLo";
4977 break;
4978 default:
4979 goto die;
4980 }
4981 break;
4982 case 19:
4983 switch (sel) {
4984 case 0 ... 7:
4985 gen_helper_1i(mtc0_watchhi, arg, sel);
4986 rn = "WatchHi";
4987 break;
4988 default:
4989 goto die;
4990 }
4991 break;
4992 case 20:
4993 switch (sel) {
4994 case 0:
4995 check_insn(env, ctx, ISA_MIPS3);
4996 gen_helper_mtc0_xcontext(arg);
4997 rn = "XContext";
4998 break;
4999 default:
5000 goto die;
5001 }
5002 break;
5003 case 21:
5004 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5005 switch (sel) {
5006 case 0:
5007 gen_helper_mtc0_framemask(arg);
5008 rn = "Framemask";
5009 break;
5010 default:
5011 goto die;
5012 }
5013 break;
5014 case 22:
5015 /* ignored */
5016 rn = "Diagnostic"; /* implementation dependent */
5017 break;
5018 case 23:
5019 switch (sel) {
5020 case 0:
5021 gen_helper_mtc0_debug(arg); /* EJTAG support */
5022 /* BS_STOP isn't good enough here, hflags may have changed. */
5023 gen_save_pc(ctx->pc + 4);
5024 ctx->bstate = BS_EXCP;
5025 rn = "Debug";
5026 break;
5027 case 1:
5028 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5029 /* Stop translation as we may have switched the execution mode */
5030 ctx->bstate = BS_STOP;
5031 rn = "TraceControl";
5032 // break;
5033 case 2:
5034 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5035 /* Stop translation as we may have switched the execution mode */
5036 ctx->bstate = BS_STOP;
5037 rn = "TraceControl2";
5038 // break;
5039 case 3:
5040 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5041 /* Stop translation as we may have switched the execution mode */
5042 ctx->bstate = BS_STOP;
5043 rn = "UserTraceData";
5044 // break;
5045 case 4:
5046 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5047 /* Stop translation as we may have switched the execution mode */
5048 ctx->bstate = BS_STOP;
5049 rn = "TraceBPC";
5050 // break;
5051 default:
5052 goto die;
5053 }
5054 break;
5055 case 24:
5056 switch (sel) {
5057 case 0:
5058 /* EJTAG support */
5059 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5060 rn = "DEPC";
5061 break;
5062 default:
5063 goto die;
5064 }
5065 break;
5066 case 25:
5067 switch (sel) {
5068 case 0:
5069 gen_helper_mtc0_performance0(arg);
5070 rn = "Performance0";
5071 break;
5072 case 1:
5073 // gen_helper_mtc0_performance1(arg);
5074 rn = "Performance1";
5075 // break;
5076 case 2:
5077 // gen_helper_mtc0_performance2(arg);
5078 rn = "Performance2";
5079 // break;
5080 case 3:
5081 // gen_helper_mtc0_performance3(arg);
5082 rn = "Performance3";
5083 // break;
5084 case 4:
5085 // gen_helper_mtc0_performance4(arg);
5086 rn = "Performance4";
5087 // break;
5088 case 5:
5089 // gen_helper_mtc0_performance5(arg);
5090 rn = "Performance5";
5091 // break;
5092 case 6:
5093 // gen_helper_mtc0_performance6(arg);
5094 rn = "Performance6";
5095 // break;
5096 case 7:
5097 // gen_helper_mtc0_performance7(arg);
5098 rn = "Performance7";
5099 // break;
5100 default:
5101 goto die;
5102 }
5103 break;
5104 case 26:
5105 /* ignored */
5106 rn = "ECC";
5107 break;
5108 case 27:
5109 switch (sel) {
5110 case 0 ... 3:
5111 /* ignored */
5112 rn = "CacheErr";
5113 break;
5114 default:
5115 goto die;
5116 }
5117 break;
5118 case 28:
5119 switch (sel) {
5120 case 0:
5121 case 2:
5122 case 4:
5123 case 6:
5124 gen_helper_mtc0_taglo(arg);
5125 rn = "TagLo";
5126 break;
5127 case 1:
5128 case 3:
5129 case 5:
5130 case 7:
5131 gen_helper_mtc0_datalo(arg);
5132 rn = "DataLo";
5133 break;
5134 default:
5135 goto die;
5136 }
5137 break;
5138 case 29:
5139 switch (sel) {
5140 case 0:
5141 case 2:
5142 case 4:
5143 case 6:
5144 gen_helper_mtc0_taghi(arg);
5145 rn = "TagHi";
5146 break;
5147 case 1:
5148 case 3:
5149 case 5:
5150 case 7:
5151 gen_helper_mtc0_datahi(arg);
5152 rn = "DataHi";
5153 break;
5154 default:
5155 rn = "invalid sel";
5156 goto die;
5157 }
5158 break;
5159 case 30:
5160 switch (sel) {
5161 case 0:
5162 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5163 rn = "ErrorEPC";
5164 break;
5165 default:
5166 goto die;
5167 }
5168 break;
5169 case 31:
5170 switch (sel) {
5171 case 0:
5172 /* EJTAG support */
5173 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5174 rn = "DESAVE";
5175 break;
5176 default:
5177 goto die;
5178 }
5179 /* Stop translation as we may have switched the execution mode */
5180 ctx->bstate = BS_STOP;
5181 break;
5182 default:
5183 goto die;
5184 }
5185 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5186 /* For simplicity assume that all writes can cause interrupts. */
5187 if (use_icount) {
5188 gen_io_end();
5189 ctx->bstate = BS_STOP;
5190 }
5191 return;
5192
5193 die:
5194 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5195 generate_exception(ctx, EXCP_RI);
5196 }
5197 #endif /* TARGET_MIPS64 */
5198
5199 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5200 int u, int sel, int h)
5201 {
5202 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5203 TCGv t0 = tcg_temp_local_new();
5204
5205 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5206 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5207 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5208 tcg_gen_movi_tl(t0, -1);
5209 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5210 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5211 tcg_gen_movi_tl(t0, -1);
5212 else if (u == 0) {
5213 switch (rt) {
5214 case 2:
5215 switch (sel) {
5216 case 1:
5217 gen_helper_mftc0_tcstatus(t0);
5218 break;
5219 case 2:
5220 gen_helper_mftc0_tcbind(t0);
5221 break;
5222 case 3:
5223 gen_helper_mftc0_tcrestart(t0);
5224 break;
5225 case 4:
5226 gen_helper_mftc0_tchalt(t0);
5227 break;
5228 case 5:
5229 gen_helper_mftc0_tccontext(t0);
5230 break;
5231 case 6:
5232 gen_helper_mftc0_tcschedule(t0);
5233 break;
5234 case 7:
5235 gen_helper_mftc0_tcschefback(t0);
5236 break;
5237 default:
5238 gen_mfc0(env, ctx, t0, rt, sel);
5239 break;
5240 }
5241 break;
5242 case 10:
5243 switch (sel) {
5244 case 0:
5245 gen_helper_mftc0_entryhi(t0);
5246 break;
5247 default:
5248 gen_mfc0(env, ctx, t0, rt, sel);
5249 break;
5250 }
5251 case 12:
5252 switch (sel) {
5253 case 0:
5254 gen_helper_mftc0_status(t0);
5255 break;
5256 default:
5257 gen_mfc0(env, ctx, t0, rt, sel);
5258 break;
5259 }
5260 case 23:
5261 switch (sel) {
5262 case 0:
5263 gen_helper_mftc0_debug(t0);
5264 break;
5265 default:
5266 gen_mfc0(env, ctx, t0, rt, sel);
5267 break;
5268 }
5269 break;
5270 default:
5271 gen_mfc0(env, ctx, t0, rt, sel);
5272 }
5273 } else switch (sel) {
5274 /* GPR registers. */
5275 case 0:
5276 gen_helper_1i(mftgpr, t0, rt);
5277 break;
5278 /* Auxiliary CPU registers */
5279 case 1:
5280 switch (rt) {
5281 case 0:
5282 gen_helper_1i(mftlo, t0, 0);
5283 break;
5284 case 1:
5285 gen_helper_1i(mfthi, t0, 0);
5286 break;
5287 case 2:
5288 gen_helper_1i(mftacx, t0, 0);
5289 break;
5290 case 4:
5291 gen_helper_1i(mftlo, t0, 1);
5292 break;
5293 case 5:
5294 gen_helper_1i(mfthi, t0, 1);
5295 break;
5296 case 6:
5297 gen_helper_1i(mftacx, t0, 1);
5298 break;
5299 case 8:
5300 gen_helper_1i(mftlo, t0, 2);
5301 break;
5302 case 9:
5303 gen_helper_1i(mfthi, t0, 2);
5304 break;
5305 case 10:
5306 gen_helper_1i(mftacx, t0, 2);
5307 break;
5308 case 12:
5309 gen_helper_1i(mftlo, t0, 3);
5310 break;
5311 case 13:
5312 gen_helper_1i(mfthi, t0, 3);
5313 break;
5314 case 14:
5315 gen_helper_1i(mftacx, t0, 3);
5316 break;
5317 case 16:
5318 gen_helper_mftdsp(t0);
5319 break;
5320 default:
5321 goto die;
5322 }
5323 break;
5324 /* Floating point (COP1). */
5325 case 2:
5326 /* XXX: For now we support only a single FPU context. */
5327 if (h == 0) {
5328 TCGv_i32 fp0 = tcg_temp_new_i32();
5329
5330 gen_load_fpr32(fp0, rt);
5331 tcg_gen_ext_i32_tl(t0, fp0);
5332 tcg_temp_free_i32(fp0);
5333 } else {
5334 TCGv_i32 fp0 = tcg_temp_new_i32();
5335
5336 gen_load_fpr32h(fp0, rt);
5337 tcg_gen_ext_i32_tl(t0, fp0);
5338 tcg_temp_free_i32(fp0);
5339 }
5340 break;
5341 case 3:
5342 /* XXX: For now we support only a single FPU context. */
5343 gen_helper_1i(cfc1, t0, rt);
5344 break;
5345 /* COP2: Not implemented. */
5346 case 4:
5347 case 5:
5348 /* fall through */
5349 default:
5350 goto die;
5351 }
5352 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5353 gen_store_gpr(t0, rd);
5354 tcg_temp_free(t0);
5355 return;
5356
5357 die:
5358 tcg_temp_free(t0);
5359 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5360 generate_exception(ctx, EXCP_RI);
5361 }
5362
5363 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5364 int u, int sel, int h)
5365 {
5366 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5367 TCGv t0 = tcg_temp_local_new();
5368
5369 gen_load_gpr(t0, rt);
5370 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5371 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5372 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5373 /* NOP */ ;
5374 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5375 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5376 /* NOP */ ;
5377 else if (u == 0) {
5378 switch (rd) {
5379 case 2:
5380 switch (sel) {
5381 case 1:
5382 gen_helper_mttc0_tcstatus(t0);
5383 break;
5384 case 2:
5385 gen_helper_mttc0_tcbind(t0);
5386 break;
5387 case 3:
5388 gen_helper_mttc0_tcrestart(t0);
5389 break;
5390 case 4:
5391 gen_helper_mttc0_tchalt(t0);
5392 break;
5393 case 5:
5394 gen_helper_mttc0_tccontext(t0);
5395 break;
5396 case 6:
5397 gen_helper_mttc0_tcschedule(t0);
5398 break;
5399 case 7:
5400 gen_helper_mttc0_tcschefback(t0);
5401 break;
5402 default:
5403 gen_mtc0(env, ctx, t0, rd, sel);
5404 break;
5405 }
5406 break;
5407 case 10:
5408 switch (sel) {
5409 case 0:
5410 gen_helper_mttc0_entryhi(t0);
5411 break;
5412 default:
5413 gen_mtc0(env, ctx, t0, rd, sel);
5414 break;
5415 }
5416 case 12:
5417 switch (sel) {
5418 case 0:
5419 gen_helper_mttc0_status(t0);
5420 break;
5421 default:
5422 gen_mtc0(env, ctx, t0, rd, sel);
5423 break;
5424 }
5425 case 23:
5426 switch (sel) {
5427 case 0:
5428 gen_helper_mttc0_debug(t0);
5429 break;
5430 default:
5431 gen_mtc0(env, ctx, t0, rd, sel);
5432 break;
5433 }
5434 break;
5435 default:
5436 gen_mtc0(env, ctx, t0, rd, sel);
5437 }
5438 } else switch (sel) {
5439 /* GPR registers. */
5440 case 0:
5441 gen_helper_1i(mttgpr, t0, rd);
5442 break;
5443 /* Auxiliary CPU registers */
5444 case 1:
5445 switch (rd) {
5446 case 0:
5447 gen_helper_1i(mttlo, t0, 0);
5448 break;
5449 case 1:
5450 gen_helper_1i(mtthi, t0, 0);
5451 break;
5452 case 2:
5453 gen_helper_1i(mttacx, t0, 0);
5454 break;
5455 case 4:
5456 gen_helper_1i(mttlo, t0, 1);
5457 break;
5458 case 5:
5459 gen_helper_1i(mtthi, t0, 1);
5460 break;
5461 case 6:
5462 gen_helper_1i(mttacx, t0, 1);
5463 break;
5464 case 8:
5465 gen_helper_1i(mttlo, t0, 2);
5466 break;
5467 case 9:
5468 gen_helper_1i(mtthi, t0, 2);
5469 break;
5470 case 10:
5471 gen_helper_1i(mttacx, t0, 2);
5472 break;
5473 case 12:
5474 gen_helper_1i(mttlo, t0, 3);
5475 break;
5476 case 13:
5477 gen_helper_1i(mtthi, t0, 3);
5478 break;
5479 case 14:
5480 gen_helper_1i(mttacx, t0, 3);
5481 break;
5482 case 16:
5483 gen_helper_mttdsp(t0);
5484 break;
5485 default:
5486 goto die;
5487 }
5488 break;
5489 /* Floating point (COP1). */
5490 case 2:
5491 /* XXX: For now we support only a single FPU context. */
5492 if (h == 0) {
5493 TCGv_i32 fp0 = tcg_temp_new_i32();
5494
5495 tcg_gen_trunc_tl_i32(fp0, t0);
5496 gen_store_fpr32(fp0, rd);
5497 tcg_temp_free_i32(fp0);
5498 } else {
5499 TCGv_i32 fp0 = tcg_temp_new_i32();
5500
5501 tcg_gen_trunc_tl_i32(fp0, t0);
5502 gen_store_fpr32h(fp0, rd);
5503 tcg_temp_free_i32(fp0);
5504 }
5505 break;
5506 case 3:
5507 /* XXX: For now we support only a single FPU context. */
5508 gen_helper_1i(ctc1, t0, rd);
5509 break;
5510 /* COP2: Not implemented. */
5511 case 4:
5512 case 5:
5513 /* fall through */
5514 default:
5515 goto die;
5516 }
5517 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5518 tcg_temp_free(t0);
5519 return;
5520
5521 die:
5522 tcg_temp_free(t0);
5523 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5524 generate_exception(ctx, EXCP_RI);
5525 }
5526
5527 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5528 {
5529 const char *opn = "ldst";
5530
5531 switch (opc) {
5532 case OPC_MFC0:
5533 if (rt == 0) {
5534 /* Treat as NOP. */
5535 return;
5536 }
5537 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5538 opn = "mfc0";
5539 break;
5540 case OPC_MTC0:
5541 {
5542 TCGv t0 = tcg_temp_new();
5543
5544 gen_load_gpr(t0, rt);
5545 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5546 tcg_temp_free(t0);
5547 }
5548 opn = "mtc0";
5549 break;
5550 #if defined(TARGET_MIPS64)
5551 case OPC_DMFC0:
5552 check_insn(env, ctx, ISA_MIPS3);
5553 if (rt == 0) {
5554 /* Treat as NOP. */
5555 return;
5556 }
5557 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5558 opn = "dmfc0";
5559 break;
5560 case OPC_DMTC0:
5561 check_insn(env, ctx, ISA_MIPS3);
5562 {
5563 TCGv t0 = tcg_temp_new();
5564
5565 gen_load_gpr(t0, rt);
5566 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5567 tcg_temp_free(t0);
5568 }
5569 opn = "dmtc0";
5570 break;
5571 #endif
5572 case OPC_MFTR:
5573 check_insn(env, ctx, ASE_MT);
5574 if (rd == 0) {
5575 /* Treat as NOP. */
5576 return;
5577 }
5578 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5579 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5580 opn = "mftr";
5581 break;
5582 case OPC_MTTR:
5583 check_insn(env, ctx, ASE_MT);
5584 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5585 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5586 opn = "mttr";
5587 break;
5588 case OPC_TLBWI:
5589 opn = "tlbwi";
5590 if (!env->tlb->helper_tlbwi)
5591 goto die;
5592 gen_helper_tlbwi();
5593 break;
5594 case OPC_TLBWR:
5595 opn = "tlbwr";
5596 if (!env->tlb->helper_tlbwr)
5597 goto die;
5598 gen_helper_tlbwr();
5599 break;
5600 case OPC_TLBP:
5601 opn = "tlbp";
5602 if (!env->tlb->helper_tlbp)
5603 goto die;
5604 gen_helper_tlbp();
5605 break;
5606 case OPC_TLBR:
5607 opn = "tlbr";
5608 if (!env->tlb->helper_tlbr)
5609 goto die;
5610 gen_helper_tlbr();
5611 break;
5612 case OPC_ERET:
5613 opn = "eret";
5614 check_insn(env, ctx, ISA_MIPS2);
5615 gen_helper_eret();
5616 ctx->bstate = BS_EXCP;
5617 break;
5618 case OPC_DERET:
5619 opn = "deret";
5620 check_insn(env, ctx, ISA_MIPS32);
5621 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5622 MIPS_INVAL(opn);
5623 generate_exception(ctx, EXCP_RI);
5624 } else {
5625 gen_helper_deret();
5626 ctx->bstate = BS_EXCP;
5627 }
5628 break;
5629 case OPC_WAIT:
5630 opn = "wait";
5631 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5632 /* If we get an exception, we want to restart at next instruction */
5633 ctx->pc += 4;
5634 save_cpu_state(ctx, 1);
5635 ctx->pc -= 4;
5636 gen_helper_wait();
5637 ctx->bstate = BS_EXCP;
5638 break;
5639 default:
5640 die:
5641 MIPS_INVAL(opn);
5642 generate_exception(ctx, EXCP_RI);
5643 return;
5644 }
5645 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5646 }
5647 #endif /* !CONFIG_USER_ONLY */
5648
5649 /* CP1 Branches (before delay slot) */
5650 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5651 int32_t cc, int32_t offset)
5652 {
5653 target_ulong btarget;
5654 const char *opn = "cp1 cond branch";
5655 TCGv_i32 t0 = tcg_temp_new_i32();
5656
5657 if (cc != 0)
5658 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5659
5660 btarget = ctx->pc + 4 + offset;
5661
5662 switch (op) {
5663 case OPC_BC1F:
5664 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5665 tcg_gen_not_i32(t0, t0);
5666 tcg_gen_andi_i32(t0, t0, 1);
5667 tcg_gen_extu_i32_tl(bcond, t0);
5668 opn = "bc1f";
5669 goto not_likely;
5670 case OPC_BC1FL:
5671 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5672 tcg_gen_not_i32(t0, t0);
5673 tcg_gen_andi_i32(t0, t0, 1);
5674 tcg_gen_extu_i32_tl(bcond, t0);
5675 opn = "bc1fl";
5676 goto likely;
5677 case OPC_BC1T:
5678 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5679 tcg_gen_andi_i32(t0, t0, 1);
5680 tcg_gen_extu_i32_tl(bcond, t0);
5681 opn = "bc1t";
5682 goto not_likely;
5683 case OPC_BC1TL:
5684 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5685 tcg_gen_andi_i32(t0, t0, 1);
5686 tcg_gen_extu_i32_tl(bcond, t0);
5687 opn = "bc1tl";
5688 likely:
5689 ctx->hflags |= MIPS_HFLAG_BL;
5690 break;
5691 case OPC_BC1FANY2:
5692 {
5693 TCGv_i32 t1 = tcg_temp_new_i32();
5694 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5695 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5696 tcg_gen_or_i32(t0, t0, t1);
5697 tcg_temp_free_i32(t1);
5698 tcg_gen_not_i32(t0, t0);
5699 tcg_gen_andi_i32(t0, t0, 1);
5700 tcg_gen_extu_i32_tl(bcond, t0);
5701 }
5702 opn = "bc1any2f";
5703 goto not_likely;
5704 case OPC_BC1TANY2:
5705 {
5706 TCGv_i32 t1 = tcg_temp_new_i32();
5707 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5708 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5709 tcg_gen_or_i32(t0, t0, t1);
5710 tcg_temp_free_i32(t1);
5711 tcg_gen_andi_i32(t0, t0, 1);
5712 tcg_gen_extu_i32_tl(bcond, t0);
5713 }
5714 opn = "bc1any2t";
5715 goto not_likely;
5716 case OPC_BC1FANY4:
5717 {
5718 TCGv_i32 t1 = tcg_temp_new_i32();
5719 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5720 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5721 tcg_gen_or_i32(t0, t0, t1);
5722 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5723 tcg_gen_or_i32(t0, t0, t1);
5724 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5725 tcg_gen_or_i32(t0, t0, t1);
5726 tcg_temp_free_i32(t1);
5727 tcg_gen_not_i32(t0, t0);
5728 tcg_gen_andi_i32(t0, t0, 1);
5729 tcg_gen_extu_i32_tl(bcond, t0);
5730 }
5731 opn = "bc1any4f";
5732 goto not_likely;
5733 case OPC_BC1TANY4:
5734 {
5735 TCGv_i32 t1 = tcg_temp_new_i32();
5736 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5737 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5738 tcg_gen_or_i32(t0, t0, t1);
5739 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5740 tcg_gen_or_i32(t0, t0, t1);
5741 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5742 tcg_gen_or_i32(t0, t0, t1);
5743 tcg_temp_free_i32(t1);
5744 tcg_gen_andi_i32(t0, t0, 1);
5745 tcg_gen_extu_i32_tl(bcond, t0);
5746 }
5747 opn = "bc1any4t";
5748 not_likely:
5749 ctx->hflags |= MIPS_HFLAG_BC;
5750 break;
5751 default:
5752 MIPS_INVAL(opn);
5753 generate_exception (ctx, EXCP_RI);
5754 goto out;
5755 }
5756 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5757 ctx->hflags, btarget);
5758 ctx->btarget = btarget;
5759
5760 out:
5761 tcg_temp_free_i32(t0);
5762 }
5763
5764 /* Coprocessor 1 (FPU) */
5765
5766 #define FOP(func, fmt) (((fmt) << 21) | (func))
5767
5768 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5769 {
5770 const char *opn = "cp1 move";
5771 TCGv t0 = tcg_temp_new();
5772
5773 switch (opc) {
5774 case OPC_MFC1:
5775 {
5776 TCGv_i32 fp0 = tcg_temp_new_i32();
5777
5778 gen_load_fpr32(fp0, fs);
5779 tcg_gen_ext_i32_tl(t0, fp0);
5780 tcg_temp_free_i32(fp0);
5781 }
5782 gen_store_gpr(t0, rt);
5783 opn = "mfc1";
5784 break;
5785 case OPC_MTC1:
5786 gen_load_gpr(t0, rt);
5787 {
5788 TCGv_i32 fp0 = tcg_temp_new_i32();
5789
5790 tcg_gen_trunc_tl_i32(fp0, t0);
5791 gen_store_fpr32(fp0, fs);
5792 tcg_temp_free_i32(fp0);
5793 }
5794 opn = "mtc1";
5795 break;
5796 case OPC_CFC1:
5797 gen_helper_1i(cfc1, t0, fs);
5798 gen_store_gpr(t0, rt);
5799 opn = "cfc1";
5800 break;
5801 case OPC_CTC1:
5802 gen_load_gpr(t0, rt);
5803 gen_helper_1i(ctc1, t0, fs);
5804 opn = "ctc1";
5805 break;
5806 #if defined(TARGET_MIPS64)
5807 case OPC_DMFC1:
5808 gen_load_fpr64(ctx, t0, fs);
5809 gen_store_gpr(t0, rt);
5810 opn = "dmfc1";
5811 break;
5812 case OPC_DMTC1:
5813 gen_load_gpr(t0, rt);
5814 gen_store_fpr64(ctx, t0, fs);
5815 opn = "dmtc1";
5816 break;
5817 #endif
5818 case OPC_MFHC1:
5819 {
5820 TCGv_i32 fp0 = tcg_temp_new_i32();
5821
5822 gen_load_fpr32h(fp0, fs);
5823 tcg_gen_ext_i32_tl(t0, fp0);
5824 tcg_temp_free_i32(fp0);
5825 }
5826 gen_store_gpr(t0, rt);
5827 opn = "mfhc1";
5828 break;
5829 case OPC_MTHC1:
5830 gen_load_gpr(t0, rt);
5831 {
5832 TCGv_i32 fp0 = tcg_temp_new_i32();
5833
5834 tcg_gen_trunc_tl_i32(fp0, t0);
5835 gen_store_fpr32h(fp0, fs);
5836 tcg_temp_free_i32(fp0);
5837 }
5838 opn = "mthc1";
5839 break;
5840 default:
5841 MIPS_INVAL(opn);
5842 generate_exception (ctx, EXCP_RI);
5843 goto out;
5844 }
5845 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5846
5847 out:
5848 tcg_temp_free(t0);
5849 }
5850
5851 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5852 {
5853 int l1;
5854 TCGCond cond;
5855 TCGv_i32 t0;
5856
5857 if (rd == 0) {
5858 /* Treat as NOP. */
5859 return;
5860 }
5861
5862 if (tf)
5863 cond = TCG_COND_EQ;
5864 else
5865 cond = TCG_COND_NE;
5866
5867 l1 = gen_new_label();
5868 t0 = tcg_temp_new_i32();
5869 tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5870 tcg_gen_brcondi_i32(cond, t0, 0, l1);
5871 tcg_temp_free_i32(t0);
5872 if (rs == 0) {
5873 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5874 } else {
5875 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5876 }
5877 gen_set_label(l1);
5878 }
5879
5880 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5881 {
5882 int cond;
5883 TCGv_i32 t0 = tcg_temp_new_i32();
5884 int l1 = gen_new_label();
5885
5886 if (tf)
5887 cond = TCG_COND_EQ;
5888 else
5889 cond = TCG_COND_NE;
5890
5891 tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5892 tcg_gen_brcondi_i32(cond, t0, 0, l1);
5893 gen_load_fpr32(t0, fs);
5894 gen_store_fpr32(t0, fd);
5895 gen_set_label(l1);
5896 tcg_temp_free_i32(t0);
5897 }
5898
5899 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5900 {
5901 int cond;
5902 TCGv_i32 t0 = tcg_temp_new_i32();
5903 TCGv_i64 fp0;
5904 int l1 = gen_new_label();
5905
5906 if (tf)
5907 cond = TCG_COND_EQ;
5908 else
5909 cond = TCG_COND_NE;
5910
5911 tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5912 tcg_gen_brcondi_i32(cond, t0, 0, l1);
5913 tcg_temp_free_i32(t0);
5914 fp0 = tcg_temp_new_i64();
5915 gen_load_fpr64(ctx, fp0, fs);
5916 gen_store_fpr64(ctx, fp0, fd);
5917 tcg_temp_free_i64(fp0);
5918 gen_set_label(l1);
5919 }
5920
5921 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5922 {
5923 int cond;
5924 TCGv_i32 t0 = tcg_temp_new_i32();
5925 int l1 = gen_new_label();
5926 int l2 = gen_new_label();
5927
5928 if (tf)
5929 cond = TCG_COND_EQ;
5930 else
5931 cond = TCG_COND_NE;
5932
5933 tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5934 tcg_gen_brcondi_i32(cond, t0, 0, l1);
5935 gen_load_fpr32(t0, fs);
5936 gen_store_fpr32(t0, fd);
5937 gen_set_label(l1);
5938
5939 tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc+1));
5940 tcg_gen_brcondi_i32(cond, t0, 0, l2);
5941 gen_load_fpr32h(t0, fs);
5942 gen_store_fpr32h(t0, fd);
5943 tcg_temp_free_i32(t0);
5944 gen_set_label(l2);
5945 }
5946
5947
5948 static void gen_farith (DisasContext *ctx, uint32_t op1,
5949 int ft, int fs, int fd, int cc)
5950 {
5951 const char *opn = "farith";
5952 const char *condnames[] = {
5953 "c.f",
5954 "c.un",
5955 "c.eq",
5956 "c.ueq",
5957 "c.olt",
5958 "c.ult",
5959 "c.ole",
5960 "c.ule",
5961 "c.sf",
5962 "c.ngle",
5963 "c.seq",
5964 "c.ngl",
5965 "c.lt",
5966 "c.nge",
5967 "c.le",
5968 "c.ngt",
5969 };
5970 const char *condnames_abs[] = {
5971 "cabs.f",
5972 "cabs.un",
5973 "cabs.eq",
5974 "cabs.ueq",
5975 "cabs.olt",
5976 "cabs.ult",
5977 "cabs.ole",
5978 "cabs.ule",
5979 "cabs.sf",
5980 "cabs.ngle",
5981 "cabs.seq",
5982 "cabs.ngl",
5983 "cabs.lt",
5984 "cabs.nge",
5985 "cabs.le",
5986 "cabs.ngt",
5987 };
5988 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5989 uint32_t func = ctx->opcode & 0x3f;
5990
5991 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5992 case FOP(0, 16):
5993 {
5994 TCGv_i32 fp0 = tcg_temp_new_i32();
5995 TCGv_i32 fp1 = tcg_temp_new_i32();
5996
5997 gen_load_fpr32(fp0, fs);
5998 gen_load_fpr32(fp1, ft);
5999 gen_helper_float_add_s(fp0, fp0, fp1);
6000 tcg_temp_free_i32(fp1);
6001 gen_store_fpr32(fp0, fd);
6002 tcg_temp_free_i32(fp0);
6003 }
6004 opn = "add.s";
6005 optype = BINOP;
6006 break;
6007 case FOP(1, 16):
6008 {
6009 TCGv_i32 fp0 = tcg_temp_new_i32();
6010 TCGv_i32 fp1 = tcg_temp_new_i32();
6011
6012 gen_load_fpr32(fp0, fs);
6013 gen_load_fpr32(fp1, ft);
6014 gen_helper_float_sub_s(fp0, fp0, fp1);
6015 tcg_temp_free_i32(fp1);
6016 gen_store_fpr32(fp0, fd);
6017 tcg_temp_free_i32(fp0);
6018 }
6019 opn = "sub.s";
6020 optype = BINOP;
6021 break;
6022 case FOP(2, 16):
6023 {
6024 TCGv_i32 fp0 = tcg_temp_new_i32();
6025 TCGv_i32 fp1 = tcg_temp_new_i32();
6026
6027 gen_load_fpr32(fp0, fs);
6028 gen_load_fpr32(fp1, ft);
6029 gen_helper_float_mul_s(fp0, fp0, fp1);
6030 tcg_temp_free_i32(fp1);
6031 gen_store_fpr32(fp0, fd);
6032 tcg_temp_free_i32(fp0);
6033 }
6034 opn = "mul.s";
6035 optype = BINOP;
6036 break;
6037 case FOP(3, 16):
6038 {
6039 TCGv_i32 fp0 = tcg_temp_new_i32();
6040 TCGv_i32 fp1 = tcg_temp_new_i32();
6041
6042 gen_load_fpr32(fp0, fs);
6043 gen_load_fpr32(fp1, ft);
6044 gen_helper_float_div_s(fp0, fp0, fp1);
6045 tcg_temp_free_i32(fp1);
6046 gen_store_fpr32(fp0, fd);
6047 tcg_temp_free_i32(fp0);
6048 }
6049 opn = "div.s";
6050 optype = BINOP;
6051 break;
6052 case FOP(4, 16):
6053 {
6054 TCGv_i32 fp0 = tcg_temp_new_i32();
6055
6056 gen_load_fpr32(fp0, fs);
6057 gen_helper_float_sqrt_s(fp0, fp0);
6058 gen_store_fpr32(fp0, fd);
6059 tcg_temp_free_i32(fp0);
6060 }
6061 opn = "sqrt.s";
6062 break;
6063 case FOP(5, 16):
6064 {
6065 TCGv_i32 fp0 = tcg_temp_new_i32();
6066
6067 gen_load_fpr32(fp0, fs);
6068 gen_helper_float_abs_s(fp0, fp0);
6069 gen_store_fpr32(fp0, fd);
6070 tcg_temp_free_i32(fp0);
6071 }
6072 opn = "abs.s";
6073 break;
6074 case FOP(6, 16):
6075 {
6076 TCGv_i32 fp0 = tcg_temp_new_i32();
6077
6078 gen_load_fpr32(fp0, fs);
6079 gen_store_fpr32(fp0, fd);
6080 tcg_temp_free_i32(fp0);
6081 }
6082 opn = "mov.s";
6083 break;
6084 case FOP(7, 16):
6085 {
6086 TCGv_i32 fp0 = tcg_temp_new_i32();
6087
6088 gen_load_fpr32(fp0, fs);
6089 gen_helper_float_chs_s(fp0, fp0);
6090 gen_store_fpr32(fp0, fd);
6091 tcg_temp_free_i32(fp0);
6092 }
6093 opn = "neg.s";
6094 break;
6095 case FOP(8, 16):
6096 check_cp1_64bitmode(ctx);
6097 {
6098 TCGv_i32 fp32 = tcg_temp_new_i32();
6099 TCGv_i64 fp64 = tcg_temp_new_i64();
6100
6101 gen_load_fpr32(fp32, fs);
6102 gen_helper_float_roundl_s(fp64, fp32);
6103 tcg_temp_free_i32(fp32);
6104 gen_store_fpr64(ctx, fp64, fd);
6105 tcg_temp_free_i64(fp64);
6106 }
6107 opn = "round.l.s";
6108 break;
6109 case FOP(9, 16):
6110 check_cp1_64bitmode(ctx);
6111 {
6112 TCGv_i32 fp32 = tcg_temp_new_i32();
6113 TCGv_i64 fp64 = tcg_temp_new_i64();
6114
6115 gen_load_fpr32(fp32, fs);
6116 gen_helper_float_truncl_s(fp64, fp32);
6117 tcg_temp_free_i32(fp32);
6118 gen_store_fpr64(ctx, fp64, fd);
6119 tcg_temp_free_i64(fp64);
6120 }
6121 opn = "trunc.l.s";
6122 break;
6123 case FOP(10, 16):
6124 check_cp1_64bitmode(ctx);
6125 {
6126 TCGv_i32 fp32 = tcg_temp_new_i32();
6127 TCGv_i64 fp64 = tcg_temp_new_i64();
6128
6129 gen_load_fpr32(fp32, fs);
6130 gen_helper_float_ceill_s(fp64, fp32);
6131 tcg_temp_free_i32(fp32);
6132 gen_store_fpr64(ctx, fp64, fd);
6133 tcg_temp_free_i64(fp64);
6134 }
6135 opn = "ceil.l.s";
6136 break;
6137 case FOP(11, 16):
6138 check_cp1_64bitmode(ctx);
6139 {
6140 TCGv_i32 fp32 = tcg_temp_new_i32();
6141 TCGv_i64 fp64 = tcg_temp_new_i64();
6142
6143 gen_load_fpr32(fp32, fs);
6144 gen_helper_float_floorl_s(fp64, fp32);
6145 tcg_temp_free_i32(fp32);
6146 gen_store_fpr64(ctx, fp64, fd);
6147 tcg_temp_free_i64(fp64);
6148 }
6149 opn = "floor.l.s";
6150 break;
6151 case FOP(12, 16):
6152 {
6153 TCGv_i32 fp0 = tcg_temp_new_i32();
6154
6155 gen_load_fpr32(fp0, fs);
6156 gen_helper_float_roundw_s(fp0, fp0);
6157 gen_store_fpr32(fp0, fd);
6158 tcg_temp_free_i32(fp0);
6159 }
6160 opn = "round.w.s";
6161 break;
6162 case FOP(13, 16):
6163 {
6164 TCGv_i32 fp0 = tcg_temp_new_i32();
6165
6166 gen_load_fpr32(fp0, fs);
6167 gen_helper_float_truncw_s(fp0, fp0);
6168 gen_store_fpr32(fp0, fd);
6169 tcg_temp_free_i32(fp0);
6170 }
6171 opn = "trunc.w.s";
6172 break;
6173 case FOP(14, 16):
6174 {
6175 TCGv_i32 fp0 = tcg_temp_new_i32();
6176
6177 gen_load_fpr32(fp0, fs);
6178 gen_helper_float_ceilw_s(fp0, fp0);
6179 gen_store_fpr32(fp0, fd);
6180 tcg_temp_free_i32(fp0);
6181 }
6182 opn = "ceil.w.s";
6183 break;
6184 case FOP(15, 16):
6185 {
6186 TCGv_i32 fp0 = tcg_temp_new_i32();
6187
6188 gen_load_fpr32(fp0, fs);
6189 gen_helper_float_floorw_s(fp0, fp0);
6190 gen_store_fpr32(fp0, fd);
6191 tcg_temp_free_i32(fp0);
6192 }
6193 opn = "floor.w.s";
6194 break;
6195 case FOP(17, 16):
6196 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6197 opn = "movcf.s";
6198 break;
6199 case FOP(18, 16):
6200 {
6201 int l1 = gen_new_label();
6202 TCGv_i32 fp0;
6203
6204 if (ft != 0) {
6205 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6206 }
6207 fp0 = tcg_temp_new_i32();
6208 gen_load_fpr32(fp0, fs);
6209 gen_store_fpr32(fp0, fd);
6210 tcg_temp_free_i32(fp0);
6211 gen_set_label(l1);
6212 }
6213 opn = "movz.s";
6214 break;
6215 case FOP(19, 16):
6216 {
6217 int l1 = gen_new_label();
6218 TCGv_i32 fp0;
6219
6220 if (ft != 0) {
6221 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6222 fp0 = tcg_temp_new_i32();
6223 gen_load_fpr32(fp0, fs);
6224 gen_store_fpr32(fp0, fd);
6225 tcg_temp_free_i32(fp0);
6226 gen_set_label(l1);
6227 }
6228 }
6229 opn = "movn.s";
6230 break;
6231 case FOP(21, 16):
6232 check_cop1x(ctx);
6233 {
6234 TCGv_i32 fp0 = tcg_temp_new_i32();
6235
6236 gen_load_fpr32(fp0, fs);
6237 gen_helper_float_recip_s(fp0, fp0);
6238 gen_store_fpr32(fp0, fd);
6239 tcg_temp_free_i32(fp0);
6240 }
6241 opn = "recip.s";
6242 break;
6243 case FOP(22, 16):
6244 check_cop1x(ctx);
6245 {
6246 TCGv_i32 fp0 = tcg_temp_new_i32();
6247
6248 gen_load_fpr32(fp0, fs);
6249 gen_helper_float_rsqrt_s(fp0, fp0);
6250 gen_store_fpr32(fp0, fd);
6251 tcg_temp_free_i32(fp0);
6252 }
6253 opn = "rsqrt.s";
6254 break;
6255 case FOP(28, 16):
6256 check_cp1_64bitmode(ctx);
6257 {
6258 TCGv_i32 fp0 = tcg_temp_new_i32();
6259 TCGv_i32 fp1 = tcg_temp_new_i32();
6260
6261 gen_load_fpr32(fp0, fs);
6262 gen_load_fpr32(fp1, fd);
6263 gen_helper_float_recip2_s(fp0, fp0, fp1);
6264 tcg_temp_free_i32(fp1);
6265 gen_store_fpr32(fp0, fd);
6266 tcg_temp_free_i32(fp0);
6267 }
6268 opn = "recip2.s";
6269 break;
6270 case FOP(29, 16):
6271 check_cp1_64bitmode(ctx);
6272 {
6273 TCGv_i32 fp0 = tcg_temp_new_i32();
6274
6275 gen_load_fpr32(fp0, fs);
6276 gen_helper_float_recip1_s(fp0, fp0);
6277 gen_store_fpr32(fp0, fd);
6278 tcg_temp_free_i32(fp0);
6279 }
6280 opn = "recip1.s";
6281 break;
6282 case FOP(30, 16):
6283 check_cp1_64bitmode(ctx);
6284 {
6285 TCGv_i32 fp0 = tcg_temp_new_i32();
6286
6287 gen_load_fpr32(fp0, fs);
6288 gen_helper_float_rsqrt1_s(fp0, fp0);
6289 gen_store_fpr32(fp0, fd);
6290 tcg_temp_free_i32(fp0);
6291 }
6292 opn = "rsqrt1.s";
6293 break;
6294 case FOP(31, 16):
6295 check_cp1_64bitmode(ctx);
6296 {
6297 TCGv_i32 fp0 = tcg_temp_new_i32();
6298 TCGv_i32 fp1 = tcg_temp_new_i32();
6299
6300 gen_load_fpr32(fp0, fs);
6301 gen_load_fpr32(fp1, ft);
6302 gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6303 tcg_temp_free_i32(fp1);
6304 gen_store_fpr32(fp0, fd);
6305 tcg_temp_free_i32(fp0);
6306 }
6307 opn = "rsqrt2.s";
6308 break;
6309 case FOP(33, 16):
6310 check_cp1_registers(ctx, fd);
6311 {
6312 TCGv_i32 fp32 = tcg_temp_new_i32();
6313 TCGv_i64 fp64 = tcg_temp_new_i64();
6314
6315 gen_load_fpr32(fp32, fs);
6316 gen_helper_float_cvtd_s(fp64, fp32);
6317 tcg_temp_free_i32(fp32);
6318 gen_store_fpr64(ctx, fp64, fd);
6319 tcg_temp_free_i64(fp64);
6320 }
6321 opn = "cvt.d.s";
6322 break;
6323 case FOP(36, 16):
6324 {
6325 TCGv_i32 fp0 = tcg_temp_new_i32();
6326
6327 gen_load_fpr32(fp0, fs);
6328 gen_helper_float_cvtw_s(fp0, fp0);
6329 gen_store_fpr32(fp0, fd);
6330 tcg_temp_free_i32(fp0);
6331 }
6332 opn = "cvt.w.s";
6333 break;
6334 case FOP(37, 16):
6335 check_cp1_64bitmode(ctx);
6336 {
6337 TCGv_i32 fp32 = tcg_temp_new_i32();
6338 TCGv_i64 fp64 = tcg_temp_new_i64();
6339
6340 gen_load_fpr32(fp32, fs);
6341 gen_helper_float_cvtl_s(fp64, fp32);
6342 tcg_temp_free_i32(fp32);
6343 gen_store_fpr64(ctx, fp64, fd);
6344 tcg_temp_free_i64(fp64);
6345 }
6346 opn = "cvt.l.s";
6347 break;
6348 case FOP(38, 16):
6349 check_cp1_64bitmode(ctx);
6350 {
6351 TCGv_i64 fp64 = tcg_temp_new_i64();
6352 TCGv_i32 fp32_0 = tcg_temp_new_i32();
6353 TCGv_i32 fp32_1 = tcg_temp_new_i32();
6354
6355 gen_load_fpr32(fp32_0, fs);
6356 gen_load_fpr32(fp32_1, ft);
6357 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6358 tcg_temp_free_i32(fp32_1);
6359 tcg_temp_free_i32(fp32_0);
6360 gen_store_fpr64(ctx, fp64, fd);
6361 tcg_temp_free_i64(fp64);
6362 }
6363 opn = "cvt.ps.s";
6364 break;
6365 case FOP(48, 16):
6366 case FOP(49, 16):
6367 case FOP(50, 16):
6368 case FOP(51, 16):
6369 case FOP(52, 16):
6370 case FOP(53, 16):
6371 case FOP(54, 16):
6372 case FOP(55, 16):
6373 case FOP(56, 16):
6374 case FOP(57, 16):
6375 case FOP(58, 16):
6376 case FOP(59, 16):
6377 case FOP(60, 16):
6378 case FOP(61, 16):
6379 case FOP(62, 16):
6380 case FOP(63, 16):
6381 {
6382 TCGv_i32 fp0 = tcg_temp_new_i32();
6383 TCGv_i32 fp1 = tcg_temp_new_i32();
6384
6385 if (ctx->opcode & (1 << 6)) {
6386 check_cop1x(ctx);
6387 }
6388
6389 gen_load_fpr32(fp0, fs);
6390 gen_load_fpr32(fp1, ft);
6391 if (ctx->opcode & (1 << 6)) {
6392 gen_cmpabs_s(func-48, fp0, fp1, cc);
6393 opn = condnames_abs[func-48];
6394 } else {
6395 gen_cmp_s(func-48, fp0, fp1, cc);
6396 opn = condnames[func-48];
6397 }
6398 tcg_temp_free_i32(fp0);
6399 tcg_temp_free_i32(fp1);
6400 }
6401 break;
6402 case FOP(0, 17):
6403 check_cp1_registers(ctx, fs | ft | fd);
6404 {
6405 TCGv_i64 fp0 = tcg_temp_new_i64();
6406 TCGv_i64 fp1 = tcg_temp_new_i64();
6407
6408 gen_load_fpr64(ctx, fp0, fs);
6409 gen_load_fpr64(ctx, fp1, ft);
6410 gen_helper_float_add_d(fp0, fp0, fp1);
6411 tcg_temp_free_i64(fp1);
6412 gen_store_fpr64(ctx, fp0, fd);
6413 tcg_temp_free_i64(fp0);
6414 }
6415 opn = "add.d";
6416 optype = BINOP;
6417 break;
6418 case FOP(1, 17):
6419 check_cp1_registers(ctx, fs | ft | fd);
6420 {
6421 TCGv_i64 fp0 = tcg_temp_new_i64();
6422 TCGv_i64 fp1 = tcg_temp_new_i64();
6423
6424 gen_load_fpr64(ctx, fp0, fs);
6425 gen_load_fpr64(ctx, fp1, ft);
6426 gen_helper_float_sub_d(fp0, fp0, fp1);
6427 tcg_temp_free_i64(fp1);
6428 gen_store_fpr64(ctx, fp0, fd);
6429 tcg_temp_free_i64(fp0);
6430 }
6431 opn = "sub.d";
6432 optype = BINOP;
6433 break;
6434 case FOP(2, 17):
6435 check_cp1_registers(ctx, fs | ft | fd);
6436 {
6437 TCGv_i64 fp0 = tcg_temp_new_i64();
6438 TCGv_i64 fp1 = tcg_temp_new_i64();
6439
6440 gen_load_fpr64(ctx, fp0, fs);
6441 gen_load_fpr64(ctx, fp1, ft);
6442 gen_helper_float_mul_d(fp0, fp0, fp1);
6443 tcg_temp_free_i64(fp1);
6444 gen_store_fpr64(ctx, fp0, fd);
6445 tcg_temp_free_i64(fp0);
6446 }
6447 opn = "mul.d";
6448 optype = BINOP;
6449 break;
6450 case FOP(3, 17):
6451 check_cp1_registers(ctx, fs | ft | fd);
6452 {
6453 TCGv_i64 fp0 = tcg_temp_new_i64();
6454 TCGv_i64 fp1 = tcg_temp_new_i64();
6455
6456 gen_load_fpr64(ctx, fp0, fs);
6457 gen_load_fpr64(ctx, fp1, ft);
6458 gen_helper_float_div_d(fp0, fp0, fp1);
6459 tcg_temp_free_i64(fp1);
6460 gen_store_fpr64(ctx, fp0, fd);
6461 tcg_temp_free_i64(fp0);
6462 }
6463 opn = "div.d";
6464 optype = BINOP;
6465 break;
6466 case FOP(4, 17):
6467 check_cp1_registers(ctx, fs | fd);
6468 {
6469 TCGv_i64 fp0 = tcg_temp_new_i64();
6470
6471 gen_load_fpr64(ctx, fp0, fs);
6472 gen_helper_float_sqrt_d(fp0, fp0);
6473 gen_store_fpr64(ctx, fp0, fd);
6474 tcg_temp_free_i64(fp0);
6475 }
6476 opn = "sqrt.d";
6477 break;
6478 case FOP(5, 17):
6479 check_cp1_registers(ctx, fs | fd);
6480 {
6481 TCGv_i64 fp0 = tcg_temp_new_i64();
6482
6483 gen_load_fpr64(ctx, fp0, fs);
6484 gen_helper_float_abs_d(fp0, fp0);
6485 gen_store_fpr64(ctx, fp0, fd);
6486 tcg_temp_free_i64(fp0);
6487 }
6488 opn = "abs.d";
6489 break;
6490 case FOP(6, 17):
6491 check_cp1_registers(ctx, fs | fd);
6492 {
6493 TCGv_i64 fp0 = tcg_temp_new_i64();
6494
6495 gen_load_fpr64(ctx, fp0, fs);
6496 gen_store_fpr64(ctx, fp0, fd);
6497 tcg_temp_free_i64(fp0);
6498 }
6499 opn = "mov.d";
6500 break;
6501 case FOP(7, 17):
6502 check_cp1_registers(ctx, fs | fd);
6503 {
6504 TCGv_i64 fp0 = tcg_temp_new_i64();
6505
6506 gen_load_fpr64(ctx, fp0, fs);
6507 gen_helper_float_chs_d(fp0, fp0);
6508 gen_store_fpr64(ctx, fp0, fd);
6509 tcg_temp_free_i64(fp0);
6510 }
6511 opn = "neg.d";
6512 break;
6513 case FOP(8, 17):
6514 check_cp1_64bitmode(ctx);
6515 {
6516 TCGv_i64 fp0 = tcg_temp_new_i64();
6517
6518 gen_load_fpr64(ctx, fp0, fs);
6519 gen_helper_float_roundl_d(fp0, fp0);
6520 gen_store_fpr64(ctx, fp0, fd);
6521 tcg_temp_free_i64(fp0);
6522 }
6523 opn = "round.l.d";
6524 break;
6525 case FOP(9, 17):
6526 check_cp1_64bitmode(ctx);
6527 {
6528 TCGv_i64 fp0 = tcg_temp_new_i64();
6529
6530 gen_load_fpr64(ctx, fp0, fs);
6531 gen_helper_float_truncl_d(fp0, fp0);
6532 gen_store_fpr64(ctx, fp0, fd);
6533 tcg_temp_free_i64(fp0);
6534 }
6535 opn = "trunc.l.d";
6536 break;
6537 case FOP(10, 17):
6538 check_cp1_64bitmode(ctx);
6539 {
6540 TCGv_i64 fp0 = tcg_temp_new_i64();
6541
6542 gen_load_fpr64(ctx, fp0, fs);
6543 gen_helper_float_ceill_d(fp0, fp0);
6544 gen_store_fpr64(ctx, fp0, fd);
6545 tcg_temp_free_i64(fp0);
6546 }
6547 opn = "ceil.l.d";
6548 break;
6549 case FOP(11, 17):
6550 check_cp1_64bitmode(ctx);
6551 {
6552 TCGv_i64 fp0 = tcg_temp_new_i64();
6553
6554 gen_load_fpr64(ctx, fp0, fs);
6555 gen_helper_float_floorl_d(fp0, fp0);
6556 gen_store_fpr64(ctx, fp0, fd);
6557 tcg_temp_free_i64(fp0);
6558 }
6559 opn = "floor.l.d";
6560 break;
6561 case FOP(12, 17):
6562 check_cp1_registers(ctx, fs);
6563 {
6564 TCGv_i32 fp32 = tcg_temp_new_i32();
6565 TCGv_i64 fp64 = tcg_temp_new_i64();
6566
6567 gen_load_fpr64(ctx, fp64, fs);
6568 gen_helper_float_roundw_d(fp32, fp64);
6569 tcg_temp_free_i64(fp64);
6570 gen_store_fpr32(fp32, fd);
6571 tcg_temp_free_i32(fp32);
6572 }
6573 opn = "round.w.d";
6574 break;
6575 case FOP(13, 17):
6576 check_cp1_registers(ctx, fs);
6577 {
6578 TCGv_i32 fp32 = tcg_temp_new_i32();
6579 TCGv_i64 fp64 = tcg_temp_new_i64();
6580
6581 gen_load_fpr64(ctx, fp64, fs);
6582 gen_helper_float_truncw_d(fp32, fp64);
6583 tcg_temp_free_i64(fp64);
6584 gen_store_fpr32(fp32, fd);
6585 tcg_temp_free_i32(fp32);
6586 }
6587 opn = "trunc.w.d";
6588 break;
6589 case FOP(14, 17):
6590 check_cp1_registers(ctx, fs);
6591 {
6592 TCGv_i32 fp32 = tcg_temp_new_i32();
6593 TCGv_i64 fp64 = tcg_temp_new_i64();
6594
6595 gen_load_fpr64(ctx, fp64, fs);
6596 gen_helper_float_ceilw_d(fp32, fp64);
6597 tcg_temp_free_i64(fp64);
6598 gen_store_fpr32(fp32, fd);
6599 tcg_temp_free_i32(fp32);
6600 }
6601 opn = "ceil.w.d";
6602 break;
6603 case FOP(15, 17):
6604 check_cp1_registers(ctx, fs);
6605 {
6606 TCGv_i32 fp32 = tcg_temp_new_i32();
6607 TCGv_i64 fp64 = tcg_temp_new_i64();
6608
6609 gen_load_fpr64(ctx, fp64, fs);
6610 gen_helper_float_floorw_d(fp32, fp64);
6611 tcg_temp_free_i64(fp64);
6612 gen_store_fpr32(fp32, fd);
6613 tcg_temp_free_i32(fp32);
6614 }
6615 opn = "floor.w.d";
6616 break;
6617 case FOP(17, 17):
6618 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6619 opn = "movcf.d";
6620 break;
6621 case FOP(18, 17):
6622 {
6623 int l1 = gen_new_label();
6624 TCGv_i64 fp0;
6625
6626 if (ft != 0) {
6627 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6628 }
6629 fp0 = tcg_temp_new_i64();
6630 gen_load_fpr64(ctx, fp0, fs);
6631 gen_store_fpr64(ctx, fp0, fd);
6632 tcg_temp_free_i64(fp0);
6633 gen_set_label(l1);
6634 }
6635 opn = "movz.d";
6636 break;
6637 case FOP(19, 17):
6638 {
6639 int l1 = gen_new_label();
6640 TCGv_i64 fp0;
6641
6642 if (ft != 0) {
6643 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6644 fp0 = tcg_temp_new_i64();
6645 gen_load_fpr64(ctx, fp0, fs);
6646 gen_store_fpr64(ctx, fp0, fd);
6647 tcg_temp_free_i64(fp0);
6648 gen_set_label(l1);
6649 }
6650 }
6651 opn = "movn.d";
6652 break;
6653 case FOP(21, 17):
6654 check_cp1_64bitmode(ctx);
6655 {
6656 TCGv_i64 fp0 = tcg_temp_new_i64();
6657
6658 gen_load_fpr64(ctx, fp0, fs);
6659 gen_helper_float_recip_d(fp0, fp0);
6660 gen_store_fpr64(ctx, fp0, fd);
6661 tcg_temp_free_i64(fp0);
6662 }
6663 opn = "recip.d";
6664 break;
6665 case FOP(22, 17):
6666 check_cp1_64bitmode(ctx);
6667 {
6668 TCGv_i64 fp0 = tcg_temp_new_i64();
6669
6670 gen_load_fpr64(ctx, fp0, fs);
6671 gen_helper_float_rsqrt_d(fp0, fp0);
6672 gen_store_fpr64(ctx, fp0, fd);
6673 tcg_temp_free_i64(fp0);
6674 }
6675 opn = "rsqrt.d";
6676 break;
6677 case FOP(28, 17):
6678 check_cp1_64bitmode(ctx);
6679 {
6680 TCGv_i64 fp0 = tcg_temp_new_i64();
6681 TCGv_i64 fp1 = tcg_temp_new_i64();
6682
6683 gen_load_fpr64(ctx, fp0, fs);
6684 gen_load_fpr64(ctx, fp1, ft);
6685 gen_helper_float_recip2_d(fp0, fp0, fp1);
6686 tcg_temp_free_i64(fp1);
6687 gen_store_fpr64(ctx, fp0, fd);
6688 tcg_temp_free_i64(fp0);
6689 }
6690 opn = "recip2.d";
6691 break;
6692 case FOP(29, 17):
6693 check_cp1_64bitmode(ctx);
6694 {
6695 TCGv_i64 fp0 = tcg_temp_new_i64();
6696
6697 gen_load_fpr64(ctx, fp0, fs);
6698 gen_helper_float_recip1_d(fp0, fp0);
6699 gen_store_fpr64(ctx, fp0, fd);
6700 tcg_temp_free_i64(fp0);
6701 }
6702 opn = "recip1.d";
6703 break;
6704 case FOP(30, 17):
6705 check_cp1_64bitmode(ctx);
6706 {
6707 TCGv_i64 fp0 = tcg_temp_new_i64();
6708
6709 gen_load_fpr64(ctx, fp0, fs);
6710 gen_helper_float_rsqrt1_d(fp0, fp0);
6711 gen_store_fpr64(ctx, fp0, fd);
6712 tcg_temp_free_i64(fp0);
6713 }
6714 opn = "rsqrt1.d";
6715 break;
6716 case FOP(31, 17):
6717 check_cp1_64bitmode(ctx);
6718 {
6719 TCGv_i64 fp0 = tcg_temp_new_i64();
6720 TCGv_i64 fp1 = tcg_temp_new_i64();
6721
6722 gen_load_fpr64(ctx, fp0, fs);
6723 gen_load_fpr64(ctx, fp1, ft);
6724 gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6725 tcg_temp_free_i64(fp1);
6726 gen_store_fpr64(ctx, fp0, fd);
6727 tcg_temp_free_i64(fp0);
6728 }
6729 opn = "rsqrt2.d";
6730 break;
6731 case FOP(48, 17):
6732 case FOP(49, 17):
6733 case FOP(50, 17):
6734 case FOP(51, 17):
6735 case FOP(52, 17):
6736 case FOP(53, 17):
6737 case FOP(54, 17):
6738 case FOP(55, 17):
6739 case FOP(56, 17):
6740 case FOP(57, 17):
6741 case FOP(58, 17):
6742 case FOP(59, 17):
6743 case FOP(60, 17):
6744 case FOP(61, 17):
6745 case FOP(62, 17):
6746 case FOP(63, 17):
6747 {
6748 TCGv_i64 fp0 = tcg_temp_new_i64();
6749 TCGv_i64 fp1 = tcg_temp_new_i64();
6750 if (ctx->opcode & (1 << 6)) {
6751 check_cop1x(ctx);
6752 }
6753 check_cp1_registers(ctx, fs | ft);
6754
6755 gen_load_fpr64(ctx, fp0, fs);
6756 gen_load_fpr64(ctx, fp1, ft);
6757 if (ctx->opcode & (1 << 6)) {
6758 gen_cmpabs_d(func-48, fp0, fp1, cc);
6759 opn = condnames_abs[func-48];
6760 } else {
6761 gen_cmp_d(func-48, fp0, fp1, cc);
6762 opn = condnames[func-48];
6763 }
6764 tcg_temp_free_i64(fp0);
6765 tcg_temp_free_i64(fp1);
6766 }
6767 break;
6768 case FOP(32, 17):
6769 check_cp1_registers(ctx, fs);
6770 {
6771 TCGv_i32 fp32 = tcg_temp_new_i32();
6772 TCGv_i64 fp64 = tcg_temp_new_i64();
6773
6774 gen_load_fpr64(ctx, fp64, fs);
6775 gen_helper_float_cvts_d(fp32, fp64);
6776 tcg_temp_free_i64(fp64);
6777 gen_store_fpr32(fp32, fd);
6778 tcg_temp_free_i32(fp32);
6779 }
6780 opn = "cvt.s.d";
6781 break;
6782 case FOP(36, 17):
6783 check_cp1_registers(ctx, fs);
6784 {
6785 TCGv_i32 fp32 = tcg_temp_new_i32();
6786 TCGv_i64 fp64 = tcg_temp_new_i64();
6787
6788 gen_load_fpr64(ctx, fp64, fs);
6789 gen_helper_float_cvtw_d(fp32, fp64);
6790 tcg_temp_free_i64(fp64);
6791 gen_store_fpr32(fp32, fd);
6792 tcg_temp_free_i32(fp32);
6793 }
6794 opn = "cvt.w.d";
6795 break;
6796 case FOP(37, 17):
6797 check_cp1_64bitmode(ctx);
6798 {
6799 TCGv_i64 fp0 = tcg_temp_new_i64();
6800
6801 gen_load_fpr64(ctx, fp0, fs);
6802 gen_helper_float_cvtl_d(fp0, fp0);
6803 gen_store_fpr64(ctx, fp0, fd);
6804 tcg_temp_free_i64(fp0);
6805 }
6806 opn = "cvt.l.d";
6807 break;
6808 case FOP(32, 20):
6809 {
6810 TCGv_i32 fp0 = tcg_temp_new_i32();
6811
6812 gen_load_fpr32(fp0, fs);
6813 gen_helper_float_cvts_w(fp0, fp0);
6814 gen_store_fpr32(fp0, fd);
6815 tcg_temp_free_i32(fp0);
6816 }
6817 opn = "cvt.s.w";
6818 break;
6819 case FOP(33, 20):
6820 check_cp1_registers(ctx, fd);
6821 {
6822 TCGv_i32 fp32 = tcg_temp_new_i32();
6823 TCGv_i64 fp64 = tcg_temp_new_i64();
6824
6825 gen_load_fpr32(fp32, fs);
6826 gen_helper_float_cvtd_w(fp64, fp32);
6827 tcg_temp_free_i32(fp32);
6828 gen_store_fpr64(ctx, fp64, fd);
6829 tcg_temp_free_i64(fp64);
6830 }
6831 opn = "cvt.d.w";
6832 break;
6833 case FOP(32, 21):
6834 check_cp1_64bitmode(ctx);
6835 {
6836 TCGv_i32 fp32 = tcg_temp_new_i32();
6837 TCGv_i64 fp64 = tcg_temp_new_i64();
6838
6839 gen_load_fpr64(ctx, fp64, fs);
6840 gen_helper_float_cvts_l(fp32, fp64);
6841 tcg_temp_free_i64(fp64);
6842 gen_store_fpr32(fp32, fd);
6843 tcg_temp_free_i32(fp32);
6844 }
6845 opn = "cvt.s.l";
6846 break;
6847 case FOP(33, 21):
6848 check_cp1_64bitmode(ctx);
6849 {
6850 TCGv_i64 fp0 = tcg_temp_new_i64();
6851
6852 gen_load_fpr64(ctx, fp0, fs);
6853 gen_helper_float_cvtd_l(fp0, fp0);
6854 gen_store_fpr64(ctx, fp0, fd);
6855 tcg_temp_free_i64(fp0);
6856 }
6857 opn = "cvt.d.l";
6858 break;
6859 case FOP(38, 20):
6860 check_cp1_64bitmode(ctx);
6861 {
6862 TCGv_i64 fp0 = tcg_temp_new_i64();
6863
6864 gen_load_fpr64(ctx, fp0, fs);
6865 gen_helper_float_cvtps_pw(fp0, fp0);
6866 gen_store_fpr64(ctx, fp0, fd);
6867 tcg_temp_free_i64(fp0);
6868 }
6869 opn = "cvt.ps.pw";
6870 break;
6871 case FOP(0, 22):
6872 check_cp1_64bitmode(ctx);
6873 {
6874 TCGv_i64 fp0 = tcg_temp_new_i64();
6875 TCGv_i64 fp1 = tcg_temp_new_i64();
6876
6877 gen_load_fpr64(ctx, fp0, fs);
6878 gen_load_fpr64(ctx, fp1, ft);
6879 gen_helper_float_add_ps(fp0, fp0, fp1);
6880 tcg_temp_free_i64(fp1);
6881 gen_store_fpr64(ctx, fp0, fd);
6882 tcg_temp_free_i64(fp0);
6883 }
6884 opn = "add.ps";
6885 break;
6886 case FOP(1, 22):
6887 check_cp1_64bitmode(ctx);
6888 {
6889 TCGv_i64 fp0 = tcg_temp_new_i64();
6890 TCGv_i64 fp1 = tcg_temp_new_i64();
6891
6892 gen_load_fpr64(ctx, fp0, fs);
6893 gen_load_fpr64(ctx, fp1, ft);
6894 gen_helper_float_sub_ps(fp0, fp0, fp1);
6895 tcg_temp_free_i64(fp1);
6896 gen_store_fpr64(ctx, fp0, fd);
6897 tcg_temp_free_i64(fp0);
6898 }
6899 opn = "sub.ps";
6900 break;
6901 case FOP(2, 22):
6902 check_cp1_64bitmode(ctx);
6903 {
6904 TCGv_i64 fp0 = tcg_temp_new_i64();
6905 TCGv_i64 fp1 = tcg_temp_new_i64();
6906
6907 gen_load_fpr64(ctx, fp0, fs);
6908 gen_load_fpr64(ctx, fp1, ft);
6909 gen_helper_float_mul_ps(fp0, fp0, fp1);
6910 tcg_temp_free_i64(fp1);
6911 gen_store_fpr64(ctx, fp0, fd);
6912 tcg_temp_free_i64(fp0);
6913 }
6914 opn = "mul.ps";
6915 break;
6916 case FOP(5, 22):
6917 check_cp1_64bitmode(ctx);
6918 {
6919 TCGv_i64 fp0 = tcg_temp_new_i64();
6920
6921 gen_load_fpr64(ctx, fp0, fs);
6922 gen_helper_float_abs_ps(fp0, fp0);
6923 gen_store_fpr64(ctx, fp0, fd);
6924 tcg_temp_free_i64(fp0);
6925 }
6926 opn = "abs.ps";
6927 break;
6928 case FOP(6, 22):
6929 check_cp1_64bitmode(ctx);
6930 {
6931 TCGv_i64 fp0 = tcg_temp_new_i64();
6932
6933 gen_load_fpr64(ctx, fp0, fs);
6934 gen_store_fpr64(ctx, fp0, fd);
6935 tcg_temp_free_i64(fp0);
6936 }
6937 opn = "mov.ps";
6938 break;
6939 case FOP(7, 22):
6940 check_cp1_64bitmode(ctx);
6941 {
6942 TCGv_i64 fp0 = tcg_temp_new_i64();
6943
6944 gen_load_fpr64(ctx, fp0, fs);
6945 gen_helper_float_chs_ps(fp0, fp0);
6946 gen_store_fpr64(ctx, fp0, fd);
6947 tcg_temp_free_i64(fp0);
6948 }
6949 opn = "neg.ps";
6950 break;
6951 case FOP(17, 22):
6952 check_cp1_64bitmode(ctx);
6953 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6954 opn = "movcf.ps";
6955 break;
6956 case FOP(18, 22):
6957 check_cp1_64bitmode(ctx);
6958 {
6959 int l1 = gen_new_label();
6960 TCGv_i64 fp0;
6961
6962 if (ft != 0)
6963 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6964 fp0 = tcg_temp_new_i64();
6965 gen_load_fpr64(ctx, fp0, fs);
6966 gen_store_fpr64(ctx, fp0, fd);
6967 tcg_temp_free_i64(fp0);
6968 gen_set_label(l1);
6969 }
6970 opn = "movz.ps";
6971 break;
6972 case FOP(19, 22):
6973 check_cp1_64bitmode(ctx);
6974 {
6975 int l1 = gen_new_label();
6976 TCGv_i64 fp0;
6977
6978 if (ft != 0) {
6979 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6980 fp0 = tcg_temp_new_i64();
6981 gen_load_fpr64(ctx, fp0, fs);
6982 gen_store_fpr64(ctx, fp0, fd);
6983 tcg_temp_free_i64(fp0);
6984 gen_set_label(l1);
6985 }
6986 }
6987 opn = "movn.ps";
6988 break;
6989 case FOP(24, 22):
6990 check_cp1_64bitmode(ctx);
6991 {
6992 TCGv_i64 fp0 = tcg_temp_new_i64();
6993 TCGv_i64 fp1 = tcg_temp_new_i64();
6994
6995 gen_load_fpr64(ctx, fp0, ft);
6996 gen_load_fpr64(ctx, fp1, fs);
6997 gen_helper_float_addr_ps(fp0, fp0, fp1);
6998 tcg_temp_free_i64(fp1);
6999 gen_store_fpr64(ctx, fp0, fd);
7000 tcg_temp_free_i64(fp0);
7001 }
7002 opn = "addr.ps";
7003 break;
7004 case FOP(26, 22):
7005 check_cp1_64bitmode(ctx);
7006 {
7007 TCGv_i64 fp0 = tcg_temp_new_i64();
7008 TCGv_i64 fp1 = tcg_temp_new_i64();
7009
7010 gen_load_fpr64(ctx, fp0, ft);
7011 gen_load_fpr64(ctx, fp1, fs);
7012 gen_helper_float_mulr_ps(fp0, fp0, fp1);
7013 tcg_temp_free_i64(fp1);
7014 gen_store_fpr64(ctx, fp0, fd);
7015 tcg_temp_free_i64(fp0);
7016 }
7017 opn = "mulr.ps";
7018 break;
7019 case FOP(28, 22):
7020 check_cp1_64bitmode(ctx);
7021 {
7022 TCGv_i64 fp0 = tcg_temp_new_i64();
7023 TCGv_i64 fp1 = tcg_temp_new_i64();
7024
7025 gen_load_fpr64(ctx, fp0, fs);
7026 gen_load_fpr64(ctx, fp1, fd);
7027 gen_helper_float_recip2_ps(fp0, fp0, fp1);
7028 tcg_temp_free_i64(fp1);
7029 gen_store_fpr64(ctx, fp0, fd);
7030 tcg_temp_free_i64(fp0);
7031 }
7032 opn = "recip2.ps";
7033 break;
7034 case FOP(29, 22):
7035 check_cp1_64bitmode(ctx);
7036 {
7037 TCGv_i64 fp0 = tcg_temp_new_i64();
7038
7039 gen_load_fpr64(ctx, fp0, fs);
7040 gen_helper_float_recip1_ps(fp0, fp0);
7041 gen_store_fpr64(ctx, fp0, fd);
7042 tcg_temp_free_i64(fp0);
7043 }
7044 opn = "recip1.ps";
7045 break;
7046 case FOP(30, 22):
7047 check_cp1_64bitmode(ctx);
7048 {
7049 TCGv_i64 fp0 = tcg_temp_new_i64();
7050
7051 gen_load_fpr64(ctx, fp0, fs);
7052 gen_helper_float_rsqrt1_ps(fp0, fp0);
7053 gen_store_fpr64(ctx, fp0, fd);
7054 tcg_temp_free_i64(fp0);
7055 }
7056 opn = "rsqrt1.ps";
7057 break;
7058 case FOP(31, 22):
7059 check_cp1_64bitmode(ctx);
7060 {
7061 TCGv_i64 fp0 = tcg_temp_new_i64();
7062 TCGv_i64 fp1 = tcg_temp_new_i64();
7063
7064 gen_load_fpr64(ctx, fp0, fs);
7065 gen_load_fpr64(ctx, fp1, ft);
7066 gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7067 tcg_temp_free_i64(fp1);
7068 gen_store_fpr64(ctx, fp0, fd);
7069 tcg_temp_free_i64(fp0);
7070 }
7071 opn = "rsqrt2.ps";
7072 break;
7073 case FOP(32, 22):
7074 check_cp1_64bitmode(ctx);
7075 {
7076 TCGv_i32 fp0 = tcg_temp_new_i32();
7077
7078 gen_load_fpr32h(fp0, fs);
7079 gen_helper_float_cvts_pu(fp0, fp0);
7080 gen_store_fpr32(fp0, fd);
7081 tcg_temp_free_i32(fp0);
7082 }
7083 opn = "cvt.s.pu";
7084 break;
7085 case FOP(36, 22):
7086 check_cp1_64bitmode(ctx);
7087 {
7088 TCGv_i64 fp0 = tcg_temp_new_i64();
7089
7090 gen_load_fpr64(ctx, fp0, fs);
7091 gen_helper_float_cvtpw_ps(fp0, fp0);
7092 gen_store_fpr64(ctx, fp0, fd);
7093 tcg_temp_free_i64(fp0);
7094 }
7095 opn = "cvt.pw.ps";
7096 break;
7097 case FOP(40, 22):
7098 check_cp1_64bitmode(ctx);
7099 {
7100 TCGv_i32 fp0 = tcg_temp_new_i32();
7101
7102 gen_load_fpr32(fp0, fs);
7103 gen_helper_float_cvts_pl(fp0, fp0);
7104 gen_store_fpr32(fp0, fd);
7105 tcg_temp_free_i32(fp0);
7106 }
7107 opn = "cvt.s.pl";
7108 break;
7109 case FOP(44, 22):
7110 check_cp1_64bitmode(ctx);
7111 {
7112 TCGv_i32 fp0 = tcg_temp_new_i32();
7113 TCGv_i32 fp1 = tcg_temp_new_i32();
7114
7115 gen_load_fpr32(fp0, fs);
7116 gen_load_fpr32(fp1, ft);
7117 gen_store_fpr32h(fp0, fd);
7118 gen_store_fpr32(fp1, fd);
7119 tcg_temp_free_i32(fp0);
7120 tcg_temp_free_i32(fp1);
7121 }
7122 opn = "pll.ps";
7123 break;
7124 case FOP(45, 22):
7125 check_cp1_64bitmode(ctx);
7126 {
7127 TCGv_i32 fp0 = tcg_temp_new_i32();
7128 TCGv_i32 fp1 = tcg_temp_new_i32();
7129
7130 gen_load_fpr32(fp0, fs);
7131 gen_load_fpr32h(fp1, ft);
7132 gen_store_fpr32(fp1, fd);
7133 gen_store_fpr32h(fp0, fd);
7134 tcg_temp_free_i32(fp0);
7135 tcg_temp_free_i32(fp1);
7136 }
7137 opn = "plu.ps";
7138 break;
7139 case FOP(46, 22):
7140 check_cp1_64bitmode(ctx);
7141 {
7142 TCGv_i32 fp0 = tcg_temp_new_i32();
7143 TCGv_i32 fp1 = tcg_temp_new_i32();
7144
7145 gen_load_fpr32h(fp0, fs);
7146 gen_load_fpr32(fp1, ft);
7147 gen_store_fpr32(fp1, fd);
7148 gen_store_fpr32h(fp0, fd);
7149 tcg_temp_free_i32(fp0);
7150 tcg_temp_free_i32(fp1);
7151 }
7152 opn = "pul.ps";
7153 break;
7154 case FOP(47, 22):
7155 check_cp1_64bitmode(ctx);
7156 {
7157 TCGv_i32 fp0 = tcg_temp_new_i32();
7158 TCGv_i32 fp1 = tcg_temp_new_i32();
7159
7160 gen_load_fpr32h(fp0, fs);
7161 gen_load_fpr32h(fp1, ft);
7162 gen_store_fpr32(fp1, fd);
7163 gen_store_fpr32h(fp0, fd);
7164 tcg_temp_free_i32(fp0);
7165 tcg_temp_free_i32(fp1);
7166 }
7167 opn = "puu.ps";
7168 break;
7169 case FOP(48, 22):
7170 case FOP(49, 22):
7171 case FOP(50, 22):
7172 case FOP(51, 22):
7173 case FOP(52, 22):
7174 case FOP(53, 22):
7175 case FOP(54, 22):
7176 case FOP(55, 22):
7177 case FOP(56, 22):
7178 case FOP(57, 22):
7179 case FOP(58, 22):
7180 case FOP(59, 22):
7181 case FOP(60, 22):
7182 case FOP(61, 22):
7183 case FOP(62, 22):
7184 case FOP(63, 22):
7185 check_cp1_64bitmode(ctx);
7186 {
7187 TCGv_i64 fp0 = tcg_temp_new_i64();
7188 TCGv_i64 fp1 = tcg_temp_new_i64();
7189
7190 gen_load_fpr64(ctx, fp0, fs);
7191 gen_load_fpr64(ctx, fp1, ft);
7192 if (ctx->opcode & (1 << 6)) {
7193 gen_cmpabs_ps(func-48, fp0, fp1, cc);
7194 opn = condnames_abs[func-48];
7195 } else {
7196 gen_cmp_ps(func-48, fp0, fp1, cc);
7197 opn = condnames[func-48];
7198 }
7199 tcg_temp_free_i64(fp0);
7200 tcg_temp_free_i64(fp1);
7201 }
7202 break;
7203 default:
7204 MIPS_INVAL(opn);
7205 generate_exception (ctx, EXCP_RI);
7206 return;
7207 }
7208 switch (optype) {
7209 case BINOP:
7210 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7211 break;
7212 case CMPOP:
7213 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7214 break;
7215 default:
7216 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7217 break;
7218 }
7219 }
7220
7221 /* Coprocessor 3 (FPU) */
7222 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7223 int fd, int fs, int base, int index)
7224 {
7225 const char *opn = "extended float load/store";
7226 int store = 0;
7227 TCGv t0 = tcg_temp_new();
7228
7229 switch (opc) {
7230 case OPC_LWXC1:
7231 case OPC_SWXC1:
7232 check_cop1x(ctx);
7233 break;
7234 case OPC_LDXC1:
7235 case OPC_SDXC1:
7236 check_cop1x(ctx);
7237 check_cp1_registers(ctx, fd);
7238 break;
7239 case OPC_LUXC1:
7240 case OPC_SUXC1:
7241 check_cp1_64bitmode(ctx);
7242 break;
7243 }
7244
7245 if (base == 0) {
7246 gen_load_gpr(t0, index);
7247 } else if (index == 0) {
7248 gen_load_gpr(t0, base);
7249 } else {
7250 gen_load_gpr(t0, index);
7251 gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7252 }
7253 /* Don't do NOP if destination is zero: we must perform the actual
7254 memory access. */
7255 save_cpu_state(ctx, 0);
7256 switch (opc) {
7257 case OPC_LWXC1:
7258 {
7259 TCGv_i32 fp0 = tcg_temp_new_i32();
7260
7261 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7262 tcg_gen_trunc_tl_i32(fp0, t0);
7263 gen_store_fpr32(fp0, fd);
7264 tcg_temp_free_i32(fp0);
7265 }
7266 opn = "lwxc1";
7267 break;
7268 case OPC_LDXC1:
7269 {
7270 TCGv_i64 fp0 = tcg_temp_new_i64();
7271
7272 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7273 gen_store_fpr64(ctx, fp0, fd);
7274 tcg_temp_free_i64(fp0);
7275 }
7276 opn = "ldxc1";
7277 break;
7278 case OPC_LUXC1:
7279 tcg_gen_andi_tl(t0, t0, ~0x7);
7280 {
7281 TCGv_i64 fp0 = tcg_temp_new_i64();
7282
7283 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7284 gen_store_fpr64(ctx, fp0, fd);
7285 tcg_temp_free_i64(fp0);
7286 }
7287 opn = "luxc1";
7288 break;
7289 case OPC_SWXC1:
7290 {
7291 TCGv_i32 fp0 = tcg_temp_new_i32();
7292 TCGv t1 = tcg_temp_new();
7293
7294 gen_load_fpr32(fp0, fs);
7295 tcg_gen_extu_i32_tl(t1, fp0);
7296 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7297 tcg_temp_free_i32(fp0);
7298 tcg_temp_free_i32(t1);
7299 }
7300 opn = "swxc1";
7301 store = 1;
7302 break;
7303 case OPC_SDXC1:
7304 {
7305 TCGv_i64 fp0 = tcg_temp_new_i64();
7306
7307 gen_load_fpr64(ctx, fp0, fs);
7308 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7309 tcg_temp_free_i64(fp0);
7310 }
7311 opn = "sdxc1";
7312 store = 1;
7313 break;
7314 case OPC_SUXC1:
7315 tcg_gen_andi_tl(t0, t0, ~0x7);
7316 {
7317 TCGv_i64 fp0 = tcg_temp_new_i64();
7318
7319 gen_load_fpr64(ctx, fp0, fs);
7320 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7321 tcg_temp_free_i64(fp0);
7322 }
7323 opn = "suxc1";
7324 store = 1;
7325 break;
7326 }
7327 tcg_temp_free(t0);
7328 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7329 regnames[index], regnames[base]);
7330 }
7331
7332 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7333 int fd, int fr, int fs, int ft)
7334 {
7335 const char *opn = "flt3_arith";
7336
7337 switch (opc) {
7338 case OPC_ALNV_PS:
7339 check_cp1_64bitmode(ctx);
7340 {
7341 TCGv t0 = tcg_temp_local_new();
7342 TCGv_i32 fp = tcg_temp_new_i32();
7343 TCGv_i32 fph = tcg_temp_new_i32();
7344 int l1 = gen_new_label();
7345 int l2 = gen_new_label();
7346
7347 gen_load_gpr(t0, fr);
7348 tcg_gen_andi_tl(t0, t0, 0x7);
7349
7350 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7351 gen_load_fpr32(fp, fs);
7352 gen_load_fpr32h(fph, fs);
7353 gen_store_fpr32(fp, fd);
7354 gen_store_fpr32h(fph, fd);
7355 tcg_gen_br(l2);
7356 gen_set_label(l1);
7357 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7358 tcg_temp_free(t0);
7359 #ifdef TARGET_WORDS_BIGENDIAN
7360 gen_load_fpr32(fp, fs);
7361 gen_load_fpr32h(fph, ft);
7362 gen_store_fpr32h(fp, fd);
7363 gen_store_fpr32(fph, fd);
7364 #else
7365 gen_load_fpr32h(fph, fs);
7366 gen_load_fpr32(fp, ft);
7367 gen_store_fpr32(fph, fd);
7368 gen_store_fpr32h(fp, fd);
7369 #endif
7370 gen_set_label(l2);
7371 tcg_temp_free_i32(fp);
7372 tcg_temp_free_i32(fph);
7373 }
7374 opn = "alnv.ps";
7375 break;
7376 case OPC_MADD_S:
7377 check_cop1x(ctx);
7378 {
7379 TCGv_i32 fp0 = tcg_temp_new_i32();
7380 TCGv_i32 fp1 = tcg_temp_new_i32();
7381 TCGv_i32 fp2 = tcg_temp_new_i32();
7382
7383 gen_load_fpr32(fp0, fs);
7384 gen_load_fpr32(fp1, ft);
7385 gen_load_fpr32(fp2, fr);
7386 gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7387 tcg_temp_free_i32(fp0);
7388 tcg_temp_free_i32(fp1);
7389 gen_store_fpr32(fp2, fd);
7390 tcg_temp_free_i32(fp2);
7391 }
7392 opn = "madd.s";
7393 break;
7394 case OPC_MADD_D:
7395 check_cop1x(ctx);
7396 check_cp1_registers(ctx, fd | fs | ft | fr);
7397 {
7398 TCGv_i64 fp0 = tcg_temp_new_i64();
7399 TCGv_i64 fp1 = tcg_temp_new_i64();
7400 TCGv_i64 fp2 = tcg_temp_new_i64();
7401
7402 gen_load_fpr64(ctx, fp0, fs);
7403 gen_load_fpr64(ctx, fp1, ft);
7404 gen_load_fpr64(ctx, fp2, fr);
7405 gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7406 tcg_temp_free_i64(fp0);
7407 tcg_temp_free_i64(fp1);
7408 gen_store_fpr64(ctx, fp2, fd);
7409 tcg_temp_free_i64(fp2);
7410 }
7411 opn = "madd.d";
7412 break;
7413 case OPC_MADD_PS:
7414 check_cp1_64bitmode(ctx);
7415 {
7416 TCGv_i64 fp0 = tcg_temp_new_i64();
7417 TCGv_i64 fp1 = tcg_temp_new_i64();
7418 TCGv_i64 fp2 = tcg_temp_new_i64();
7419
7420 gen_load_fpr64(ctx, fp0, fs);
7421 gen_load_fpr64(ctx, fp1, ft);
7422 gen_load_fpr64(ctx, fp2, fr);
7423 gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7424 tcg_temp_free_i64(fp0);
7425 tcg_temp_free_i64(fp1);
7426 gen_store_fpr64(ctx, fp2, fd);
7427 tcg_temp_free_i64(fp2);
7428 }
7429 opn = "madd.ps";
7430 break;
7431 case OPC_MSUB_S:
7432 check_cop1x(ctx);
7433 {
7434 TCGv_i32 fp0 = tcg_temp_new_i32();
7435 TCGv_i32 fp1 = tcg_temp_new_i32();
7436 TCGv_i32 fp2 = tcg_temp_new_i32();
7437
7438 gen_load_fpr32(fp0, fs);
7439 gen_load_fpr32(fp1, ft);
7440 gen_load_fpr32(fp2, fr);
7441 gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7442 tcg_temp_free_i32(fp0);
7443 tcg_temp_free_i32(fp1);
7444 gen_store_fpr32(fp2, fd);
7445 tcg_temp_free_i32(fp2);
7446 }
7447 opn = "msub.s";
7448 break;
7449 case OPC_MSUB_D:
7450 check_cop1x(ctx);
7451 check_cp1_registers(ctx, fd | fs | ft | fr);
7452 {
7453 TCGv_i64 fp0 = tcg_temp_new_i64();
7454 TCGv_i64 fp1 = tcg_temp_new_i64();
7455 TCGv_i64 fp2 = tcg_temp_new_i64();
7456
7457 gen_load_fpr64(ctx, fp0, fs);
7458 gen_load_fpr64(ctx, fp1, ft);
7459 gen_load_fpr64(ctx, fp2, fr);
7460 gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7461 tcg_temp_free_i64(fp0);
7462 tcg_temp_free_i64(fp1);
7463 gen_store_fpr64(ctx, fp2, fd);
7464 tcg_temp_free_i64(fp2);
7465 }
7466 opn = "msub.d";
7467 break;
7468 case OPC_MSUB_PS:
7469 check_cp1_64bitmode(ctx);
7470 {
7471 TCGv_i64 fp0 = tcg_temp_new_i64();
7472 TCGv_i64 fp1 = tcg_temp_new_i64();
7473 TCGv_i64 fp2 = tcg_temp_new_i64();
7474
7475 gen_load_fpr64(ctx, fp0, fs);
7476 gen_load_fpr64(ctx, fp1, ft);
7477 gen_load_fpr64(ctx, fp2, fr);
7478 gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7479 tcg_temp_free_i64(fp0);
7480 tcg_temp_free_i64(fp1);
7481 gen_store_fpr64(ctx, fp2, fd);
7482 tcg_temp_free_i64(fp2);
7483 }
7484 opn = "msub.ps";
7485 break;
7486 case OPC_NMADD_S:
7487 check_cop1x(ctx);
7488 {
7489 TCGv_i32 fp0 = tcg_temp_new_i32();
7490 TCGv_i32 fp1 = tcg_temp_new_i32();
7491 TCGv_i32 fp2 = tcg_temp_new_i32();
7492
7493 gen_load_fpr32(fp0, fs);
7494 gen_load_fpr32(fp1, ft);
7495 gen_load_fpr32(fp2, fr);
7496 gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7497 tcg_temp_free_i32(fp0);
7498 tcg_temp_free_i32(fp1);
7499 gen_store_fpr32(fp2, fd);
7500 tcg_temp_free_i32(fp2);
7501 }
7502 opn = "nmadd.s";
7503 break;
7504 case OPC_NMADD_D:
7505 check_cop1x(ctx);
7506 check_cp1_registers(ctx, fd | fs | ft | fr);
7507 {
7508 TCGv_i64 fp0 = tcg_temp_new_i64();
7509 TCGv_i64 fp1 = tcg_temp_new_i64();
7510 TCGv_i64 fp2 = tcg_temp_new_i64();
7511
7512 gen_load_fpr64(ctx, fp0, fs);
7513 gen_load_fpr64(ctx, fp1, ft);
7514 gen_load_fpr64(ctx, fp2, fr);
7515 gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7516 tcg_temp_free_i64(fp0);
7517 tcg_temp_free_i64(fp1);
7518 gen_store_fpr64(ctx, fp2, fd);
7519 tcg_temp_free_i64(fp2);
7520 }
7521 opn = "nmadd.d";
7522 break;
7523 case OPC_NMADD_PS:
7524 check_cp1_64bitmode(ctx);
7525 {
7526 TCGv_i64 fp0 = tcg_temp_new_i64();
7527 TCGv_i64 fp1 = tcg_temp_new_i64();
7528 TCGv_i64 fp2 = tcg_temp_new_i64();
7529
7530 gen_load_fpr64(ctx, fp0, fs);
7531 gen_load_fpr64(ctx, fp1, ft);
7532 gen_load_fpr64(ctx, fp2, fr);
7533 gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7534 tcg_temp_free_i64(fp0);
7535 tcg_temp_free_i64(fp1);
7536 gen_store_fpr64(ctx, fp2, fd);
7537 tcg_temp_free_i64(fp2);
7538 }
7539 opn = "nmadd.ps";
7540 break;
7541 case OPC_NMSUB_S:
7542 check_cop1x(ctx);
7543 {
7544 TCGv_i32 fp0 = tcg_temp_new_i32();
7545 TCGv_i32 fp1 = tcg_temp_new_i32();
7546 TCGv_i32 fp2 = tcg_temp_new_i32();
7547
7548 gen_load_fpr32(fp0, fs);
7549 gen_load_fpr32(fp1, ft);
7550 gen_load_fpr32(fp2, fr);
7551 gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7552 tcg_temp_free_i32(fp0);
7553 tcg_temp_free_i32(fp1);
7554 gen_store_fpr32(fp2, fd);
7555 tcg_temp_free_i32(fp2);
7556 }
7557 opn = "nmsub.s";
7558 break;
7559 case OPC_NMSUB_D:
7560 check_cop1x(ctx);
7561 check_cp1_registers(ctx, fd | fs | ft | fr);
7562 {
7563 TCGv_i64 fp0 = tcg_temp_new_i64();
7564 TCGv_i64 fp1 = tcg_temp_new_i64();
7565 TCGv_i64 fp2 = tcg_temp_new_i64();
7566
7567 gen_load_fpr64(ctx, fp0, fs);
7568 gen_load_fpr64(ctx, fp1, ft);
7569 gen_load_fpr64(ctx, fp2, fr);
7570 gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7571 tcg_temp_free_i64(fp0);
7572 tcg_temp_free_i64(fp1);
7573 gen_store_fpr64(ctx, fp2, fd);
7574 tcg_temp_free_i64(fp2);
7575 }
7576 opn = "nmsub.d";
7577 break;
7578 case OPC_NMSUB_PS:
7579 check_cp1_64bitmode(ctx);
7580 {
7581 TCGv_i64 fp0 = tcg_temp_new_i64();
7582 TCGv_i64 fp1 = tcg_temp_new_i64();
7583 TCGv_i64 fp2 = tcg_temp_new_i64();
7584
7585 gen_load_fpr64(ctx, fp0, fs);
7586 gen_load_fpr64(ctx, fp1, ft);
7587 gen_load_fpr64(ctx, fp2, fr);
7588 gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7589 tcg_temp_free_i64(fp0);
7590 tcg_temp_free_i64(fp1);
7591 gen_store_fpr64(ctx, fp2, fd);
7592 tcg_temp_free_i64(fp2);
7593 }
7594 opn = "nmsub.ps";
7595 break;
7596 default:
7597 MIPS_INVAL(opn);
7598 generate_exception (ctx, EXCP_RI);
7599 return;
7600 }
7601 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7602 fregnames[fs], fregnames[ft]);
7603 }
7604
7605 /* ISA extensions (ASEs) */
7606 /* MIPS16 extension to MIPS32 */
7607 /* SmartMIPS extension to MIPS32 */
7608
7609 #if defined(TARGET_MIPS64)
7610
7611 /* MDMX extension to MIPS64 */
7612
7613 #endif
7614
7615 static void decode_opc (CPUState *env, DisasContext *ctx)
7616 {
7617 int32_t offset;
7618 int rs, rt, rd, sa;
7619 uint32_t op, op1, op2;
7620 int16_t imm;
7621
7622 /* make sure instructions are on a word boundary */
7623 if (ctx->pc & 0x3) {
7624 env->CP0_BadVAddr = ctx->pc;
7625 generate_exception(ctx, EXCP_AdEL);
7626 return;
7627 }
7628
7629 /* Handle blikely not taken case */
7630 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7631 int l1 = gen_new_label();
7632
7633 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7634 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7635 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7636 gen_goto_tb(ctx, 1, ctx->pc + 4);
7637 gen_set_label(l1);
7638 }
7639 op = MASK_OP_MAJOR(ctx->opcode);
7640 rs = (ctx->opcode >> 21) & 0x1f;
7641 rt = (ctx->opcode >> 16) & 0x1f;
7642 rd = (ctx->opcode >> 11) & 0x1f;
7643 sa = (ctx->opcode >> 6) & 0x1f;
7644 imm = (int16_t)ctx->opcode;
7645 switch (op) {
7646 case OPC_SPECIAL:
7647 op1 = MASK_SPECIAL(ctx->opcode);
7648 switch (op1) {
7649 case OPC_SLL: /* Shift with immediate */
7650 case OPC_SRA:
7651 case OPC_SRL:
7652 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7653 break;
7654 case OPC_MOVN: /* Conditional move */
7655 case OPC_MOVZ:
7656 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7657 gen_cond_move(env, op1, rd, rs, rt);
7658 break;
7659 case OPC_ADD ... OPC_SUBU:
7660 gen_arith(env, ctx, op1, rd, rs, rt);
7661 break;
7662 case OPC_SLLV: /* Shifts */
7663 case OPC_SRLV:
7664 case OPC_SRAV:
7665 gen_shift(env, ctx, op1, rd, rs, rt);
7666 break;
7667 case OPC_SLT: /* Set on less than */
7668 case OPC_SLTU:
7669 gen_slt(env, op1, rd, rs, rt);
7670 break;
7671 case OPC_AND: /* Logic*/
7672 case OPC_OR:
7673 case OPC_NOR:
7674 case OPC_XOR:
7675 gen_logic(env, op1, rd, rs, rt);
7676 break;
7677 case OPC_MULT ... OPC_DIVU:
7678 if (sa) {
7679 check_insn(env, ctx, INSN_VR54XX);
7680 op1 = MASK_MUL_VR54XX(ctx->opcode);
7681 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7682 } else
7683 gen_muldiv(ctx, op1, rs, rt);
7684 break;
7685 case OPC_JR ... OPC_JALR:
7686 gen_compute_branch(ctx, op1, rs, rd, sa);
7687 return;
7688 case OPC_TGE ... OPC_TEQ: /* Traps */
7689 case OPC_TNE:
7690 gen_trap(ctx, op1, rs, rt, -1);
7691 break;
7692 case OPC_MFHI: /* Move from HI/LO */
7693 case OPC_MFLO:
7694 gen_HILO(ctx, op1, rd);
7695 break;
7696 case OPC_MTHI:
7697 case OPC_MTLO: /* Move to HI/LO */
7698 gen_HILO(ctx, op1, rs);
7699 break;
7700 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
7701 #ifdef MIPS_STRICT_STANDARD
7702 MIPS_INVAL("PMON / selsl");
7703 generate_exception(ctx, EXCP_RI);
7704 #else
7705 gen_helper_0i(pmon, sa);
7706 #endif
7707 break;
7708 case OPC_SYSCALL:
7709 generate_exception(ctx, EXCP_SYSCALL);
7710 ctx->bstate = BS_STOP;
7711 break;
7712 case OPC_BREAK:
7713 generate_exception(ctx, EXCP_BREAK);
7714 break;
7715 case OPC_SPIM:
7716 #ifdef MIPS_STRICT_STANDARD
7717 MIPS_INVAL("SPIM");
7718 generate_exception(ctx, EXCP_RI);
7719 #else
7720 /* Implemented as RI exception for now. */
7721 MIPS_INVAL("spim (unofficial)");
7722 generate_exception(ctx, EXCP_RI);
7723 #endif
7724 break;
7725 case OPC_SYNC:
7726 /* Treat as NOP. */
7727 break;
7728
7729 case OPC_MOVCI:
7730 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7731 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7732 check_cp1_enabled(ctx);
7733 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7734 (ctx->opcode >> 16) & 1);
7735 } else {
7736 generate_exception_err(ctx, EXCP_CpU, 1);
7737 }
7738 break;
7739
7740 #if defined(TARGET_MIPS64)
7741 /* MIPS64 specific opcodes */
7742 case OPC_DSLL:
7743 case OPC_DSRA:
7744 case OPC_DSRL:
7745 case OPC_DSLL32:
7746 case OPC_DSRA32:
7747 case OPC_DSRL32:
7748 check_insn(env, ctx, ISA_MIPS3);
7749 check_mips_64(ctx);
7750 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7751 break;
7752 case OPC_DADD ... OPC_DSUBU:
7753 check_insn(env, ctx, ISA_MIPS3);
7754 check_mips_64(ctx);
7755 gen_arith(env, ctx, op1, rd, rs, rt);
7756 break;
7757 case OPC_DSLLV:
7758 case OPC_DSRAV:
7759 case OPC_DSRLV:
7760 check_insn(env, ctx, ISA_MIPS3);
7761 check_mips_64(ctx);
7762 gen_shift(env, ctx, op1, rd, rs, rt);
7763 break;
7764 case OPC_DMULT ... OPC_DDIVU:
7765 check_insn(env, ctx, ISA_MIPS3);
7766 check_mips_64(ctx);
7767 gen_muldiv(ctx, op1, rs, rt);
7768 break;
7769 #endif
7770 default: /* Invalid */
7771 MIPS_INVAL("special");
7772 generate_exception(ctx, EXCP_RI);
7773 break;
7774 }
7775 break;
7776 case OPC_SPECIAL2:
7777 op1 = MASK_SPECIAL2(ctx->opcode);
7778 switch (op1) {
7779 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7780 case OPC_MSUB ... OPC_MSUBU:
7781 check_insn(env, ctx, ISA_MIPS32);
7782 gen_muldiv(ctx, op1, rs, rt);
7783 break;
7784 case OPC_MUL:
7785 gen_arith(env, ctx, op1, rd, rs, rt);
7786 break;
7787 case OPC_CLO:
7788 case OPC_CLZ:
7789 check_insn(env, ctx, ISA_MIPS32);
7790 gen_cl(ctx, op1, rd, rs);
7791 break;
7792 case OPC_SDBBP:
7793 /* XXX: not clear which exception should be raised
7794 * when in debug mode...
7795 */
7796 check_insn(env, ctx, ISA_MIPS32);
7797 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7798 generate_exception(ctx, EXCP_DBp);
7799 } else {
7800 generate_exception(ctx, EXCP_DBp);
7801 }
7802 /* Treat as NOP. */
7803 break;
7804 #if defined(TARGET_MIPS64)
7805 case OPC_DCLO:
7806 case OPC_DCLZ:
7807 check_insn(env, ctx, ISA_MIPS64);
7808 check_mips_64(ctx);
7809 gen_cl(ctx, op1, rd, rs);
7810 break;
7811 #endif
7812 default: /* Invalid */
7813 MIPS_INVAL("special2");
7814 generate_exception(ctx, EXCP_RI);
7815 break;
7816 }
7817 break;
7818 case OPC_SPECIAL3:
7819 op1 = MASK_SPECIAL3(ctx->opcode);
7820 switch (op1) {
7821 case OPC_EXT:
7822 case OPC_INS:
7823 check_insn(env, ctx, ISA_MIPS32R2);
7824 gen_bitops(ctx, op1, rt, rs, sa, rd);
7825 break;
7826 case OPC_BSHFL:
7827 check_insn(env, ctx, ISA_MIPS32R2);
7828 op2 = MASK_BSHFL(ctx->opcode);
7829 gen_bshfl(ctx, op2, rt, rd);
7830 break;
7831 case OPC_RDHWR:
7832 check_insn(env, ctx, ISA_MIPS32R2);
7833 {
7834 TCGv t0 = tcg_temp_new();
7835
7836 switch (rd) {
7837 case 0:
7838 save_cpu_state(ctx, 1);
7839 gen_helper_rdhwr_cpunum(t0);
7840 gen_store_gpr(t0, rt);
7841 break;
7842 case 1:
7843 save_cpu_state(ctx, 1);
7844 gen_helper_rdhwr_synci_step(t0);
7845 gen_store_gpr(t0, rt);
7846 break;
7847 case 2:
7848 save_cpu_state(ctx, 1);
7849 gen_helper_rdhwr_cc(t0);
7850 gen_store_gpr(t0, rt);
7851 break;
7852 case 3:
7853 save_cpu_state(ctx, 1);
7854 gen_helper_rdhwr_ccres(t0);
7855 gen_store_gpr(t0, rt);
7856 break;
7857 case 29:
7858 #if defined(CONFIG_USER_ONLY)
7859 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7860 gen_store_gpr(t0, rt);
7861 break;
7862 #else
7863 /* XXX: Some CPUs implement this in hardware.
7864 Not supported yet. */
7865 #endif
7866 default: /* Invalid */
7867 MIPS_INVAL("rdhwr");
7868 generate_exception(ctx, EXCP_RI);
7869 break;
7870 }
7871 tcg_temp_free(t0);
7872 }
7873 break;
7874 case OPC_FORK:
7875 check_insn(env, ctx, ASE_MT);
7876 {
7877 TCGv t0 = tcg_temp_new();
7878 TCGv t1 = tcg_temp_new();
7879
7880 gen_load_gpr(t0, rt);
7881 gen_load_gpr(t1, rs);
7882 gen_helper_fork(t0, t1);
7883 tcg_temp_free(t0);
7884 tcg_temp_free(t1);
7885 }
7886 break;
7887 case OPC_YIELD:
7888 check_insn(env, ctx, ASE_MT);
7889 {
7890 TCGv t0 = tcg_temp_new();
7891
7892 save_cpu_state(ctx, 1);
7893 gen_load_gpr(t0, rs);
7894 gen_helper_yield(t0, t0);
7895 gen_store_gpr(t0, rd);
7896 tcg_temp_free(t0);
7897 }
7898 break;
7899 #if defined(TARGET_MIPS64)
7900 case OPC_DEXTM ... OPC_DEXT:
7901 case OPC_DINSM ... OPC_DINS:
7902 check_insn(env, ctx, ISA_MIPS64R2);
7903 check_mips_64(ctx);
7904 gen_bitops(ctx, op1, rt, rs, sa, rd);
7905 break;
7906 case OPC_DBSHFL:
7907 check_insn(env, ctx, ISA_MIPS64R2);
7908 check_mips_64(ctx);
7909 op2 = MASK_DBSHFL(ctx->opcode);
7910 gen_bshfl(ctx, op2, rt, rd);
7911 break;
7912 #endif
7913 default: /* Invalid */
7914 MIPS_INVAL("special3");
7915 generate_exception(ctx, EXCP_RI);
7916 break;
7917 }
7918 break;
7919 case OPC_REGIMM:
7920 op1 = MASK_REGIMM(ctx->opcode);
7921 switch (op1) {
7922 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7923 case OPC_BLTZAL ... OPC_BGEZALL:
7924 gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7925 return;
7926 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7927 case OPC_TNEI:
7928 gen_trap(ctx, op1, rs, -1, imm);
7929 break;
7930 case OPC_SYNCI:
7931 check_insn(env, ctx, ISA_MIPS32R2);
7932 /* Treat as NOP. */
7933 break;
7934 default: /* Invalid */
7935 MIPS_INVAL("regimm");
7936 generate_exception(ctx, EXCP_RI);
7937 break;
7938 }
7939 break;
7940 case OPC_CP0:
7941 check_cp0_enabled(ctx);
7942 op1 = MASK_CP0(ctx->opcode);
7943 switch (op1) {
7944 case OPC_MFC0:
7945 case OPC_MTC0:
7946 case OPC_MFTR:
7947 case OPC_MTTR:
7948 #if defined(TARGET_MIPS64)
7949 case OPC_DMFC0:
7950 case OPC_DMTC0:
7951 #endif
7952 #ifndef CONFIG_USER_ONLY
7953 gen_cp0(env, ctx, op1, rt, rd);
7954 #endif /* !CONFIG_USER_ONLY */
7955 break;
7956 case OPC_C0_FIRST ... OPC_C0_LAST:
7957 #ifndef CONFIG_USER_ONLY
7958 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7959 #endif /* !CONFIG_USER_ONLY */
7960 break;
7961 case OPC_MFMC0:
7962 #ifndef CONFIG_USER_ONLY
7963 {
7964 TCGv t0 = tcg_temp_new();
7965
7966 op2 = MASK_MFMC0(ctx->opcode);
7967 switch (op2) {
7968 case OPC_DMT:
7969 check_insn(env, ctx, ASE_MT);
7970 gen_helper_dmt(t0, t0);
7971 gen_store_gpr(t0, rt);
7972 break;
7973 case OPC_EMT:
7974 check_insn(env, ctx, ASE_MT);
7975 gen_helper_emt(t0, t0);
7976 gen_store_gpr(t0, rt);
7977 break;
7978 case OPC_DVPE:
7979 check_insn(env, ctx, ASE_MT);
7980 gen_helper_dvpe(t0, t0);
7981 gen_store_gpr(t0, rt);
7982 break;
7983 case OPC_EVPE:
7984 check_insn(env, ctx, ASE_MT);
7985 gen_helper_evpe(t0, t0);
7986 gen_store_gpr(t0, rt);
7987 break;
7988 case OPC_DI:
7989 check_insn(env, ctx, ISA_MIPS32R2);
7990 save_cpu_state(ctx, 1);
7991 gen_helper_di(t0);
7992 gen_store_gpr(t0, rt);
7993 /* Stop translation as we may have switched the execution mode */
7994 ctx->bstate = BS_STOP;
7995 break;
7996 case OPC_EI:
7997 check_insn(env, ctx, ISA_MIPS32R2);
7998 save_cpu_state(ctx, 1);
7999 gen_helper_ei(t0);
8000 gen_store_gpr(t0, rt);
8001 /* Stop translation as we may have switched the execution mode */
8002 ctx->bstate = BS_STOP;
8003 break;
8004 default: /* Invalid */
8005 MIPS_INVAL("mfmc0");
8006 generate_exception(ctx, EXCP_RI);
8007 break;
8008 }
8009 tcg_temp_free(t0);
8010 }
8011 #endif /* !CONFIG_USER_ONLY */
8012 break;
8013 case OPC_RDPGPR:
8014 check_insn(env, ctx, ISA_MIPS32R2);
8015 gen_load_srsgpr(rt, rd);
8016 break;
8017 case OPC_WRPGPR:
8018 check_insn(env, ctx, ISA_MIPS32R2);
8019 gen_store_srsgpr(rt, rd);
8020 break;
8021 default:
8022 MIPS_INVAL("cp0");
8023 generate_exception(ctx, EXCP_RI);
8024 break;
8025 }
8026 break;
8027 case OPC_ADDI: /* Arithmetic with immediate opcode */
8028 case OPC_ADDIU:
8029 gen_arith_imm(env, ctx, op, rt, rs, imm);
8030 break;
8031 case OPC_SLTI: /* Set on less than with immediate opcode */
8032 case OPC_SLTIU:
8033 gen_slt_imm(env, op, rt, rs, imm);
8034 break;
8035 case OPC_ANDI: /* Arithmetic with immediate opcode */
8036 case OPC_LUI:
8037 case OPC_ORI:
8038 case OPC_XORI:
8039 gen_logic_imm(env, op, rt, rs, imm);
8040 break;
8041 case OPC_J ... OPC_JAL: /* Jump */
8042 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8043 gen_compute_branch(ctx, op, rs, rt, offset);
8044 return;
8045 case OPC_BEQ ... OPC_BGTZ: /* Branch */
8046 case OPC_BEQL ... OPC_BGTZL:
8047 gen_compute_branch(ctx, op, rs, rt, imm << 2);
8048 return;
8049 case OPC_LB ... OPC_LWR: /* Load and stores */
8050 case OPC_SB ... OPC_SW:
8051 case OPC_SWR:
8052 case OPC_LL:
8053 gen_ldst(ctx, op, rt, rs, imm);
8054 break;
8055 case OPC_SC:
8056 gen_st_cond(ctx, op, rt, rs, imm);
8057 break;
8058 case OPC_CACHE:
8059 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8060 /* Treat as NOP. */
8061 break;
8062 case OPC_PREF:
8063 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8064 /* Treat as NOP. */
8065 break;
8066
8067 /* Floating point (COP1). */
8068 case OPC_LWC1:
8069 case OPC_LDC1:
8070 case OPC_SWC1:
8071 case OPC_SDC1:
8072 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8073 check_cp1_enabled(ctx);
8074 gen_flt_ldst(ctx, op, rt, rs, imm);
8075 } else {
8076 generate_exception_err(ctx, EXCP_CpU, 1);
8077 }
8078 break;
8079
8080 case OPC_CP1:
8081 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8082 check_cp1_enabled(ctx);
8083 op1 = MASK_CP1(ctx->opcode);
8084 switch (op1) {
8085 case OPC_MFHC1:
8086 case OPC_MTHC1:
8087 check_insn(env, ctx, ISA_MIPS32R2);
8088 case OPC_MFC1:
8089 case OPC_CFC1:
8090 case OPC_MTC1:
8091 case OPC_CTC1:
8092 gen_cp1(ctx, op1, rt, rd);
8093 break;
8094 #if defined(TARGET_MIPS64)
8095 case OPC_DMFC1:
8096 case OPC_DMTC1:
8097 check_insn(env, ctx, ISA_MIPS3);
8098 gen_cp1(ctx, op1, rt, rd);
8099 break;
8100 #endif
8101 case OPC_BC1ANY2:
8102 case OPC_BC1ANY4:
8103 check_cop1x(ctx);
8104 check_insn(env, ctx, ASE_MIPS3D);
8105 /* fall through */
8106 case OPC_BC1:
8107 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8108 (rt >> 2) & 0x7, imm << 2);
8109 return;
8110 case OPC_S_FMT:
8111 case OPC_D_FMT:
8112 case OPC_W_FMT:
8113 case OPC_L_FMT:
8114 case OPC_PS_FMT:
8115 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8116 (imm >> 8) & 0x7);
8117 break;
8118 default:
8119 MIPS_INVAL("cp1");
8120 generate_exception (ctx, EXCP_RI);
8121 break;
8122 }
8123 } else {
8124 generate_exception_err(ctx, EXCP_CpU, 1);
8125 }
8126 break;
8127
8128 /* COP2. */
8129 case OPC_LWC2:
8130 case OPC_LDC2:
8131 case OPC_SWC2:
8132 case OPC_SDC2:
8133 case OPC_CP2:
8134 /* COP2: Not implemented. */
8135 generate_exception_err(ctx, EXCP_CpU, 2);
8136 break;
8137
8138 case OPC_CP3:
8139 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8140 check_cp1_enabled(ctx);
8141 op1 = MASK_CP3(ctx->opcode);
8142 switch (op1) {
8143 case OPC_LWXC1:
8144 case OPC_LDXC1:
8145 case OPC_LUXC1:
8146 case OPC_SWXC1:
8147 case OPC_SDXC1:
8148 case OPC_SUXC1:
8149 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8150 break;
8151 case OPC_PREFX:
8152 /* Treat as NOP. */
8153 break;
8154 case OPC_ALNV_PS:
8155 case OPC_MADD_S:
8156 case OPC_MADD_D:
8157 case OPC_MADD_PS:
8158 case OPC_MSUB_S:
8159 case OPC_MSUB_D:
8160 case OPC_MSUB_PS:
8161 case OPC_NMADD_S:
8162 case OPC_NMADD_D:
8163 case OPC_NMADD_PS:
8164 case OPC_NMSUB_S:
8165 case OPC_NMSUB_D:
8166 case OPC_NMSUB_PS:
8167 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8168 break;
8169 default:
8170 MIPS_INVAL("cp3");
8171 generate_exception (ctx, EXCP_RI);
8172 break;
8173 }
8174 } else {
8175 generate_exception_err(ctx, EXCP_CpU, 1);
8176 }
8177 break;
8178
8179 #if defined(TARGET_MIPS64)
8180 /* MIPS64 opcodes */
8181 case OPC_LWU:
8182 case OPC_LDL ... OPC_LDR:
8183 case OPC_SDL ... OPC_SDR:
8184 case OPC_LLD:
8185 case OPC_LD:
8186 case OPC_SD:
8187 check_insn(env, ctx, ISA_MIPS3);
8188 check_mips_64(ctx);
8189 gen_ldst(ctx, op, rt, rs, imm);
8190 break;
8191 case OPC_SCD:
8192 check_insn(env, ctx, ISA_MIPS3);
8193 check_mips_64(ctx);
8194 gen_st_cond(ctx, op, rt, rs, imm);
8195 break;
8196 case OPC_DADDI:
8197 case OPC_DADDIU:
8198 check_insn(env, ctx, ISA_MIPS3);
8199 check_mips_64(ctx);
8200 gen_arith_imm(env, ctx, op, rt, rs, imm);
8201 break;
8202 #endif
8203 case OPC_JALX:
8204 check_insn(env, ctx, ASE_MIPS16);
8205 /* MIPS16: Not implemented. */
8206 case OPC_MDMX:
8207 check_insn(env, ctx, ASE_MDMX);
8208 /* MDMX: Not implemented. */
8209 default: /* Invalid */
8210 MIPS_INVAL("major opcode");
8211 generate_exception(ctx, EXCP_RI);
8212 break;
8213 }
8214 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8215 int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8216 /* Branches completion */
8217 ctx->hflags &= ~MIPS_HFLAG_BMASK;
8218 ctx->bstate = BS_BRANCH;
8219 save_cpu_state(ctx, 0);
8220 /* FIXME: Need to clear can_do_io. */
8221 switch (hflags) {
8222 case MIPS_HFLAG_B:
8223 /* unconditional branch */
8224 MIPS_DEBUG("unconditional branch");
8225 gen_goto_tb(ctx, 0, ctx->btarget);
8226 break;
8227 case MIPS_HFLAG_BL:
8228 /* blikely taken case */
8229 MIPS_DEBUG("blikely branch taken");
8230 gen_goto_tb(ctx, 0, ctx->btarget);
8231 break;
8232 case MIPS_HFLAG_BC:
8233 /* Conditional branch */
8234 MIPS_DEBUG("conditional branch");
8235 {
8236 int l1 = gen_new_label();
8237
8238 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8239 gen_goto_tb(ctx, 1, ctx->pc + 4);
8240 gen_set_label(l1);
8241 gen_goto_tb(ctx, 0, ctx->btarget);
8242 }
8243 break;
8244 case MIPS_HFLAG_BR:
8245 /* unconditional branch to register */
8246 MIPS_DEBUG("branch to register");
8247 tcg_gen_mov_tl(cpu_PC, btarget);
8248 tcg_gen_exit_tb(0);
8249 break;
8250 default:
8251 MIPS_DEBUG("unknown branch");
8252 break;
8253 }
8254 }
8255 }
8256
8257 static inline void
8258 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8259 int search_pc)
8260 {
8261 DisasContext ctx;
8262 target_ulong pc_start;
8263 uint16_t *gen_opc_end;
8264 CPUBreakpoint *bp;
8265 int j, lj = -1;
8266 int num_insns;
8267 int max_insns;
8268
8269 if (search_pc)
8270 qemu_log("search pc %d\n", search_pc);
8271
8272 pc_start = tb->pc;
8273 /* Leave some spare opc slots for branch handling. */
8274 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8275 ctx.pc = pc_start;
8276 ctx.saved_pc = -1;
8277 ctx.tb = tb;
8278 ctx.bstate = BS_NONE;
8279 /* Restore delay slot state from the tb context. */
8280 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8281 restore_cpu_state(env, &ctx);
8282 #ifdef CONFIG_USER_ONLY
8283 ctx.mem_idx = MIPS_HFLAG_UM;
8284 #else
8285 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8286 #endif
8287 num_insns = 0;
8288 max_insns = tb->cflags & CF_COUNT_MASK;
8289 if (max_insns == 0)
8290 max_insns = CF_COUNT_MASK;
8291 #ifdef DEBUG_DISAS
8292 qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8293 /* FIXME: This may print out stale hflags from env... */
8294 log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8295 #endif
8296 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8297 gen_icount_start();
8298 while (ctx.bstate == BS_NONE) {
8299 if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8300 TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8301 if (bp->pc == ctx.pc) {
8302 save_cpu_state(&ctx, 1);
8303 ctx.bstate = BS_BRANCH;
8304 gen_helper_0i(raise_exception, EXCP_DEBUG);
8305 /* Include the breakpoint location or the tb won't
8306 * be flushed when it must be. */
8307 ctx.pc += 4;
8308 goto done_generating;
8309 }
8310 }
8311 }
8312
8313 if (search_pc) {
8314 j = gen_opc_ptr - gen_opc_buf;
8315 if (lj < j) {
8316 lj++;
8317 while (lj < j)
8318 gen_opc_instr_start[lj++] = 0;
8319 }
8320 gen_opc_pc[lj] = ctx.pc;
8321 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8322 gen_opc_instr_start[lj] = 1;
8323 gen_opc_icount[lj] = num_insns;
8324 }
8325 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8326 gen_io_start();
8327 ctx.opcode = ldl_code(ctx.pc);
8328 decode_opc(env, &ctx);
8329 ctx.pc += 4;
8330 num_insns++;
8331
8332 if (env->singlestep_enabled)
8333 break;
8334
8335 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8336 break;
8337
8338 if (gen_opc_ptr >= gen_opc_end)
8339 break;
8340
8341 if (num_insns >= max_insns)
8342 break;
8343
8344 if (singlestep)
8345 break;
8346 }
8347 if (tb->cflags & CF_LAST_IO)
8348 gen_io_end();
8349 if (env->singlestep_enabled) {
8350 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8351 gen_helper_0i(raise_exception, EXCP_DEBUG);
8352 } else {
8353 switch (ctx.bstate) {
8354 case BS_STOP:
8355 gen_helper_interrupt_restart();
8356 gen_goto_tb(&ctx, 0, ctx.pc);
8357 break;
8358 case BS_NONE:
8359 save_cpu_state(&ctx, 0);
8360 gen_goto_tb(&ctx, 0, ctx.pc);
8361 break;
8362 case BS_EXCP:
8363 gen_helper_interrupt_restart();
8364 tcg_gen_exit_tb(0);
8365 break;
8366 case BS_BRANCH:
8367 default:
8368 break;
8369 }
8370 }
8371 done_generating:
8372 gen_icount_end(tb, num_insns);
8373 *gen_opc_ptr = INDEX_op_end;
8374 if (search_pc) {
8375 j = gen_opc_ptr - gen_opc_buf;
8376 lj++;
8377 while (lj <= j)
8378 gen_opc_instr_start[lj++] = 0;
8379 } else {
8380 tb->size = ctx.pc - pc_start;
8381 tb->icount = num_insns;
8382 }
8383 #ifdef DEBUG_DISAS
8384 LOG_DISAS("\n");
8385 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8386 qemu_log("IN: %s\n", lookup_symbol(pc_start));
8387 log_target_disas(pc_start, ctx.pc - pc_start, 0);
8388 qemu_log("\n");
8389 }
8390 qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8391 #endif
8392 }
8393
8394 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8395 {
8396 gen_intermediate_code_internal(env, tb, 0);
8397 }
8398
8399 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8400 {
8401 gen_intermediate_code_internal(env, tb, 1);
8402 }
8403
8404 static void fpu_dump_state(CPUState *env, FILE *f,
8405 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8406 int flags)
8407 {
8408 int i;
8409 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8410
8411 #define printfpr(fp) \
8412 do { \
8413 if (is_fpu64) \
8414 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n", \
8415 (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd, \
8416 (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8417 else { \
8418 fpr_t tmp; \
8419 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
8420 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
8421 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n", \
8422 tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd, \
8423 tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]); \
8424 } \
8425 } while(0)
8426
8427
8428 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
8429 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8430 get_float_exception_flags(&env->active_fpu.fp_status));
8431 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8432 fpu_fprintf(f, "%3s: ", fregnames[i]);
8433 printfpr(&env->active_fpu.fpr[i]);
8434 }
8435
8436 #undef printfpr
8437 }
8438
8439 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8440 /* Debug help: The architecture requires 32bit code to maintain proper
8441 sign-extended values on 64bit machines. */
8442
8443 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8444
8445 static void
8446 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8447 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8448 int flags)
8449 {
8450 int i;
8451
8452 if (!SIGN_EXT_P(env->active_tc.PC))
8453 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8454 if (!SIGN_EXT_P(env->active_tc.HI[0]))
8455 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8456 if (!SIGN_EXT_P(env->active_tc.LO[0]))
8457 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8458 if (!SIGN_EXT_P(env->btarget))
8459 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8460
8461 for (i = 0; i < 32; i++) {
8462 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8463 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8464 }
8465
8466 if (!SIGN_EXT_P(env->CP0_EPC))
8467 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8468 if (!SIGN_EXT_P(env->CP0_LLAddr))
8469 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8470 }
8471 #endif
8472
8473 void cpu_dump_state (CPUState *env, FILE *f,
8474 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8475 int flags)
8476 {
8477 int i;
8478
8479 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
8480 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8481 env->hflags, env->btarget, env->bcond);
8482 for (i = 0; i < 32; i++) {
8483 if ((i & 3) == 0)
8484 cpu_fprintf(f, "GPR%02d:", i);
8485 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8486 if ((i & 3) == 3)
8487 cpu_fprintf(f, "\n");
8488 }
8489
8490 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
8491 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8492 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8493 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8494 if (env->hflags & MIPS_HFLAG_FPU)
8495 fpu_dump_state(env, f, cpu_fprintf, flags);
8496 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8497 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8498 #endif
8499 }
8500
8501 static void mips_tcg_init(void)
8502 {
8503 int i;
8504 static int inited;
8505
8506 /* Initialize various static tables. */
8507 if (inited)
8508 return;
8509
8510 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8511 TCGV_UNUSED(cpu_gpr[0]);
8512 for (i = 1; i < 32; i++)
8513 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8514 offsetof(CPUState, active_tc.gpr[i]),
8515 regnames[i]);
8516 cpu_PC = tcg_global_mem_new(TCG_AREG0,
8517 offsetof(CPUState, active_tc.PC), "PC");
8518 for (i = 0; i < MIPS_DSP_ACC; i++) {
8519 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8520 offsetof(CPUState, active_tc.HI[i]),
8521 regnames_HI[i]);
8522 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8523 offsetof(CPUState, active_tc.LO[i]),
8524 regnames_LO[i]);
8525 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8526 offsetof(CPUState, active_tc.ACX[i]),
8527 regnames_ACX[i]);
8528 }
8529 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8530 offsetof(CPUState, active_tc.DSPControl),
8531 "DSPControl");
8532 bcond = tcg_global_mem_new(TCG_AREG0,
8533 offsetof(CPUState, bcond), "bcond");
8534 btarget = tcg_global_mem_new(TCG_AREG0,
8535 offsetof(CPUState, btarget), "btarget");
8536 hflags = tcg_global_mem_new_i32(TCG_AREG0,
8537 offsetof(CPUState, hflags), "hflags");
8538
8539 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8540 offsetof(CPUState, active_fpu.fcr0),
8541 "fcr0");
8542 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8543 offsetof(CPUState, active_fpu.fcr31),
8544 "fcr31");
8545
8546 /* register helpers */
8547 #define GEN_HELPER 2
8548 #include "helper.h"
8549
8550 inited = 1;
8551 }
8552
8553 #include "translate_init.c"
8554
8555 CPUMIPSState *cpu_mips_init (const char *cpu_model)
8556 {
8557 CPUMIPSState *env;
8558 const mips_def_t *def;
8559
8560 def = cpu_mips_find_by_name(cpu_model);
8561 if (!def)
8562 return NULL;
8563 env = qemu_mallocz(sizeof(CPUMIPSState));
8564 env->cpu_model = def;
8565
8566 cpu_exec_init(env);
8567 env->cpu_model_str = cpu_model;
8568 mips_tcg_init();
8569 cpu_reset(env);
8570 return env;
8571 }
8572
8573 void cpu_reset (CPUMIPSState *env)
8574 {
8575 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8576 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8577 log_cpu_state(env, 0);
8578 }
8579
8580 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8581
8582 tlb_flush(env, 1);
8583
8584 /* Minimal init */
8585 #if defined(CONFIG_USER_ONLY)
8586 env->hflags = MIPS_HFLAG_UM;
8587 #else
8588 if (env->hflags & MIPS_HFLAG_BMASK) {
8589 /* If the exception was raised from a delay slot,
8590 come back to the jump. */
8591 env->CP0_ErrorEPC = env->active_tc.PC - 4;
8592 } else {
8593 env->CP0_ErrorEPC = env->active_tc.PC;
8594 }
8595 env->active_tc.PC = (int32_t)0xBFC00000;
8596 env->CP0_Wired = 0;
8597 /* SMP not implemented */
8598 env->CP0_EBase = 0x80000000;
8599 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8600 /* vectored interrupts not implemented, timer on int 7,
8601 no performance counters. */
8602 env->CP0_IntCtl = 0xe0000000;
8603 {
8604 int i;
8605
8606 for (i = 0; i < 7; i++) {
8607 env->CP0_WatchLo[i] = 0;
8608 env->CP0_WatchHi[i] = 0x80000000;
8609 }
8610 env->CP0_WatchLo[7] = 0;
8611 env->CP0_WatchHi[7] = 0;
8612 }
8613 /* Count register increments in debug mode, EJTAG version 1 */
8614 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8615 env->hflags = MIPS_HFLAG_CP0;
8616 #endif
8617 env->exception_index = EXCP_NONE;
8618 cpu_mips_register(env, env->cpu_model);
8619 }
8620
8621 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8622 unsigned long searched_pc, int pc_pos, void *puc)
8623 {
8624 env->active_tc.PC = gen_opc_pc[pc_pos];
8625 env->hflags &= ~MIPS_HFLAG_BMASK;
8626 env->hflags |= gen_opc_hflags[pc_pos];
8627 }