]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
target-mips: gen_bshfl()
[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_i32 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 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(t0, 0); \
699 tcg_gen_br(l2); \
700 gen_set_label(l1); \
701 tcg_gen_movi_tl(t0, 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 t, target_ulong val) \
714 { \
715 int l1 = gen_new_label(); \
716 int l2 = gen_new_label(); \
717 \
718 tcg_gen_brcondi_tl(cond, t, val, l1); \
719 tcg_gen_movi_tl(t, 0); \
720 tcg_gen_br(l2); \
721 gen_set_label(l1); \
722 tcg_gen_movi_tl(t, 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 t) \
731 { \
732 int l1 = gen_new_label(); \
733 int l2 = gen_new_label(); \
734 \
735 tcg_gen_brcondi_tl(cond, t, 0, l1); \
736 tcg_gen_movi_tl(t, 0); \
737 tcg_gen_br(l2); \
738 gen_set_label(l1); \
739 tcg_gen_movi_tl(t, 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, uimm);
1313 opn = "slti";
1314 break;
1315 case OPC_SLTIU:
1316 gen_op_ltiu(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, t1);
1600 opn = "slt";
1601 break;
1602 case OPC_SLTU:
1603 gen_op_ltu(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_local_new();
2170 TCGv t1 = tcg_temp_local_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 tcg_gen_movi_tl(t0, 1);
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 goto out;
2221 default:
2222 MIPS_INVAL("trap");
2223 generate_exception(ctx, EXCP_RI);
2224 goto out;
2225 }
2226 } else {
2227 switch (opc) {
2228 case OPC_TEQ:
2229 case OPC_TEQI:
2230 gen_op_eq(t0, t1);
2231 break;
2232 case OPC_TGE:
2233 case OPC_TGEI:
2234 gen_op_ge(t0, t1);
2235 break;
2236 case OPC_TGEU:
2237 case OPC_TGEIU:
2238 gen_op_geu(t0, t1);
2239 break;
2240 case OPC_TLT:
2241 case OPC_TLTI:
2242 gen_op_lt(t0, t1);
2243 break;
2244 case OPC_TLTU:
2245 case OPC_TLTIU:
2246 gen_op_ltu(t0, t1);
2247 break;
2248 case OPC_TNE:
2249 case OPC_TNEI:
2250 gen_op_ne(t0, t1);
2251 break;
2252 default:
2253 MIPS_INVAL("trap");
2254 generate_exception(ctx, EXCP_RI);
2255 goto out;
2256 }
2257 }
2258 save_cpu_state(ctx, 1);
2259 {
2260 int l1 = gen_new_label();
2261
2262 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2263 gen_helper_0i(raise_exception, EXCP_TRAP);
2264 gen_set_label(l1);
2265 }
2266 ctx->bstate = BS_STOP;
2267 out:
2268 tcg_temp_free(t0);
2269 tcg_temp_free(t1);
2270 }
2271
2272 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2273 {
2274 TranslationBlock *tb;
2275 tb = ctx->tb;
2276 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2277 tcg_gen_goto_tb(n);
2278 gen_save_pc(dest);
2279 tcg_gen_exit_tb((long)tb + n);
2280 } else {
2281 gen_save_pc(dest);
2282 tcg_gen_exit_tb(0);
2283 }
2284 }
2285
2286 /* Branches (before delay slot) */
2287 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2288 int rs, int rt, int32_t offset)
2289 {
2290 target_ulong btgt = -1;
2291 int blink = 0;
2292 int bcond_compute = 0;
2293 TCGv t0 = tcg_temp_local_new();
2294 TCGv t1 = tcg_temp_local_new();
2295
2296 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2297 #ifdef MIPS_DEBUG_DISAS
2298 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2299 #endif
2300 generate_exception(ctx, EXCP_RI);
2301 goto out;
2302 }
2303
2304 /* Load needed operands */
2305 switch (opc) {
2306 case OPC_BEQ:
2307 case OPC_BEQL:
2308 case OPC_BNE:
2309 case OPC_BNEL:
2310 /* Compare two registers */
2311 if (rs != rt) {
2312 gen_load_gpr(t0, rs);
2313 gen_load_gpr(t1, rt);
2314 bcond_compute = 1;
2315 }
2316 btgt = ctx->pc + 4 + offset;
2317 break;
2318 case OPC_BGEZ:
2319 case OPC_BGEZAL:
2320 case OPC_BGEZALL:
2321 case OPC_BGEZL:
2322 case OPC_BGTZ:
2323 case OPC_BGTZL:
2324 case OPC_BLEZ:
2325 case OPC_BLEZL:
2326 case OPC_BLTZ:
2327 case OPC_BLTZAL:
2328 case OPC_BLTZALL:
2329 case OPC_BLTZL:
2330 /* Compare to zero */
2331 if (rs != 0) {
2332 gen_load_gpr(t0, rs);
2333 bcond_compute = 1;
2334 }
2335 btgt = ctx->pc + 4 + offset;
2336 break;
2337 case OPC_J:
2338 case OPC_JAL:
2339 /* Jump to immediate */
2340 btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2341 break;
2342 case OPC_JR:
2343 case OPC_JALR:
2344 /* Jump to register */
2345 if (offset != 0 && offset != 16) {
2346 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2347 others are reserved. */
2348 MIPS_INVAL("jump hint");
2349 generate_exception(ctx, EXCP_RI);
2350 goto out;
2351 }
2352 gen_load_gpr(btarget, rs);
2353 break;
2354 default:
2355 MIPS_INVAL("branch/jump");
2356 generate_exception(ctx, EXCP_RI);
2357 goto out;
2358 }
2359 if (bcond_compute == 0) {
2360 /* No condition to be computed */
2361 switch (opc) {
2362 case OPC_BEQ: /* rx == rx */
2363 case OPC_BEQL: /* rx == rx likely */
2364 case OPC_BGEZ: /* 0 >= 0 */
2365 case OPC_BGEZL: /* 0 >= 0 likely */
2366 case OPC_BLEZ: /* 0 <= 0 */
2367 case OPC_BLEZL: /* 0 <= 0 likely */
2368 /* Always take */
2369 ctx->hflags |= MIPS_HFLAG_B;
2370 MIPS_DEBUG("balways");
2371 break;
2372 case OPC_BGEZAL: /* 0 >= 0 */
2373 case OPC_BGEZALL: /* 0 >= 0 likely */
2374 /* Always take and link */
2375 blink = 31;
2376 ctx->hflags |= MIPS_HFLAG_B;
2377 MIPS_DEBUG("balways and link");
2378 break;
2379 case OPC_BNE: /* rx != rx */
2380 case OPC_BGTZ: /* 0 > 0 */
2381 case OPC_BLTZ: /* 0 < 0 */
2382 /* Treat as NOP. */
2383 MIPS_DEBUG("bnever (NOP)");
2384 goto out;
2385 case OPC_BLTZAL: /* 0 < 0 */
2386 tcg_gen_movi_tl(t0, ctx->pc + 8);
2387 gen_store_gpr(t0, 31);
2388 MIPS_DEBUG("bnever and link");
2389 goto out;
2390 case OPC_BLTZALL: /* 0 < 0 likely */
2391 tcg_gen_movi_tl(t0, ctx->pc + 8);
2392 gen_store_gpr(t0, 31);
2393 /* Skip the instruction in the delay slot */
2394 MIPS_DEBUG("bnever, link and skip");
2395 ctx->pc += 4;
2396 goto out;
2397 case OPC_BNEL: /* rx != rx likely */
2398 case OPC_BGTZL: /* 0 > 0 likely */
2399 case OPC_BLTZL: /* 0 < 0 likely */
2400 /* Skip the instruction in the delay slot */
2401 MIPS_DEBUG("bnever and skip");
2402 ctx->pc += 4;
2403 goto out;
2404 case OPC_J:
2405 ctx->hflags |= MIPS_HFLAG_B;
2406 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2407 break;
2408 case OPC_JAL:
2409 blink = 31;
2410 ctx->hflags |= MIPS_HFLAG_B;
2411 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2412 break;
2413 case OPC_JR:
2414 ctx->hflags |= MIPS_HFLAG_BR;
2415 MIPS_DEBUG("jr %s", regnames[rs]);
2416 break;
2417 case OPC_JALR:
2418 blink = rt;
2419 ctx->hflags |= MIPS_HFLAG_BR;
2420 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2421 break;
2422 default:
2423 MIPS_INVAL("branch/jump");
2424 generate_exception(ctx, EXCP_RI);
2425 goto out;
2426 }
2427 } else {
2428 switch (opc) {
2429 case OPC_BEQ:
2430 gen_op_eq(t0, t1);
2431 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2432 regnames[rs], regnames[rt], btgt);
2433 goto not_likely;
2434 case OPC_BEQL:
2435 gen_op_eq(t0, t1);
2436 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2437 regnames[rs], regnames[rt], btgt);
2438 goto likely;
2439 case OPC_BNE:
2440 gen_op_ne(t0, t1);
2441 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2442 regnames[rs], regnames[rt], btgt);
2443 goto not_likely;
2444 case OPC_BNEL:
2445 gen_op_ne(t0, t1);
2446 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2447 regnames[rs], regnames[rt], btgt);
2448 goto likely;
2449 case OPC_BGEZ:
2450 gen_op_gez(t0);
2451 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2452 goto not_likely;
2453 case OPC_BGEZL:
2454 gen_op_gez(t0);
2455 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2456 goto likely;
2457 case OPC_BGEZAL:
2458 gen_op_gez(t0);
2459 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2460 blink = 31;
2461 goto not_likely;
2462 case OPC_BGEZALL:
2463 gen_op_gez(t0);
2464 blink = 31;
2465 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2466 goto likely;
2467 case OPC_BGTZ:
2468 gen_op_gtz(t0);
2469 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2470 goto not_likely;
2471 case OPC_BGTZL:
2472 gen_op_gtz(t0);
2473 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2474 goto likely;
2475 case OPC_BLEZ:
2476 gen_op_lez(t0);
2477 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2478 goto not_likely;
2479 case OPC_BLEZL:
2480 gen_op_lez(t0);
2481 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2482 goto likely;
2483 case OPC_BLTZ:
2484 gen_op_ltz(t0);
2485 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2486 goto not_likely;
2487 case OPC_BLTZL:
2488 gen_op_ltz(t0);
2489 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2490 goto likely;
2491 case OPC_BLTZAL:
2492 gen_op_ltz(t0);
2493 blink = 31;
2494 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2495 not_likely:
2496 ctx->hflags |= MIPS_HFLAG_BC;
2497 tcg_gen_trunc_tl_i32(bcond, t0);
2498 break;
2499 case OPC_BLTZALL:
2500 gen_op_ltz(t0);
2501 blink = 31;
2502 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2503 likely:
2504 ctx->hflags |= MIPS_HFLAG_BL;
2505 tcg_gen_trunc_tl_i32(bcond, t0);
2506 break;
2507 default:
2508 MIPS_INVAL("conditional branch/jump");
2509 generate_exception(ctx, EXCP_RI);
2510 goto out;
2511 }
2512 }
2513 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2514 blink, ctx->hflags, btgt);
2515
2516 ctx->btarget = btgt;
2517 if (blink > 0) {
2518 tcg_gen_movi_tl(t0, ctx->pc + 8);
2519 gen_store_gpr(t0, blink);
2520 }
2521
2522 out:
2523 tcg_temp_free(t0);
2524 tcg_temp_free(t1);
2525 }
2526
2527 /* special3 bitfield operations */
2528 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2529 int rs, int lsb, int msb)
2530 {
2531 TCGv t0 = tcg_temp_new();
2532 TCGv t1 = tcg_temp_new();
2533 target_ulong mask;
2534
2535 gen_load_gpr(t1, rs);
2536 switch (opc) {
2537 case OPC_EXT:
2538 if (lsb + msb > 31)
2539 goto fail;
2540 tcg_gen_shri_tl(t0, t1, lsb);
2541 if (msb != 31) {
2542 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2543 } else {
2544 tcg_gen_ext32s_tl(t0, t0);
2545 }
2546 break;
2547 #if defined(TARGET_MIPS64)
2548 case OPC_DEXTM:
2549 tcg_gen_shri_tl(t0, t1, lsb);
2550 if (msb != 31) {
2551 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2552 }
2553 break;
2554 case OPC_DEXTU:
2555 tcg_gen_shri_tl(t0, t1, lsb + 32);
2556 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2557 break;
2558 case OPC_DEXT:
2559 tcg_gen_shri_tl(t0, t1, lsb);
2560 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2561 break;
2562 #endif
2563 case OPC_INS:
2564 if (lsb > msb)
2565 goto fail;
2566 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2567 gen_load_gpr(t0, rt);
2568 tcg_gen_andi_tl(t0, t0, ~mask);
2569 tcg_gen_shli_tl(t1, t1, lsb);
2570 tcg_gen_andi_tl(t1, t1, mask);
2571 tcg_gen_or_tl(t0, t0, t1);
2572 tcg_gen_ext32s_tl(t0, t0);
2573 break;
2574 #if defined(TARGET_MIPS64)
2575 case OPC_DINSM:
2576 if (lsb > msb)
2577 goto fail;
2578 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2579 gen_load_gpr(t0, rt);
2580 tcg_gen_andi_tl(t0, t0, ~mask);
2581 tcg_gen_shli_tl(t1, t1, lsb);
2582 tcg_gen_andi_tl(t1, t1, mask);
2583 tcg_gen_or_tl(t0, t0, t1);
2584 break;
2585 case OPC_DINSU:
2586 if (lsb > msb)
2587 goto fail;
2588 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2589 gen_load_gpr(t0, rt);
2590 tcg_gen_andi_tl(t0, t0, ~mask);
2591 tcg_gen_shli_tl(t1, t1, lsb + 32);
2592 tcg_gen_andi_tl(t1, t1, mask);
2593 tcg_gen_or_tl(t0, t0, t1);
2594 break;
2595 case OPC_DINS:
2596 if (lsb > msb)
2597 goto fail;
2598 gen_load_gpr(t0, rt);
2599 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2600 gen_load_gpr(t0, rt);
2601 tcg_gen_andi_tl(t0, t0, ~mask);
2602 tcg_gen_shli_tl(t1, t1, lsb);
2603 tcg_gen_andi_tl(t1, t1, mask);
2604 tcg_gen_or_tl(t0, t0, t1);
2605 break;
2606 #endif
2607 default:
2608 fail:
2609 MIPS_INVAL("bitops");
2610 generate_exception(ctx, EXCP_RI);
2611 tcg_temp_free(t0);
2612 tcg_temp_free(t1);
2613 return;
2614 }
2615 gen_store_gpr(t0, rt);
2616 tcg_temp_free(t0);
2617 tcg_temp_free(t1);
2618 }
2619
2620 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2621 {
2622 TCGv t0;
2623
2624 if (rd == 0) {
2625 /* If no destination, treat it as a NOP. */
2626 MIPS_DEBUG("NOP");
2627 return;
2628 }
2629
2630 t0 = tcg_temp_new();
2631 gen_load_gpr(t0, rt);
2632 switch (op2) {
2633 case OPC_WSBH:
2634 {
2635 TCGv t1 = tcg_temp_new();
2636
2637 tcg_gen_shri_tl(t1, t0, 8);
2638 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2639 tcg_gen_shli_tl(t0, t0, 8);
2640 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2641 tcg_gen_or_tl(t0, t0, t1);
2642 tcg_temp_free(t1);
2643 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2644 }
2645 break;
2646 case OPC_SEB:
2647 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2648 break;
2649 case OPC_SEH:
2650 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2651 break;
2652 #if defined(TARGET_MIPS64)
2653 case OPC_DSBH:
2654 {
2655 TCGv t1 = tcg_temp_new();
2656
2657 tcg_gen_shri_tl(t1, t0, 8);
2658 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2659 tcg_gen_shli_tl(t0, t0, 8);
2660 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2661 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2662 tcg_temp_free(t1);
2663 }
2664 break;
2665 case OPC_DSHD:
2666 {
2667 TCGv t1 = tcg_temp_new();
2668
2669 tcg_gen_shri_tl(t1, t0, 16);
2670 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2671 tcg_gen_shli_tl(t0, t0, 16);
2672 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2673 tcg_gen_or_tl(t0, t0, t1);
2674 tcg_gen_shri_tl(t1, t0, 32);
2675 tcg_gen_shli_tl(t0, t0, 32);
2676 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2677 tcg_temp_free(t1);
2678 }
2679 break;
2680 #endif
2681 default:
2682 MIPS_INVAL("bsfhl");
2683 generate_exception(ctx, EXCP_RI);
2684 tcg_temp_free(t0);
2685 return;
2686 }
2687 tcg_temp_free(t0);
2688 }
2689
2690 #ifndef CONFIG_USER_ONLY
2691 /* CP0 (MMU and control) */
2692 static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2693 {
2694 TCGv_i32 r_tmp = tcg_temp_new_i32();
2695
2696 tcg_gen_ld_i32(r_tmp, cpu_env, off);
2697 tcg_gen_ext_i32_tl(t, r_tmp);
2698 tcg_temp_free_i32(r_tmp);
2699 }
2700
2701 static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2702 {
2703 tcg_gen_ld_tl(t, cpu_env, off);
2704 tcg_gen_ext32s_tl(t, t);
2705 }
2706
2707 static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2708 {
2709 TCGv_i32 r_tmp = tcg_temp_new_i32();
2710
2711 tcg_gen_trunc_tl_i32(r_tmp, t);
2712 tcg_gen_st_i32(r_tmp, cpu_env, off);
2713 tcg_temp_free_i32(r_tmp);
2714 }
2715
2716 static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2717 {
2718 tcg_gen_ext32s_tl(t, t);
2719 tcg_gen_st_tl(t, cpu_env, off);
2720 }
2721
2722 static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2723 {
2724 const char *rn = "invalid";
2725
2726 if (sel != 0)
2727 check_insn(env, ctx, ISA_MIPS32);
2728
2729 switch (reg) {
2730 case 0:
2731 switch (sel) {
2732 case 0:
2733 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
2734 rn = "Index";
2735 break;
2736 case 1:
2737 check_insn(env, ctx, ASE_MT);
2738 gen_helper_mfc0_mvpcontrol(t0);
2739 rn = "MVPControl";
2740 break;
2741 case 2:
2742 check_insn(env, ctx, ASE_MT);
2743 gen_helper_mfc0_mvpconf0(t0);
2744 rn = "MVPConf0";
2745 break;
2746 case 3:
2747 check_insn(env, ctx, ASE_MT);
2748 gen_helper_mfc0_mvpconf1(t0);
2749 rn = "MVPConf1";
2750 break;
2751 default:
2752 goto die;
2753 }
2754 break;
2755 case 1:
2756 switch (sel) {
2757 case 0:
2758 gen_helper_mfc0_random(t0);
2759 rn = "Random";
2760 break;
2761 case 1:
2762 check_insn(env, ctx, ASE_MT);
2763 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
2764 rn = "VPEControl";
2765 break;
2766 case 2:
2767 check_insn(env, ctx, ASE_MT);
2768 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
2769 rn = "VPEConf0";
2770 break;
2771 case 3:
2772 check_insn(env, ctx, ASE_MT);
2773 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
2774 rn = "VPEConf1";
2775 break;
2776 case 4:
2777 check_insn(env, ctx, ASE_MT);
2778 gen_mfc0_load64(t0, offsetof(CPUState, CP0_YQMask));
2779 rn = "YQMask";
2780 break;
2781 case 5:
2782 check_insn(env, ctx, ASE_MT);
2783 gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPESchedule));
2784 rn = "VPESchedule";
2785 break;
2786 case 6:
2787 check_insn(env, ctx, ASE_MT);
2788 gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPEScheFBack));
2789 rn = "VPEScheFBack";
2790 break;
2791 case 7:
2792 check_insn(env, ctx, ASE_MT);
2793 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
2794 rn = "VPEOpt";
2795 break;
2796 default:
2797 goto die;
2798 }
2799 break;
2800 case 2:
2801 switch (sel) {
2802 case 0:
2803 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2804 tcg_gen_ext32s_tl(t0, t0);
2805 rn = "EntryLo0";
2806 break;
2807 case 1:
2808 check_insn(env, ctx, ASE_MT);
2809 gen_helper_mfc0_tcstatus(t0);
2810 rn = "TCStatus";
2811 break;
2812 case 2:
2813 check_insn(env, ctx, ASE_MT);
2814 gen_helper_mfc0_tcbind(t0);
2815 rn = "TCBind";
2816 break;
2817 case 3:
2818 check_insn(env, ctx, ASE_MT);
2819 gen_helper_mfc0_tcrestart(t0);
2820 rn = "TCRestart";
2821 break;
2822 case 4:
2823 check_insn(env, ctx, ASE_MT);
2824 gen_helper_mfc0_tchalt(t0);
2825 rn = "TCHalt";
2826 break;
2827 case 5:
2828 check_insn(env, ctx, ASE_MT);
2829 gen_helper_mfc0_tccontext(t0);
2830 rn = "TCContext";
2831 break;
2832 case 6:
2833 check_insn(env, ctx, ASE_MT);
2834 gen_helper_mfc0_tcschedule(t0);
2835 rn = "TCSchedule";
2836 break;
2837 case 7:
2838 check_insn(env, ctx, ASE_MT);
2839 gen_helper_mfc0_tcschefback(t0);
2840 rn = "TCScheFBack";
2841 break;
2842 default:
2843 goto die;
2844 }
2845 break;
2846 case 3:
2847 switch (sel) {
2848 case 0:
2849 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
2850 tcg_gen_ext32s_tl(t0, t0);
2851 rn = "EntryLo1";
2852 break;
2853 default:
2854 goto die;
2855 }
2856 break;
2857 case 4:
2858 switch (sel) {
2859 case 0:
2860 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
2861 tcg_gen_ext32s_tl(t0, t0);
2862 rn = "Context";
2863 break;
2864 case 1:
2865 // gen_helper_mfc0_contextconfig(t0); /* SmartMIPS ASE */
2866 rn = "ContextConfig";
2867 // break;
2868 default:
2869 goto die;
2870 }
2871 break;
2872 case 5:
2873 switch (sel) {
2874 case 0:
2875 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
2876 rn = "PageMask";
2877 break;
2878 case 1:
2879 check_insn(env, ctx, ISA_MIPS32R2);
2880 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
2881 rn = "PageGrain";
2882 break;
2883 default:
2884 goto die;
2885 }
2886 break;
2887 case 6:
2888 switch (sel) {
2889 case 0:
2890 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
2891 rn = "Wired";
2892 break;
2893 case 1:
2894 check_insn(env, ctx, ISA_MIPS32R2);
2895 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
2896 rn = "SRSConf0";
2897 break;
2898 case 2:
2899 check_insn(env, ctx, ISA_MIPS32R2);
2900 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
2901 rn = "SRSConf1";
2902 break;
2903 case 3:
2904 check_insn(env, ctx, ISA_MIPS32R2);
2905 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
2906 rn = "SRSConf2";
2907 break;
2908 case 4:
2909 check_insn(env, ctx, ISA_MIPS32R2);
2910 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
2911 rn = "SRSConf3";
2912 break;
2913 case 5:
2914 check_insn(env, ctx, ISA_MIPS32R2);
2915 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
2916 rn = "SRSConf4";
2917 break;
2918 default:
2919 goto die;
2920 }
2921 break;
2922 case 7:
2923 switch (sel) {
2924 case 0:
2925 check_insn(env, ctx, ISA_MIPS32R2);
2926 gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
2927 rn = "HWREna";
2928 break;
2929 default:
2930 goto die;
2931 }
2932 break;
2933 case 8:
2934 switch (sel) {
2935 case 0:
2936 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
2937 tcg_gen_ext32s_tl(t0, t0);
2938 rn = "BadVAddr";
2939 break;
2940 default:
2941 goto die;
2942 }
2943 break;
2944 case 9:
2945 switch (sel) {
2946 case 0:
2947 /* Mark as an IO operation because we read the time. */
2948 if (use_icount)
2949 gen_io_start();
2950 gen_helper_mfc0_count(t0);
2951 if (use_icount) {
2952 gen_io_end();
2953 ctx->bstate = BS_STOP;
2954 }
2955 rn = "Count";
2956 break;
2957 /* 6,7 are implementation dependent */
2958 default:
2959 goto die;
2960 }
2961 break;
2962 case 10:
2963 switch (sel) {
2964 case 0:
2965 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
2966 tcg_gen_ext32s_tl(t0, t0);
2967 rn = "EntryHi";
2968 break;
2969 default:
2970 goto die;
2971 }
2972 break;
2973 case 11:
2974 switch (sel) {
2975 case 0:
2976 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
2977 rn = "Compare";
2978 break;
2979 /* 6,7 are implementation dependent */
2980 default:
2981 goto die;
2982 }
2983 break;
2984 case 12:
2985 switch (sel) {
2986 case 0:
2987 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
2988 rn = "Status";
2989 break;
2990 case 1:
2991 check_insn(env, ctx, ISA_MIPS32R2);
2992 gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
2993 rn = "IntCtl";
2994 break;
2995 case 2:
2996 check_insn(env, ctx, ISA_MIPS32R2);
2997 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
2998 rn = "SRSCtl";
2999 break;
3000 case 3:
3001 check_insn(env, ctx, ISA_MIPS32R2);
3002 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
3003 rn = "SRSMap";
3004 break;
3005 default:
3006 goto die;
3007 }
3008 break;
3009 case 13:
3010 switch (sel) {
3011 case 0:
3012 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
3013 rn = "Cause";
3014 break;
3015 default:
3016 goto die;
3017 }
3018 break;
3019 case 14:
3020 switch (sel) {
3021 case 0:
3022 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
3023 tcg_gen_ext32s_tl(t0, t0);
3024 rn = "EPC";
3025 break;
3026 default:
3027 goto die;
3028 }
3029 break;
3030 case 15:
3031 switch (sel) {
3032 case 0:
3033 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
3034 rn = "PRid";
3035 break;
3036 case 1:
3037 check_insn(env, ctx, ISA_MIPS32R2);
3038 gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
3039 rn = "EBase";
3040 break;
3041 default:
3042 goto die;
3043 }
3044 break;
3045 case 16:
3046 switch (sel) {
3047 case 0:
3048 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
3049 rn = "Config";
3050 break;
3051 case 1:
3052 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
3053 rn = "Config1";
3054 break;
3055 case 2:
3056 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
3057 rn = "Config2";
3058 break;
3059 case 3:
3060 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
3061 rn = "Config3";
3062 break;
3063 /* 4,5 are reserved */
3064 /* 6,7 are implementation dependent */
3065 case 6:
3066 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
3067 rn = "Config6";
3068 break;
3069 case 7:
3070 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
3071 rn = "Config7";
3072 break;
3073 default:
3074 goto die;
3075 }
3076 break;
3077 case 17:
3078 switch (sel) {
3079 case 0:
3080 gen_helper_mfc0_lladdr(t0);
3081 rn = "LLAddr";
3082 break;
3083 default:
3084 goto die;
3085 }
3086 break;
3087 case 18:
3088 switch (sel) {
3089 case 0 ... 7:
3090 gen_helper_1i(mfc0_watchlo, t0, sel);
3091 rn = "WatchLo";
3092 break;
3093 default:
3094 goto die;
3095 }
3096 break;
3097 case 19:
3098 switch (sel) {
3099 case 0 ...7:
3100 gen_helper_1i(mfc0_watchhi, t0, sel);
3101 rn = "WatchHi";
3102 break;
3103 default:
3104 goto die;
3105 }
3106 break;
3107 case 20:
3108 switch (sel) {
3109 case 0:
3110 #if defined(TARGET_MIPS64)
3111 check_insn(env, ctx, ISA_MIPS3);
3112 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
3113 tcg_gen_ext32s_tl(t0, t0);
3114 rn = "XContext";
3115 break;
3116 #endif
3117 default:
3118 goto die;
3119 }
3120 break;
3121 case 21:
3122 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3123 switch (sel) {
3124 case 0:
3125 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
3126 rn = "Framemask";
3127 break;
3128 default:
3129 goto die;
3130 }
3131 break;
3132 case 22:
3133 tcg_gen_movi_tl(t0, 0); /* unimplemented */
3134 rn = "'Diagnostic"; /* implementation dependent */
3135 break;
3136 case 23:
3137 switch (sel) {
3138 case 0:
3139 gen_helper_mfc0_debug(t0); /* EJTAG support */
3140 rn = "Debug";
3141 break;
3142 case 1:
3143 // gen_helper_mfc0_tracecontrol(t0); /* PDtrace support */
3144 rn = "TraceControl";
3145 // break;
3146 case 2:
3147 // gen_helper_mfc0_tracecontrol2(t0); /* PDtrace support */
3148 rn = "TraceControl2";
3149 // break;
3150 case 3:
3151 // gen_helper_mfc0_usertracedata(t0); /* PDtrace support */
3152 rn = "UserTraceData";
3153 // break;
3154 case 4:
3155 // gen_helper_mfc0_tracebpc(t0); /* PDtrace support */
3156 rn = "TraceBPC";
3157 // break;
3158 default:
3159 goto die;
3160 }
3161 break;
3162 case 24:
3163 switch (sel) {
3164 case 0:
3165 /* EJTAG support */
3166 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
3167 tcg_gen_ext32s_tl(t0, t0);
3168 rn = "DEPC";
3169 break;
3170 default:
3171 goto die;
3172 }
3173 break;
3174 case 25:
3175 switch (sel) {
3176 case 0:
3177 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
3178 rn = "Performance0";
3179 break;
3180 case 1:
3181 // gen_helper_mfc0_performance1(t0);
3182 rn = "Performance1";
3183 // break;
3184 case 2:
3185 // gen_helper_mfc0_performance2(t0);
3186 rn = "Performance2";
3187 // break;
3188 case 3:
3189 // gen_helper_mfc0_performance3(t0);
3190 rn = "Performance3";
3191 // break;
3192 case 4:
3193 // gen_helper_mfc0_performance4(t0);
3194 rn = "Performance4";
3195 // break;
3196 case 5:
3197 // gen_helper_mfc0_performance5(t0);
3198 rn = "Performance5";
3199 // break;
3200 case 6:
3201 // gen_helper_mfc0_performance6(t0);
3202 rn = "Performance6";
3203 // break;
3204 case 7:
3205 // gen_helper_mfc0_performance7(t0);
3206 rn = "Performance7";
3207 // break;
3208 default:
3209 goto die;
3210 }
3211 break;
3212 case 26:
3213 tcg_gen_movi_tl(t0, 0); /* unimplemented */
3214 rn = "ECC";
3215 break;
3216 case 27:
3217 switch (sel) {
3218 case 0 ... 3:
3219 tcg_gen_movi_tl(t0, 0); /* unimplemented */
3220 rn = "CacheErr";
3221 break;
3222 default:
3223 goto die;
3224 }
3225 break;
3226 case 28:
3227 switch (sel) {
3228 case 0:
3229 case 2:
3230 case 4:
3231 case 6:
3232 gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
3233 rn = "TagLo";
3234 break;
3235 case 1:
3236 case 3:
3237 case 5:
3238 case 7:
3239 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
3240 rn = "DataLo";
3241 break;
3242 default:
3243 goto die;
3244 }
3245 break;
3246 case 29:
3247 switch (sel) {
3248 case 0:
3249 case 2:
3250 case 4:
3251 case 6:
3252 gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
3253 rn = "TagHi";
3254 break;
3255 case 1:
3256 case 3:
3257 case 5:
3258 case 7:
3259 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
3260 rn = "DataHi";
3261 break;
3262 default:
3263 goto die;
3264 }
3265 break;
3266 case 30:
3267 switch (sel) {
3268 case 0:
3269 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3270 tcg_gen_ext32s_tl(t0, t0);
3271 rn = "ErrorEPC";
3272 break;
3273 default:
3274 goto die;
3275 }
3276 break;
3277 case 31:
3278 switch (sel) {
3279 case 0:
3280 /* EJTAG support */
3281 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
3282 rn = "DESAVE";
3283 break;
3284 default:
3285 goto die;
3286 }
3287 break;
3288 default:
3289 goto die;
3290 }
3291 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3292 return;
3293
3294 die:
3295 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3296 generate_exception(ctx, EXCP_RI);
3297 }
3298
3299 static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3300 {
3301 const char *rn = "invalid";
3302
3303 if (sel != 0)
3304 check_insn(env, ctx, ISA_MIPS32);
3305
3306 if (use_icount)
3307 gen_io_start();
3308
3309 switch (reg) {
3310 case 0:
3311 switch (sel) {
3312 case 0:
3313 gen_helper_mtc0_index(t0);
3314 rn = "Index";
3315 break;
3316 case 1:
3317 check_insn(env, ctx, ASE_MT);
3318 gen_helper_mtc0_mvpcontrol(t0);
3319 rn = "MVPControl";
3320 break;
3321 case 2:
3322 check_insn(env, ctx, ASE_MT);
3323 /* ignored */
3324 rn = "MVPConf0";
3325 break;
3326 case 3:
3327 check_insn(env, ctx, ASE_MT);
3328 /* ignored */
3329 rn = "MVPConf1";
3330 break;
3331 default:
3332 goto die;
3333 }
3334 break;
3335 case 1:
3336 switch (sel) {
3337 case 0:
3338 /* ignored */
3339 rn = "Random";
3340 break;
3341 case 1:
3342 check_insn(env, ctx, ASE_MT);
3343 gen_helper_mtc0_vpecontrol(t0);
3344 rn = "VPEControl";
3345 break;
3346 case 2:
3347 check_insn(env, ctx, ASE_MT);
3348 gen_helper_mtc0_vpeconf0(t0);
3349 rn = "VPEConf0";
3350 break;
3351 case 3:
3352 check_insn(env, ctx, ASE_MT);
3353 gen_helper_mtc0_vpeconf1(t0);
3354 rn = "VPEConf1";
3355 break;
3356 case 4:
3357 check_insn(env, ctx, ASE_MT);
3358 gen_helper_mtc0_yqmask(t0);
3359 rn = "YQMask";
3360 break;
3361 case 5:
3362 check_insn(env, ctx, ASE_MT);
3363 gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPESchedule));
3364 rn = "VPESchedule";
3365 break;
3366 case 6:
3367 check_insn(env, ctx, ASE_MT);
3368 gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPEScheFBack));
3369 rn = "VPEScheFBack";
3370 break;
3371 case 7:
3372 check_insn(env, ctx, ASE_MT);
3373 gen_helper_mtc0_vpeopt(t0);
3374 rn = "VPEOpt";
3375 break;
3376 default:
3377 goto die;
3378 }
3379 break;
3380 case 2:
3381 switch (sel) {
3382 case 0:
3383 gen_helper_mtc0_entrylo0(t0);
3384 rn = "EntryLo0";
3385 break;
3386 case 1:
3387 check_insn(env, ctx, ASE_MT);
3388 gen_helper_mtc0_tcstatus(t0);
3389 rn = "TCStatus";
3390 break;
3391 case 2:
3392 check_insn(env, ctx, ASE_MT);
3393 gen_helper_mtc0_tcbind(t0);
3394 rn = "TCBind";
3395 break;
3396 case 3:
3397 check_insn(env, ctx, ASE_MT);
3398 gen_helper_mtc0_tcrestart(t0);
3399 rn = "TCRestart";
3400 break;
3401 case 4:
3402 check_insn(env, ctx, ASE_MT);
3403 gen_helper_mtc0_tchalt(t0);
3404 rn = "TCHalt";
3405 break;
3406 case 5:
3407 check_insn(env, ctx, ASE_MT);
3408 gen_helper_mtc0_tccontext(t0);
3409 rn = "TCContext";
3410 break;
3411 case 6:
3412 check_insn(env, ctx, ASE_MT);
3413 gen_helper_mtc0_tcschedule(t0);
3414 rn = "TCSchedule";
3415 break;
3416 case 7:
3417 check_insn(env, ctx, ASE_MT);
3418 gen_helper_mtc0_tcschefback(t0);
3419 rn = "TCScheFBack";
3420 break;
3421 default:
3422 goto die;
3423 }
3424 break;
3425 case 3:
3426 switch (sel) {
3427 case 0:
3428 gen_helper_mtc0_entrylo1(t0);
3429 rn = "EntryLo1";
3430 break;
3431 default:
3432 goto die;
3433 }
3434 break;
3435 case 4:
3436 switch (sel) {
3437 case 0:
3438 gen_helper_mtc0_context(t0);
3439 rn = "Context";
3440 break;
3441 case 1:
3442 // gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
3443 rn = "ContextConfig";
3444 // break;
3445 default:
3446 goto die;
3447 }
3448 break;
3449 case 5:
3450 switch (sel) {
3451 case 0:
3452 gen_helper_mtc0_pagemask(t0);
3453 rn = "PageMask";
3454 break;
3455 case 1:
3456 check_insn(env, ctx, ISA_MIPS32R2);
3457 gen_helper_mtc0_pagegrain(t0);
3458 rn = "PageGrain";
3459 break;
3460 default:
3461 goto die;
3462 }
3463 break;
3464 case 6:
3465 switch (sel) {
3466 case 0:
3467 gen_helper_mtc0_wired(t0);
3468 rn = "Wired";
3469 break;
3470 case 1:
3471 check_insn(env, ctx, ISA_MIPS32R2);
3472 gen_helper_mtc0_srsconf0(t0);
3473 rn = "SRSConf0";
3474 break;
3475 case 2:
3476 check_insn(env, ctx, ISA_MIPS32R2);
3477 gen_helper_mtc0_srsconf1(t0);
3478 rn = "SRSConf1";
3479 break;
3480 case 3:
3481 check_insn(env, ctx, ISA_MIPS32R2);
3482 gen_helper_mtc0_srsconf2(t0);
3483 rn = "SRSConf2";
3484 break;
3485 case 4:
3486 check_insn(env, ctx, ISA_MIPS32R2);
3487 gen_helper_mtc0_srsconf3(t0);
3488 rn = "SRSConf3";
3489 break;
3490 case 5:
3491 check_insn(env, ctx, ISA_MIPS32R2);
3492 gen_helper_mtc0_srsconf4(t0);
3493 rn = "SRSConf4";
3494 break;
3495 default:
3496 goto die;
3497 }
3498 break;
3499 case 7:
3500 switch (sel) {
3501 case 0:
3502 check_insn(env, ctx, ISA_MIPS32R2);
3503 gen_helper_mtc0_hwrena(t0);
3504 rn = "HWREna";
3505 break;
3506 default:
3507 goto die;
3508 }
3509 break;
3510 case 8:
3511 /* ignored */
3512 rn = "BadVAddr";
3513 break;
3514 case 9:
3515 switch (sel) {
3516 case 0:
3517 gen_helper_mtc0_count(t0);
3518 rn = "Count";
3519 break;
3520 /* 6,7 are implementation dependent */
3521 default:
3522 goto die;
3523 }
3524 /* Stop translation as we may have switched the execution mode */
3525 ctx->bstate = BS_STOP;
3526 break;
3527 case 10:
3528 switch (sel) {
3529 case 0:
3530 gen_helper_mtc0_entryhi(t0);
3531 rn = "EntryHi";
3532 break;
3533 default:
3534 goto die;
3535 }
3536 break;
3537 case 11:
3538 switch (sel) {
3539 case 0:
3540 gen_helper_mtc0_compare(t0);
3541 rn = "Compare";
3542 break;
3543 /* 6,7 are implementation dependent */
3544 default:
3545 goto die;
3546 }
3547 /* Stop translation as we may have switched the execution mode */
3548 ctx->bstate = BS_STOP;
3549 break;
3550 case 12:
3551 switch (sel) {
3552 case 0:
3553 gen_helper_mtc0_status(t0);
3554 /* BS_STOP isn't good enough here, hflags may have changed. */
3555 gen_save_pc(ctx->pc + 4);
3556 ctx->bstate = BS_EXCP;
3557 rn = "Status";
3558 break;
3559 case 1:
3560 check_insn(env, ctx, ISA_MIPS32R2);
3561 gen_helper_mtc0_intctl(t0);
3562 /* Stop translation as we may have switched the execution mode */
3563 ctx->bstate = BS_STOP;
3564 rn = "IntCtl";
3565 break;
3566 case 2:
3567 check_insn(env, ctx, ISA_MIPS32R2);
3568 gen_helper_mtc0_srsctl(t0);
3569 /* Stop translation as we may have switched the execution mode */
3570 ctx->bstate = BS_STOP;
3571 rn = "SRSCtl";
3572 break;
3573 case 3:
3574 check_insn(env, ctx, ISA_MIPS32R2);
3575 gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
3576 /* Stop translation as we may have switched the execution mode */
3577 ctx->bstate = BS_STOP;
3578 rn = "SRSMap";
3579 break;
3580 default:
3581 goto die;
3582 }
3583 break;
3584 case 13:
3585 switch (sel) {
3586 case 0:
3587 gen_helper_mtc0_cause(t0);
3588 rn = "Cause";
3589 break;
3590 default:
3591 goto die;
3592 }
3593 /* Stop translation as we may have switched the execution mode */
3594 ctx->bstate = BS_STOP;
3595 break;
3596 case 14:
3597 switch (sel) {
3598 case 0:
3599 gen_mtc0_store64(t0, offsetof(CPUState, CP0_EPC));
3600 rn = "EPC";
3601 break;
3602 default:
3603 goto die;
3604 }
3605 break;
3606 case 15:
3607 switch (sel) {
3608 case 0:
3609 /* ignored */
3610 rn = "PRid";
3611 break;
3612 case 1:
3613 check_insn(env, ctx, ISA_MIPS32R2);
3614 gen_helper_mtc0_ebase(t0);
3615 rn = "EBase";
3616 break;
3617 default:
3618 goto die;
3619 }
3620 break;
3621 case 16:
3622 switch (sel) {
3623 case 0:
3624 gen_helper_mtc0_config0(t0);
3625 rn = "Config";
3626 /* Stop translation as we may have switched the execution mode */
3627 ctx->bstate = BS_STOP;
3628 break;
3629 case 1:
3630 /* ignored, read only */
3631 rn = "Config1";
3632 break;
3633 case 2:
3634 gen_helper_mtc0_config2(t0);
3635 rn = "Config2";
3636 /* Stop translation as we may have switched the execution mode */
3637 ctx->bstate = BS_STOP;
3638 break;
3639 case 3:
3640 /* ignored, read only */
3641 rn = "Config3";
3642 break;
3643 /* 4,5 are reserved */
3644 /* 6,7 are implementation dependent */
3645 case 6:
3646 /* ignored */
3647 rn = "Config6";
3648 break;
3649 case 7:
3650 /* ignored */
3651 rn = "Config7";
3652 break;
3653 default:
3654 rn = "Invalid config selector";
3655 goto die;
3656 }
3657 break;
3658 case 17:
3659 switch (sel) {
3660 case 0:
3661 /* ignored */
3662 rn = "LLAddr";
3663 break;
3664 default:
3665 goto die;
3666 }
3667 break;
3668 case 18:
3669 switch (sel) {
3670 case 0 ... 7:
3671 gen_helper_1i(mtc0_watchlo, t0, sel);
3672 rn = "WatchLo";
3673 break;
3674 default:
3675 goto die;
3676 }
3677 break;
3678 case 19:
3679 switch (sel) {
3680 case 0 ... 7:
3681 gen_helper_1i(mtc0_watchhi, t0, sel);
3682 rn = "WatchHi";
3683 break;
3684 default:
3685 goto die;
3686 }
3687 break;
3688 case 20:
3689 switch (sel) {
3690 case 0:
3691 #if defined(TARGET_MIPS64)
3692 check_insn(env, ctx, ISA_MIPS3);
3693 gen_helper_mtc0_xcontext(t0);
3694 rn = "XContext";
3695 break;
3696 #endif
3697 default:
3698 goto die;
3699 }
3700 break;
3701 case 21:
3702 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3703 switch (sel) {
3704 case 0:
3705 gen_helper_mtc0_framemask(t0);
3706 rn = "Framemask";
3707 break;
3708 default:
3709 goto die;
3710 }
3711 break;
3712 case 22:
3713 /* ignored */
3714 rn = "Diagnostic"; /* implementation dependent */
3715 break;
3716 case 23:
3717 switch (sel) {
3718 case 0:
3719 gen_helper_mtc0_debug(t0); /* EJTAG support */
3720 /* BS_STOP isn't good enough here, hflags may have changed. */
3721 gen_save_pc(ctx->pc + 4);
3722 ctx->bstate = BS_EXCP;
3723 rn = "Debug";
3724 break;
3725 case 1:
3726 // gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
3727 rn = "TraceControl";
3728 /* Stop translation as we may have switched the execution mode */
3729 ctx->bstate = BS_STOP;
3730 // break;
3731 case 2:
3732 // gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
3733 rn = "TraceControl2";
3734 /* Stop translation as we may have switched the execution mode */
3735 ctx->bstate = BS_STOP;
3736 // break;
3737 case 3:
3738 /* Stop translation as we may have switched the execution mode */
3739 ctx->bstate = BS_STOP;
3740 // gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
3741 rn = "UserTraceData";
3742 /* Stop translation as we may have switched the execution mode */
3743 ctx->bstate = BS_STOP;
3744 // break;
3745 case 4:
3746 // gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
3747 /* Stop translation as we may have switched the execution mode */
3748 ctx->bstate = BS_STOP;
3749 rn = "TraceBPC";
3750 // break;
3751 default:
3752 goto die;
3753 }
3754 break;
3755 case 24:
3756 switch (sel) {
3757 case 0:
3758 /* EJTAG support */
3759 gen_mtc0_store64(t0, offsetof(CPUState, CP0_DEPC));
3760 rn = "DEPC";
3761 break;
3762 default:
3763 goto die;
3764 }
3765 break;
3766 case 25:
3767 switch (sel) {
3768 case 0:
3769 gen_helper_mtc0_performance0(t0);
3770 rn = "Performance0";
3771 break;
3772 case 1:
3773 // gen_helper_mtc0_performance1(t0);
3774 rn = "Performance1";
3775 // break;
3776 case 2:
3777 // gen_helper_mtc0_performance2(t0);
3778 rn = "Performance2";
3779 // break;
3780 case 3:
3781 // gen_helper_mtc0_performance3(t0);
3782 rn = "Performance3";
3783 // break;
3784 case 4:
3785 // gen_helper_mtc0_performance4(t0);
3786 rn = "Performance4";
3787 // break;
3788 case 5:
3789 // gen_helper_mtc0_performance5(t0);
3790 rn = "Performance5";
3791 // break;
3792 case 6:
3793 // gen_helper_mtc0_performance6(t0);
3794 rn = "Performance6";
3795 // break;
3796 case 7:
3797 // gen_helper_mtc0_performance7(t0);
3798 rn = "Performance7";
3799 // break;
3800 default:
3801 goto die;
3802 }
3803 break;
3804 case 26:
3805 /* ignored */
3806 rn = "ECC";
3807 break;
3808 case 27:
3809 switch (sel) {
3810 case 0 ... 3:
3811 /* ignored */
3812 rn = "CacheErr";
3813 break;
3814 default:
3815 goto die;
3816 }
3817 break;
3818 case 28:
3819 switch (sel) {
3820 case 0:
3821 case 2:
3822 case 4:
3823 case 6:
3824 gen_helper_mtc0_taglo(t0);
3825 rn = "TagLo";
3826 break;
3827 case 1:
3828 case 3:
3829 case 5:
3830 case 7:
3831 gen_helper_mtc0_datalo(t0);
3832 rn = "DataLo";
3833 break;
3834 default:
3835 goto die;
3836 }
3837 break;
3838 case 29:
3839 switch (sel) {
3840 case 0:
3841 case 2:
3842 case 4:
3843 case 6:
3844 gen_helper_mtc0_taghi(t0);
3845 rn = "TagHi";
3846 break;
3847 case 1:
3848 case 3:
3849 case 5:
3850 case 7:
3851 gen_helper_mtc0_datahi(t0);
3852 rn = "DataHi";
3853 break;
3854 default:
3855 rn = "invalid sel";
3856 goto die;
3857 }
3858 break;
3859 case 30:
3860 switch (sel) {
3861 case 0:
3862 gen_mtc0_store64(t0, offsetof(CPUState, CP0_ErrorEPC));
3863 rn = "ErrorEPC";
3864 break;
3865 default:
3866 goto die;
3867 }
3868 break;
3869 case 31:
3870 switch (sel) {
3871 case 0:
3872 /* EJTAG support */
3873 gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
3874 rn = "DESAVE";
3875 break;
3876 default:
3877 goto die;
3878 }
3879 /* Stop translation as we may have switched the execution mode */
3880 ctx->bstate = BS_STOP;
3881 break;
3882 default:
3883 goto die;
3884 }
3885 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3886 /* For simplicity assume that all writes can cause interrupts. */
3887 if (use_icount) {
3888 gen_io_end();
3889 ctx->bstate = BS_STOP;
3890 }
3891 return;
3892
3893 die:
3894 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3895 generate_exception(ctx, EXCP_RI);
3896 }
3897
3898 #if defined(TARGET_MIPS64)
3899 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3900 {
3901 const char *rn = "invalid";
3902
3903 if (sel != 0)
3904 check_insn(env, ctx, ISA_MIPS64);
3905
3906 switch (reg) {
3907 case 0:
3908 switch (sel) {
3909 case 0:
3910 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
3911 rn = "Index";
3912 break;
3913 case 1:
3914 check_insn(env, ctx, ASE_MT);
3915 gen_helper_mfc0_mvpcontrol(t0);
3916 rn = "MVPControl";
3917 break;
3918 case 2:
3919 check_insn(env, ctx, ASE_MT);
3920 gen_helper_mfc0_mvpconf0(t0);
3921 rn = "MVPConf0";
3922 break;
3923 case 3:
3924 check_insn(env, ctx, ASE_MT);
3925 gen_helper_mfc0_mvpconf1(t0);
3926 rn = "MVPConf1";
3927 break;
3928 default:
3929 goto die;
3930 }
3931 break;
3932 case 1:
3933 switch (sel) {
3934 case 0:
3935 gen_helper_mfc0_random(t0);
3936 rn = "Random";
3937 break;
3938 case 1:
3939 check_insn(env, ctx, ASE_MT);
3940 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
3941 rn = "VPEControl";
3942 break;
3943 case 2:
3944 check_insn(env, ctx, ASE_MT);
3945 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
3946 rn = "VPEConf0";
3947 break;
3948 case 3:
3949 check_insn(env, ctx, ASE_MT);
3950 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
3951 rn = "VPEConf1";
3952 break;
3953 case 4:
3954 check_insn(env, ctx, ASE_MT);
3955 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_YQMask));
3956 rn = "YQMask";
3957 break;
3958 case 5:
3959 check_insn(env, ctx, ASE_MT);
3960 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
3961 rn = "VPESchedule";
3962 break;
3963 case 6:
3964 check_insn(env, ctx, ASE_MT);
3965 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3966 rn = "VPEScheFBack";
3967 break;
3968 case 7:
3969 check_insn(env, ctx, ASE_MT);
3970 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
3971 rn = "VPEOpt";
3972 break;
3973 default:
3974 goto die;
3975 }
3976 break;
3977 case 2:
3978 switch (sel) {
3979 case 0:
3980 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
3981 rn = "EntryLo0";
3982 break;
3983 case 1:
3984 check_insn(env, ctx, ASE_MT);
3985 gen_helper_mfc0_tcstatus(t0);
3986 rn = "TCStatus";
3987 break;
3988 case 2:
3989 check_insn(env, ctx, ASE_MT);
3990 gen_helper_mfc0_tcbind(t0);
3991 rn = "TCBind";
3992 break;
3993 case 3:
3994 check_insn(env, ctx, ASE_MT);
3995 gen_helper_dmfc0_tcrestart(t0);
3996 rn = "TCRestart";
3997 break;
3998 case 4:
3999 check_insn(env, ctx, ASE_MT);
4000 gen_helper_dmfc0_tchalt(t0);
4001 rn = "TCHalt";
4002 break;
4003 case 5:
4004 check_insn(env, ctx, ASE_MT);
4005 gen_helper_dmfc0_tccontext(t0);
4006 rn = "TCContext";
4007 break;
4008 case 6:
4009 check_insn(env, ctx, ASE_MT);
4010 gen_helper_dmfc0_tcschedule(t0);
4011 rn = "TCSchedule";
4012 break;
4013 case 7:
4014 check_insn(env, ctx, ASE_MT);
4015 gen_helper_dmfc0_tcschefback(t0);
4016 rn = "TCScheFBack";
4017 break;
4018 default:
4019 goto die;
4020 }
4021 break;
4022 case 3:
4023 switch (sel) {
4024 case 0:
4025 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4026 rn = "EntryLo1";
4027 break;
4028 default:
4029 goto die;
4030 }
4031 break;
4032 case 4:
4033 switch (sel) {
4034 case 0:
4035 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
4036 rn = "Context";
4037 break;
4038 case 1:
4039 // gen_helper_dmfc0_contextconfig(t0); /* SmartMIPS ASE */
4040 rn = "ContextConfig";
4041 // break;
4042 default:
4043 goto die;
4044 }
4045 break;
4046 case 5:
4047 switch (sel) {
4048 case 0:
4049 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
4050 rn = "PageMask";
4051 break;
4052 case 1:
4053 check_insn(env, ctx, ISA_MIPS32R2);
4054 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
4055 rn = "PageGrain";
4056 break;
4057 default:
4058 goto die;
4059 }
4060 break;
4061 case 6:
4062 switch (sel) {
4063 case 0:
4064 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
4065 rn = "Wired";
4066 break;
4067 case 1:
4068 check_insn(env, ctx, ISA_MIPS32R2);
4069 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
4070 rn = "SRSConf0";
4071 break;
4072 case 2:
4073 check_insn(env, ctx, ISA_MIPS32R2);
4074 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
4075 rn = "SRSConf1";
4076 break;
4077 case 3:
4078 check_insn(env, ctx, ISA_MIPS32R2);
4079 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
4080 rn = "SRSConf2";
4081 break;
4082 case 4:
4083 check_insn(env, ctx, ISA_MIPS32R2);
4084 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
4085 rn = "SRSConf3";
4086 break;
4087 case 5:
4088 check_insn(env, ctx, ISA_MIPS32R2);
4089 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
4090 rn = "SRSConf4";
4091 break;
4092 default:
4093 goto die;
4094 }
4095 break;
4096 case 7:
4097 switch (sel) {
4098 case 0:
4099 check_insn(env, ctx, ISA_MIPS32R2);
4100 gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
4101 rn = "HWREna";
4102 break;
4103 default:
4104 goto die;
4105 }
4106 break;
4107 case 8:
4108 switch (sel) {
4109 case 0:
4110 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4111 rn = "BadVAddr";
4112 break;
4113 default:
4114 goto die;
4115 }
4116 break;
4117 case 9:
4118 switch (sel) {
4119 case 0:
4120 /* Mark as an IO operation because we read the time. */
4121 if (use_icount)
4122 gen_io_start();
4123 gen_helper_mfc0_count(t0);
4124 if (use_icount) {
4125 gen_io_end();
4126 ctx->bstate = BS_STOP;
4127 }
4128 rn = "Count";
4129 break;
4130 /* 6,7 are implementation dependent */
4131 default:
4132 goto die;
4133 }
4134 break;
4135 case 10:
4136 switch (sel) {
4137 case 0:
4138 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
4139 rn = "EntryHi";
4140 break;
4141 default:
4142 goto die;
4143 }
4144 break;
4145 case 11:
4146 switch (sel) {
4147 case 0:
4148 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
4149 rn = "Compare";
4150 break;
4151 /* 6,7 are implementation dependent */
4152 default:
4153 goto die;
4154 }
4155 break;
4156 case 12:
4157 switch (sel) {
4158 case 0:
4159 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
4160 rn = "Status";
4161 break;
4162 case 1:
4163 check_insn(env, ctx, ISA_MIPS32R2);
4164 gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
4165 rn = "IntCtl";
4166 break;
4167 case 2:
4168 check_insn(env, ctx, ISA_MIPS32R2);
4169 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
4170 rn = "SRSCtl";
4171 break;
4172 case 3:
4173 check_insn(env, ctx, ISA_MIPS32R2);
4174 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
4175 rn = "SRSMap";
4176 break;
4177 default:
4178 goto die;
4179 }
4180 break;
4181 case 13:
4182 switch (sel) {
4183 case 0:
4184 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
4185 rn = "Cause";
4186 break;
4187 default:
4188 goto die;
4189 }
4190 break;
4191 case 14:
4192 switch (sel) {
4193 case 0:
4194 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4195 rn = "EPC";
4196 break;
4197 default:
4198 goto die;
4199 }
4200 break;
4201 case 15:
4202 switch (sel) {
4203 case 0:
4204 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
4205 rn = "PRid";
4206 break;
4207 case 1:
4208 check_insn(env, ctx, ISA_MIPS32R2);
4209 gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
4210 rn = "EBase";
4211 break;
4212 default:
4213 goto die;
4214 }
4215 break;
4216 case 16:
4217 switch (sel) {
4218 case 0:
4219 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
4220 rn = "Config";
4221 break;
4222 case 1:
4223 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
4224 rn = "Config1";
4225 break;
4226 case 2:
4227 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
4228 rn = "Config2";
4229 break;
4230 case 3:
4231 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
4232 rn = "Config3";
4233 break;
4234 /* 6,7 are implementation dependent */
4235 case 6:
4236 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
4237 rn = "Config6";
4238 break;
4239 case 7:
4240 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
4241 rn = "Config7";
4242 break;
4243 default:
4244 goto die;
4245 }
4246 break;
4247 case 17:
4248 switch (sel) {
4249 case 0:
4250 gen_helper_dmfc0_lladdr(t0);
4251 rn = "LLAddr";
4252 break;
4253 default:
4254 goto die;
4255 }
4256 break;
4257 case 18:
4258 switch (sel) {
4259 case 0 ... 7:
4260 gen_helper_1i(dmfc0_watchlo, t0, sel);
4261 rn = "WatchLo";
4262 break;
4263 default:
4264 goto die;
4265 }
4266 break;
4267 case 19:
4268 switch (sel) {
4269 case 0 ... 7:
4270 gen_helper_1i(mfc0_watchhi, t0, sel);
4271 rn = "WatchHi";
4272 break;
4273 default:
4274 goto die;
4275 }
4276 break;
4277 case 20:
4278 switch (sel) {
4279 case 0:
4280 check_insn(env, ctx, ISA_MIPS3);
4281 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
4282 rn = "XContext";
4283 break;
4284 default:
4285 goto die;
4286 }
4287 break;
4288 case 21:
4289 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4290 switch (sel) {
4291 case 0:
4292 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
4293 rn = "Framemask";
4294 break;
4295 default:
4296 goto die;
4297 }
4298 break;
4299 case 22:
4300 tcg_gen_movi_tl(t0, 0); /* unimplemented */
4301 rn = "'Diagnostic"; /* implementation dependent */
4302 break;
4303 case 23:
4304 switch (sel) {
4305 case 0:
4306 gen_helper_mfc0_debug(t0); /* EJTAG support */
4307 rn = "Debug";
4308 break;
4309 case 1:
4310 // gen_helper_dmfc0_tracecontrol(t0); /* PDtrace support */
4311 rn = "TraceControl";
4312 // break;
4313 case 2:
4314 // gen_helper_dmfc0_tracecontrol2(t0); /* PDtrace support */
4315 rn = "TraceControl2";
4316 // break;
4317 case 3:
4318 // gen_helper_dmfc0_usertracedata(t0); /* PDtrace support */
4319 rn = "UserTraceData";
4320 // break;
4321 case 4:
4322 // gen_helper_dmfc0_tracebpc(t0); /* PDtrace support */
4323 rn = "TraceBPC";
4324 // break;
4325 default:
4326 goto die;
4327 }
4328 break;
4329 case 24:
4330 switch (sel) {
4331 case 0:
4332 /* EJTAG support */
4333 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4334 rn = "DEPC";
4335 break;
4336 default:
4337 goto die;
4338 }
4339 break;
4340 case 25:
4341 switch (sel) {
4342 case 0:
4343 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
4344 rn = "Performance0";
4345 break;
4346 case 1:
4347 // gen_helper_dmfc0_performance1(t0);
4348 rn = "Performance1";
4349 // break;
4350 case 2:
4351 // gen_helper_dmfc0_performance2(t0);
4352 rn = "Performance2";
4353 // break;
4354 case 3:
4355 // gen_helper_dmfc0_performance3(t0);
4356 rn = "Performance3";
4357 // break;
4358 case 4:
4359 // gen_helper_dmfc0_performance4(t0);
4360 rn = "Performance4";
4361 // break;
4362 case 5:
4363 // gen_helper_dmfc0_performance5(t0);
4364 rn = "Performance5";
4365 // break;
4366 case 6:
4367 // gen_helper_dmfc0_performance6(t0);
4368 rn = "Performance6";
4369 // break;
4370 case 7:
4371 // gen_helper_dmfc0_performance7(t0);
4372 rn = "Performance7";
4373 // break;
4374 default:
4375 goto die;
4376 }
4377 break;
4378 case 26:
4379 tcg_gen_movi_tl(t0, 0); /* unimplemented */
4380 rn = "ECC";
4381 break;
4382 case 27:
4383 switch (sel) {
4384 /* ignored */
4385 case 0 ... 3:
4386 tcg_gen_movi_tl(t0, 0); /* unimplemented */
4387 rn = "CacheErr";
4388 break;
4389 default:
4390 goto die;
4391 }
4392 break;
4393 case 28:
4394 switch (sel) {
4395 case 0:
4396 case 2:
4397 case 4:
4398 case 6:
4399 gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
4400 rn = "TagLo";
4401 break;
4402 case 1:
4403 case 3:
4404 case 5:
4405 case 7:
4406 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
4407 rn = "DataLo";
4408 break;
4409 default:
4410 goto die;
4411 }
4412 break;
4413 case 29:
4414 switch (sel) {
4415 case 0:
4416 case 2:
4417 case 4:
4418 case 6:
4419 gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
4420 rn = "TagHi";
4421 break;
4422 case 1:
4423 case 3:
4424 case 5:
4425 case 7:
4426 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
4427 rn = "DataHi";
4428 break;
4429 default:
4430 goto die;
4431 }
4432 break;
4433 case 30:
4434 switch (sel) {
4435 case 0:
4436 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4437 rn = "ErrorEPC";
4438 break;
4439 default:
4440 goto die;
4441 }
4442 break;
4443 case 31:
4444 switch (sel) {
4445 case 0:
4446 /* EJTAG support */
4447 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
4448 rn = "DESAVE";
4449 break;
4450 default:
4451 goto die;
4452 }
4453 break;
4454 default:
4455 goto die;
4456 }
4457 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4458 return;
4459
4460 die:
4461 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4462 generate_exception(ctx, EXCP_RI);
4463 }
4464
4465 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4466 {
4467 const char *rn = "invalid";
4468
4469 if (sel != 0)
4470 check_insn(env, ctx, ISA_MIPS64);
4471
4472 if (use_icount)
4473 gen_io_start();
4474
4475 switch (reg) {
4476 case 0:
4477 switch (sel) {
4478 case 0:
4479 gen_helper_mtc0_index(t0);
4480 rn = "Index";
4481 break;
4482 case 1:
4483 check_insn(env, ctx, ASE_MT);
4484 gen_helper_mtc0_mvpcontrol(t0);
4485 rn = "MVPControl";
4486 break;
4487 case 2:
4488 check_insn(env, ctx, ASE_MT);
4489 /* ignored */
4490 rn = "MVPConf0";
4491 break;
4492 case 3:
4493 check_insn(env, ctx, ASE_MT);
4494 /* ignored */
4495 rn = "MVPConf1";
4496 break;
4497 default:
4498 goto die;
4499 }
4500 break;
4501 case 1:
4502 switch (sel) {
4503 case 0:
4504 /* ignored */
4505 rn = "Random";
4506 break;
4507 case 1:
4508 check_insn(env, ctx, ASE_MT);
4509 gen_helper_mtc0_vpecontrol(t0);
4510 rn = "VPEControl";
4511 break;
4512 case 2:
4513 check_insn(env, ctx, ASE_MT);
4514 gen_helper_mtc0_vpeconf0(t0);
4515 rn = "VPEConf0";
4516 break;
4517 case 3:
4518 check_insn(env, ctx, ASE_MT);
4519 gen_helper_mtc0_vpeconf1(t0);
4520 rn = "VPEConf1";
4521 break;
4522 case 4:
4523 check_insn(env, ctx, ASE_MT);
4524 gen_helper_mtc0_yqmask(t0);
4525 rn = "YQMask";
4526 break;
4527 case 5:
4528 check_insn(env, ctx, ASE_MT);
4529 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4530 rn = "VPESchedule";
4531 break;
4532 case 6:
4533 check_insn(env, ctx, ASE_MT);
4534 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4535 rn = "VPEScheFBack";
4536 break;
4537 case 7:
4538 check_insn(env, ctx, ASE_MT);
4539 gen_helper_mtc0_vpeopt(t0);
4540 rn = "VPEOpt";
4541 break;
4542 default:
4543 goto die;
4544 }
4545 break;
4546 case 2:
4547 switch (sel) {
4548 case 0:
4549 gen_helper_mtc0_entrylo0(t0);
4550 rn = "EntryLo0";
4551 break;
4552 case 1:
4553 check_insn(env, ctx, ASE_MT);
4554 gen_helper_mtc0_tcstatus(t0);
4555 rn = "TCStatus";
4556 break;
4557 case 2:
4558 check_insn(env, ctx, ASE_MT);
4559 gen_helper_mtc0_tcbind(t0);
4560 rn = "TCBind";
4561 break;
4562 case 3:
4563 check_insn(env, ctx, ASE_MT);
4564 gen_helper_mtc0_tcrestart(t0);
4565 rn = "TCRestart";
4566 break;
4567 case 4:
4568 check_insn(env, ctx, ASE_MT);
4569 gen_helper_mtc0_tchalt(t0);
4570 rn = "TCHalt";
4571 break;
4572 case 5:
4573 check_insn(env, ctx, ASE_MT);
4574 gen_helper_mtc0_tccontext(t0);
4575 rn = "TCContext";
4576 break;
4577 case 6:
4578 check_insn(env, ctx, ASE_MT);
4579 gen_helper_mtc0_tcschedule(t0);
4580 rn = "TCSchedule";
4581 break;
4582 case 7:
4583 check_insn(env, ctx, ASE_MT);
4584 gen_helper_mtc0_tcschefback(t0);
4585 rn = "TCScheFBack";
4586 break;
4587 default:
4588 goto die;
4589 }
4590 break;
4591 case 3:
4592 switch (sel) {
4593 case 0:
4594 gen_helper_mtc0_entrylo1(t0);
4595 rn = "EntryLo1";
4596 break;
4597 default:
4598 goto die;
4599 }
4600 break;
4601 case 4:
4602 switch (sel) {
4603 case 0:
4604 gen_helper_mtc0_context(t0);
4605 rn = "Context";
4606 break;
4607 case 1:
4608 // gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
4609 rn = "ContextConfig";
4610 // break;
4611 default:
4612 goto die;
4613 }
4614 break;
4615 case 5:
4616 switch (sel) {
4617 case 0:
4618 gen_helper_mtc0_pagemask(t0);
4619 rn = "PageMask";
4620 break;
4621 case 1:
4622 check_insn(env, ctx, ISA_MIPS32R2);
4623 gen_helper_mtc0_pagegrain(t0);
4624 rn = "PageGrain";
4625 break;
4626 default:
4627 goto die;
4628 }
4629 break;
4630 case 6:
4631 switch (sel) {
4632 case 0:
4633 gen_helper_mtc0_wired(t0);
4634 rn = "Wired";
4635 break;
4636 case 1:
4637 check_insn(env, ctx, ISA_MIPS32R2);
4638 gen_helper_mtc0_srsconf0(t0);
4639 rn = "SRSConf0";
4640 break;
4641 case 2:
4642 check_insn(env, ctx, ISA_MIPS32R2);
4643 gen_helper_mtc0_srsconf1(t0);
4644 rn = "SRSConf1";
4645 break;
4646 case 3:
4647 check_insn(env, ctx, ISA_MIPS32R2);
4648 gen_helper_mtc0_srsconf2(t0);
4649 rn = "SRSConf2";
4650 break;
4651 case 4:
4652 check_insn(env, ctx, ISA_MIPS32R2);
4653 gen_helper_mtc0_srsconf3(t0);
4654 rn = "SRSConf3";
4655 break;
4656 case 5:
4657 check_insn(env, ctx, ISA_MIPS32R2);
4658 gen_helper_mtc0_srsconf4(t0);
4659 rn = "SRSConf4";
4660 break;
4661 default:
4662 goto die;
4663 }
4664 break;
4665 case 7:
4666 switch (sel) {
4667 case 0:
4668 check_insn(env, ctx, ISA_MIPS32R2);
4669 gen_helper_mtc0_hwrena(t0);
4670 rn = "HWREna";
4671 break;
4672 default:
4673 goto die;
4674 }
4675 break;
4676 case 8:
4677 /* ignored */
4678 rn = "BadVAddr";
4679 break;
4680 case 9:
4681 switch (sel) {
4682 case 0:
4683 gen_helper_mtc0_count(t0);
4684 rn = "Count";
4685 break;
4686 /* 6,7 are implementation dependent */
4687 default:
4688 goto die;
4689 }
4690 /* Stop translation as we may have switched the execution mode */
4691 ctx->bstate = BS_STOP;
4692 break;
4693 case 10:
4694 switch (sel) {
4695 case 0:
4696 gen_helper_mtc0_entryhi(t0);
4697 rn = "EntryHi";
4698 break;
4699 default:
4700 goto die;
4701 }
4702 break;
4703 case 11:
4704 switch (sel) {
4705 case 0:
4706 gen_helper_mtc0_compare(t0);
4707 rn = "Compare";
4708 break;
4709 /* 6,7 are implementation dependent */
4710 default:
4711 goto die;
4712 }
4713 /* Stop translation as we may have switched the execution mode */
4714 ctx->bstate = BS_STOP;
4715 break;
4716 case 12:
4717 switch (sel) {
4718 case 0:
4719 gen_helper_mtc0_status(t0);
4720 /* BS_STOP isn't good enough here, hflags may have changed. */
4721 gen_save_pc(ctx->pc + 4);
4722 ctx->bstate = BS_EXCP;
4723 rn = "Status";
4724 break;
4725 case 1:
4726 check_insn(env, ctx, ISA_MIPS32R2);
4727 gen_helper_mtc0_intctl(t0);
4728 /* Stop translation as we may have switched the execution mode */
4729 ctx->bstate = BS_STOP;
4730 rn = "IntCtl";
4731 break;
4732 case 2:
4733 check_insn(env, ctx, ISA_MIPS32R2);
4734 gen_helper_mtc0_srsctl(t0);
4735 /* Stop translation as we may have switched the execution mode */
4736 ctx->bstate = BS_STOP;
4737 rn = "SRSCtl";
4738 break;
4739 case 3:
4740 check_insn(env, ctx, ISA_MIPS32R2);
4741 gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
4742 /* Stop translation as we may have switched the execution mode */
4743 ctx->bstate = BS_STOP;
4744 rn = "SRSMap";
4745 break;
4746 default:
4747 goto die;
4748 }
4749 break;
4750 case 13:
4751 switch (sel) {
4752 case 0:
4753 gen_helper_mtc0_cause(t0);
4754 rn = "Cause";
4755 break;
4756 default:
4757 goto die;
4758 }
4759 /* Stop translation as we may have switched the execution mode */
4760 ctx->bstate = BS_STOP;
4761 break;
4762 case 14:
4763 switch (sel) {
4764 case 0:
4765 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4766 rn = "EPC";
4767 break;
4768 default:
4769 goto die;
4770 }
4771 break;
4772 case 15:
4773 switch (sel) {
4774 case 0:
4775 /* ignored */
4776 rn = "PRid";
4777 break;
4778 case 1:
4779 check_insn(env, ctx, ISA_MIPS32R2);
4780 gen_helper_mtc0_ebase(t0);
4781 rn = "EBase";
4782 break;
4783 default:
4784 goto die;
4785 }
4786 break;
4787 case 16:
4788 switch (sel) {
4789 case 0:
4790 gen_helper_mtc0_config0(t0);
4791 rn = "Config";
4792 /* Stop translation as we may have switched the execution mode */
4793 ctx->bstate = BS_STOP;
4794 break;
4795 case 1:
4796 /* ignored */
4797 rn = "Config1";
4798 break;
4799 case 2:
4800 gen_helper_mtc0_config2(t0);
4801 rn = "Config2";
4802 /* Stop translation as we may have switched the execution mode */
4803 ctx->bstate = BS_STOP;
4804 break;
4805 case 3:
4806 /* ignored */
4807 rn = "Config3";
4808 break;
4809 /* 6,7 are implementation dependent */
4810 default:
4811 rn = "Invalid config selector";
4812 goto die;
4813 }
4814 break;
4815 case 17:
4816 switch (sel) {
4817 case 0:
4818 /* ignored */
4819 rn = "LLAddr";
4820 break;
4821 default:
4822 goto die;
4823 }
4824 break;
4825 case 18:
4826 switch (sel) {
4827 case 0 ... 7:
4828 gen_helper_1i(mtc0_watchlo, t0, sel);
4829 rn = "WatchLo";
4830 break;
4831 default:
4832 goto die;
4833 }
4834 break;
4835 case 19:
4836 switch (sel) {
4837 case 0 ... 7:
4838 gen_helper_1i(mtc0_watchhi, t0, sel);
4839 rn = "WatchHi";
4840 break;
4841 default:
4842 goto die;
4843 }
4844 break;
4845 case 20:
4846 switch (sel) {
4847 case 0:
4848 check_insn(env, ctx, ISA_MIPS3);
4849 gen_helper_mtc0_xcontext(t0);
4850 rn = "XContext";
4851 break;
4852 default:
4853 goto die;
4854 }
4855 break;
4856 case 21:
4857 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4858 switch (sel) {
4859 case 0:
4860 gen_helper_mtc0_framemask(t0);
4861 rn = "Framemask";
4862 break;
4863 default:
4864 goto die;
4865 }
4866 break;
4867 case 22:
4868 /* ignored */
4869 rn = "Diagnostic"; /* implementation dependent */
4870 break;
4871 case 23:
4872 switch (sel) {
4873 case 0:
4874 gen_helper_mtc0_debug(t0); /* EJTAG support */
4875 /* BS_STOP isn't good enough here, hflags may have changed. */
4876 gen_save_pc(ctx->pc + 4);
4877 ctx->bstate = BS_EXCP;
4878 rn = "Debug";
4879 break;
4880 case 1:
4881 // gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
4882 /* Stop translation as we may have switched the execution mode */
4883 ctx->bstate = BS_STOP;
4884 rn = "TraceControl";
4885 // break;
4886 case 2:
4887 // gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
4888 /* Stop translation as we may have switched the execution mode */
4889 ctx->bstate = BS_STOP;
4890 rn = "TraceControl2";
4891 // break;
4892 case 3:
4893 // gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
4894 /* Stop translation as we may have switched the execution mode */
4895 ctx->bstate = BS_STOP;
4896 rn = "UserTraceData";
4897 // break;
4898 case 4:
4899 // gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
4900 /* Stop translation as we may have switched the execution mode */
4901 ctx->bstate = BS_STOP;
4902 rn = "TraceBPC";
4903 // break;
4904 default:
4905 goto die;
4906 }
4907 break;
4908 case 24:
4909 switch (sel) {
4910 case 0:
4911 /* EJTAG support */
4912 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4913 rn = "DEPC";
4914 break;
4915 default:
4916 goto die;
4917 }
4918 break;
4919 case 25:
4920 switch (sel) {
4921 case 0:
4922 gen_helper_mtc0_performance0(t0);
4923 rn = "Performance0";
4924 break;
4925 case 1:
4926 // gen_helper_mtc0_performance1(t0);
4927 rn = "Performance1";
4928 // break;
4929 case 2:
4930 // gen_helper_mtc0_performance2(t0);
4931 rn = "Performance2";
4932 // break;
4933 case 3:
4934 // gen_helper_mtc0_performance3(t0);
4935 rn = "Performance3";
4936 // break;
4937 case 4:
4938 // gen_helper_mtc0_performance4(t0);
4939 rn = "Performance4";
4940 // break;
4941 case 5:
4942 // gen_helper_mtc0_performance5(t0);
4943 rn = "Performance5";
4944 // break;
4945 case 6:
4946 // gen_helper_mtc0_performance6(t0);
4947 rn = "Performance6";
4948 // break;
4949 case 7:
4950 // gen_helper_mtc0_performance7(t0);
4951 rn = "Performance7";
4952 // break;
4953 default:
4954 goto die;
4955 }
4956 break;
4957 case 26:
4958 /* ignored */
4959 rn = "ECC";
4960 break;
4961 case 27:
4962 switch (sel) {
4963 case 0 ... 3:
4964 /* ignored */
4965 rn = "CacheErr";
4966 break;
4967 default:
4968 goto die;
4969 }
4970 break;
4971 case 28:
4972 switch (sel) {
4973 case 0:
4974 case 2:
4975 case 4:
4976 case 6:
4977 gen_helper_mtc0_taglo(t0);
4978 rn = "TagLo";
4979 break;
4980 case 1:
4981 case 3:
4982 case 5:
4983 case 7:
4984 gen_helper_mtc0_datalo(t0);
4985 rn = "DataLo";
4986 break;
4987 default:
4988 goto die;
4989 }
4990 break;
4991 case 29:
4992 switch (sel) {
4993 case 0:
4994 case 2:
4995 case 4:
4996 case 6:
4997 gen_helper_mtc0_taghi(t0);
4998 rn = "TagHi";
4999 break;
5000 case 1:
5001 case 3:
5002 case 5:
5003 case 7:
5004 gen_helper_mtc0_datahi(t0);
5005 rn = "DataHi";
5006 break;
5007 default:
5008 rn = "invalid sel";
5009 goto die;
5010 }
5011 break;
5012 case 30:
5013 switch (sel) {
5014 case 0:
5015 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5016 rn = "ErrorEPC";
5017 break;
5018 default:
5019 goto die;
5020 }
5021 break;
5022 case 31:
5023 switch (sel) {
5024 case 0:
5025 /* EJTAG support */
5026 gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
5027 rn = "DESAVE";
5028 break;
5029 default:
5030 goto die;
5031 }
5032 /* Stop translation as we may have switched the execution mode */
5033 ctx->bstate = BS_STOP;
5034 break;
5035 default:
5036 goto die;
5037 }
5038 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5039 /* For simplicity assume that all writes can cause interrupts. */
5040 if (use_icount) {
5041 gen_io_end();
5042 ctx->bstate = BS_STOP;
5043 }
5044 return;
5045
5046 die:
5047 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5048 generate_exception(ctx, EXCP_RI);
5049 }
5050 #endif /* TARGET_MIPS64 */
5051
5052 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5053 int u, int sel, int h)
5054 {
5055 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5056 TCGv t0 = tcg_temp_local_new();
5057
5058 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5059 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5060 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5061 tcg_gen_movi_tl(t0, -1);
5062 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5063 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5064 tcg_gen_movi_tl(t0, -1);
5065 else if (u == 0) {
5066 switch (rt) {
5067 case 2:
5068 switch (sel) {
5069 case 1:
5070 gen_helper_mftc0_tcstatus(t0);
5071 break;
5072 case 2:
5073 gen_helper_mftc0_tcbind(t0);
5074 break;
5075 case 3:
5076 gen_helper_mftc0_tcrestart(t0);
5077 break;
5078 case 4:
5079 gen_helper_mftc0_tchalt(t0);
5080 break;
5081 case 5:
5082 gen_helper_mftc0_tccontext(t0);
5083 break;
5084 case 6:
5085 gen_helper_mftc0_tcschedule(t0);
5086 break;
5087 case 7:
5088 gen_helper_mftc0_tcschefback(t0);
5089 break;
5090 default:
5091 gen_mfc0(env, ctx, t0, rt, sel);
5092 break;
5093 }
5094 break;
5095 case 10:
5096 switch (sel) {
5097 case 0:
5098 gen_helper_mftc0_entryhi(t0);
5099 break;
5100 default:
5101 gen_mfc0(env, ctx, t0, rt, sel);
5102 break;
5103 }
5104 case 12:
5105 switch (sel) {
5106 case 0:
5107 gen_helper_mftc0_status(t0);
5108 break;
5109 default:
5110 gen_mfc0(env, ctx, t0, rt, sel);
5111 break;
5112 }
5113 case 23:
5114 switch (sel) {
5115 case 0:
5116 gen_helper_mftc0_debug(t0);
5117 break;
5118 default:
5119 gen_mfc0(env, ctx, t0, rt, sel);
5120 break;
5121 }
5122 break;
5123 default:
5124 gen_mfc0(env, ctx, t0, rt, sel);
5125 }
5126 } else switch (sel) {
5127 /* GPR registers. */
5128 case 0:
5129 gen_helper_1i(mftgpr, t0, rt);
5130 break;
5131 /* Auxiliary CPU registers */
5132 case 1:
5133 switch (rt) {
5134 case 0:
5135 gen_helper_1i(mftlo, t0, 0);
5136 break;
5137 case 1:
5138 gen_helper_1i(mfthi, t0, 0);
5139 break;
5140 case 2:
5141 gen_helper_1i(mftacx, t0, 0);
5142 break;
5143 case 4:
5144 gen_helper_1i(mftlo, t0, 1);
5145 break;
5146 case 5:
5147 gen_helper_1i(mfthi, t0, 1);
5148 break;
5149 case 6:
5150 gen_helper_1i(mftacx, t0, 1);
5151 break;
5152 case 8:
5153 gen_helper_1i(mftlo, t0, 2);
5154 break;
5155 case 9:
5156 gen_helper_1i(mfthi, t0, 2);
5157 break;
5158 case 10:
5159 gen_helper_1i(mftacx, t0, 2);
5160 break;
5161 case 12:
5162 gen_helper_1i(mftlo, t0, 3);
5163 break;
5164 case 13:
5165 gen_helper_1i(mfthi, t0, 3);
5166 break;
5167 case 14:
5168 gen_helper_1i(mftacx, t0, 3);
5169 break;
5170 case 16:
5171 gen_helper_mftdsp(t0);
5172 break;
5173 default:
5174 goto die;
5175 }
5176 break;
5177 /* Floating point (COP1). */
5178 case 2:
5179 /* XXX: For now we support only a single FPU context. */
5180 if (h == 0) {
5181 TCGv_i32 fp0 = tcg_temp_new_i32();
5182
5183 gen_load_fpr32(fp0, rt);
5184 tcg_gen_ext_i32_tl(t0, fp0);
5185 tcg_temp_free_i32(fp0);
5186 } else {
5187 TCGv_i32 fp0 = tcg_temp_new_i32();
5188
5189 gen_load_fpr32h(fp0, rt);
5190 tcg_gen_ext_i32_tl(t0, fp0);
5191 tcg_temp_free_i32(fp0);
5192 }
5193 break;
5194 case 3:
5195 /* XXX: For now we support only a single FPU context. */
5196 gen_helper_1i(cfc1, t0, rt);
5197 break;
5198 /* COP2: Not implemented. */
5199 case 4:
5200 case 5:
5201 /* fall through */
5202 default:
5203 goto die;
5204 }
5205 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5206 gen_store_gpr(t0, rd);
5207 tcg_temp_free(t0);
5208 return;
5209
5210 die:
5211 tcg_temp_free(t0);
5212 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5213 generate_exception(ctx, EXCP_RI);
5214 }
5215
5216 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5217 int u, int sel, int h)
5218 {
5219 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5220 TCGv t0 = tcg_temp_local_new();
5221
5222 gen_load_gpr(t0, rt);
5223 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5224 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5225 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5226 /* NOP */ ;
5227 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5228 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5229 /* NOP */ ;
5230 else if (u == 0) {
5231 switch (rd) {
5232 case 2:
5233 switch (sel) {
5234 case 1:
5235 gen_helper_mttc0_tcstatus(t0);
5236 break;
5237 case 2:
5238 gen_helper_mttc0_tcbind(t0);
5239 break;
5240 case 3:
5241 gen_helper_mttc0_tcrestart(t0);
5242 break;
5243 case 4:
5244 gen_helper_mttc0_tchalt(t0);
5245 break;
5246 case 5:
5247 gen_helper_mttc0_tccontext(t0);
5248 break;
5249 case 6:
5250 gen_helper_mttc0_tcschedule(t0);
5251 break;
5252 case 7:
5253 gen_helper_mttc0_tcschefback(t0);
5254 break;
5255 default:
5256 gen_mtc0(env, ctx, t0, rd, sel);
5257 break;
5258 }
5259 break;
5260 case 10:
5261 switch (sel) {
5262 case 0:
5263 gen_helper_mttc0_entryhi(t0);
5264 break;
5265 default:
5266 gen_mtc0(env, ctx, t0, rd, sel);
5267 break;
5268 }
5269 case 12:
5270 switch (sel) {
5271 case 0:
5272 gen_helper_mttc0_status(t0);
5273 break;
5274 default:
5275 gen_mtc0(env, ctx, t0, rd, sel);
5276 break;
5277 }
5278 case 23:
5279 switch (sel) {
5280 case 0:
5281 gen_helper_mttc0_debug(t0);
5282 break;
5283 default:
5284 gen_mtc0(env, ctx, t0, rd, sel);
5285 break;
5286 }
5287 break;
5288 default:
5289 gen_mtc0(env, ctx, t0, rd, sel);
5290 }
5291 } else switch (sel) {
5292 /* GPR registers. */
5293 case 0:
5294 gen_helper_1i(mttgpr, t0, rd);
5295 break;
5296 /* Auxiliary CPU registers */
5297 case 1:
5298 switch (rd) {
5299 case 0:
5300 gen_helper_1i(mttlo, t0, 0);
5301 break;
5302 case 1:
5303 gen_helper_1i(mtthi, t0, 0);
5304 break;
5305 case 2:
5306 gen_helper_1i(mttacx, t0, 0);
5307 break;
5308 case 4:
5309 gen_helper_1i(mttlo, t0, 1);
5310 break;
5311 case 5:
5312 gen_helper_1i(mtthi, t0, 1);
5313 break;
5314 case 6:
5315 gen_helper_1i(mttacx, t0, 1);
5316 break;
5317 case 8:
5318 gen_helper_1i(mttlo, t0, 2);
5319 break;
5320 case 9:
5321 gen_helper_1i(mtthi, t0, 2);
5322 break;
5323 case 10:
5324 gen_helper_1i(mttacx, t0, 2);
5325 break;
5326 case 12:
5327 gen_helper_1i(mttlo, t0, 3);
5328 break;
5329 case 13:
5330 gen_helper_1i(mtthi, t0, 3);
5331 break;
5332 case 14:
5333 gen_helper_1i(mttacx, t0, 3);
5334 break;
5335 case 16:
5336 gen_helper_mttdsp(t0);
5337 break;
5338 default:
5339 goto die;
5340 }
5341 break;
5342 /* Floating point (COP1). */
5343 case 2:
5344 /* XXX: For now we support only a single FPU context. */
5345 if (h == 0) {
5346 TCGv_i32 fp0 = tcg_temp_new_i32();
5347
5348 tcg_gen_trunc_tl_i32(fp0, t0);
5349 gen_store_fpr32(fp0, rd);
5350 tcg_temp_free_i32(fp0);
5351 } else {
5352 TCGv_i32 fp0 = tcg_temp_new_i32();
5353
5354 tcg_gen_trunc_tl_i32(fp0, t0);
5355 gen_store_fpr32h(fp0, rd);
5356 tcg_temp_free_i32(fp0);
5357 }
5358 break;
5359 case 3:
5360 /* XXX: For now we support only a single FPU context. */
5361 gen_helper_1i(ctc1, t0, rd);
5362 break;
5363 /* COP2: Not implemented. */
5364 case 4:
5365 case 5:
5366 /* fall through */
5367 default:
5368 goto die;
5369 }
5370 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5371 tcg_temp_free(t0);
5372 return;
5373
5374 die:
5375 tcg_temp_free(t0);
5376 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5377 generate_exception(ctx, EXCP_RI);
5378 }
5379
5380 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5381 {
5382 const char *opn = "ldst";
5383
5384 switch (opc) {
5385 case OPC_MFC0:
5386 if (rt == 0) {
5387 /* Treat as NOP. */
5388 return;
5389 }
5390 {
5391 TCGv t0 = tcg_temp_local_new();
5392
5393 gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5394 gen_store_gpr(t0, rt);
5395 tcg_temp_free(t0);
5396 }
5397 opn = "mfc0";
5398 break;
5399 case OPC_MTC0:
5400 {
5401 TCGv t0 = tcg_temp_local_new();
5402
5403 gen_load_gpr(t0, rt);
5404 save_cpu_state(ctx, 1);
5405 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5406 tcg_temp_free(t0);
5407 }
5408 opn = "mtc0";
5409 break;
5410 #if defined(TARGET_MIPS64)
5411 case OPC_DMFC0:
5412 check_insn(env, ctx, ISA_MIPS3);
5413 if (rt == 0) {
5414 /* Treat as NOP. */
5415 return;
5416 }
5417 {
5418 TCGv t0 = tcg_temp_local_new();
5419
5420 gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5421 gen_store_gpr(t0, rt);
5422 tcg_temp_free(t0);
5423 }
5424 opn = "dmfc0";
5425 break;
5426 case OPC_DMTC0:
5427 check_insn(env, ctx, ISA_MIPS3);
5428 {
5429 TCGv t0 = tcg_temp_local_new();
5430
5431 gen_load_gpr(t0, rt);
5432 save_cpu_state(ctx, 1);
5433 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5434 tcg_temp_free(t0);
5435 }
5436 opn = "dmtc0";
5437 break;
5438 #endif
5439 case OPC_MFTR:
5440 check_insn(env, ctx, ASE_MT);
5441 if (rd == 0) {
5442 /* Treat as NOP. */
5443 return;
5444 }
5445 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5446 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5447 opn = "mftr";
5448 break;
5449 case OPC_MTTR:
5450 check_insn(env, ctx, ASE_MT);
5451 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5452 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5453 opn = "mttr";
5454 break;
5455 case OPC_TLBWI:
5456 opn = "tlbwi";
5457 if (!env->tlb->helper_tlbwi)
5458 goto die;
5459 gen_helper_tlbwi();
5460 break;
5461 case OPC_TLBWR:
5462 opn = "tlbwr";
5463 if (!env->tlb->helper_tlbwr)
5464 goto die;
5465 gen_helper_tlbwr();
5466 break;
5467 case OPC_TLBP:
5468 opn = "tlbp";
5469 if (!env->tlb->helper_tlbp)
5470 goto die;
5471 gen_helper_tlbp();
5472 break;
5473 case OPC_TLBR:
5474 opn = "tlbr";
5475 if (!env->tlb->helper_tlbr)
5476 goto die;
5477 gen_helper_tlbr();
5478 break;
5479 case OPC_ERET:
5480 opn = "eret";
5481 check_insn(env, ctx, ISA_MIPS2);
5482 save_cpu_state(ctx, 1);
5483 gen_helper_eret();
5484 ctx->bstate = BS_EXCP;
5485 break;
5486 case OPC_DERET:
5487 opn = "deret";
5488 check_insn(env, ctx, ISA_MIPS32);
5489 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5490 MIPS_INVAL(opn);
5491 generate_exception(ctx, EXCP_RI);
5492 } else {
5493 save_cpu_state(ctx, 1);
5494 gen_helper_deret();
5495 ctx->bstate = BS_EXCP;
5496 }
5497 break;
5498 case OPC_WAIT:
5499 opn = "wait";
5500 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5501 /* If we get an exception, we want to restart at next instruction */
5502 ctx->pc += 4;
5503 save_cpu_state(ctx, 1);
5504 ctx->pc -= 4;
5505 gen_helper_wait();
5506 ctx->bstate = BS_EXCP;
5507 break;
5508 default:
5509 die:
5510 MIPS_INVAL(opn);
5511 generate_exception(ctx, EXCP_RI);
5512 return;
5513 }
5514 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5515 }
5516 #endif /* !CONFIG_USER_ONLY */
5517
5518 /* CP1 Branches (before delay slot) */
5519 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5520 int32_t cc, int32_t offset)
5521 {
5522 target_ulong btarget;
5523 const char *opn = "cp1 cond branch";
5524 TCGv_i32 t0 = tcg_temp_new_i32();
5525
5526 if (cc != 0)
5527 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5528
5529 btarget = ctx->pc + 4 + offset;
5530
5531 switch (op) {
5532 case OPC_BC1F:
5533 {
5534 int l1 = gen_new_label();
5535 int l2 = gen_new_label();
5536
5537 get_fp_cond(t0);
5538 tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5539 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5540 tcg_gen_movi_i32(bcond, 0);
5541 tcg_gen_br(l2);
5542 gen_set_label(l1);
5543 tcg_gen_movi_i32(bcond, 1);
5544 gen_set_label(l2);
5545 }
5546 opn = "bc1f";
5547 goto not_likely;
5548 case OPC_BC1FL:
5549 {
5550 int l1 = gen_new_label();
5551 int l2 = gen_new_label();
5552
5553 get_fp_cond(t0);
5554 tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5555 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5556 tcg_gen_movi_i32(bcond, 0);
5557 tcg_gen_br(l2);
5558 gen_set_label(l1);
5559 tcg_gen_movi_i32(bcond, 1);
5560 gen_set_label(l2);
5561 }
5562 opn = "bc1fl";
5563 goto likely;
5564 case OPC_BC1T:
5565 {
5566 int l1 = gen_new_label();
5567 int l2 = gen_new_label();
5568
5569 get_fp_cond(t0);
5570 tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5571 tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5572 tcg_gen_movi_i32(bcond, 0);
5573 tcg_gen_br(l2);
5574 gen_set_label(l1);
5575 tcg_gen_movi_i32(bcond, 1);
5576 gen_set_label(l2);
5577 }
5578 opn = "bc1t";
5579 goto not_likely;
5580 case OPC_BC1TL:
5581 {
5582 int l1 = gen_new_label();
5583 int l2 = gen_new_label();
5584
5585 get_fp_cond(t0);
5586 tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5587 tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5588 tcg_gen_movi_i32(bcond, 0);
5589 tcg_gen_br(l2);
5590 gen_set_label(l1);
5591 tcg_gen_movi_i32(bcond, 1);
5592 gen_set_label(l2);
5593 }
5594 opn = "bc1tl";
5595 likely:
5596 ctx->hflags |= MIPS_HFLAG_BL;
5597 break;
5598 case OPC_BC1FANY2:
5599 {
5600 int l1 = gen_new_label();
5601 int l2 = gen_new_label();
5602
5603 get_fp_cond(t0);
5604 tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5605 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5606 tcg_gen_movi_i32(bcond, 0);
5607 tcg_gen_br(l2);
5608 gen_set_label(l1);
5609 tcg_gen_movi_i32(bcond, 1);
5610 gen_set_label(l2);
5611 }
5612 opn = "bc1any2f";
5613 goto not_likely;
5614 case OPC_BC1TANY2:
5615 {
5616 int l1 = gen_new_label();
5617 int l2 = gen_new_label();
5618
5619 get_fp_cond(t0);
5620 tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5621 tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5622 tcg_gen_movi_i32(bcond, 0);
5623 tcg_gen_br(l2);
5624 gen_set_label(l1);
5625 tcg_gen_movi_i32(bcond, 1);
5626 gen_set_label(l2);
5627 }
5628 opn = "bc1any2t";
5629 goto not_likely;
5630 case OPC_BC1FANY4:
5631 {
5632 int l1 = gen_new_label();
5633 int l2 = gen_new_label();
5634
5635 get_fp_cond(t0);
5636 tcg_gen_andi_i32(t0, t0, 0xf << cc);
5637 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5638 tcg_gen_movi_i32(bcond, 0);
5639 tcg_gen_br(l2);
5640 gen_set_label(l1);
5641 tcg_gen_movi_i32(bcond, 1);
5642 gen_set_label(l2);
5643 }
5644 opn = "bc1any4f";
5645 goto not_likely;
5646 case OPC_BC1TANY4:
5647 {
5648 int l1 = gen_new_label();
5649 int l2 = gen_new_label();
5650
5651 get_fp_cond(t0);
5652 tcg_gen_andi_i32(t0, t0, 0xf << cc);
5653 tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5654 tcg_gen_movi_i32(bcond, 0);
5655 tcg_gen_br(l2);
5656 gen_set_label(l1);
5657 tcg_gen_movi_i32(bcond, 1);
5658 gen_set_label(l2);
5659 }
5660 opn = "bc1any4t";
5661 not_likely:
5662 ctx->hflags |= MIPS_HFLAG_BC;
5663 break;
5664 default:
5665 MIPS_INVAL(opn);
5666 generate_exception (ctx, EXCP_RI);
5667 goto out;
5668 }
5669 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5670 ctx->hflags, btarget);
5671 ctx->btarget = btarget;
5672
5673 out:
5674 tcg_temp_free_i32(t0);
5675 }
5676
5677 /* Coprocessor 1 (FPU) */
5678
5679 #define FOP(func, fmt) (((fmt) << 21) | (func))
5680
5681 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5682 {
5683 const char *opn = "cp1 move";
5684 TCGv t0 = tcg_temp_local_new();
5685
5686 switch (opc) {
5687 case OPC_MFC1:
5688 {
5689 TCGv_i32 fp0 = tcg_temp_new_i32();
5690
5691 gen_load_fpr32(fp0, fs);
5692 tcg_gen_ext_i32_tl(t0, fp0);
5693 tcg_temp_free_i32(fp0);
5694 }
5695 gen_store_gpr(t0, rt);
5696 opn = "mfc1";
5697 break;
5698 case OPC_MTC1:
5699 gen_load_gpr(t0, rt);
5700 {
5701 TCGv_i32 fp0 = tcg_temp_new_i32();
5702
5703 tcg_gen_trunc_tl_i32(fp0, t0);
5704 gen_store_fpr32(fp0, fs);
5705 tcg_temp_free_i32(fp0);
5706 }
5707 opn = "mtc1";
5708 break;
5709 case OPC_CFC1:
5710 gen_helper_1i(cfc1, t0, fs);
5711 gen_store_gpr(t0, rt);
5712 opn = "cfc1";
5713 break;
5714 case OPC_CTC1:
5715 gen_load_gpr(t0, rt);
5716 gen_helper_1i(ctc1, t0, fs);
5717 opn = "ctc1";
5718 break;
5719 case OPC_DMFC1:
5720 {
5721 TCGv_i64 fp0 = tcg_temp_new_i64();
5722
5723 gen_load_fpr64(ctx, fp0, fs);
5724 tcg_gen_trunc_i64_tl(t0, fp0);
5725 tcg_temp_free_i64(fp0);
5726 }
5727 gen_store_gpr(t0, rt);
5728 opn = "dmfc1";
5729 break;
5730 case OPC_DMTC1:
5731 gen_load_gpr(t0, rt);
5732 {
5733 TCGv_i64 fp0 = tcg_temp_new_i64();
5734
5735 tcg_gen_extu_tl_i64(fp0, t0);
5736 gen_store_fpr64(ctx, fp0, fs);
5737 tcg_temp_free_i64(fp0);
5738 }
5739 opn = "dmtc1";
5740 break;
5741 case OPC_MFHC1:
5742 {
5743 TCGv_i32 fp0 = tcg_temp_new_i32();
5744
5745 gen_load_fpr32h(fp0, fs);
5746 tcg_gen_ext_i32_tl(t0, fp0);
5747 tcg_temp_free_i32(fp0);
5748 }
5749 gen_store_gpr(t0, rt);
5750 opn = "mfhc1";
5751 break;
5752 case OPC_MTHC1:
5753 gen_load_gpr(t0, rt);
5754 {
5755 TCGv_i32 fp0 = tcg_temp_new_i32();
5756
5757 tcg_gen_trunc_tl_i32(fp0, t0);
5758 gen_store_fpr32h(fp0, fs);
5759 tcg_temp_free_i32(fp0);
5760 }
5761 opn = "mthc1";
5762 break;
5763 default:
5764 MIPS_INVAL(opn);
5765 generate_exception (ctx, EXCP_RI);
5766 goto out;
5767 }
5768 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5769
5770 out:
5771 tcg_temp_free(t0);
5772 }
5773
5774 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5775 {
5776 int l1 = gen_new_label();
5777 uint32_t ccbit;
5778 TCGCond cond;
5779 TCGv t0 = tcg_temp_local_new();
5780 TCGv_i32 r_tmp = tcg_temp_new_i32();
5781
5782 if (cc)
5783 ccbit = 1 << (24 + cc);
5784 else
5785 ccbit = 1 << 23;
5786 if (tf)
5787 cond = TCG_COND_EQ;
5788 else
5789 cond = TCG_COND_NE;
5790
5791 gen_load_gpr(t0, rd);
5792 tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
5793 tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5794 tcg_temp_free_i32(r_tmp);
5795 gen_load_gpr(t0, rs);
5796 gen_set_label(l1);
5797 gen_store_gpr(t0, rd);
5798 tcg_temp_free(t0);
5799 }
5800
5801 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5802 {
5803 uint32_t ccbit;
5804 int cond;
5805 TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5806 TCGv_i32 fp0 = tcg_temp_local_new_i32();
5807 int l1 = gen_new_label();
5808
5809 if (cc)
5810 ccbit = 1 << (24 + cc);
5811 else
5812 ccbit = 1 << 23;
5813
5814 if (tf)
5815 cond = TCG_COND_EQ;
5816 else
5817 cond = TCG_COND_NE;
5818
5819 gen_load_fpr32(fp0, fd);
5820 tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5821 tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5822 tcg_temp_free_i32(r_tmp1);
5823 gen_load_fpr32(fp0, fs);
5824 gen_set_label(l1);
5825 gen_store_fpr32(fp0, fd);
5826 tcg_temp_free_i32(fp0);
5827 }
5828
5829 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5830 {
5831 uint32_t ccbit;
5832 int cond;
5833 TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5834 TCGv_i64 fp0 = tcg_temp_local_new_i64();
5835 int l1 = gen_new_label();
5836
5837 if (cc)
5838 ccbit = 1 << (24 + cc);
5839 else
5840 ccbit = 1 << 23;
5841
5842 if (tf)
5843 cond = TCG_COND_EQ;
5844 else
5845 cond = TCG_COND_NE;
5846
5847 gen_load_fpr64(ctx, fp0, fd);
5848 tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5849 tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5850 tcg_temp_free_i32(r_tmp1);
5851 gen_load_fpr64(ctx, fp0, fs);
5852 gen_set_label(l1);
5853 gen_store_fpr64(ctx, fp0, fd);
5854 tcg_temp_free_i64(fp0);
5855 }
5856
5857 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5858 {
5859 uint32_t ccbit1, ccbit2;
5860 int cond;
5861 TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5862 TCGv_i32 fp0 = tcg_temp_local_new_i32();
5863 int l1 = gen_new_label();
5864 int l2 = gen_new_label();
5865
5866 if (cc) {
5867 ccbit1 = 1 << (24 + cc);
5868 ccbit2 = 1 << (25 + cc);
5869 } else {
5870 ccbit1 = 1 << 23;
5871 ccbit2 = 1 << 25;
5872 }
5873
5874 if (tf)
5875 cond = TCG_COND_EQ;
5876 else
5877 cond = TCG_COND_NE;
5878
5879 gen_load_fpr32(fp0, fd);
5880 tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
5881 tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5882 gen_load_fpr32(fp0, fs);
5883 gen_set_label(l1);
5884 gen_store_fpr32(fp0, fd);
5885
5886 gen_load_fpr32h(fp0, fd);
5887 tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
5888 tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
5889 gen_load_fpr32h(fp0, fs);
5890 gen_set_label(l2);
5891 gen_store_fpr32h(fp0, fd);
5892
5893 tcg_temp_free_i32(r_tmp1);
5894 tcg_temp_free_i32(fp0);
5895 }
5896
5897
5898 static void gen_farith (DisasContext *ctx, uint32_t op1,
5899 int ft, int fs, int fd, int cc)
5900 {
5901 const char *opn = "farith";
5902 const char *condnames[] = {
5903 "c.f",
5904 "c.un",
5905 "c.eq",
5906 "c.ueq",
5907 "c.olt",
5908 "c.ult",
5909 "c.ole",
5910 "c.ule",
5911 "c.sf",
5912 "c.ngle",
5913 "c.seq",
5914 "c.ngl",
5915 "c.lt",
5916 "c.nge",
5917 "c.le",
5918 "c.ngt",
5919 };
5920 const char *condnames_abs[] = {
5921 "cabs.f",
5922 "cabs.un",
5923 "cabs.eq",
5924 "cabs.ueq",
5925 "cabs.olt",
5926 "cabs.ult",
5927 "cabs.ole",
5928 "cabs.ule",
5929 "cabs.sf",
5930 "cabs.ngle",
5931 "cabs.seq",
5932 "cabs.ngl",
5933 "cabs.lt",
5934 "cabs.nge",
5935 "cabs.le",
5936 "cabs.ngt",
5937 };
5938 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5939 uint32_t func = ctx->opcode & 0x3f;
5940
5941 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5942 case FOP(0, 16):
5943 {
5944 TCGv_i32 fp0 = tcg_temp_new_i32();
5945 TCGv_i32 fp1 = tcg_temp_new_i32();
5946
5947 gen_load_fpr32(fp0, fs);
5948 gen_load_fpr32(fp1, ft);
5949 gen_helper_float_add_s(fp0, fp0, fp1);
5950 tcg_temp_free_i32(fp1);
5951 gen_store_fpr32(fp0, fd);
5952 tcg_temp_free_i32(fp0);
5953 }
5954 opn = "add.s";
5955 optype = BINOP;
5956 break;
5957 case FOP(1, 16):
5958 {
5959 TCGv_i32 fp0 = tcg_temp_new_i32();
5960 TCGv_i32 fp1 = tcg_temp_new_i32();
5961
5962 gen_load_fpr32(fp0, fs);
5963 gen_load_fpr32(fp1, ft);
5964 gen_helper_float_sub_s(fp0, fp0, fp1);
5965 tcg_temp_free_i32(fp1);
5966 gen_store_fpr32(fp0, fd);
5967 tcg_temp_free_i32(fp0);
5968 }
5969 opn = "sub.s";
5970 optype = BINOP;
5971 break;
5972 case FOP(2, 16):
5973 {
5974 TCGv_i32 fp0 = tcg_temp_new_i32();
5975 TCGv_i32 fp1 = tcg_temp_new_i32();
5976
5977 gen_load_fpr32(fp0, fs);
5978 gen_load_fpr32(fp1, ft);
5979 gen_helper_float_mul_s(fp0, fp0, fp1);
5980 tcg_temp_free_i32(fp1);
5981 gen_store_fpr32(fp0, fd);
5982 tcg_temp_free_i32(fp0);
5983 }
5984 opn = "mul.s";
5985 optype = BINOP;
5986 break;
5987 case FOP(3, 16):
5988 {
5989 TCGv_i32 fp0 = tcg_temp_new_i32();
5990 TCGv_i32 fp1 = tcg_temp_new_i32();
5991
5992 gen_load_fpr32(fp0, fs);
5993 gen_load_fpr32(fp1, ft);
5994 gen_helper_float_div_s(fp0, fp0, fp1);
5995 tcg_temp_free_i32(fp1);
5996 gen_store_fpr32(fp0, fd);
5997 tcg_temp_free_i32(fp0);
5998 }
5999 opn = "div.s";
6000 optype = BINOP;
6001 break;
6002 case FOP(4, 16):
6003 {
6004 TCGv_i32 fp0 = tcg_temp_new_i32();
6005
6006 gen_load_fpr32(fp0, fs);
6007 gen_helper_float_sqrt_s(fp0, fp0);
6008 gen_store_fpr32(fp0, fd);
6009 tcg_temp_free_i32(fp0);
6010 }
6011 opn = "sqrt.s";
6012 break;
6013 case FOP(5, 16):
6014 {
6015 TCGv_i32 fp0 = tcg_temp_new_i32();
6016
6017 gen_load_fpr32(fp0, fs);
6018 gen_helper_float_abs_s(fp0, fp0);
6019 gen_store_fpr32(fp0, fd);
6020 tcg_temp_free_i32(fp0);
6021 }
6022 opn = "abs.s";
6023 break;
6024 case FOP(6, 16):
6025 {
6026 TCGv_i32 fp0 = tcg_temp_new_i32();
6027
6028 gen_load_fpr32(fp0, fs);
6029 gen_store_fpr32(fp0, fd);
6030 tcg_temp_free_i32(fp0);
6031 }
6032 opn = "mov.s";
6033 break;
6034 case FOP(7, 16):
6035 {
6036 TCGv_i32 fp0 = tcg_temp_new_i32();
6037
6038 gen_load_fpr32(fp0, fs);
6039 gen_helper_float_chs_s(fp0, fp0);
6040 gen_store_fpr32(fp0, fd);
6041 tcg_temp_free_i32(fp0);
6042 }
6043 opn = "neg.s";
6044 break;
6045 case FOP(8, 16):
6046 check_cp1_64bitmode(ctx);
6047 {
6048 TCGv_i32 fp32 = tcg_temp_new_i32();
6049 TCGv_i64 fp64 = tcg_temp_new_i64();
6050
6051 gen_load_fpr32(fp32, fs);
6052 gen_helper_float_roundl_s(fp64, fp32);
6053 tcg_temp_free_i32(fp32);
6054 gen_store_fpr64(ctx, fp64, fd);
6055 tcg_temp_free_i64(fp64);
6056 }
6057 opn = "round.l.s";
6058 break;
6059 case FOP(9, 16):
6060 check_cp1_64bitmode(ctx);
6061 {
6062 TCGv_i32 fp32 = tcg_temp_new_i32();
6063 TCGv_i64 fp64 = tcg_temp_new_i64();
6064
6065 gen_load_fpr32(fp32, fs);
6066 gen_helper_float_truncl_s(fp64, fp32);
6067 tcg_temp_free_i32(fp32);
6068 gen_store_fpr64(ctx, fp64, fd);
6069 tcg_temp_free_i64(fp64);
6070 }
6071 opn = "trunc.l.s";
6072 break;
6073 case FOP(10, 16):
6074 check_cp1_64bitmode(ctx);
6075 {
6076 TCGv_i32 fp32 = tcg_temp_new_i32();
6077 TCGv_i64 fp64 = tcg_temp_new_i64();
6078
6079 gen_load_fpr32(fp32, fs);
6080 gen_helper_float_ceill_s(fp64, fp32);
6081 tcg_temp_free_i32(fp32);
6082 gen_store_fpr64(ctx, fp64, fd);
6083 tcg_temp_free_i64(fp64);
6084 }
6085 opn = "ceil.l.s";
6086 break;
6087 case FOP(11, 16):
6088 check_cp1_64bitmode(ctx);
6089 {
6090 TCGv_i32 fp32 = tcg_temp_new_i32();
6091 TCGv_i64 fp64 = tcg_temp_new_i64();
6092
6093 gen_load_fpr32(fp32, fs);
6094 gen_helper_float_floorl_s(fp64, fp32);
6095 tcg_temp_free_i32(fp32);
6096 gen_store_fpr64(ctx, fp64, fd);
6097 tcg_temp_free_i64(fp64);
6098 }
6099 opn = "floor.l.s";
6100 break;
6101 case FOP(12, 16):
6102 {
6103 TCGv_i32 fp0 = tcg_temp_new_i32();
6104
6105 gen_load_fpr32(fp0, fs);
6106 gen_helper_float_roundw_s(fp0, fp0);
6107 gen_store_fpr32(fp0, fd);
6108 tcg_temp_free_i32(fp0);
6109 }
6110 opn = "round.w.s";
6111 break;
6112 case FOP(13, 16):
6113 {
6114 TCGv_i32 fp0 = tcg_temp_new_i32();
6115
6116 gen_load_fpr32(fp0, fs);
6117 gen_helper_float_truncw_s(fp0, fp0);
6118 gen_store_fpr32(fp0, fd);
6119 tcg_temp_free_i32(fp0);
6120 }
6121 opn = "trunc.w.s";
6122 break;
6123 case FOP(14, 16):
6124 {
6125 TCGv_i32 fp0 = tcg_temp_new_i32();
6126
6127 gen_load_fpr32(fp0, fs);
6128 gen_helper_float_ceilw_s(fp0, fp0);
6129 gen_store_fpr32(fp0, fd);
6130 tcg_temp_free_i32(fp0);
6131 }
6132 opn = "ceil.w.s";
6133 break;
6134 case FOP(15, 16):
6135 {
6136 TCGv_i32 fp0 = tcg_temp_new_i32();
6137
6138 gen_load_fpr32(fp0, fs);
6139 gen_helper_float_floorw_s(fp0, fp0);
6140 gen_store_fpr32(fp0, fd);
6141 tcg_temp_free_i32(fp0);
6142 }
6143 opn = "floor.w.s";
6144 break;
6145 case FOP(17, 16):
6146 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6147 opn = "movcf.s";
6148 break;
6149 case FOP(18, 16):
6150 {
6151 int l1 = gen_new_label();
6152 TCGv t0 = tcg_temp_new();
6153 TCGv_i32 fp0 = tcg_temp_local_new_i32();
6154
6155 gen_load_gpr(t0, ft);
6156 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6157 gen_load_fpr32(fp0, fs);
6158 gen_store_fpr32(fp0, fd);
6159 tcg_temp_free_i32(fp0);
6160 gen_set_label(l1);
6161 tcg_temp_free(t0);
6162 }
6163 opn = "movz.s";
6164 break;
6165 case FOP(19, 16):
6166 {
6167 int l1 = gen_new_label();
6168 TCGv t0 = tcg_temp_new();
6169 TCGv_i32 fp0 = tcg_temp_local_new_i32();
6170
6171 gen_load_gpr(t0, ft);
6172 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6173 gen_load_fpr32(fp0, fs);
6174 gen_store_fpr32(fp0, fd);
6175 tcg_temp_free_i32(fp0);
6176 gen_set_label(l1);
6177 tcg_temp_free(t0);
6178 }
6179 opn = "movn.s";
6180 break;
6181 case FOP(21, 16):
6182 check_cop1x(ctx);
6183 {
6184 TCGv_i32 fp0 = tcg_temp_new_i32();
6185
6186 gen_load_fpr32(fp0, fs);
6187 gen_helper_float_recip_s(fp0, fp0);
6188 gen_store_fpr32(fp0, fd);
6189 tcg_temp_free_i32(fp0);
6190 }
6191 opn = "recip.s";
6192 break;
6193 case FOP(22, 16):
6194 check_cop1x(ctx);
6195 {
6196 TCGv_i32 fp0 = tcg_temp_new_i32();
6197
6198 gen_load_fpr32(fp0, fs);
6199 gen_helper_float_rsqrt_s(fp0, fp0);
6200 gen_store_fpr32(fp0, fd);
6201 tcg_temp_free_i32(fp0);
6202 }
6203 opn = "rsqrt.s";
6204 break;
6205 case FOP(28, 16):
6206 check_cp1_64bitmode(ctx);
6207 {
6208 TCGv_i32 fp0 = tcg_temp_new_i32();
6209 TCGv_i32 fp1 = tcg_temp_new_i32();
6210
6211 gen_load_fpr32(fp0, fs);
6212 gen_load_fpr32(fp1, fd);
6213 gen_helper_float_recip2_s(fp0, fp0, fp1);
6214 tcg_temp_free_i32(fp1);
6215 gen_store_fpr32(fp0, fd);
6216 tcg_temp_free_i32(fp0);
6217 }
6218 opn = "recip2.s";
6219 break;
6220 case FOP(29, 16):
6221 check_cp1_64bitmode(ctx);
6222 {
6223 TCGv_i32 fp0 = tcg_temp_new_i32();
6224
6225 gen_load_fpr32(fp0, fs);
6226 gen_helper_float_recip1_s(fp0, fp0);
6227 gen_store_fpr32(fp0, fd);
6228 tcg_temp_free_i32(fp0);
6229 }
6230 opn = "recip1.s";
6231 break;
6232 case FOP(30, 16):
6233 check_cp1_64bitmode(ctx);
6234 {
6235 TCGv_i32 fp0 = tcg_temp_new_i32();
6236
6237 gen_load_fpr32(fp0, fs);
6238 gen_helper_float_rsqrt1_s(fp0, fp0);
6239 gen_store_fpr32(fp0, fd);
6240 tcg_temp_free_i32(fp0);
6241 }
6242 opn = "rsqrt1.s";
6243 break;
6244 case FOP(31, 16):
6245 check_cp1_64bitmode(ctx);
6246 {
6247 TCGv_i32 fp0 = tcg_temp_new_i32();
6248 TCGv_i32 fp1 = tcg_temp_new_i32();
6249
6250 gen_load_fpr32(fp0, fs);
6251 gen_load_fpr32(fp1, ft);
6252 gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6253 tcg_temp_free_i32(fp1);
6254 gen_store_fpr32(fp0, fd);
6255 tcg_temp_free_i32(fp0);
6256 }
6257 opn = "rsqrt2.s";
6258 break;
6259 case FOP(33, 16):
6260 check_cp1_registers(ctx, fd);
6261 {
6262 TCGv_i32 fp32 = tcg_temp_new_i32();
6263 TCGv_i64 fp64 = tcg_temp_new_i64();
6264
6265 gen_load_fpr32(fp32, fs);
6266 gen_helper_float_cvtd_s(fp64, fp32);
6267 tcg_temp_free_i32(fp32);
6268 gen_store_fpr64(ctx, fp64, fd);
6269 tcg_temp_free_i64(fp64);
6270 }
6271 opn = "cvt.d.s";
6272 break;
6273 case FOP(36, 16):
6274 {
6275 TCGv_i32 fp0 = tcg_temp_new_i32();
6276
6277 gen_load_fpr32(fp0, fs);
6278 gen_helper_float_cvtw_s(fp0, fp0);
6279 gen_store_fpr32(fp0, fd);
6280 tcg_temp_free_i32(fp0);
6281 }
6282 opn = "cvt.w.s";
6283 break;
6284 case FOP(37, 16):
6285 check_cp1_64bitmode(ctx);
6286 {
6287 TCGv_i32 fp32 = tcg_temp_new_i32();
6288 TCGv_i64 fp64 = tcg_temp_new_i64();
6289
6290 gen_load_fpr32(fp32, fs);
6291 gen_helper_float_cvtl_s(fp64, fp32);
6292 tcg_temp_free_i32(fp32);
6293 gen_store_fpr64(ctx, fp64, fd);
6294 tcg_temp_free_i64(fp64);
6295 }
6296 opn = "cvt.l.s";
6297 break;
6298 case FOP(38, 16):
6299 check_cp1_64bitmode(ctx);
6300 {
6301 TCGv_i64 fp64 = tcg_temp_new_i64();
6302 TCGv_i32 fp32_0 = tcg_temp_new_i32();
6303 TCGv_i32 fp32_1 = tcg_temp_new_i32();
6304
6305 gen_load_fpr32(fp32_0, fs);
6306 gen_load_fpr32(fp32_1, ft);
6307 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6308 tcg_temp_free_i32(fp32_1);
6309 tcg_temp_free_i32(fp32_0);
6310 gen_store_fpr64(ctx, fp64, fd);
6311 tcg_temp_free_i64(fp64);
6312 }
6313 opn = "cvt.ps.s";
6314 break;
6315 case FOP(48, 16):
6316 case FOP(49, 16):
6317 case FOP(50, 16):
6318 case FOP(51, 16):
6319 case FOP(52, 16):
6320 case FOP(53, 16):
6321 case FOP(54, 16):
6322 case FOP(55, 16):
6323 case FOP(56, 16):
6324 case FOP(57, 16):
6325 case FOP(58, 16):
6326 case FOP(59, 16):
6327 case FOP(60, 16):
6328 case FOP(61, 16):
6329 case FOP(62, 16):
6330 case FOP(63, 16):
6331 {
6332 TCGv_i32 fp0 = tcg_temp_new_i32();
6333 TCGv_i32 fp1 = tcg_temp_new_i32();
6334
6335 gen_load_fpr32(fp0, fs);
6336 gen_load_fpr32(fp1, ft);
6337 if (ctx->opcode & (1 << 6)) {
6338 check_cop1x(ctx);
6339 gen_cmpabs_s(func-48, fp0, fp1, cc);
6340 opn = condnames_abs[func-48];
6341 } else {
6342 gen_cmp_s(func-48, fp0, fp1, cc);
6343 opn = condnames[func-48];
6344 }
6345 tcg_temp_free_i32(fp0);
6346 tcg_temp_free_i32(fp1);
6347 }
6348 break;
6349 case FOP(0, 17):
6350 check_cp1_registers(ctx, fs | ft | fd);
6351 {
6352 TCGv_i64 fp0 = tcg_temp_new_i64();
6353 TCGv_i64 fp1 = tcg_temp_new_i64();
6354
6355 gen_load_fpr64(ctx, fp0, fs);
6356 gen_load_fpr64(ctx, fp1, ft);
6357 gen_helper_float_add_d(fp0, fp0, fp1);
6358 tcg_temp_free_i64(fp1);
6359 gen_store_fpr64(ctx, fp0, fd);
6360 tcg_temp_free_i64(fp0);
6361 }
6362 opn = "add.d";
6363 optype = BINOP;
6364 break;
6365 case FOP(1, 17):
6366 check_cp1_registers(ctx, fs | ft | fd);
6367 {
6368 TCGv_i64 fp0 = tcg_temp_new_i64();
6369 TCGv_i64 fp1 = tcg_temp_new_i64();
6370
6371 gen_load_fpr64(ctx, fp0, fs);
6372 gen_load_fpr64(ctx, fp1, ft);
6373 gen_helper_float_sub_d(fp0, fp0, fp1);
6374 tcg_temp_free_i64(fp1);
6375 gen_store_fpr64(ctx, fp0, fd);
6376 tcg_temp_free_i64(fp0);
6377 }
6378 opn = "sub.d";
6379 optype = BINOP;
6380 break;
6381 case FOP(2, 17):
6382 check_cp1_registers(ctx, fs | ft | fd);
6383 {
6384 TCGv_i64 fp0 = tcg_temp_new_i64();
6385 TCGv_i64 fp1 = tcg_temp_new_i64();
6386
6387 gen_load_fpr64(ctx, fp0, fs);
6388 gen_load_fpr64(ctx, fp1, ft);
6389 gen_helper_float_mul_d(fp0, fp0, fp1);
6390 tcg_temp_free_i64(fp1);
6391 gen_store_fpr64(ctx, fp0, fd);
6392 tcg_temp_free_i64(fp0);
6393 }
6394 opn = "mul.d";
6395 optype = BINOP;
6396 break;
6397 case FOP(3, 17):
6398 check_cp1_registers(ctx, fs | ft | fd);
6399 {
6400 TCGv_i64 fp0 = tcg_temp_new_i64();
6401 TCGv_i64 fp1 = tcg_temp_new_i64();
6402
6403 gen_load_fpr64(ctx, fp0, fs);
6404 gen_load_fpr64(ctx, fp1, ft);
6405 gen_helper_float_div_d(fp0, fp0, fp1);
6406 tcg_temp_free_i64(fp1);
6407 gen_store_fpr64(ctx, fp0, fd);
6408 tcg_temp_free_i64(fp0);
6409 }
6410 opn = "div.d";
6411 optype = BINOP;
6412 break;
6413 case FOP(4, 17):
6414 check_cp1_registers(ctx, fs | fd);
6415 {
6416 TCGv_i64 fp0 = tcg_temp_new_i64();
6417
6418 gen_load_fpr64(ctx, fp0, fs);
6419 gen_helper_float_sqrt_d(fp0, fp0);
6420 gen_store_fpr64(ctx, fp0, fd);
6421 tcg_temp_free_i64(fp0);
6422 }
6423 opn = "sqrt.d";
6424 break;
6425 case FOP(5, 17):
6426 check_cp1_registers(ctx, fs | fd);
6427 {
6428 TCGv_i64 fp0 = tcg_temp_new_i64();
6429
6430 gen_load_fpr64(ctx, fp0, fs);
6431 gen_helper_float_abs_d(fp0, fp0);
6432 gen_store_fpr64(ctx, fp0, fd);
6433 tcg_temp_free_i64(fp0);
6434 }
6435 opn = "abs.d";
6436 break;
6437 case FOP(6, 17):
6438 check_cp1_registers(ctx, fs | fd);
6439 {
6440 TCGv_i64 fp0 = tcg_temp_new_i64();
6441
6442 gen_load_fpr64(ctx, fp0, fs);
6443 gen_store_fpr64(ctx, fp0, fd);
6444 tcg_temp_free_i64(fp0);
6445 }
6446 opn = "mov.d";
6447 break;
6448 case FOP(7, 17):
6449 check_cp1_registers(ctx, fs | fd);
6450 {
6451 TCGv_i64 fp0 = tcg_temp_new_i64();
6452
6453 gen_load_fpr64(ctx, fp0, fs);
6454 gen_helper_float_chs_d(fp0, fp0);
6455 gen_store_fpr64(ctx, fp0, fd);
6456 tcg_temp_free_i64(fp0);
6457 }
6458 opn = "neg.d";
6459 break;
6460 case FOP(8, 17):
6461 check_cp1_64bitmode(ctx);
6462 {
6463 TCGv_i64 fp0 = tcg_temp_new_i64();
6464
6465 gen_load_fpr64(ctx, fp0, fs);
6466 gen_helper_float_roundl_d(fp0, fp0);
6467 gen_store_fpr64(ctx, fp0, fd);
6468 tcg_temp_free_i64(fp0);
6469 }
6470 opn = "round.l.d";
6471 break;
6472 case FOP(9, 17):
6473 check_cp1_64bitmode(ctx);
6474 {
6475 TCGv_i64 fp0 = tcg_temp_new_i64();
6476
6477 gen_load_fpr64(ctx, fp0, fs);
6478 gen_helper_float_truncl_d(fp0, fp0);
6479 gen_store_fpr64(ctx, fp0, fd);
6480 tcg_temp_free_i64(fp0);
6481 }
6482 opn = "trunc.l.d";
6483 break;
6484 case FOP(10, 17):
6485 check_cp1_64bitmode(ctx);
6486 {
6487 TCGv_i64 fp0 = tcg_temp_new_i64();
6488
6489 gen_load_fpr64(ctx, fp0, fs);
6490 gen_helper_float_ceill_d(fp0, fp0);
6491 gen_store_fpr64(ctx, fp0, fd);
6492 tcg_temp_free_i64(fp0);
6493 }
6494 opn = "ceil.l.d";
6495 break;
6496 case FOP(11, 17):
6497 check_cp1_64bitmode(ctx);
6498 {
6499 TCGv_i64 fp0 = tcg_temp_new_i64();
6500
6501 gen_load_fpr64(ctx, fp0, fs);
6502 gen_helper_float_floorl_d(fp0, fp0);
6503 gen_store_fpr64(ctx, fp0, fd);
6504 tcg_temp_free_i64(fp0);
6505 }
6506 opn = "floor.l.d";
6507 break;
6508 case FOP(12, 17):
6509 check_cp1_registers(ctx, fs);
6510 {
6511 TCGv_i32 fp32 = tcg_temp_new_i32();
6512 TCGv_i64 fp64 = tcg_temp_new_i64();
6513
6514 gen_load_fpr64(ctx, fp64, fs);
6515 gen_helper_float_roundw_d(fp32, fp64);
6516 tcg_temp_free_i64(fp64);
6517 gen_store_fpr32(fp32, fd);
6518 tcg_temp_free_i32(fp32);
6519 }
6520 opn = "round.w.d";
6521 break;
6522 case FOP(13, 17):
6523 check_cp1_registers(ctx, fs);
6524 {
6525 TCGv_i32 fp32 = tcg_temp_new_i32();
6526 TCGv_i64 fp64 = tcg_temp_new_i64();
6527
6528 gen_load_fpr64(ctx, fp64, fs);
6529 gen_helper_float_truncw_d(fp32, fp64);
6530 tcg_temp_free_i64(fp64);
6531 gen_store_fpr32(fp32, fd);
6532 tcg_temp_free_i32(fp32);
6533 }
6534 opn = "trunc.w.d";
6535 break;
6536 case FOP(14, 17):
6537 check_cp1_registers(ctx, fs);
6538 {
6539 TCGv_i32 fp32 = tcg_temp_new_i32();
6540 TCGv_i64 fp64 = tcg_temp_new_i64();
6541
6542 gen_load_fpr64(ctx, fp64, fs);
6543 gen_helper_float_ceilw_d(fp32, fp64);
6544 tcg_temp_free_i64(fp64);
6545 gen_store_fpr32(fp32, fd);
6546 tcg_temp_free_i32(fp32);
6547 }
6548 opn = "ceil.w.d";
6549 break;
6550 case FOP(15, 17):
6551 check_cp1_registers(ctx, fs);
6552 {
6553 TCGv_i32 fp32 = tcg_temp_new_i32();
6554 TCGv_i64 fp64 = tcg_temp_new_i64();
6555
6556 gen_load_fpr64(ctx, fp64, fs);
6557 gen_helper_float_floorw_d(fp32, fp64);
6558 tcg_temp_free_i64(fp64);
6559 gen_store_fpr32(fp32, fd);
6560 tcg_temp_free_i32(fp32);
6561 }
6562 opn = "floor.w.d";
6563 break;
6564 case FOP(17, 17):
6565 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6566 opn = "movcf.d";
6567 break;
6568 case FOP(18, 17):
6569 {
6570 int l1 = gen_new_label();
6571 TCGv t0 = tcg_temp_new();
6572 TCGv_i64 fp0 = tcg_temp_local_new_i64();
6573
6574 gen_load_gpr(t0, ft);
6575 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6576 gen_load_fpr64(ctx, fp0, fs);
6577 gen_store_fpr64(ctx, fp0, fd);
6578 tcg_temp_free_i64(fp0);
6579 gen_set_label(l1);
6580 tcg_temp_free(t0);
6581 }
6582 opn = "movz.d";
6583 break;
6584 case FOP(19, 17):
6585 {
6586 int l1 = gen_new_label();
6587 TCGv t0 = tcg_temp_new();
6588 TCGv_i64 fp0 = tcg_temp_local_new_i64();
6589
6590 gen_load_gpr(t0, ft);
6591 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6592 gen_load_fpr64(ctx, fp0, fs);
6593 gen_store_fpr64(ctx, fp0, fd);
6594 tcg_temp_free_i64(fp0);
6595 gen_set_label(l1);
6596 tcg_temp_free(t0);
6597 }
6598 opn = "movn.d";
6599 break;
6600 case FOP(21, 17):
6601 check_cp1_64bitmode(ctx);
6602 {
6603 TCGv_i64 fp0 = tcg_temp_new_i64();
6604
6605 gen_load_fpr64(ctx, fp0, fs);
6606 gen_helper_float_recip_d(fp0, fp0);
6607 gen_store_fpr64(ctx, fp0, fd);
6608 tcg_temp_free_i64(fp0);
6609 }
6610 opn = "recip.d";
6611 break;
6612 case FOP(22, 17):
6613 check_cp1_64bitmode(ctx);
6614 {
6615 TCGv_i64 fp0 = tcg_temp_new_i64();
6616
6617 gen_load_fpr64(ctx, fp0, fs);
6618 gen_helper_float_rsqrt_d(fp0, fp0);
6619 gen_store_fpr64(ctx, fp0, fd);
6620 tcg_temp_free_i64(fp0);
6621 }
6622 opn = "rsqrt.d";
6623 break;
6624 case FOP(28, 17):
6625 check_cp1_64bitmode(ctx);
6626 {
6627 TCGv_i64 fp0 = tcg_temp_new_i64();
6628 TCGv_i64 fp1 = tcg_temp_new_i64();
6629
6630 gen_load_fpr64(ctx, fp0, fs);
6631 gen_load_fpr64(ctx, fp1, ft);
6632 gen_helper_float_recip2_d(fp0, fp0, fp1);
6633 tcg_temp_free_i64(fp1);
6634 gen_store_fpr64(ctx, fp0, fd);
6635 tcg_temp_free_i64(fp0);
6636 }
6637 opn = "recip2.d";
6638 break;
6639 case FOP(29, 17):
6640 check_cp1_64bitmode(ctx);
6641 {
6642 TCGv_i64 fp0 = tcg_temp_new_i64();
6643
6644 gen_load_fpr64(ctx, fp0, fs);
6645 gen_helper_float_recip1_d(fp0, fp0);
6646 gen_store_fpr64(ctx, fp0, fd);
6647 tcg_temp_free_i64(fp0);
6648 }
6649 opn = "recip1.d";
6650 break;
6651 case FOP(30, 17):
6652 check_cp1_64bitmode(ctx);
6653 {
6654 TCGv_i64 fp0 = tcg_temp_new_i64();
6655
6656 gen_load_fpr64(ctx, fp0, fs);
6657 gen_helper_float_rsqrt1_d(fp0, fp0);
6658 gen_store_fpr64(ctx, fp0, fd);
6659 tcg_temp_free_i64(fp0);
6660 }
6661 opn = "rsqrt1.d";
6662 break;
6663 case FOP(31, 17):
6664 check_cp1_64bitmode(ctx);
6665 {
6666 TCGv_i64 fp0 = tcg_temp_new_i64();
6667 TCGv_i64 fp1 = tcg_temp_new_i64();
6668
6669 gen_load_fpr64(ctx, fp0, fs);
6670 gen_load_fpr64(ctx, fp1, ft);
6671 gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6672 tcg_temp_free_i64(fp1);
6673 gen_store_fpr64(ctx, fp0, fd);
6674 tcg_temp_free_i64(fp0);
6675 }
6676 opn = "rsqrt2.d";
6677 break;
6678 case FOP(48, 17):
6679 case FOP(49, 17):
6680 case FOP(50, 17):
6681 case FOP(51, 17):
6682 case FOP(52, 17):
6683 case FOP(53, 17):
6684 case FOP(54, 17):
6685 case FOP(55, 17):
6686 case FOP(56, 17):
6687 case FOP(57, 17):
6688 case FOP(58, 17):
6689 case FOP(59, 17):
6690 case FOP(60, 17):
6691 case FOP(61, 17):
6692 case FOP(62, 17):
6693 case FOP(63, 17):
6694 {
6695 TCGv_i64 fp0 = tcg_temp_new_i64();
6696 TCGv_i64 fp1 = tcg_temp_new_i64();
6697
6698 gen_load_fpr64(ctx, fp0, fs);
6699 gen_load_fpr64(ctx, fp1, ft);
6700 if (ctx->opcode & (1 << 6)) {
6701 check_cop1x(ctx);
6702 check_cp1_registers(ctx, fs | ft);
6703 gen_cmpabs_d(func-48, fp0, fp1, cc);
6704 opn = condnames_abs[func-48];
6705 } else {
6706 check_cp1_registers(ctx, fs | ft);
6707 gen_cmp_d(func-48, fp0, fp1, cc);
6708 opn = condnames[func-48];
6709 }
6710 tcg_temp_free_i64(fp0);
6711 tcg_temp_free_i64(fp1);
6712 }
6713 break;
6714 case FOP(32, 17):
6715 check_cp1_registers(ctx, fs);
6716 {
6717 TCGv_i32 fp32 = tcg_temp_new_i32();
6718 TCGv_i64 fp64 = tcg_temp_new_i64();
6719
6720 gen_load_fpr64(ctx, fp64, fs);
6721 gen_helper_float_cvts_d(fp32, fp64);
6722 tcg_temp_free_i64(fp64);
6723 gen_store_fpr32(fp32, fd);
6724 tcg_temp_free_i32(fp32);
6725 }
6726 opn = "cvt.s.d";
6727 break;
6728 case FOP(36, 17):
6729 check_cp1_registers(ctx, fs);
6730 {
6731 TCGv_i32 fp32 = tcg_temp_new_i32();
6732 TCGv_i64 fp64 = tcg_temp_new_i64();
6733
6734 gen_load_fpr64(ctx, fp64, fs);
6735 gen_helper_float_cvtw_d(fp32, fp64);
6736 tcg_temp_free_i64(fp64);
6737 gen_store_fpr32(fp32, fd);
6738 tcg_temp_free_i32(fp32);
6739 }
6740 opn = "cvt.w.d";
6741 break;
6742 case FOP(37, 17):
6743 check_cp1_64bitmode(ctx);
6744 {
6745 TCGv_i64 fp0 = tcg_temp_new_i64();
6746
6747 gen_load_fpr64(ctx, fp0, fs);
6748 gen_helper_float_cvtl_d(fp0, fp0);
6749 gen_store_fpr64(ctx, fp0, fd);
6750 tcg_temp_free_i64(fp0);
6751 }
6752 opn = "cvt.l.d";
6753 break;
6754 case FOP(32, 20):
6755 {
6756 TCGv_i32 fp0 = tcg_temp_new_i32();
6757
6758 gen_load_fpr32(fp0, fs);
6759 gen_helper_float_cvts_w(fp0, fp0);
6760 gen_store_fpr32(fp0, fd);
6761 tcg_temp_free_i32(fp0);
6762 }
6763 opn = "cvt.s.w";
6764 break;
6765 case FOP(33, 20):
6766 check_cp1_registers(ctx, fd);
6767 {
6768 TCGv_i32 fp32 = tcg_temp_new_i32();
6769 TCGv_i64 fp64 = tcg_temp_new_i64();
6770
6771 gen_load_fpr32(fp32, fs);
6772 gen_helper_float_cvtd_w(fp64, fp32);
6773 tcg_temp_free_i32(fp32);
6774 gen_store_fpr64(ctx, fp64, fd);
6775 tcg_temp_free_i64(fp64);
6776 }
6777 opn = "cvt.d.w";
6778 break;
6779 case FOP(32, 21):
6780 check_cp1_64bitmode(ctx);
6781 {
6782 TCGv_i32 fp32 = tcg_temp_new_i32();
6783 TCGv_i64 fp64 = tcg_temp_new_i64();
6784
6785 gen_load_fpr64(ctx, fp64, fs);
6786 gen_helper_float_cvts_l(fp32, fp64);
6787 tcg_temp_free_i64(fp64);
6788 gen_store_fpr32(fp32, fd);
6789 tcg_temp_free_i32(fp32);
6790 }
6791 opn = "cvt.s.l";
6792 break;
6793 case FOP(33, 21):
6794 check_cp1_64bitmode(ctx);
6795 {
6796 TCGv_i64 fp0 = tcg_temp_new_i64();
6797
6798 gen_load_fpr64(ctx, fp0, fs);
6799 gen_helper_float_cvtd_l(fp0, fp0);
6800 gen_store_fpr64(ctx, fp0, fd);
6801 tcg_temp_free_i64(fp0);
6802 }
6803 opn = "cvt.d.l";
6804 break;
6805 case FOP(38, 20):
6806 check_cp1_64bitmode(ctx);
6807 {
6808 TCGv_i64 fp0 = tcg_temp_new_i64();
6809
6810 gen_load_fpr64(ctx, fp0, fs);
6811 gen_helper_float_cvtps_pw(fp0, fp0);
6812 gen_store_fpr64(ctx, fp0, fd);
6813 tcg_temp_free_i64(fp0);
6814 }
6815 opn = "cvt.ps.pw";
6816 break;
6817 case FOP(0, 22):
6818 check_cp1_64bitmode(ctx);
6819 {
6820 TCGv_i64 fp0 = tcg_temp_new_i64();
6821 TCGv_i64 fp1 = tcg_temp_new_i64();
6822
6823 gen_load_fpr64(ctx, fp0, fs);
6824 gen_load_fpr64(ctx, fp1, ft);
6825 gen_helper_float_add_ps(fp0, fp0, fp1);
6826 tcg_temp_free_i64(fp1);
6827 gen_store_fpr64(ctx, fp0, fd);
6828 tcg_temp_free_i64(fp0);
6829 }
6830 opn = "add.ps";
6831 break;
6832 case FOP(1, 22):
6833 check_cp1_64bitmode(ctx);
6834 {
6835 TCGv_i64 fp0 = tcg_temp_new_i64();
6836 TCGv_i64 fp1 = tcg_temp_new_i64();
6837
6838 gen_load_fpr64(ctx, fp0, fs);
6839 gen_load_fpr64(ctx, fp1, ft);
6840 gen_helper_float_sub_ps(fp0, fp0, fp1);
6841 tcg_temp_free_i64(fp1);
6842 gen_store_fpr64(ctx, fp0, fd);
6843 tcg_temp_free_i64(fp0);
6844 }
6845 opn = "sub.ps";
6846 break;
6847 case FOP(2, 22):
6848 check_cp1_64bitmode(ctx);
6849 {
6850 TCGv_i64 fp0 = tcg_temp_new_i64();
6851 TCGv_i64 fp1 = tcg_temp_new_i64();
6852
6853 gen_load_fpr64(ctx, fp0, fs);
6854 gen_load_fpr64(ctx, fp1, ft);
6855 gen_helper_float_mul_ps(fp0, fp0, fp1);
6856 tcg_temp_free_i64(fp1);
6857 gen_store_fpr64(ctx, fp0, fd);
6858 tcg_temp_free_i64(fp0);
6859 }
6860 opn = "mul.ps";
6861 break;
6862 case FOP(5, 22):
6863 check_cp1_64bitmode(ctx);
6864 {
6865 TCGv_i64 fp0 = tcg_temp_new_i64();
6866
6867 gen_load_fpr64(ctx, fp0, fs);
6868 gen_helper_float_abs_ps(fp0, fp0);
6869 gen_store_fpr64(ctx, fp0, fd);
6870 tcg_temp_free_i64(fp0);
6871 }
6872 opn = "abs.ps";
6873 break;
6874 case FOP(6, 22):
6875 check_cp1_64bitmode(ctx);
6876 {
6877 TCGv_i64 fp0 = tcg_temp_new_i64();
6878
6879 gen_load_fpr64(ctx, fp0, fs);
6880 gen_store_fpr64(ctx, fp0, fd);
6881 tcg_temp_free_i64(fp0);
6882 }
6883 opn = "mov.ps";
6884 break;
6885 case FOP(7, 22):
6886 check_cp1_64bitmode(ctx);
6887 {
6888 TCGv_i64 fp0 = tcg_temp_new_i64();
6889
6890 gen_load_fpr64(ctx, fp0, fs);
6891 gen_helper_float_chs_ps(fp0, fp0);
6892 gen_store_fpr64(ctx, fp0, fd);
6893 tcg_temp_free_i64(fp0);
6894 }
6895 opn = "neg.ps";
6896 break;
6897 case FOP(17, 22):
6898 check_cp1_64bitmode(ctx);
6899 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6900 opn = "movcf.ps";
6901 break;
6902 case FOP(18, 22):
6903 check_cp1_64bitmode(ctx);
6904 {
6905 int l1 = gen_new_label();
6906 TCGv t0 = tcg_temp_new();
6907 TCGv_i32 fp0 = tcg_temp_local_new_i32();
6908 TCGv_i32 fph0 = tcg_temp_local_new_i32();
6909
6910 gen_load_gpr(t0, ft);
6911 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6912 gen_load_fpr32(fp0, fs);
6913 gen_load_fpr32h(fph0, fs);
6914 gen_store_fpr32(fp0, fd);
6915 gen_store_fpr32h(fph0, fd);
6916 tcg_temp_free_i32(fp0);
6917 tcg_temp_free_i32(fph0);
6918 gen_set_label(l1);
6919 tcg_temp_free(t0);
6920 }
6921 opn = "movz.ps";
6922 break;
6923 case FOP(19, 22):
6924 check_cp1_64bitmode(ctx);
6925 {
6926 int l1 = gen_new_label();
6927 TCGv t0 = tcg_temp_new();
6928 TCGv_i32 fp0 = tcg_temp_local_new_i32();
6929 TCGv_i32 fph0 = tcg_temp_local_new_i32();
6930
6931 gen_load_gpr(t0, ft);
6932 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6933 gen_load_fpr32(fp0, fs);
6934 gen_load_fpr32h(fph0, fs);
6935 gen_store_fpr32(fp0, fd);
6936 gen_store_fpr32h(fph0, fd);
6937 tcg_temp_free_i32(fp0);
6938 tcg_temp_free_i32(fph0);
6939 gen_set_label(l1);
6940 tcg_temp_free(t0);
6941 }
6942 opn = "movn.ps";
6943 break;
6944 case FOP(24, 22):
6945 check_cp1_64bitmode(ctx);
6946 {
6947 TCGv_i64 fp0 = tcg_temp_new_i64();
6948 TCGv_i64 fp1 = tcg_temp_new_i64();
6949
6950 gen_load_fpr64(ctx, fp0, ft);
6951 gen_load_fpr64(ctx, fp1, fs);
6952 gen_helper_float_addr_ps(fp0, fp0, fp1);
6953 tcg_temp_free_i64(fp1);
6954 gen_store_fpr64(ctx, fp0, fd);
6955 tcg_temp_free_i64(fp0);
6956 }
6957 opn = "addr.ps";
6958 break;
6959 case FOP(26, 22):
6960 check_cp1_64bitmode(ctx);
6961 {
6962 TCGv_i64 fp0 = tcg_temp_new_i64();
6963 TCGv_i64 fp1 = tcg_temp_new_i64();
6964
6965 gen_load_fpr64(ctx, fp0, ft);
6966 gen_load_fpr64(ctx, fp1, fs);
6967 gen_helper_float_mulr_ps(fp0, fp0, fp1);
6968 tcg_temp_free_i64(fp1);
6969 gen_store_fpr64(ctx, fp0, fd);
6970 tcg_temp_free_i64(fp0);
6971 }
6972 opn = "mulr.ps";
6973 break;
6974 case FOP(28, 22):
6975 check_cp1_64bitmode(ctx);
6976 {
6977 TCGv_i64 fp0 = tcg_temp_new_i64();
6978 TCGv_i64 fp1 = tcg_temp_new_i64();
6979
6980 gen_load_fpr64(ctx, fp0, fs);
6981 gen_load_fpr64(ctx, fp1, fd);
6982 gen_helper_float_recip2_ps(fp0, fp0, fp1);
6983 tcg_temp_free_i64(fp1);
6984 gen_store_fpr64(ctx, fp0, fd);
6985 tcg_temp_free_i64(fp0);
6986 }
6987 opn = "recip2.ps";
6988 break;
6989 case FOP(29, 22):
6990 check_cp1_64bitmode(ctx);
6991 {
6992 TCGv_i64 fp0 = tcg_temp_new_i64();
6993
6994 gen_load_fpr64(ctx, fp0, fs);
6995 gen_helper_float_recip1_ps(fp0, fp0);
6996 gen_store_fpr64(ctx, fp0, fd);
6997 tcg_temp_free_i64(fp0);
6998 }
6999 opn = "recip1.ps";
7000 break;
7001 case FOP(30, 22):
7002 check_cp1_64bitmode(ctx);
7003 {
7004 TCGv_i64 fp0 = tcg_temp_new_i64();
7005
7006 gen_load_fpr64(ctx, fp0, fs);
7007 gen_helper_float_rsqrt1_ps(fp0, fp0);
7008 gen_store_fpr64(ctx, fp0, fd);
7009 tcg_temp_free_i64(fp0);
7010 }
7011 opn = "rsqrt1.ps";
7012 break;
7013 case FOP(31, 22):
7014 check_cp1_64bitmode(ctx);
7015 {
7016 TCGv_i64 fp0 = tcg_temp_new_i64();
7017 TCGv_i64 fp1 = tcg_temp_new_i64();
7018
7019 gen_load_fpr64(ctx, fp0, fs);
7020 gen_load_fpr64(ctx, fp1, ft);
7021 gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7022 tcg_temp_free_i64(fp1);
7023 gen_store_fpr64(ctx, fp0, fd);
7024 tcg_temp_free_i64(fp0);
7025 }
7026 opn = "rsqrt2.ps";
7027 break;
7028 case FOP(32, 22):
7029 check_cp1_64bitmode(ctx);
7030 {
7031 TCGv_i32 fp0 = tcg_temp_new_i32();
7032
7033 gen_load_fpr32h(fp0, fs);
7034 gen_helper_float_cvts_pu(fp0, fp0);
7035 gen_store_fpr32(fp0, fd);
7036 tcg_temp_free_i32(fp0);
7037 }
7038 opn = "cvt.s.pu";
7039 break;
7040 case FOP(36, 22):
7041 check_cp1_64bitmode(ctx);
7042 {
7043 TCGv_i64 fp0 = tcg_temp_new_i64();
7044
7045 gen_load_fpr64(ctx, fp0, fs);
7046 gen_helper_float_cvtpw_ps(fp0, fp0);
7047 gen_store_fpr64(ctx, fp0, fd);
7048 tcg_temp_free_i64(fp0);
7049 }
7050 opn = "cvt.pw.ps";
7051 break;
7052 case FOP(40, 22):
7053 check_cp1_64bitmode(ctx);
7054 {
7055 TCGv_i32 fp0 = tcg_temp_new_i32();
7056
7057 gen_load_fpr32(fp0, fs);
7058 gen_helper_float_cvts_pl(fp0, fp0);
7059 gen_store_fpr32(fp0, fd);
7060 tcg_temp_free_i32(fp0);
7061 }
7062 opn = "cvt.s.pl";
7063 break;
7064 case FOP(44, 22):
7065 check_cp1_64bitmode(ctx);
7066 {
7067 TCGv_i32 fp0 = tcg_temp_new_i32();
7068 TCGv_i32 fp1 = tcg_temp_new_i32();
7069
7070 gen_load_fpr32(fp0, fs);
7071 gen_load_fpr32(fp1, ft);
7072 gen_store_fpr32h(fp0, fd);
7073 gen_store_fpr32(fp1, fd);
7074 tcg_temp_free_i32(fp0);
7075 tcg_temp_free_i32(fp1);
7076 }
7077 opn = "pll.ps";
7078 break;
7079 case FOP(45, 22):
7080 check_cp1_64bitmode(ctx);
7081 {
7082 TCGv_i32 fp0 = tcg_temp_new_i32();
7083 TCGv_i32 fp1 = tcg_temp_new_i32();
7084
7085 gen_load_fpr32(fp0, fs);
7086 gen_load_fpr32h(fp1, ft);
7087 gen_store_fpr32(fp1, fd);
7088 gen_store_fpr32h(fp0, fd);
7089 tcg_temp_free_i32(fp0);
7090 tcg_temp_free_i32(fp1);
7091 }
7092 opn = "plu.ps";
7093 break;
7094 case FOP(46, 22):
7095 check_cp1_64bitmode(ctx);
7096 {
7097 TCGv_i32 fp0 = tcg_temp_new_i32();
7098 TCGv_i32 fp1 = tcg_temp_new_i32();
7099
7100 gen_load_fpr32h(fp0, fs);
7101 gen_load_fpr32(fp1, ft);
7102 gen_store_fpr32(fp1, fd);
7103 gen_store_fpr32h(fp0, fd);
7104 tcg_temp_free_i32(fp0);
7105 tcg_temp_free_i32(fp1);
7106 }
7107 opn = "pul.ps";
7108 break;
7109 case FOP(47, 22):
7110 check_cp1_64bitmode(ctx);
7111 {
7112 TCGv_i32 fp0 = tcg_temp_new_i32();
7113 TCGv_i32 fp1 = tcg_temp_new_i32();
7114
7115 gen_load_fpr32h(fp0, fs);
7116 gen_load_fpr32h(fp1, ft);
7117 gen_store_fpr32(fp1, fd);
7118 gen_store_fpr32h(fp0, fd);
7119 tcg_temp_free_i32(fp0);
7120 tcg_temp_free_i32(fp1);
7121 }
7122 opn = "puu.ps";
7123 break;
7124 case FOP(48, 22):
7125 case FOP(49, 22):
7126 case FOP(50, 22):
7127 case FOP(51, 22):
7128 case FOP(52, 22):
7129 case FOP(53, 22):
7130 case FOP(54, 22):
7131 case FOP(55, 22):
7132 case FOP(56, 22):
7133 case FOP(57, 22):
7134 case FOP(58, 22):
7135 case FOP(59, 22):
7136 case FOP(60, 22):
7137 case FOP(61, 22):
7138 case FOP(62, 22):
7139 case FOP(63, 22):
7140 check_cp1_64bitmode(ctx);
7141 {
7142 TCGv_i64 fp0 = tcg_temp_new_i64();
7143 TCGv_i64 fp1 = tcg_temp_new_i64();
7144
7145 gen_load_fpr64(ctx, fp0, fs);
7146 gen_load_fpr64(ctx, fp1, ft);
7147 if (ctx->opcode & (1 << 6)) {
7148 gen_cmpabs_ps(func-48, fp0, fp1, cc);
7149 opn = condnames_abs[func-48];
7150 } else {
7151 gen_cmp_ps(func-48, fp0, fp1, cc);
7152 opn = condnames[func-48];
7153 }
7154 tcg_temp_free_i64(fp0);
7155 tcg_temp_free_i64(fp1);
7156 }
7157 break;
7158 default:
7159 MIPS_INVAL(opn);
7160 generate_exception (ctx, EXCP_RI);
7161 return;
7162 }
7163 switch (optype) {
7164 case BINOP:
7165 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7166 break;
7167 case CMPOP:
7168 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7169 break;
7170 default:
7171 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7172 break;
7173 }
7174 }
7175
7176 /* Coprocessor 3 (FPU) */
7177 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7178 int fd, int fs, int base, int index)
7179 {
7180 const char *opn = "extended float load/store";
7181 int store = 0;
7182 TCGv t0 = tcg_temp_local_new();
7183 TCGv t1 = tcg_temp_local_new();
7184
7185 if (base == 0) {
7186 gen_load_gpr(t0, index);
7187 } else if (index == 0) {
7188 gen_load_gpr(t0, base);
7189 } else {
7190 gen_load_gpr(t0, index);
7191 gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7192 }
7193 /* Don't do NOP if destination is zero: we must perform the actual
7194 memory access. */
7195 switch (opc) {
7196 case OPC_LWXC1:
7197 check_cop1x(ctx);
7198 {
7199 TCGv_i32 fp0 = tcg_temp_new_i32();
7200
7201 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7202 tcg_gen_trunc_tl_i32(fp0, t1);
7203 gen_store_fpr32(fp0, fd);
7204 tcg_temp_free_i32(fp0);
7205 }
7206 opn = "lwxc1";
7207 break;
7208 case OPC_LDXC1:
7209 check_cop1x(ctx);
7210 check_cp1_registers(ctx, fd);
7211 {
7212 TCGv_i64 fp0 = tcg_temp_new_i64();
7213
7214 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7215 gen_store_fpr64(ctx, fp0, fd);
7216 tcg_temp_free_i64(fp0);
7217 }
7218 opn = "ldxc1";
7219 break;
7220 case OPC_LUXC1:
7221 check_cp1_64bitmode(ctx);
7222 tcg_gen_andi_tl(t0, t0, ~0x7);
7223 {
7224 TCGv_i64 fp0 = tcg_temp_new_i64();
7225
7226 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7227 gen_store_fpr64(ctx, fp0, fd);
7228 tcg_temp_free_i64(fp0);
7229 }
7230 opn = "luxc1";
7231 break;
7232 case OPC_SWXC1:
7233 check_cop1x(ctx);
7234 {
7235 TCGv_i32 fp0 = tcg_temp_new_i32();
7236
7237 gen_load_fpr32(fp0, fs);
7238 tcg_gen_extu_i32_tl(t1, fp0);
7239 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7240 tcg_temp_free_i32(fp0);
7241 }
7242 opn = "swxc1";
7243 store = 1;
7244 break;
7245 case OPC_SDXC1:
7246 check_cop1x(ctx);
7247 check_cp1_registers(ctx, fs);
7248 {
7249 TCGv_i64 fp0 = tcg_temp_new_i64();
7250
7251 gen_load_fpr64(ctx, fp0, fs);
7252 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7253 tcg_temp_free_i64(fp0);
7254 }
7255 opn = "sdxc1";
7256 store = 1;
7257 break;
7258 case OPC_SUXC1:
7259 check_cp1_64bitmode(ctx);
7260 tcg_gen_andi_tl(t0, t0, ~0x7);
7261 {
7262 TCGv_i64 fp0 = tcg_temp_new_i64();
7263
7264 gen_load_fpr64(ctx, fp0, fs);
7265 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7266 tcg_temp_free_i64(fp0);
7267 }
7268 opn = "suxc1";
7269 store = 1;
7270 break;
7271 default:
7272 MIPS_INVAL(opn);
7273 generate_exception(ctx, EXCP_RI);
7274 tcg_temp_free(t0);
7275 tcg_temp_free(t1);
7276 return;
7277 }
7278 tcg_temp_free(t0);
7279 tcg_temp_free(t1);
7280 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7281 regnames[index], regnames[base]);
7282 }
7283
7284 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7285 int fd, int fr, int fs, int ft)
7286 {
7287 const char *opn = "flt3_arith";
7288
7289 switch (opc) {
7290 case OPC_ALNV_PS:
7291 check_cp1_64bitmode(ctx);
7292 {
7293 TCGv t0 = tcg_temp_local_new();
7294 TCGv_i32 fp0 = tcg_temp_local_new_i32();
7295 TCGv_i32 fph0 = tcg_temp_local_new_i32();
7296 TCGv_i32 fp1 = tcg_temp_local_new_i32();
7297 TCGv_i32 fph1 = tcg_temp_local_new_i32();
7298 int l1 = gen_new_label();
7299 int l2 = gen_new_label();
7300
7301 gen_load_gpr(t0, fr);
7302 tcg_gen_andi_tl(t0, t0, 0x7);
7303 gen_load_fpr32(fp0, fs);
7304 gen_load_fpr32h(fph0, fs);
7305 gen_load_fpr32(fp1, ft);
7306 gen_load_fpr32h(fph1, ft);
7307
7308 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7309 gen_store_fpr32(fp0, fd);
7310 gen_store_fpr32h(fph0, fd);
7311 tcg_gen_br(l2);
7312 gen_set_label(l1);
7313 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7314 tcg_temp_free(t0);
7315 #ifdef TARGET_WORDS_BIGENDIAN
7316 gen_store_fpr32(fph1, fd);
7317 gen_store_fpr32h(fp0, fd);
7318 #else
7319 gen_store_fpr32(fph0, fd);
7320 gen_store_fpr32h(fp1, fd);
7321 #endif
7322 gen_set_label(l2);
7323 tcg_temp_free_i32(fp0);
7324 tcg_temp_free_i32(fph0);
7325 tcg_temp_free_i32(fp1);
7326 tcg_temp_free_i32(fph1);
7327 }
7328 opn = "alnv.ps";
7329 break;
7330 case OPC_MADD_S:
7331 check_cop1x(ctx);
7332 {
7333 TCGv_i32 fp0 = tcg_temp_new_i32();
7334 TCGv_i32 fp1 = tcg_temp_new_i32();
7335 TCGv_i32 fp2 = tcg_temp_new_i32();
7336
7337 gen_load_fpr32(fp0, fs);
7338 gen_load_fpr32(fp1, ft);
7339 gen_load_fpr32(fp2, fr);
7340 gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7341 tcg_temp_free_i32(fp0);
7342 tcg_temp_free_i32(fp1);
7343 gen_store_fpr32(fp2, fd);
7344 tcg_temp_free_i32(fp2);
7345 }
7346 opn = "madd.s";
7347 break;
7348 case OPC_MADD_D:
7349 check_cop1x(ctx);
7350 check_cp1_registers(ctx, fd | fs | ft | fr);
7351 {
7352 TCGv_i64 fp0 = tcg_temp_new_i64();
7353 TCGv_i64 fp1 = tcg_temp_new_i64();
7354 TCGv_i64 fp2 = tcg_temp_new_i64();
7355
7356 gen_load_fpr64(ctx, fp0, fs);
7357 gen_load_fpr64(ctx, fp1, ft);
7358 gen_load_fpr64(ctx, fp2, fr);
7359 gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7360 tcg_temp_free_i64(fp0);
7361 tcg_temp_free_i64(fp1);
7362 gen_store_fpr64(ctx, fp2, fd);
7363 tcg_temp_free_i64(fp2);
7364 }
7365 opn = "madd.d";
7366 break;
7367 case OPC_MADD_PS:
7368 check_cp1_64bitmode(ctx);
7369 {
7370 TCGv_i64 fp0 = tcg_temp_new_i64();
7371 TCGv_i64 fp1 = tcg_temp_new_i64();
7372 TCGv_i64 fp2 = tcg_temp_new_i64();
7373
7374 gen_load_fpr64(ctx, fp0, fs);
7375 gen_load_fpr64(ctx, fp1, ft);
7376 gen_load_fpr64(ctx, fp2, fr);
7377 gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7378 tcg_temp_free_i64(fp0);
7379 tcg_temp_free_i64(fp1);
7380 gen_store_fpr64(ctx, fp2, fd);
7381 tcg_temp_free_i64(fp2);
7382 }
7383 opn = "madd.ps";
7384 break;
7385 case OPC_MSUB_S:
7386 check_cop1x(ctx);
7387 {
7388 TCGv_i32 fp0 = tcg_temp_new_i32();
7389 TCGv_i32 fp1 = tcg_temp_new_i32();
7390 TCGv_i32 fp2 = tcg_temp_new_i32();
7391
7392 gen_load_fpr32(fp0, fs);
7393 gen_load_fpr32(fp1, ft);
7394 gen_load_fpr32(fp2, fr);
7395 gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7396 tcg_temp_free_i32(fp0);
7397 tcg_temp_free_i32(fp1);
7398 gen_store_fpr32(fp2, fd);
7399 tcg_temp_free_i32(fp2);
7400 }
7401 opn = "msub.s";
7402 break;
7403 case OPC_MSUB_D:
7404 check_cop1x(ctx);
7405 check_cp1_registers(ctx, fd | fs | ft | fr);
7406 {
7407 TCGv_i64 fp0 = tcg_temp_new_i64();
7408 TCGv_i64 fp1 = tcg_temp_new_i64();
7409 TCGv_i64 fp2 = tcg_temp_new_i64();
7410
7411 gen_load_fpr64(ctx, fp0, fs);
7412 gen_load_fpr64(ctx, fp1, ft);
7413 gen_load_fpr64(ctx, fp2, fr);
7414 gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7415 tcg_temp_free_i64(fp0);
7416 tcg_temp_free_i64(fp1);
7417 gen_store_fpr64(ctx, fp2, fd);
7418 tcg_temp_free_i64(fp2);
7419 }
7420 opn = "msub.d";
7421 break;
7422 case OPC_MSUB_PS:
7423 check_cp1_64bitmode(ctx);
7424 {
7425 TCGv_i64 fp0 = tcg_temp_new_i64();
7426 TCGv_i64 fp1 = tcg_temp_new_i64();
7427 TCGv_i64 fp2 = tcg_temp_new_i64();
7428
7429 gen_load_fpr64(ctx, fp0, fs);
7430 gen_load_fpr64(ctx, fp1, ft);
7431 gen_load_fpr64(ctx, fp2, fr);
7432 gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7433 tcg_temp_free_i64(fp0);
7434 tcg_temp_free_i64(fp1);
7435 gen_store_fpr64(ctx, fp2, fd);
7436 tcg_temp_free_i64(fp2);
7437 }
7438 opn = "msub.ps";
7439 break;
7440 case OPC_NMADD_S:
7441 check_cop1x(ctx);
7442 {
7443 TCGv_i32 fp0 = tcg_temp_new_i32();
7444 TCGv_i32 fp1 = tcg_temp_new_i32();
7445 TCGv_i32 fp2 = tcg_temp_new_i32();
7446
7447 gen_load_fpr32(fp0, fs);
7448 gen_load_fpr32(fp1, ft);
7449 gen_load_fpr32(fp2, fr);
7450 gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7451 tcg_temp_free_i32(fp0);
7452 tcg_temp_free_i32(fp1);
7453 gen_store_fpr32(fp2, fd);
7454 tcg_temp_free_i32(fp2);
7455 }
7456 opn = "nmadd.s";
7457 break;
7458 case OPC_NMADD_D:
7459 check_cop1x(ctx);
7460 check_cp1_registers(ctx, fd | fs | ft | fr);
7461 {
7462 TCGv_i64 fp0 = tcg_temp_new_i64();
7463 TCGv_i64 fp1 = tcg_temp_new_i64();
7464 TCGv_i64 fp2 = tcg_temp_new_i64();
7465
7466 gen_load_fpr64(ctx, fp0, fs);
7467 gen_load_fpr64(ctx, fp1, ft);
7468 gen_load_fpr64(ctx, fp2, fr);
7469 gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7470 tcg_temp_free_i64(fp0);
7471 tcg_temp_free_i64(fp1);
7472 gen_store_fpr64(ctx, fp2, fd);
7473 tcg_temp_free_i64(fp2);
7474 }
7475 opn = "nmadd.d";
7476 break;
7477 case OPC_NMADD_PS:
7478 check_cp1_64bitmode(ctx);
7479 {
7480 TCGv_i64 fp0 = tcg_temp_new_i64();
7481 TCGv_i64 fp1 = tcg_temp_new_i64();
7482 TCGv_i64 fp2 = tcg_temp_new_i64();
7483
7484 gen_load_fpr64(ctx, fp0, fs);
7485 gen_load_fpr64(ctx, fp1, ft);
7486 gen_load_fpr64(ctx, fp2, fr);
7487 gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7488 tcg_temp_free_i64(fp0);
7489 tcg_temp_free_i64(fp1);
7490 gen_store_fpr64(ctx, fp2, fd);
7491 tcg_temp_free_i64(fp2);
7492 }
7493 opn = "nmadd.ps";
7494 break;
7495 case OPC_NMSUB_S:
7496 check_cop1x(ctx);
7497 {
7498 TCGv_i32 fp0 = tcg_temp_new_i32();
7499 TCGv_i32 fp1 = tcg_temp_new_i32();
7500 TCGv_i32 fp2 = tcg_temp_new_i32();
7501
7502 gen_load_fpr32(fp0, fs);
7503 gen_load_fpr32(fp1, ft);
7504 gen_load_fpr32(fp2, fr);
7505 gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7506 tcg_temp_free_i32(fp0);
7507 tcg_temp_free_i32(fp1);
7508 gen_store_fpr32(fp2, fd);
7509 tcg_temp_free_i32(fp2);
7510 }
7511 opn = "nmsub.s";
7512 break;
7513 case OPC_NMSUB_D:
7514 check_cop1x(ctx);
7515 check_cp1_registers(ctx, fd | fs | ft | fr);
7516 {
7517 TCGv_i64 fp0 = tcg_temp_new_i64();
7518 TCGv_i64 fp1 = tcg_temp_new_i64();
7519 TCGv_i64 fp2 = tcg_temp_new_i64();
7520
7521 gen_load_fpr64(ctx, fp0, fs);
7522 gen_load_fpr64(ctx, fp1, ft);
7523 gen_load_fpr64(ctx, fp2, fr);
7524 gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7525 tcg_temp_free_i64(fp0);
7526 tcg_temp_free_i64(fp1);
7527 gen_store_fpr64(ctx, fp2, fd);
7528 tcg_temp_free_i64(fp2);
7529 }
7530 opn = "nmsub.d";
7531 break;
7532 case OPC_NMSUB_PS:
7533 check_cp1_64bitmode(ctx);
7534 {
7535 TCGv_i64 fp0 = tcg_temp_new_i64();
7536 TCGv_i64 fp1 = tcg_temp_new_i64();
7537 TCGv_i64 fp2 = tcg_temp_new_i64();
7538
7539 gen_load_fpr64(ctx, fp0, fs);
7540 gen_load_fpr64(ctx, fp1, ft);
7541 gen_load_fpr64(ctx, fp2, fr);
7542 gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7543 tcg_temp_free_i64(fp0);
7544 tcg_temp_free_i64(fp1);
7545 gen_store_fpr64(ctx, fp2, fd);
7546 tcg_temp_free_i64(fp2);
7547 }
7548 opn = "nmsub.ps";
7549 break;
7550 default:
7551 MIPS_INVAL(opn);
7552 generate_exception (ctx, EXCP_RI);
7553 return;
7554 }
7555 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7556 fregnames[fs], fregnames[ft]);
7557 }
7558
7559 /* ISA extensions (ASEs) */
7560 /* MIPS16 extension to MIPS32 */
7561 /* SmartMIPS extension to MIPS32 */
7562
7563 #if defined(TARGET_MIPS64)
7564
7565 /* MDMX extension to MIPS64 */
7566
7567 #endif
7568
7569 static void decode_opc (CPUState *env, DisasContext *ctx)
7570 {
7571 int32_t offset;
7572 int rs, rt, rd, sa;
7573 uint32_t op, op1, op2;
7574 int16_t imm;
7575
7576 /* make sure instructions are on a word boundary */
7577 if (ctx->pc & 0x3) {
7578 env->CP0_BadVAddr = ctx->pc;
7579 generate_exception(ctx, EXCP_AdEL);
7580 return;
7581 }
7582
7583 /* Handle blikely not taken case */
7584 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7585 int l1 = gen_new_label();
7586
7587 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7588 tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7589 {
7590 TCGv_i32 r_tmp = tcg_temp_new_i32();
7591
7592 tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7593 tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7594 tcg_temp_free_i32(r_tmp);
7595 }
7596 gen_goto_tb(ctx, 1, ctx->pc + 4);
7597 gen_set_label(l1);
7598 }
7599 op = MASK_OP_MAJOR(ctx->opcode);
7600 rs = (ctx->opcode >> 21) & 0x1f;
7601 rt = (ctx->opcode >> 16) & 0x1f;
7602 rd = (ctx->opcode >> 11) & 0x1f;
7603 sa = (ctx->opcode >> 6) & 0x1f;
7604 imm = (int16_t)ctx->opcode;
7605 switch (op) {
7606 case OPC_SPECIAL:
7607 op1 = MASK_SPECIAL(ctx->opcode);
7608 switch (op1) {
7609 case OPC_SLL: /* Arithmetic with immediate */
7610 case OPC_SRL ... OPC_SRA:
7611 gen_arith_imm(env, ctx, op1, rd, rt, sa);
7612 break;
7613 case OPC_MOVZ ... OPC_MOVN:
7614 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7615 case OPC_SLLV: /* Arithmetic */
7616 case OPC_SRLV ... OPC_SRAV:
7617 case OPC_ADD ... OPC_NOR:
7618 case OPC_SLT ... OPC_SLTU:
7619 gen_arith(env, ctx, op1, rd, rs, rt);
7620 break;
7621 case OPC_MULT ... OPC_DIVU:
7622 if (sa) {
7623 check_insn(env, ctx, INSN_VR54XX);
7624 op1 = MASK_MUL_VR54XX(ctx->opcode);
7625 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7626 } else
7627 gen_muldiv(ctx, op1, rs, rt);
7628 break;
7629 case OPC_JR ... OPC_JALR:
7630 gen_compute_branch(ctx, op1, rs, rd, sa);
7631 return;
7632 case OPC_TGE ... OPC_TEQ: /* Traps */
7633 case OPC_TNE:
7634 gen_trap(ctx, op1, rs, rt, -1);
7635 break;
7636 case OPC_MFHI: /* Move from HI/LO */
7637 case OPC_MFLO:
7638 gen_HILO(ctx, op1, rd);
7639 break;
7640 case OPC_MTHI:
7641 case OPC_MTLO: /* Move to HI/LO */
7642 gen_HILO(ctx, op1, rs);
7643 break;
7644 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
7645 #ifdef MIPS_STRICT_STANDARD
7646 MIPS_INVAL("PMON / selsl");
7647 generate_exception(ctx, EXCP_RI);
7648 #else
7649 gen_helper_0i(pmon, sa);
7650 #endif
7651 break;
7652 case OPC_SYSCALL:
7653 generate_exception(ctx, EXCP_SYSCALL);
7654 break;
7655 case OPC_BREAK:
7656 generate_exception(ctx, EXCP_BREAK);
7657 break;
7658 case OPC_SPIM:
7659 #ifdef MIPS_STRICT_STANDARD
7660 MIPS_INVAL("SPIM");
7661 generate_exception(ctx, EXCP_RI);
7662 #else
7663 /* Implemented as RI exception for now. */
7664 MIPS_INVAL("spim (unofficial)");
7665 generate_exception(ctx, EXCP_RI);
7666 #endif
7667 break;
7668 case OPC_SYNC:
7669 /* Treat as NOP. */
7670 break;
7671
7672 case OPC_MOVCI:
7673 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7674 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7675 save_cpu_state(ctx, 1);
7676 check_cp1_enabled(ctx);
7677 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7678 (ctx->opcode >> 16) & 1);
7679 } else {
7680 generate_exception_err(ctx, EXCP_CpU, 1);
7681 }
7682 break;
7683
7684 #if defined(TARGET_MIPS64)
7685 /* MIPS64 specific opcodes */
7686 case OPC_DSLL:
7687 case OPC_DSRL ... OPC_DSRA:
7688 case OPC_DSLL32:
7689 case OPC_DSRL32 ... OPC_DSRA32:
7690 check_insn(env, ctx, ISA_MIPS3);
7691 check_mips_64(ctx);
7692 gen_arith_imm(env, ctx, op1, rd, rt, sa);
7693 break;
7694 case OPC_DSLLV:
7695 case OPC_DSRLV ... OPC_DSRAV:
7696 case OPC_DADD ... OPC_DSUBU:
7697 check_insn(env, ctx, ISA_MIPS3);
7698 check_mips_64(ctx);
7699 gen_arith(env, ctx, op1, rd, rs, rt);
7700 break;
7701 case OPC_DMULT ... OPC_DDIVU:
7702 check_insn(env, ctx, ISA_MIPS3);
7703 check_mips_64(ctx);
7704 gen_muldiv(ctx, op1, rs, rt);
7705 break;
7706 #endif
7707 default: /* Invalid */
7708 MIPS_INVAL("special");
7709 generate_exception(ctx, EXCP_RI);
7710 break;
7711 }
7712 break;
7713 case OPC_SPECIAL2:
7714 op1 = MASK_SPECIAL2(ctx->opcode);
7715 switch (op1) {
7716 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7717 case OPC_MSUB ... OPC_MSUBU:
7718 check_insn(env, ctx, ISA_MIPS32);
7719 gen_muldiv(ctx, op1, rs, rt);
7720 break;
7721 case OPC_MUL:
7722 gen_arith(env, ctx, op1, rd, rs, rt);
7723 break;
7724 case OPC_CLO:
7725 case OPC_CLZ:
7726 check_insn(env, ctx, ISA_MIPS32);
7727 gen_cl(ctx, op1, rd, rs);
7728 break;
7729 case OPC_SDBBP:
7730 /* XXX: not clear which exception should be raised
7731 * when in debug mode...
7732 */
7733 check_insn(env, ctx, ISA_MIPS32);
7734 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7735 generate_exception(ctx, EXCP_DBp);
7736 } else {
7737 generate_exception(ctx, EXCP_DBp);
7738 }
7739 /* Treat as NOP. */
7740 break;
7741 #if defined(TARGET_MIPS64)
7742 case OPC_DCLO:
7743 case OPC_DCLZ:
7744 check_insn(env, ctx, ISA_MIPS64);
7745 check_mips_64(ctx);
7746 gen_cl(ctx, op1, rd, rs);
7747 break;
7748 #endif
7749 default: /* Invalid */
7750 MIPS_INVAL("special2");
7751 generate_exception(ctx, EXCP_RI);
7752 break;
7753 }
7754 break;
7755 case OPC_SPECIAL3:
7756 op1 = MASK_SPECIAL3(ctx->opcode);
7757 switch (op1) {
7758 case OPC_EXT:
7759 case OPC_INS:
7760 check_insn(env, ctx, ISA_MIPS32R2);
7761 gen_bitops(ctx, op1, rt, rs, sa, rd);
7762 break;
7763 case OPC_BSHFL:
7764 check_insn(env, ctx, ISA_MIPS32R2);
7765 op2 = MASK_BSHFL(ctx->opcode);
7766 gen_bshfl(ctx, op2, rt, rd);
7767 break;
7768 case OPC_RDHWR:
7769 check_insn(env, ctx, ISA_MIPS32R2);
7770 {
7771 TCGv t0 = tcg_temp_local_new();
7772
7773 switch (rd) {
7774 case 0:
7775 save_cpu_state(ctx, 1);
7776 gen_helper_rdhwr_cpunum(t0);
7777 break;
7778 case 1:
7779 save_cpu_state(ctx, 1);
7780 gen_helper_rdhwr_synci_step(t0);
7781 break;
7782 case 2:
7783 save_cpu_state(ctx, 1);
7784 gen_helper_rdhwr_cc(t0);
7785 break;
7786 case 3:
7787 save_cpu_state(ctx, 1);
7788 gen_helper_rdhwr_ccres(t0);
7789 break;
7790 case 29:
7791 #if defined(CONFIG_USER_ONLY)
7792 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7793 break;
7794 #else
7795 /* XXX: Some CPUs implement this in hardware.
7796 Not supported yet. */
7797 #endif
7798 default: /* Invalid */
7799 MIPS_INVAL("rdhwr");
7800 generate_exception(ctx, EXCP_RI);
7801 break;
7802 }
7803 gen_store_gpr(t0, rt);
7804 tcg_temp_free(t0);
7805 }
7806 break;
7807 case OPC_FORK:
7808 check_insn(env, ctx, ASE_MT);
7809 {
7810 TCGv t0 = tcg_temp_local_new();
7811 TCGv t1 = tcg_temp_local_new();
7812
7813 gen_load_gpr(t0, rt);
7814 gen_load_gpr(t1, rs);
7815 gen_helper_fork(t0, t1);
7816 tcg_temp_free(t0);
7817 tcg_temp_free(t1);
7818 }
7819 break;
7820 case OPC_YIELD:
7821 check_insn(env, ctx, ASE_MT);
7822 {
7823 TCGv t0 = tcg_temp_local_new();
7824
7825 gen_load_gpr(t0, rs);
7826 gen_helper_yield(t0, t0);
7827 gen_store_gpr(t0, rd);
7828 tcg_temp_free(t0);
7829 }
7830 break;
7831 #if defined(TARGET_MIPS64)
7832 case OPC_DEXTM ... OPC_DEXT:
7833 case OPC_DINSM ... OPC_DINS:
7834 check_insn(env, ctx, ISA_MIPS64R2);
7835 check_mips_64(ctx);
7836 gen_bitops(ctx, op1, rt, rs, sa, rd);
7837 break;
7838 case OPC_DBSHFL:
7839 check_insn(env, ctx, ISA_MIPS64R2);
7840 check_mips_64(ctx);
7841 op2 = MASK_DBSHFL(ctx->opcode);
7842 gen_bshfl(ctx, op2, rt, rd);
7843 break;
7844 #endif
7845 default: /* Invalid */
7846 MIPS_INVAL("special3");
7847 generate_exception(ctx, EXCP_RI);
7848 break;
7849 }
7850 break;
7851 case OPC_REGIMM:
7852 op1 = MASK_REGIMM(ctx->opcode);
7853 switch (op1) {
7854 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7855 case OPC_BLTZAL ... OPC_BGEZALL:
7856 gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7857 return;
7858 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7859 case OPC_TNEI:
7860 gen_trap(ctx, op1, rs, -1, imm);
7861 break;
7862 case OPC_SYNCI:
7863 check_insn(env, ctx, ISA_MIPS32R2);
7864 /* Treat as NOP. */
7865 break;
7866 default: /* Invalid */
7867 MIPS_INVAL("regimm");
7868 generate_exception(ctx, EXCP_RI);
7869 break;
7870 }
7871 break;
7872 case OPC_CP0:
7873 check_cp0_enabled(ctx);
7874 op1 = MASK_CP0(ctx->opcode);
7875 switch (op1) {
7876 case OPC_MFC0:
7877 case OPC_MTC0:
7878 case OPC_MFTR:
7879 case OPC_MTTR:
7880 #if defined(TARGET_MIPS64)
7881 case OPC_DMFC0:
7882 case OPC_DMTC0:
7883 #endif
7884 #ifndef CONFIG_USER_ONLY
7885 gen_cp0(env, ctx, op1, rt, rd);
7886 #endif /* !CONFIG_USER_ONLY */
7887 break;
7888 case OPC_C0_FIRST ... OPC_C0_LAST:
7889 #ifndef CONFIG_USER_ONLY
7890 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7891 #endif /* !CONFIG_USER_ONLY */
7892 break;
7893 case OPC_MFMC0:
7894 #ifndef CONFIG_USER_ONLY
7895 {
7896 TCGv t0 = tcg_temp_local_new();
7897
7898 op2 = MASK_MFMC0(ctx->opcode);
7899 switch (op2) {
7900 case OPC_DMT:
7901 check_insn(env, ctx, ASE_MT);
7902 gen_helper_dmt(t0, t0);
7903 break;
7904 case OPC_EMT:
7905 check_insn(env, ctx, ASE_MT);
7906 gen_helper_emt(t0, t0);
7907 break;
7908 case OPC_DVPE:
7909 check_insn(env, ctx, ASE_MT);
7910 gen_helper_dvpe(t0, t0);
7911 break;
7912 case OPC_EVPE:
7913 check_insn(env, ctx, ASE_MT);
7914 gen_helper_evpe(t0, t0);
7915 break;
7916 case OPC_DI:
7917 check_insn(env, ctx, ISA_MIPS32R2);
7918 save_cpu_state(ctx, 1);
7919 gen_helper_di(t0);
7920 /* Stop translation as we may have switched the execution mode */
7921 ctx->bstate = BS_STOP;
7922 break;
7923 case OPC_EI:
7924 check_insn(env, ctx, ISA_MIPS32R2);
7925 save_cpu_state(ctx, 1);
7926 gen_helper_ei(t0);
7927 /* Stop translation as we may have switched the execution mode */
7928 ctx->bstate = BS_STOP;
7929 break;
7930 default: /* Invalid */
7931 MIPS_INVAL("mfmc0");
7932 generate_exception(ctx, EXCP_RI);
7933 break;
7934 }
7935 gen_store_gpr(t0, rt);
7936 tcg_temp_free(t0);
7937 }
7938 #endif /* !CONFIG_USER_ONLY */
7939 break;
7940 case OPC_RDPGPR:
7941 check_insn(env, ctx, ISA_MIPS32R2);
7942 gen_load_srsgpr(rt, rd);
7943 break;
7944 case OPC_WRPGPR:
7945 check_insn(env, ctx, ISA_MIPS32R2);
7946 gen_store_srsgpr(rt, rd);
7947 break;
7948 default:
7949 MIPS_INVAL("cp0");
7950 generate_exception(ctx, EXCP_RI);
7951 break;
7952 }
7953 break;
7954 case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7955 gen_arith_imm(env, ctx, op, rt, rs, imm);
7956 break;
7957 case OPC_J ... OPC_JAL: /* Jump */
7958 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7959 gen_compute_branch(ctx, op, rs, rt, offset);
7960 return;
7961 case OPC_BEQ ... OPC_BGTZ: /* Branch */
7962 case OPC_BEQL ... OPC_BGTZL:
7963 gen_compute_branch(ctx, op, rs, rt, imm << 2);
7964 return;
7965 case OPC_LB ... OPC_LWR: /* Load and stores */
7966 case OPC_SB ... OPC_SW:
7967 case OPC_SWR:
7968 case OPC_LL:
7969 case OPC_SC:
7970 gen_ldst(ctx, op, rt, rs, imm);
7971 break;
7972 case OPC_CACHE:
7973 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7974 /* Treat as NOP. */
7975 break;
7976 case OPC_PREF:
7977 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7978 /* Treat as NOP. */
7979 break;
7980
7981 /* Floating point (COP1). */
7982 case OPC_LWC1:
7983 case OPC_LDC1:
7984 case OPC_SWC1:
7985 case OPC_SDC1:
7986 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7987 save_cpu_state(ctx, 1);
7988 check_cp1_enabled(ctx);
7989 gen_flt_ldst(ctx, op, rt, rs, imm);
7990 } else {
7991 generate_exception_err(ctx, EXCP_CpU, 1);
7992 }
7993 break;
7994
7995 case OPC_CP1:
7996 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7997 save_cpu_state(ctx, 1);
7998 check_cp1_enabled(ctx);
7999 op1 = MASK_CP1(ctx->opcode);
8000 switch (op1) {
8001 case OPC_MFHC1:
8002 case OPC_MTHC1:
8003 check_insn(env, ctx, ISA_MIPS32R2);
8004 case OPC_MFC1:
8005 case OPC_CFC1:
8006 case OPC_MTC1:
8007 case OPC_CTC1:
8008 gen_cp1(ctx, op1, rt, rd);
8009 break;
8010 #if defined(TARGET_MIPS64)
8011 case OPC_DMFC1:
8012 case OPC_DMTC1:
8013 check_insn(env, ctx, ISA_MIPS3);
8014 gen_cp1(ctx, op1, rt, rd);
8015 break;
8016 #endif
8017 case OPC_BC1ANY2:
8018 case OPC_BC1ANY4:
8019 check_cop1x(ctx);
8020 check_insn(env, ctx, ASE_MIPS3D);
8021 /* fall through */
8022 case OPC_BC1:
8023 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8024 (rt >> 2) & 0x7, imm << 2);
8025 return;
8026 case OPC_S_FMT:
8027 case OPC_D_FMT:
8028 case OPC_W_FMT:
8029 case OPC_L_FMT:
8030 case OPC_PS_FMT:
8031 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8032 (imm >> 8) & 0x7);
8033 break;
8034 default:
8035 MIPS_INVAL("cp1");
8036 generate_exception (ctx, EXCP_RI);
8037 break;
8038 }
8039 } else {
8040 generate_exception_err(ctx, EXCP_CpU, 1);
8041 }
8042 break;
8043
8044 /* COP2. */
8045 case OPC_LWC2:
8046 case OPC_LDC2:
8047 case OPC_SWC2:
8048 case OPC_SDC2:
8049 case OPC_CP2:
8050 /* COP2: Not implemented. */
8051 generate_exception_err(ctx, EXCP_CpU, 2);
8052 break;
8053
8054 case OPC_CP3:
8055 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8056 save_cpu_state(ctx, 1);
8057 check_cp1_enabled(ctx);
8058 op1 = MASK_CP3(ctx->opcode);
8059 switch (op1) {
8060 case OPC_LWXC1:
8061 case OPC_LDXC1:
8062 case OPC_LUXC1:
8063 case OPC_SWXC1:
8064 case OPC_SDXC1:
8065 case OPC_SUXC1:
8066 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8067 break;
8068 case OPC_PREFX:
8069 /* Treat as NOP. */
8070 break;
8071 case OPC_ALNV_PS:
8072 case OPC_MADD_S:
8073 case OPC_MADD_D:
8074 case OPC_MADD_PS:
8075 case OPC_MSUB_S:
8076 case OPC_MSUB_D:
8077 case OPC_MSUB_PS:
8078 case OPC_NMADD_S:
8079 case OPC_NMADD_D:
8080 case OPC_NMADD_PS:
8081 case OPC_NMSUB_S:
8082 case OPC_NMSUB_D:
8083 case OPC_NMSUB_PS:
8084 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8085 break;
8086 default:
8087 MIPS_INVAL("cp3");
8088 generate_exception (ctx, EXCP_RI);
8089 break;
8090 }
8091 } else {
8092 generate_exception_err(ctx, EXCP_CpU, 1);
8093 }
8094 break;
8095
8096 #if defined(TARGET_MIPS64)
8097 /* MIPS64 opcodes */
8098 case OPC_LWU:
8099 case OPC_LDL ... OPC_LDR:
8100 case OPC_SDL ... OPC_SDR:
8101 case OPC_LLD:
8102 case OPC_LD:
8103 case OPC_SCD:
8104 case OPC_SD:
8105 check_insn(env, ctx, ISA_MIPS3);
8106 check_mips_64(ctx);
8107 gen_ldst(ctx, op, rt, rs, imm);
8108 break;
8109 case OPC_DADDI ... OPC_DADDIU:
8110 check_insn(env, ctx, ISA_MIPS3);
8111 check_mips_64(ctx);
8112 gen_arith_imm(env, ctx, op, rt, rs, imm);
8113 break;
8114 #endif
8115 case OPC_JALX:
8116 check_insn(env, ctx, ASE_MIPS16);
8117 /* MIPS16: Not implemented. */
8118 case OPC_MDMX:
8119 check_insn(env, ctx, ASE_MDMX);
8120 /* MDMX: Not implemented. */
8121 default: /* Invalid */
8122 MIPS_INVAL("major opcode");
8123 generate_exception(ctx, EXCP_RI);
8124 break;
8125 }
8126 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8127 int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8128 /* Branches completion */
8129 ctx->hflags &= ~MIPS_HFLAG_BMASK;
8130 ctx->bstate = BS_BRANCH;
8131 save_cpu_state(ctx, 0);
8132 /* FIXME: Need to clear can_do_io. */
8133 switch (hflags) {
8134 case MIPS_HFLAG_B:
8135 /* unconditional branch */
8136 MIPS_DEBUG("unconditional branch");
8137 gen_goto_tb(ctx, 0, ctx->btarget);
8138 break;
8139 case MIPS_HFLAG_BL:
8140 /* blikely taken case */
8141 MIPS_DEBUG("blikely branch taken");
8142 gen_goto_tb(ctx, 0, ctx->btarget);
8143 break;
8144 case MIPS_HFLAG_BC:
8145 /* Conditional branch */
8146 MIPS_DEBUG("conditional branch");
8147 {
8148 int l1 = gen_new_label();
8149
8150 tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8151 gen_goto_tb(ctx, 1, ctx->pc + 4);
8152 gen_set_label(l1);
8153 gen_goto_tb(ctx, 0, ctx->btarget);
8154 }
8155 break;
8156 case MIPS_HFLAG_BR:
8157 /* unconditional branch to register */
8158 MIPS_DEBUG("branch to register");
8159 tcg_gen_mov_tl(cpu_PC, btarget);
8160 tcg_gen_exit_tb(0);
8161 break;
8162 default:
8163 MIPS_DEBUG("unknown branch");
8164 break;
8165 }
8166 }
8167 }
8168
8169 static inline void
8170 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8171 int search_pc)
8172 {
8173 DisasContext ctx;
8174 target_ulong pc_start;
8175 uint16_t *gen_opc_end;
8176 CPUBreakpoint *bp;
8177 int j, lj = -1;
8178 int num_insns;
8179 int max_insns;
8180
8181 if (search_pc)
8182 qemu_log("search pc %d\n", search_pc);
8183
8184 pc_start = tb->pc;
8185 /* Leave some spare opc slots for branch handling. */
8186 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8187 ctx.pc = pc_start;
8188 ctx.saved_pc = -1;
8189 ctx.tb = tb;
8190 ctx.bstate = BS_NONE;
8191 /* Restore delay slot state from the tb context. */
8192 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8193 restore_cpu_state(env, &ctx);
8194 #ifdef CONFIG_USER_ONLY
8195 ctx.mem_idx = MIPS_HFLAG_UM;
8196 #else
8197 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8198 #endif
8199 num_insns = 0;
8200 max_insns = tb->cflags & CF_COUNT_MASK;
8201 if (max_insns == 0)
8202 max_insns = CF_COUNT_MASK;
8203 #ifdef DEBUG_DISAS
8204 qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8205 /* FIXME: This may print out stale hflags from env... */
8206 log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8207 #endif
8208 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8209 gen_icount_start();
8210 while (ctx.bstate == BS_NONE) {
8211 if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8212 TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8213 if (bp->pc == ctx.pc) {
8214 save_cpu_state(&ctx, 1);
8215 ctx.bstate = BS_BRANCH;
8216 gen_helper_0i(raise_exception, EXCP_DEBUG);
8217 /* Include the breakpoint location or the tb won't
8218 * be flushed when it must be. */
8219 ctx.pc += 4;
8220 goto done_generating;
8221 }
8222 }
8223 }
8224
8225 if (search_pc) {
8226 j = gen_opc_ptr - gen_opc_buf;
8227 if (lj < j) {
8228 lj++;
8229 while (lj < j)
8230 gen_opc_instr_start[lj++] = 0;
8231 }
8232 gen_opc_pc[lj] = ctx.pc;
8233 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8234 gen_opc_instr_start[lj] = 1;
8235 gen_opc_icount[lj] = num_insns;
8236 }
8237 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8238 gen_io_start();
8239 ctx.opcode = ldl_code(ctx.pc);
8240 decode_opc(env, &ctx);
8241 ctx.pc += 4;
8242 num_insns++;
8243
8244 if (env->singlestep_enabled)
8245 break;
8246
8247 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8248 break;
8249
8250 if (gen_opc_ptr >= gen_opc_end)
8251 break;
8252
8253 if (num_insns >= max_insns)
8254 break;
8255 #if defined (MIPS_SINGLE_STEP)
8256 break;
8257 #endif
8258 }
8259 if (tb->cflags & CF_LAST_IO)
8260 gen_io_end();
8261 if (env->singlestep_enabled) {
8262 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8263 gen_helper_0i(raise_exception, EXCP_DEBUG);
8264 } else {
8265 switch (ctx.bstate) {
8266 case BS_STOP:
8267 gen_helper_interrupt_restart();
8268 gen_goto_tb(&ctx, 0, ctx.pc);
8269 break;
8270 case BS_NONE:
8271 save_cpu_state(&ctx, 0);
8272 gen_goto_tb(&ctx, 0, ctx.pc);
8273 break;
8274 case BS_EXCP:
8275 gen_helper_interrupt_restart();
8276 tcg_gen_exit_tb(0);
8277 break;
8278 case BS_BRANCH:
8279 default:
8280 break;
8281 }
8282 }
8283 done_generating:
8284 gen_icount_end(tb, num_insns);
8285 *gen_opc_ptr = INDEX_op_end;
8286 if (search_pc) {
8287 j = gen_opc_ptr - gen_opc_buf;
8288 lj++;
8289 while (lj <= j)
8290 gen_opc_instr_start[lj++] = 0;
8291 } else {
8292 tb->size = ctx.pc - pc_start;
8293 tb->icount = num_insns;
8294 }
8295 #ifdef DEBUG_DISAS
8296 LOG_DISAS("\n");
8297 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8298 qemu_log("IN: %s\n", lookup_symbol(pc_start));
8299 log_target_disas(pc_start, ctx.pc - pc_start, 0);
8300 qemu_log("\n");
8301 }
8302 qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8303 #endif
8304 }
8305
8306 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8307 {
8308 gen_intermediate_code_internal(env, tb, 0);
8309 }
8310
8311 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8312 {
8313 gen_intermediate_code_internal(env, tb, 1);
8314 }
8315
8316 static void fpu_dump_state(CPUState *env, FILE *f,
8317 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8318 int flags)
8319 {
8320 int i;
8321 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8322
8323 #define printfpr(fp) \
8324 do { \
8325 if (is_fpu64) \
8326 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n", \
8327 (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd, \
8328 (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8329 else { \
8330 fpr_t tmp; \
8331 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
8332 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
8333 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n", \
8334 tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd, \
8335 tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]); \
8336 } \
8337 } while(0)
8338
8339
8340 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
8341 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8342 get_float_exception_flags(&env->active_fpu.fp_status));
8343 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8344 fpu_fprintf(f, "%3s: ", fregnames[i]);
8345 printfpr(&env->active_fpu.fpr[i]);
8346 }
8347
8348 #undef printfpr
8349 }
8350
8351 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8352 /* Debug help: The architecture requires 32bit code to maintain proper
8353 sign-extended values on 64bit machines. */
8354
8355 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8356
8357 static void
8358 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8359 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8360 int flags)
8361 {
8362 int i;
8363
8364 if (!SIGN_EXT_P(env->active_tc.PC))
8365 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8366 if (!SIGN_EXT_P(env->active_tc.HI[0]))
8367 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8368 if (!SIGN_EXT_P(env->active_tc.LO[0]))
8369 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8370 if (!SIGN_EXT_P(env->btarget))
8371 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8372
8373 for (i = 0; i < 32; i++) {
8374 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8375 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8376 }
8377
8378 if (!SIGN_EXT_P(env->CP0_EPC))
8379 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8380 if (!SIGN_EXT_P(env->CP0_LLAddr))
8381 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8382 }
8383 #endif
8384
8385 void cpu_dump_state (CPUState *env, FILE *f,
8386 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8387 int flags)
8388 {
8389 int i;
8390
8391 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",
8392 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8393 env->hflags, env->btarget, env->bcond);
8394 for (i = 0; i < 32; i++) {
8395 if ((i & 3) == 0)
8396 cpu_fprintf(f, "GPR%02d:", i);
8397 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8398 if ((i & 3) == 3)
8399 cpu_fprintf(f, "\n");
8400 }
8401
8402 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
8403 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8404 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8405 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8406 if (env->hflags & MIPS_HFLAG_FPU)
8407 fpu_dump_state(env, f, cpu_fprintf, flags);
8408 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8409 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8410 #endif
8411 }
8412
8413 static void mips_tcg_init(void)
8414 {
8415 int i;
8416 static int inited;
8417
8418 /* Initialize various static tables. */
8419 if (inited)
8420 return;
8421
8422 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8423 for (i = 0; i < 32; i++)
8424 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8425 offsetof(CPUState, active_tc.gpr[i]),
8426 regnames[i]);
8427 cpu_PC = tcg_global_mem_new(TCG_AREG0,
8428 offsetof(CPUState, active_tc.PC), "PC");
8429 for (i = 0; i < MIPS_DSP_ACC; i++) {
8430 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8431 offsetof(CPUState, active_tc.HI[i]),
8432 regnames_HI[i]);
8433 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8434 offsetof(CPUState, active_tc.LO[i]),
8435 regnames_LO[i]);
8436 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8437 offsetof(CPUState, active_tc.ACX[i]),
8438 regnames_ACX[i]);
8439 }
8440 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8441 offsetof(CPUState, active_tc.DSPControl),
8442 "DSPControl");
8443 bcond = tcg_global_mem_new_i32(TCG_AREG0,
8444 offsetof(CPUState, bcond), "bcond");
8445 btarget = tcg_global_mem_new(TCG_AREG0,
8446 offsetof(CPUState, btarget), "btarget");
8447 for (i = 0; i < 32; i++)
8448 fpu_fpr32[i] = tcg_global_mem_new_i32(TCG_AREG0,
8449 offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8450 fregnames[i]);
8451 for (i = 0; i < 32; i++)
8452 fpu_fpr32h[i] = tcg_global_mem_new_i32(TCG_AREG0,
8453 offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8454 fregnames_h[i]);
8455 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8456 offsetof(CPUState, active_fpu.fcr0),
8457 "fcr0");
8458 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8459 offsetof(CPUState, active_fpu.fcr31),
8460 "fcr31");
8461
8462 /* register helpers */
8463 #define GEN_HELPER 2
8464 #include "helper.h"
8465
8466 inited = 1;
8467 }
8468
8469 #include "translate_init.c"
8470
8471 CPUMIPSState *cpu_mips_init (const char *cpu_model)
8472 {
8473 CPUMIPSState *env;
8474 const mips_def_t *def;
8475
8476 def = cpu_mips_find_by_name(cpu_model);
8477 if (!def)
8478 return NULL;
8479 env = qemu_mallocz(sizeof(CPUMIPSState));
8480 env->cpu_model = def;
8481
8482 cpu_exec_init(env);
8483 env->cpu_model_str = cpu_model;
8484 mips_tcg_init();
8485 cpu_reset(env);
8486 return env;
8487 }
8488
8489 void cpu_reset (CPUMIPSState *env)
8490 {
8491 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8492 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8493 log_cpu_state(env, 0);
8494 }
8495
8496 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8497
8498 tlb_flush(env, 1);
8499
8500 /* Minimal init */
8501 #if defined(CONFIG_USER_ONLY)
8502 env->hflags = MIPS_HFLAG_UM;
8503 #else
8504 if (env->hflags & MIPS_HFLAG_BMASK) {
8505 /* If the exception was raised from a delay slot,
8506 come back to the jump. */
8507 env->CP0_ErrorEPC = env->active_tc.PC - 4;
8508 } else {
8509 env->CP0_ErrorEPC = env->active_tc.PC;
8510 }
8511 env->active_tc.PC = (int32_t)0xBFC00000;
8512 env->CP0_Wired = 0;
8513 /* SMP not implemented */
8514 env->CP0_EBase = 0x80000000;
8515 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8516 /* vectored interrupts not implemented, timer on int 7,
8517 no performance counters. */
8518 env->CP0_IntCtl = 0xe0000000;
8519 {
8520 int i;
8521
8522 for (i = 0; i < 7; i++) {
8523 env->CP0_WatchLo[i] = 0;
8524 env->CP0_WatchHi[i] = 0x80000000;
8525 }
8526 env->CP0_WatchLo[7] = 0;
8527 env->CP0_WatchHi[7] = 0;
8528 }
8529 /* Count register increments in debug mode, EJTAG version 1 */
8530 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8531 env->hflags = MIPS_HFLAG_CP0;
8532 #endif
8533 env->exception_index = EXCP_NONE;
8534 cpu_mips_register(env, env->cpu_model);
8535 }
8536
8537 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8538 unsigned long searched_pc, int pc_pos, void *puc)
8539 {
8540 env->active_tc.PC = gen_opc_pc[pc_pos];
8541 env->hflags &= ~MIPS_HFLAG_BMASK;
8542 env->hflags |= gen_opc_hflags[pc_pos];
8543 }