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