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