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