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