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