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