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