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