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