]> git.proxmox.com Git - qemu.git/blob - target-mips/translate.c
Remove osdep.c/qemu-img code duplication
[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 "tcg-op.h"
33 #include "qemu-common.h"
34
35 //#define MIPS_DEBUG_DISAS
36 //#define MIPS_DEBUG_SIGN_EXTENSIONS
37 //#define MIPS_SINGLE_STEP
38
39 /* MIPS major opcodes */
40 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
41
42 enum {
43 /* indirect opcode tables */
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
47 OPC_CP1 = (0x11 << 26),
48 OPC_CP2 = (0x12 << 26),
49 OPC_CP3 = (0x13 << 26),
50 OPC_SPECIAL2 = (0x1C << 26),
51 OPC_SPECIAL3 = (0x1F << 26),
52 /* arithmetic with immediate */
53 OPC_ADDI = (0x08 << 26),
54 OPC_ADDIU = (0x09 << 26),
55 OPC_SLTI = (0x0A << 26),
56 OPC_SLTIU = (0x0B << 26),
57 OPC_ANDI = (0x0C << 26),
58 OPC_ORI = (0x0D << 26),
59 OPC_XORI = (0x0E << 26),
60 OPC_LUI = (0x0F << 26),
61 OPC_DADDI = (0x18 << 26),
62 OPC_DADDIU = (0x19 << 26),
63 /* Jump and branches */
64 OPC_J = (0x02 << 26),
65 OPC_JAL = (0x03 << 26),
66 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
67 OPC_BEQL = (0x14 << 26),
68 OPC_BNE = (0x05 << 26),
69 OPC_BNEL = (0x15 << 26),
70 OPC_BLEZ = (0x06 << 26),
71 OPC_BLEZL = (0x16 << 26),
72 OPC_BGTZ = (0x07 << 26),
73 OPC_BGTZL = (0x17 << 26),
74 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
75 /* Load and stores */
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LBU = (0x24 << 26),
83 OPC_LHU = (0x25 << 26),
84 OPC_LWR = (0x26 << 26),
85 OPC_LWU = (0x27 << 26),
86 OPC_SB = (0x28 << 26),
87 OPC_SH = (0x29 << 26),
88 OPC_SWL = (0x2A << 26),
89 OPC_SW = (0x2B << 26),
90 OPC_SDL = (0x2C << 26),
91 OPC_SDR = (0x2D << 26),
92 OPC_SWR = (0x2E << 26),
93 OPC_LL = (0x30 << 26),
94 OPC_LLD = (0x34 << 26),
95 OPC_LD = (0x37 << 26),
96 OPC_SC = (0x38 << 26),
97 OPC_SCD = (0x3C << 26),
98 OPC_SD = (0x3F << 26),
99 /* Floating point load/store */
100 OPC_LWC1 = (0x31 << 26),
101 OPC_LWC2 = (0x32 << 26),
102 OPC_LDC1 = (0x35 << 26),
103 OPC_LDC2 = (0x36 << 26),
104 OPC_SWC1 = (0x39 << 26),
105 OPC_SWC2 = (0x3A << 26),
106 OPC_SDC1 = (0x3D << 26),
107 OPC_SDC2 = (0x3E << 26),
108 /* MDMX ASE specific */
109 OPC_MDMX = (0x1E << 26),
110 /* Cache and prefetch */
111 OPC_CACHE = (0x2F << 26),
112 OPC_PREF = (0x33 << 26),
113 /* Reserved major opcode */
114 OPC_MAJOR3B_RESERVED = (0x3B << 26),
115 };
116
117 /* MIPS special opcodes */
118 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
119
120 enum {
121 /* Shifts */
122 OPC_SLL = 0x00 | OPC_SPECIAL,
123 /* NOP is SLL r0, r0, 0 */
124 /* SSNOP is SLL r0, r0, 1 */
125 /* EHB is SLL r0, r0, 3 */
126 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
127 OPC_SRA = 0x03 | OPC_SPECIAL,
128 OPC_SLLV = 0x04 | OPC_SPECIAL,
129 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
130 OPC_SRAV = 0x07 | OPC_SPECIAL,
131 OPC_DSLLV = 0x14 | OPC_SPECIAL,
132 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
133 OPC_DSRAV = 0x17 | OPC_SPECIAL,
134 OPC_DSLL = 0x38 | OPC_SPECIAL,
135 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
136 OPC_DSRA = 0x3B | OPC_SPECIAL,
137 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
138 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
139 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
140 /* Multiplication / division */
141 OPC_MULT = 0x18 | OPC_SPECIAL,
142 OPC_MULTU = 0x19 | OPC_SPECIAL,
143 OPC_DIV = 0x1A | OPC_SPECIAL,
144 OPC_DIVU = 0x1B | OPC_SPECIAL,
145 OPC_DMULT = 0x1C | OPC_SPECIAL,
146 OPC_DMULTU = 0x1D | OPC_SPECIAL,
147 OPC_DDIV = 0x1E | OPC_SPECIAL,
148 OPC_DDIVU = 0x1F | OPC_SPECIAL,
149 /* 2 registers arithmetic / logic */
150 OPC_ADD = 0x20 | OPC_SPECIAL,
151 OPC_ADDU = 0x21 | OPC_SPECIAL,
152 OPC_SUB = 0x22 | OPC_SPECIAL,
153 OPC_SUBU = 0x23 | OPC_SPECIAL,
154 OPC_AND = 0x24 | OPC_SPECIAL,
155 OPC_OR = 0x25 | OPC_SPECIAL,
156 OPC_XOR = 0x26 | OPC_SPECIAL,
157 OPC_NOR = 0x27 | OPC_SPECIAL,
158 OPC_SLT = 0x2A | OPC_SPECIAL,
159 OPC_SLTU = 0x2B | OPC_SPECIAL,
160 OPC_DADD = 0x2C | OPC_SPECIAL,
161 OPC_DADDU = 0x2D | OPC_SPECIAL,
162 OPC_DSUB = 0x2E | OPC_SPECIAL,
163 OPC_DSUBU = 0x2F | OPC_SPECIAL,
164 /* Jumps */
165 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
166 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
167 /* Traps */
168 OPC_TGE = 0x30 | OPC_SPECIAL,
169 OPC_TGEU = 0x31 | OPC_SPECIAL,
170 OPC_TLT = 0x32 | OPC_SPECIAL,
171 OPC_TLTU = 0x33 | OPC_SPECIAL,
172 OPC_TEQ = 0x34 | OPC_SPECIAL,
173 OPC_TNE = 0x36 | OPC_SPECIAL,
174 /* HI / LO registers load & stores */
175 OPC_MFHI = 0x10 | OPC_SPECIAL,
176 OPC_MTHI = 0x11 | OPC_SPECIAL,
177 OPC_MFLO = 0x12 | OPC_SPECIAL,
178 OPC_MTLO = 0x13 | OPC_SPECIAL,
179 /* Conditional moves */
180 OPC_MOVZ = 0x0A | OPC_SPECIAL,
181 OPC_MOVN = 0x0B | OPC_SPECIAL,
182
183 OPC_MOVCI = 0x01 | OPC_SPECIAL,
184
185 /* Special */
186 OPC_PMON = 0x05 | OPC_SPECIAL, /* inofficial */
187 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
188 OPC_BREAK = 0x0D | OPC_SPECIAL,
189 OPC_SPIM = 0x0E | OPC_SPECIAL, /* inofficial */
190 OPC_SYNC = 0x0F | OPC_SPECIAL,
191
192 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
193 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
194 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
195 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
196 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
197 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
198 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
199 };
200
201 /* Multiplication variants of the vr54xx. */
202 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
203
204 enum {
205 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
206 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
207 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
208 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
209 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
210 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
211 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
212 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
213 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
214 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
215 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
216 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
217 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
218 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
219 };
220
221 /* REGIMM (rt field) opcodes */
222 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
223
224 enum {
225 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
226 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
227 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
228 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
229 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
230 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
231 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
232 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
233 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
234 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
235 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
236 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
237 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
238 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
239 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
240 };
241
242 /* Special2 opcodes */
243 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
244
245 enum {
246 /* Multiply & xxx operations */
247 OPC_MADD = 0x00 | OPC_SPECIAL2,
248 OPC_MADDU = 0x01 | OPC_SPECIAL2,
249 OPC_MUL = 0x02 | OPC_SPECIAL2,
250 OPC_MSUB = 0x04 | OPC_SPECIAL2,
251 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
252 /* Misc */
253 OPC_CLZ = 0x20 | OPC_SPECIAL2,
254 OPC_CLO = 0x21 | OPC_SPECIAL2,
255 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
256 OPC_DCLO = 0x25 | OPC_SPECIAL2,
257 /* Special */
258 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
259 };
260
261 /* Special3 opcodes */
262 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
263
264 enum {
265 OPC_EXT = 0x00 | OPC_SPECIAL3,
266 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
267 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
268 OPC_DEXT = 0x03 | OPC_SPECIAL3,
269 OPC_INS = 0x04 | OPC_SPECIAL3,
270 OPC_DINSM = 0x05 | OPC_SPECIAL3,
271 OPC_DINSU = 0x06 | OPC_SPECIAL3,
272 OPC_DINS = 0x07 | OPC_SPECIAL3,
273 OPC_FORK = 0x08 | OPC_SPECIAL3,
274 OPC_YIELD = 0x09 | OPC_SPECIAL3,
275 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
276 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
277 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
278 };
279
280 /* BSHFL opcodes */
281 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
282
283 enum {
284 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
285 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
286 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
287 };
288
289 /* DBSHFL opcodes */
290 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
291
292 enum {
293 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
294 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
295 };
296
297 /* Coprocessor 0 (rs field) */
298 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
299
300 enum {
301 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
302 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
303 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
304 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
305 OPC_MFTR = (0x08 << 21) | OPC_CP0,
306 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
307 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
308 OPC_MTTR = (0x0C << 21) | OPC_CP0,
309 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
310 OPC_C0 = (0x10 << 21) | OPC_CP0,
311 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
312 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
313 };
314
315 /* MFMC0 opcodes */
316 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
317
318 enum {
319 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
320 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
321 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
322 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
323 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
324 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
325 };
326
327 /* Coprocessor 0 (with rs == C0) */
328 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
329
330 enum {
331 OPC_TLBR = 0x01 | OPC_C0,
332 OPC_TLBWI = 0x02 | OPC_C0,
333 OPC_TLBWR = 0x06 | OPC_C0,
334 OPC_TLBP = 0x08 | OPC_C0,
335 OPC_RFE = 0x10 | OPC_C0,
336 OPC_ERET = 0x18 | OPC_C0,
337 OPC_DERET = 0x1F | OPC_C0,
338 OPC_WAIT = 0x20 | OPC_C0,
339 };
340
341 /* Coprocessor 1 (rs field) */
342 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
343
344 enum {
345 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
346 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
347 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
348 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
349 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
350 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
351 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
352 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
353 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
354 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
355 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
356 OPC_S_FMT = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
357 OPC_D_FMT = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
358 OPC_E_FMT = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
359 OPC_Q_FMT = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
360 OPC_W_FMT = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
361 OPC_L_FMT = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
362 OPC_PS_FMT = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
363 };
364
365 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
366 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
367
368 enum {
369 OPC_BC1F = (0x00 << 16) | OPC_BC1,
370 OPC_BC1T = (0x01 << 16) | OPC_BC1,
371 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
372 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
373 };
374
375 enum {
376 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
377 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
378 };
379
380 enum {
381 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
382 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
383 };
384
385 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
386
387 enum {
388 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
389 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
390 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
391 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
392 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
393 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
394 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
395 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
396 OPC_BC2 = (0x08 << 21) | OPC_CP2,
397 };
398
399 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
400
401 enum {
402 OPC_LWXC1 = 0x00 | OPC_CP3,
403 OPC_LDXC1 = 0x01 | OPC_CP3,
404 OPC_LUXC1 = 0x05 | OPC_CP3,
405 OPC_SWXC1 = 0x08 | OPC_CP3,
406 OPC_SDXC1 = 0x09 | OPC_CP3,
407 OPC_SUXC1 = 0x0D | OPC_CP3,
408 OPC_PREFX = 0x0F | OPC_CP3,
409 OPC_ALNV_PS = 0x1E | OPC_CP3,
410 OPC_MADD_S = 0x20 | OPC_CP3,
411 OPC_MADD_D = 0x21 | OPC_CP3,
412 OPC_MADD_PS = 0x26 | OPC_CP3,
413 OPC_MSUB_S = 0x28 | OPC_CP3,
414 OPC_MSUB_D = 0x29 | OPC_CP3,
415 OPC_MSUB_PS = 0x2E | OPC_CP3,
416 OPC_NMADD_S = 0x30 | OPC_CP3,
417 OPC_NMADD_D = 0x31 | OPC_CP3,
418 OPC_NMADD_PS= 0x36 | OPC_CP3,
419 OPC_NMSUB_S = 0x38 | OPC_CP3,
420 OPC_NMSUB_D = 0x39 | OPC_CP3,
421 OPC_NMSUB_PS= 0x3E | OPC_CP3,
422 };
423
424
425 const unsigned char *regnames[] =
426 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
427 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
428 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
429 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
430
431 /* Warning: no function for r0 register (hard wired to zero) */
432 #define GEN32(func, NAME) \
433 static GenOpFunc *NAME ## _table [32] = { \
434 NULL, NAME ## 1, NAME ## 2, NAME ## 3, \
435 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
436 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
437 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
438 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
439 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
440 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
441 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
442 }; \
443 static always_inline void func(int n) \
444 { \
445 NAME ## _table[n](); \
446 }
447
448 /* General purpose registers moves */
449 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
450 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
451 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
452
453 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
454 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
455
456 /* Moves to/from shadow registers */
457 GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
458 GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
459
460 static const char *fregnames[] =
461 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
462 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
463 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
464 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
465
466 #define FGEN32(func, NAME) \
467 static GenOpFunc *NAME ## _table [32] = { \
468 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
469 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
470 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
471 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
472 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
473 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
474 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
475 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
476 }; \
477 static always_inline void func(int n) \
478 { \
479 NAME ## _table[n](); \
480 }
481
482 FGEN32(gen_op_load_fpr_WT0, gen_op_load_fpr_WT0_fpr);
483 FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
484
485 FGEN32(gen_op_load_fpr_WT1, gen_op_load_fpr_WT1_fpr);
486 FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
487
488 FGEN32(gen_op_load_fpr_WT2, gen_op_load_fpr_WT2_fpr);
489 FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
490
491 FGEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fpr);
492 FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
493
494 FGEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fpr);
495 FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
496
497 FGEN32(gen_op_load_fpr_DT2, gen_op_load_fpr_DT2_fpr);
498 FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
499
500 FGEN32(gen_op_load_fpr_WTH0, gen_op_load_fpr_WTH0_fpr);
501 FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
502
503 FGEN32(gen_op_load_fpr_WTH1, gen_op_load_fpr_WTH1_fpr);
504 FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
505
506 FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr);
507 FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
508
509 #define FOP_CONDS(type, fmt) \
510 static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = { \
511 gen_op_cmp ## type ## _ ## fmt ## _f, \
512 gen_op_cmp ## type ## _ ## fmt ## _un, \
513 gen_op_cmp ## type ## _ ## fmt ## _eq, \
514 gen_op_cmp ## type ## _ ## fmt ## _ueq, \
515 gen_op_cmp ## type ## _ ## fmt ## _olt, \
516 gen_op_cmp ## type ## _ ## fmt ## _ult, \
517 gen_op_cmp ## type ## _ ## fmt ## _ole, \
518 gen_op_cmp ## type ## _ ## fmt ## _ule, \
519 gen_op_cmp ## type ## _ ## fmt ## _sf, \
520 gen_op_cmp ## type ## _ ## fmt ## _ngle, \
521 gen_op_cmp ## type ## _ ## fmt ## _seq, \
522 gen_op_cmp ## type ## _ ## fmt ## _ngl, \
523 gen_op_cmp ## type ## _ ## fmt ## _lt, \
524 gen_op_cmp ## type ## _ ## fmt ## _nge, \
525 gen_op_cmp ## type ## _ ## fmt ## _le, \
526 gen_op_cmp ## type ## _ ## fmt ## _ngt, \
527 }; \
528 static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \
529 { \
530 gen_op_cmp ## type ## _ ## fmt ## _table[n](cc); \
531 }
532
533 FOP_CONDS(, d)
534 FOP_CONDS(abs, d)
535 FOP_CONDS(, s)
536 FOP_CONDS(abs, s)
537 FOP_CONDS(, ps)
538 FOP_CONDS(abs, ps)
539
540 typedef struct DisasContext {
541 struct TranslationBlock *tb;
542 target_ulong pc, saved_pc;
543 uint32_t opcode;
544 uint32_t fp_status;
545 /* Routine used to access memory */
546 int mem_idx;
547 uint32_t hflags, saved_hflags;
548 int bstate;
549 target_ulong btarget;
550 void *last_T0_store;
551 int last_T0_gpr;
552 } DisasContext;
553
554 enum {
555 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
556 * exception condition
557 */
558 BS_STOP = 1, /* We want to stop translation for any reason */
559 BS_BRANCH = 2, /* We reached a branch condition */
560 BS_EXCP = 3, /* We reached an exception condition */
561 };
562
563 #ifdef MIPS_DEBUG_DISAS
564 #define MIPS_DEBUG(fmt, args...) \
565 do { \
566 if (loglevel & CPU_LOG_TB_IN_ASM) { \
567 fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n", \
568 ctx->pc, ctx->opcode , ##args); \
569 } \
570 } while (0)
571 #else
572 #define MIPS_DEBUG(fmt, args...) do { } while(0)
573 #endif
574
575 #define MIPS_INVAL(op) \
576 do { \
577 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
578 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
579 } while (0)
580
581 #define GEN_LOAD_REG_T0(Rn) \
582 do { \
583 if (Rn == 0) { \
584 gen_op_reset_T0(); \
585 } else { \
586 if (ctx->glue(last_T0, _store) != gen_opc_ptr \
587 || ctx->glue(last_T0, _gpr) != Rn) { \
588 gen_op_load_gpr_T0(Rn); \
589 } \
590 } \
591 } while (0)
592
593 #define GEN_LOAD_REG_T1(Rn) \
594 do { \
595 if (Rn == 0) { \
596 gen_op_reset_T1(); \
597 } else { \
598 gen_op_load_gpr_T1(Rn); \
599 } \
600 } while (0)
601
602 #define GEN_LOAD_REG_T2(Rn) \
603 do { \
604 if (Rn == 0) { \
605 gen_op_reset_T2(); \
606 } else { \
607 gen_op_load_gpr_T2(Rn); \
608 } \
609 } while (0)
610
611 #define GEN_LOAD_SRSREG_TN(Tn, Rn) \
612 do { \
613 if (Rn == 0) { \
614 glue(gen_op_reset_, Tn)(); \
615 } else { \
616 glue(gen_op_load_srsgpr_, Tn)(Rn); \
617 } \
618 } while (0)
619
620 #if defined(TARGET_MIPS64)
621 #define GEN_LOAD_IMM_TN(Tn, Imm) \
622 do { \
623 if (Imm == 0) { \
624 glue(gen_op_reset_, Tn)(); \
625 } else if ((int32_t)Imm == Imm) { \
626 glue(gen_op_set_, Tn)(Imm); \
627 } else { \
628 glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm); \
629 } \
630 } while (0)
631 #else
632 #define GEN_LOAD_IMM_TN(Tn, Imm) \
633 do { \
634 if (Imm == 0) { \
635 glue(gen_op_reset_, Tn)(); \
636 } else { \
637 glue(gen_op_set_, Tn)(Imm); \
638 } \
639 } while (0)
640 #endif
641
642 #define GEN_STORE_T0_REG(Rn) \
643 do { \
644 if (Rn != 0) { \
645 glue(gen_op_store_T0,_gpr)(Rn); \
646 ctx->glue(last_T0,_store) = gen_opc_ptr; \
647 ctx->glue(last_T0,_gpr) = Rn; \
648 } \
649 } while (0)
650
651 #define GEN_STORE_T1_REG(Rn) \
652 do { \
653 if (Rn != 0) \
654 glue(gen_op_store_T1,_gpr)(Rn); \
655 } while (0)
656
657 #define GEN_STORE_TN_SRSREG(Rn, Tn) \
658 do { \
659 if (Rn != 0) { \
660 glue(glue(gen_op_store_, Tn),_srsgpr)(Rn); \
661 } \
662 } while (0)
663
664 #define GEN_LOAD_FREG_FTN(FTn, Fn) \
665 do { \
666 glue(gen_op_load_fpr_, FTn)(Fn); \
667 } while (0)
668
669 #define GEN_STORE_FTN_FREG(Fn, FTn) \
670 do { \
671 glue(gen_op_store_fpr_, FTn)(Fn); \
672 } while (0)
673
674 static always_inline void gen_save_pc(target_ulong pc)
675 {
676 #if defined(TARGET_MIPS64)
677 if (pc == (int32_t)pc) {
678 gen_op_save_pc(pc);
679 } else {
680 gen_op_save_pc64(pc >> 32, (uint32_t)pc);
681 }
682 #else
683 gen_op_save_pc(pc);
684 #endif
685 }
686
687 static always_inline void gen_save_btarget(target_ulong btarget)
688 {
689 #if defined(TARGET_MIPS64)
690 if (btarget == (int32_t)btarget) {
691 gen_op_save_btarget(btarget);
692 } else {
693 gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
694 }
695 #else
696 gen_op_save_btarget(btarget);
697 #endif
698 }
699
700 static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
701 {
702 #if defined MIPS_DEBUG_DISAS
703 if (loglevel & CPU_LOG_TB_IN_ASM) {
704 fprintf(logfile, "hflags %08x saved %08x\n",
705 ctx->hflags, ctx->saved_hflags);
706 }
707 #endif
708 if (do_save_pc && ctx->pc != ctx->saved_pc) {
709 gen_save_pc(ctx->pc);
710 ctx->saved_pc = ctx->pc;
711 }
712 if (ctx->hflags != ctx->saved_hflags) {
713 gen_op_save_state(ctx->hflags);
714 ctx->saved_hflags = ctx->hflags;
715 switch (ctx->hflags & MIPS_HFLAG_BMASK) {
716 case MIPS_HFLAG_BR:
717 gen_op_save_breg_target();
718 break;
719 case MIPS_HFLAG_BC:
720 gen_op_save_bcond();
721 /* fall through */
722 case MIPS_HFLAG_BL:
723 /* bcond was already saved by the BL insn */
724 /* fall through */
725 case MIPS_HFLAG_B:
726 gen_save_btarget(ctx->btarget);
727 break;
728 }
729 }
730 }
731
732 static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
733 {
734 ctx->saved_hflags = ctx->hflags;
735 switch (ctx->hflags & MIPS_HFLAG_BMASK) {
736 case MIPS_HFLAG_BR:
737 gen_op_restore_breg_target();
738 break;
739 case MIPS_HFLAG_B:
740 ctx->btarget = env->btarget;
741 break;
742 case MIPS_HFLAG_BC:
743 case MIPS_HFLAG_BL:
744 ctx->btarget = env->btarget;
745 gen_op_restore_bcond();
746 break;
747 }
748 }
749
750 static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
751 {
752 #if defined MIPS_DEBUG_DISAS
753 if (loglevel & CPU_LOG_TB_IN_ASM)
754 fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
755 #endif
756 save_cpu_state(ctx, 1);
757 if (err == 0)
758 gen_op_raise_exception(excp);
759 else
760 gen_op_raise_exception_err(excp, err);
761 ctx->bstate = BS_EXCP;
762 }
763
764 static always_inline void generate_exception (DisasContext *ctx, int excp)
765 {
766 generate_exception_err (ctx, excp, 0);
767 }
768
769 static always_inline void check_cp0_enabled(DisasContext *ctx)
770 {
771 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
772 generate_exception_err(ctx, EXCP_CpU, 1);
773 }
774
775 static always_inline void check_cp1_enabled(DisasContext *ctx)
776 {
777 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
778 generate_exception_err(ctx, EXCP_CpU, 1);
779 }
780
781 /* Verify that the processor is running with COP1X instructions enabled.
782 This is associated with the nabla symbol in the MIPS32 and MIPS64
783 opcode tables. */
784
785 static always_inline void check_cop1x(DisasContext *ctx)
786 {
787 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
788 generate_exception(ctx, EXCP_RI);
789 }
790
791 /* Verify that the processor is running with 64-bit floating-point
792 operations enabled. */
793
794 static always_inline void check_cp1_64bitmode(DisasContext *ctx)
795 {
796 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
797 generate_exception(ctx, EXCP_RI);
798 }
799
800 /*
801 * Verify if floating point register is valid; an operation is not defined
802 * if bit 0 of any register specification is set and the FR bit in the
803 * Status register equals zero, since the register numbers specify an
804 * even-odd pair of adjacent coprocessor general registers. When the FR bit
805 * in the Status register equals one, both even and odd register numbers
806 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
807 *
808 * Multiple 64 bit wide registers can be checked by calling
809 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
810 */
811 void check_cp1_registers(DisasContext *ctx, int regs)
812 {
813 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
814 generate_exception(ctx, EXCP_RI);
815 }
816
817 /* This code generates a "reserved instruction" exception if the
818 CPU does not support the instruction set corresponding to flags. */
819 static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
820 {
821 if (unlikely(!(env->insn_flags & flags)))
822 generate_exception(ctx, EXCP_RI);
823 }
824
825 /* This code generates a "reserved instruction" exception if 64-bit
826 instructions are not enabled. */
827 static always_inline void check_mips_64(DisasContext *ctx)
828 {
829 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
830 generate_exception(ctx, EXCP_RI);
831 }
832
833 #if defined(CONFIG_USER_ONLY)
834 #define op_ldst(name) gen_op_##name##_raw()
835 #define OP_LD_TABLE(width)
836 #define OP_ST_TABLE(width)
837 #else
838 #define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()
839 #define OP_LD_TABLE(width) \
840 static GenOpFunc *gen_op_l##width[] = { \
841 &gen_op_l##width##_kernel, \
842 &gen_op_l##width##_super, \
843 &gen_op_l##width##_user, \
844 }
845 #define OP_ST_TABLE(width) \
846 static GenOpFunc *gen_op_s##width[] = { \
847 &gen_op_s##width##_kernel, \
848 &gen_op_s##width##_super, \
849 &gen_op_s##width##_user, \
850 }
851 #endif
852
853 #if defined(TARGET_MIPS64)
854 OP_LD_TABLE(d);
855 OP_LD_TABLE(dl);
856 OP_LD_TABLE(dr);
857 OP_ST_TABLE(d);
858 OP_ST_TABLE(dl);
859 OP_ST_TABLE(dr);
860 OP_LD_TABLE(ld);
861 OP_ST_TABLE(cd);
862 OP_LD_TABLE(wu);
863 #endif
864 OP_LD_TABLE(w);
865 OP_LD_TABLE(wl);
866 OP_LD_TABLE(wr);
867 OP_ST_TABLE(w);
868 OP_ST_TABLE(wl);
869 OP_ST_TABLE(wr);
870 OP_LD_TABLE(h);
871 OP_LD_TABLE(hu);
872 OP_ST_TABLE(h);
873 OP_LD_TABLE(b);
874 OP_LD_TABLE(bu);
875 OP_ST_TABLE(b);
876 OP_LD_TABLE(l);
877 OP_ST_TABLE(c);
878 OP_LD_TABLE(wc1);
879 OP_ST_TABLE(wc1);
880 OP_LD_TABLE(dc1);
881 OP_ST_TABLE(dc1);
882 OP_LD_TABLE(uxc1);
883 OP_ST_TABLE(uxc1);
884
885 /* Load and store */
886 static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
887 int base, int16_t offset)
888 {
889 const char *opn = "ldst";
890
891 if (base == 0) {
892 GEN_LOAD_IMM_TN(T0, offset);
893 } else if (offset == 0) {
894 gen_op_load_gpr_T0(base);
895 } else {
896 gen_op_load_gpr_T0(base);
897 gen_op_set_T1(offset);
898 gen_op_addr_add();
899 }
900 /* Don't do NOP if destination is zero: we must perform the actual
901 memory access. */
902 switch (opc) {
903 #if defined(TARGET_MIPS64)
904 case OPC_LWU:
905 op_ldst(lwu);
906 GEN_STORE_T0_REG(rt);
907 opn = "lwu";
908 break;
909 case OPC_LD:
910 op_ldst(ld);
911 GEN_STORE_T0_REG(rt);
912 opn = "ld";
913 break;
914 case OPC_LLD:
915 op_ldst(lld);
916 GEN_STORE_T0_REG(rt);
917 opn = "lld";
918 break;
919 case OPC_SD:
920 GEN_LOAD_REG_T1(rt);
921 op_ldst(sd);
922 opn = "sd";
923 break;
924 case OPC_SCD:
925 save_cpu_state(ctx, 1);
926 GEN_LOAD_REG_T1(rt);
927 op_ldst(scd);
928 GEN_STORE_T0_REG(rt);
929 opn = "scd";
930 break;
931 case OPC_LDL:
932 GEN_LOAD_REG_T1(rt);
933 op_ldst(ldl);
934 GEN_STORE_T1_REG(rt);
935 opn = "ldl";
936 break;
937 case OPC_SDL:
938 GEN_LOAD_REG_T1(rt);
939 op_ldst(sdl);
940 opn = "sdl";
941 break;
942 case OPC_LDR:
943 GEN_LOAD_REG_T1(rt);
944 op_ldst(ldr);
945 GEN_STORE_T1_REG(rt);
946 opn = "ldr";
947 break;
948 case OPC_SDR:
949 GEN_LOAD_REG_T1(rt);
950 op_ldst(sdr);
951 opn = "sdr";
952 break;
953 #endif
954 case OPC_LW:
955 op_ldst(lw);
956 GEN_STORE_T0_REG(rt);
957 opn = "lw";
958 break;
959 case OPC_SW:
960 GEN_LOAD_REG_T1(rt);
961 op_ldst(sw);
962 opn = "sw";
963 break;
964 case OPC_LH:
965 op_ldst(lh);
966 GEN_STORE_T0_REG(rt);
967 opn = "lh";
968 break;
969 case OPC_SH:
970 GEN_LOAD_REG_T1(rt);
971 op_ldst(sh);
972 opn = "sh";
973 break;
974 case OPC_LHU:
975 op_ldst(lhu);
976 GEN_STORE_T0_REG(rt);
977 opn = "lhu";
978 break;
979 case OPC_LB:
980 op_ldst(lb);
981 GEN_STORE_T0_REG(rt);
982 opn = "lb";
983 break;
984 case OPC_SB:
985 GEN_LOAD_REG_T1(rt);
986 op_ldst(sb);
987 opn = "sb";
988 break;
989 case OPC_LBU:
990 op_ldst(lbu);
991 GEN_STORE_T0_REG(rt);
992 opn = "lbu";
993 break;
994 case OPC_LWL:
995 GEN_LOAD_REG_T1(rt);
996 op_ldst(lwl);
997 GEN_STORE_T1_REG(rt);
998 opn = "lwl";
999 break;
1000 case OPC_SWL:
1001 GEN_LOAD_REG_T1(rt);
1002 op_ldst(swl);
1003 opn = "swr";
1004 break;
1005 case OPC_LWR:
1006 GEN_LOAD_REG_T1(rt);
1007 op_ldst(lwr);
1008 GEN_STORE_T1_REG(rt);
1009 opn = "lwr";
1010 break;
1011 case OPC_SWR:
1012 GEN_LOAD_REG_T1(rt);
1013 op_ldst(swr);
1014 opn = "swr";
1015 break;
1016 case OPC_LL:
1017 op_ldst(ll);
1018 GEN_STORE_T0_REG(rt);
1019 opn = "ll";
1020 break;
1021 case OPC_SC:
1022 save_cpu_state(ctx, 1);
1023 GEN_LOAD_REG_T1(rt);
1024 op_ldst(sc);
1025 GEN_STORE_T0_REG(rt);
1026 opn = "sc";
1027 break;
1028 default:
1029 MIPS_INVAL(opn);
1030 generate_exception(ctx, EXCP_RI);
1031 return;
1032 }
1033 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1034 }
1035
1036 /* Load and store */
1037 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1038 int base, int16_t offset)
1039 {
1040 const char *opn = "flt_ldst";
1041
1042 if (base == 0) {
1043 GEN_LOAD_IMM_TN(T0, offset);
1044 } else if (offset == 0) {
1045 gen_op_load_gpr_T0(base);
1046 } else {
1047 gen_op_load_gpr_T0(base);
1048 gen_op_set_T1(offset);
1049 gen_op_addr_add();
1050 }
1051 /* Don't do NOP if destination is zero: we must perform the actual
1052 memory access. */
1053 switch (opc) {
1054 case OPC_LWC1:
1055 op_ldst(lwc1);
1056 GEN_STORE_FTN_FREG(ft, WT0);
1057 opn = "lwc1";
1058 break;
1059 case OPC_SWC1:
1060 GEN_LOAD_FREG_FTN(WT0, ft);
1061 op_ldst(swc1);
1062 opn = "swc1";
1063 break;
1064 case OPC_LDC1:
1065 op_ldst(ldc1);
1066 GEN_STORE_FTN_FREG(ft, DT0);
1067 opn = "ldc1";
1068 break;
1069 case OPC_SDC1:
1070 GEN_LOAD_FREG_FTN(DT0, ft);
1071 op_ldst(sdc1);
1072 opn = "sdc1";
1073 break;
1074 default:
1075 MIPS_INVAL(opn);
1076 generate_exception(ctx, EXCP_RI);
1077 return;
1078 }
1079 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1080 }
1081
1082 /* Arithmetic with immediate operand */
1083 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1084 int rt, int rs, int16_t imm)
1085 {
1086 target_ulong uimm;
1087 const char *opn = "imm arith";
1088
1089 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1090 /* If no destination, treat it as a NOP.
1091 For addi, we must generate the overflow exception when needed. */
1092 MIPS_DEBUG("NOP");
1093 return;
1094 }
1095 uimm = (uint16_t)imm;
1096 switch (opc) {
1097 case OPC_ADDI:
1098 case OPC_ADDIU:
1099 #if defined(TARGET_MIPS64)
1100 case OPC_DADDI:
1101 case OPC_DADDIU:
1102 #endif
1103 case OPC_SLTI:
1104 case OPC_SLTIU:
1105 uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1106 /* Fall through. */
1107 case OPC_ANDI:
1108 case OPC_ORI:
1109 case OPC_XORI:
1110 GEN_LOAD_REG_T0(rs);
1111 GEN_LOAD_IMM_TN(T1, uimm);
1112 break;
1113 case OPC_LUI:
1114 GEN_LOAD_IMM_TN(T0, imm << 16);
1115 break;
1116 case OPC_SLL:
1117 case OPC_SRA:
1118 case OPC_SRL:
1119 #if defined(TARGET_MIPS64)
1120 case OPC_DSLL:
1121 case OPC_DSRA:
1122 case OPC_DSRL:
1123 case OPC_DSLL32:
1124 case OPC_DSRA32:
1125 case OPC_DSRL32:
1126 #endif
1127 uimm &= 0x1f;
1128 GEN_LOAD_REG_T0(rs);
1129 GEN_LOAD_IMM_TN(T1, uimm);
1130 break;
1131 }
1132 switch (opc) {
1133 case OPC_ADDI:
1134 save_cpu_state(ctx, 1);
1135 gen_op_addo();
1136 opn = "addi";
1137 break;
1138 case OPC_ADDIU:
1139 gen_op_add();
1140 opn = "addiu";
1141 break;
1142 #if defined(TARGET_MIPS64)
1143 case OPC_DADDI:
1144 save_cpu_state(ctx, 1);
1145 gen_op_daddo();
1146 opn = "daddi";
1147 break;
1148 case OPC_DADDIU:
1149 gen_op_dadd();
1150 opn = "daddiu";
1151 break;
1152 #endif
1153 case OPC_SLTI:
1154 gen_op_lt();
1155 opn = "slti";
1156 break;
1157 case OPC_SLTIU:
1158 gen_op_ltu();
1159 opn = "sltiu";
1160 break;
1161 case OPC_ANDI:
1162 gen_op_and();
1163 opn = "andi";
1164 break;
1165 case OPC_ORI:
1166 gen_op_or();
1167 opn = "ori";
1168 break;
1169 case OPC_XORI:
1170 gen_op_xor();
1171 opn = "xori";
1172 break;
1173 case OPC_LUI:
1174 opn = "lui";
1175 break;
1176 case OPC_SLL:
1177 gen_op_sll();
1178 opn = "sll";
1179 break;
1180 case OPC_SRA:
1181 gen_op_sra();
1182 opn = "sra";
1183 break;
1184 case OPC_SRL:
1185 switch ((ctx->opcode >> 21) & 0x1f) {
1186 case 0:
1187 gen_op_srl();
1188 opn = "srl";
1189 break;
1190 case 1:
1191 /* rotr is decoded as srl on non-R2 CPUs */
1192 if (env->insn_flags & ISA_MIPS32R2) {
1193 gen_op_rotr();
1194 opn = "rotr";
1195 } else {
1196 gen_op_srl();
1197 opn = "srl";
1198 }
1199 break;
1200 default:
1201 MIPS_INVAL("invalid srl flag");
1202 generate_exception(ctx, EXCP_RI);
1203 break;
1204 }
1205 break;
1206 #if defined(TARGET_MIPS64)
1207 case OPC_DSLL:
1208 gen_op_dsll();
1209 opn = "dsll";
1210 break;
1211 case OPC_DSRA:
1212 gen_op_dsra();
1213 opn = "dsra";
1214 break;
1215 case OPC_DSRL:
1216 switch ((ctx->opcode >> 21) & 0x1f) {
1217 case 0:
1218 gen_op_dsrl();
1219 opn = "dsrl";
1220 break;
1221 case 1:
1222 /* drotr is decoded as dsrl on non-R2 CPUs */
1223 if (env->insn_flags & ISA_MIPS32R2) {
1224 gen_op_drotr();
1225 opn = "drotr";
1226 } else {
1227 gen_op_dsrl();
1228 opn = "dsrl";
1229 }
1230 break;
1231 default:
1232 MIPS_INVAL("invalid dsrl flag");
1233 generate_exception(ctx, EXCP_RI);
1234 break;
1235 }
1236 break;
1237 case OPC_DSLL32:
1238 gen_op_dsll32();
1239 opn = "dsll32";
1240 break;
1241 case OPC_DSRA32:
1242 gen_op_dsra32();
1243 opn = "dsra32";
1244 break;
1245 case OPC_DSRL32:
1246 switch ((ctx->opcode >> 21) & 0x1f) {
1247 case 0:
1248 gen_op_dsrl32();
1249 opn = "dsrl32";
1250 break;
1251 case 1:
1252 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1253 if (env->insn_flags & ISA_MIPS32R2) {
1254 gen_op_drotr32();
1255 opn = "drotr32";
1256 } else {
1257 gen_op_dsrl32();
1258 opn = "dsrl32";
1259 }
1260 break;
1261 default:
1262 MIPS_INVAL("invalid dsrl32 flag");
1263 generate_exception(ctx, EXCP_RI);
1264 break;
1265 }
1266 break;
1267 #endif
1268 default:
1269 MIPS_INVAL(opn);
1270 generate_exception(ctx, EXCP_RI);
1271 return;
1272 }
1273 GEN_STORE_T0_REG(rt);
1274 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1275 }
1276
1277 /* Arithmetic */
1278 static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1279 int rd, int rs, int rt)
1280 {
1281 const char *opn = "arith";
1282
1283 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1284 && opc != OPC_DADD && opc != OPC_DSUB) {
1285 /* If no destination, treat it as a NOP.
1286 For add & sub, we must generate the overflow exception when needed. */
1287 MIPS_DEBUG("NOP");
1288 return;
1289 }
1290 GEN_LOAD_REG_T0(rs);
1291 /* Specialcase the conventional move operation. */
1292 if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1293 || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1294 GEN_STORE_T0_REG(rd);
1295 return;
1296 }
1297 GEN_LOAD_REG_T1(rt);
1298 switch (opc) {
1299 case OPC_ADD:
1300 save_cpu_state(ctx, 1);
1301 gen_op_addo();
1302 opn = "add";
1303 break;
1304 case OPC_ADDU:
1305 gen_op_add();
1306 opn = "addu";
1307 break;
1308 case OPC_SUB:
1309 save_cpu_state(ctx, 1);
1310 gen_op_subo();
1311 opn = "sub";
1312 break;
1313 case OPC_SUBU:
1314 gen_op_sub();
1315 opn = "subu";
1316 break;
1317 #if defined(TARGET_MIPS64)
1318 case OPC_DADD:
1319 save_cpu_state(ctx, 1);
1320 gen_op_daddo();
1321 opn = "dadd";
1322 break;
1323 case OPC_DADDU:
1324 gen_op_dadd();
1325 opn = "daddu";
1326 break;
1327 case OPC_DSUB:
1328 save_cpu_state(ctx, 1);
1329 gen_op_dsubo();
1330 opn = "dsub";
1331 break;
1332 case OPC_DSUBU:
1333 gen_op_dsub();
1334 opn = "dsubu";
1335 break;
1336 #endif
1337 case OPC_SLT:
1338 gen_op_lt();
1339 opn = "slt";
1340 break;
1341 case OPC_SLTU:
1342 gen_op_ltu();
1343 opn = "sltu";
1344 break;
1345 case OPC_AND:
1346 gen_op_and();
1347 opn = "and";
1348 break;
1349 case OPC_NOR:
1350 gen_op_nor();
1351 opn = "nor";
1352 break;
1353 case OPC_OR:
1354 gen_op_or();
1355 opn = "or";
1356 break;
1357 case OPC_XOR:
1358 gen_op_xor();
1359 opn = "xor";
1360 break;
1361 case OPC_MUL:
1362 gen_op_mul();
1363 opn = "mul";
1364 break;
1365 case OPC_MOVN:
1366 gen_op_movn(rd);
1367 opn = "movn";
1368 goto print;
1369 case OPC_MOVZ:
1370 gen_op_movz(rd);
1371 opn = "movz";
1372 goto print;
1373 case OPC_SLLV:
1374 gen_op_sllv();
1375 opn = "sllv";
1376 break;
1377 case OPC_SRAV:
1378 gen_op_srav();
1379 opn = "srav";
1380 break;
1381 case OPC_SRLV:
1382 switch ((ctx->opcode >> 6) & 0x1f) {
1383 case 0:
1384 gen_op_srlv();
1385 opn = "srlv";
1386 break;
1387 case 1:
1388 /* rotrv is decoded as srlv on non-R2 CPUs */
1389 if (env->insn_flags & ISA_MIPS32R2) {
1390 gen_op_rotrv();
1391 opn = "rotrv";
1392 } else {
1393 gen_op_srlv();
1394 opn = "srlv";
1395 }
1396 break;
1397 default:
1398 MIPS_INVAL("invalid srlv flag");
1399 generate_exception(ctx, EXCP_RI);
1400 break;
1401 }
1402 break;
1403 #if defined(TARGET_MIPS64)
1404 case OPC_DSLLV:
1405 gen_op_dsllv();
1406 opn = "dsllv";
1407 break;
1408 case OPC_DSRAV:
1409 gen_op_dsrav();
1410 opn = "dsrav";
1411 break;
1412 case OPC_DSRLV:
1413 switch ((ctx->opcode >> 6) & 0x1f) {
1414 case 0:
1415 gen_op_dsrlv();
1416 opn = "dsrlv";
1417 break;
1418 case 1:
1419 /* drotrv is decoded as dsrlv on non-R2 CPUs */
1420 if (env->insn_flags & ISA_MIPS32R2) {
1421 gen_op_drotrv();
1422 opn = "drotrv";
1423 } else {
1424 gen_op_dsrlv();
1425 opn = "dsrlv";
1426 }
1427 break;
1428 default:
1429 MIPS_INVAL("invalid dsrlv flag");
1430 generate_exception(ctx, EXCP_RI);
1431 break;
1432 }
1433 break;
1434 #endif
1435 default:
1436 MIPS_INVAL(opn);
1437 generate_exception(ctx, EXCP_RI);
1438 return;
1439 }
1440 GEN_STORE_T0_REG(rd);
1441 print:
1442 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1443 }
1444
1445 /* Arithmetic on HI/LO registers */
1446 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1447 {
1448 const char *opn = "hilo";
1449
1450 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1451 /* Treat as NOP. */
1452 MIPS_DEBUG("NOP");
1453 return;
1454 }
1455 switch (opc) {
1456 case OPC_MFHI:
1457 gen_op_load_HI(0);
1458 GEN_STORE_T0_REG(reg);
1459 opn = "mfhi";
1460 break;
1461 case OPC_MFLO:
1462 gen_op_load_LO(0);
1463 GEN_STORE_T0_REG(reg);
1464 opn = "mflo";
1465 break;
1466 case OPC_MTHI:
1467 GEN_LOAD_REG_T0(reg);
1468 gen_op_store_HI(0);
1469 opn = "mthi";
1470 break;
1471 case OPC_MTLO:
1472 GEN_LOAD_REG_T0(reg);
1473 gen_op_store_LO(0);
1474 opn = "mtlo";
1475 break;
1476 default:
1477 MIPS_INVAL(opn);
1478 generate_exception(ctx, EXCP_RI);
1479 return;
1480 }
1481 MIPS_DEBUG("%s %s", opn, regnames[reg]);
1482 }
1483
1484 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1485 int rs, int rt)
1486 {
1487 const char *opn = "mul/div";
1488
1489 GEN_LOAD_REG_T0(rs);
1490 GEN_LOAD_REG_T1(rt);
1491 switch (opc) {
1492 case OPC_DIV:
1493 gen_op_div();
1494 opn = "div";
1495 break;
1496 case OPC_DIVU:
1497 gen_op_divu();
1498 opn = "divu";
1499 break;
1500 case OPC_MULT:
1501 gen_op_mult();
1502 opn = "mult";
1503 break;
1504 case OPC_MULTU:
1505 gen_op_multu();
1506 opn = "multu";
1507 break;
1508 #if defined(TARGET_MIPS64)
1509 case OPC_DDIV:
1510 gen_op_ddiv();
1511 opn = "ddiv";
1512 break;
1513 case OPC_DDIVU:
1514 gen_op_ddivu();
1515 opn = "ddivu";
1516 break;
1517 case OPC_DMULT:
1518 gen_op_dmult();
1519 opn = "dmult";
1520 break;
1521 case OPC_DMULTU:
1522 gen_op_dmultu();
1523 opn = "dmultu";
1524 break;
1525 #endif
1526 case OPC_MADD:
1527 gen_op_madd();
1528 opn = "madd";
1529 break;
1530 case OPC_MADDU:
1531 gen_op_maddu();
1532 opn = "maddu";
1533 break;
1534 case OPC_MSUB:
1535 gen_op_msub();
1536 opn = "msub";
1537 break;
1538 case OPC_MSUBU:
1539 gen_op_msubu();
1540 opn = "msubu";
1541 break;
1542 default:
1543 MIPS_INVAL(opn);
1544 generate_exception(ctx, EXCP_RI);
1545 return;
1546 }
1547 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1548 }
1549
1550 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
1551 int rd, int rs, int rt)
1552 {
1553 const char *opn = "mul vr54xx";
1554
1555 GEN_LOAD_REG_T0(rs);
1556 GEN_LOAD_REG_T1(rt);
1557
1558 switch (opc) {
1559 case OPC_VR54XX_MULS:
1560 gen_op_muls();
1561 opn = "muls";
1562 break;
1563 case OPC_VR54XX_MULSU:
1564 gen_op_mulsu();
1565 opn = "mulsu";
1566 break;
1567 case OPC_VR54XX_MACC:
1568 gen_op_macc();
1569 opn = "macc";
1570 break;
1571 case OPC_VR54XX_MACCU:
1572 gen_op_maccu();
1573 opn = "maccu";
1574 break;
1575 case OPC_VR54XX_MSAC:
1576 gen_op_msac();
1577 opn = "msac";
1578 break;
1579 case OPC_VR54XX_MSACU:
1580 gen_op_msacu();
1581 opn = "msacu";
1582 break;
1583 case OPC_VR54XX_MULHI:
1584 gen_op_mulhi();
1585 opn = "mulhi";
1586 break;
1587 case OPC_VR54XX_MULHIU:
1588 gen_op_mulhiu();
1589 opn = "mulhiu";
1590 break;
1591 case OPC_VR54XX_MULSHI:
1592 gen_op_mulshi();
1593 opn = "mulshi";
1594 break;
1595 case OPC_VR54XX_MULSHIU:
1596 gen_op_mulshiu();
1597 opn = "mulshiu";
1598 break;
1599 case OPC_VR54XX_MACCHI:
1600 gen_op_macchi();
1601 opn = "macchi";
1602 break;
1603 case OPC_VR54XX_MACCHIU:
1604 gen_op_macchiu();
1605 opn = "macchiu";
1606 break;
1607 case OPC_VR54XX_MSACHI:
1608 gen_op_msachi();
1609 opn = "msachi";
1610 break;
1611 case OPC_VR54XX_MSACHIU:
1612 gen_op_msachiu();
1613 opn = "msachiu";
1614 break;
1615 default:
1616 MIPS_INVAL("mul vr54xx");
1617 generate_exception(ctx, EXCP_RI);
1618 return;
1619 }
1620 GEN_STORE_T0_REG(rd);
1621 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1622 }
1623
1624 static void gen_cl (DisasContext *ctx, uint32_t opc,
1625 int rd, int rs)
1626 {
1627 const char *opn = "CLx";
1628 if (rd == 0) {
1629 /* Treat as NOP. */
1630 MIPS_DEBUG("NOP");
1631 return;
1632 }
1633 GEN_LOAD_REG_T0(rs);
1634 switch (opc) {
1635 case OPC_CLO:
1636 gen_op_clo();
1637 opn = "clo";
1638 break;
1639 case OPC_CLZ:
1640 gen_op_clz();
1641 opn = "clz";
1642 break;
1643 #if defined(TARGET_MIPS64)
1644 case OPC_DCLO:
1645 gen_op_dclo();
1646 opn = "dclo";
1647 break;
1648 case OPC_DCLZ:
1649 gen_op_dclz();
1650 opn = "dclz";
1651 break;
1652 #endif
1653 default:
1654 MIPS_INVAL(opn);
1655 generate_exception(ctx, EXCP_RI);
1656 return;
1657 }
1658 gen_op_store_T0_gpr(rd);
1659 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1660 }
1661
1662 /* Traps */
1663 static void gen_trap (DisasContext *ctx, uint32_t opc,
1664 int rs, int rt, int16_t imm)
1665 {
1666 int cond;
1667
1668 cond = 0;
1669 /* Load needed operands */
1670 switch (opc) {
1671 case OPC_TEQ:
1672 case OPC_TGE:
1673 case OPC_TGEU:
1674 case OPC_TLT:
1675 case OPC_TLTU:
1676 case OPC_TNE:
1677 /* Compare two registers */
1678 if (rs != rt) {
1679 GEN_LOAD_REG_T0(rs);
1680 GEN_LOAD_REG_T1(rt);
1681 cond = 1;
1682 }
1683 break;
1684 case OPC_TEQI:
1685 case OPC_TGEI:
1686 case OPC_TGEIU:
1687 case OPC_TLTI:
1688 case OPC_TLTIU:
1689 case OPC_TNEI:
1690 /* Compare register to immediate */
1691 if (rs != 0 || imm != 0) {
1692 GEN_LOAD_REG_T0(rs);
1693 GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1694 cond = 1;
1695 }
1696 break;
1697 }
1698 if (cond == 0) {
1699 switch (opc) {
1700 case OPC_TEQ: /* rs == rs */
1701 case OPC_TEQI: /* r0 == 0 */
1702 case OPC_TGE: /* rs >= rs */
1703 case OPC_TGEI: /* r0 >= 0 */
1704 case OPC_TGEU: /* rs >= rs unsigned */
1705 case OPC_TGEIU: /* r0 >= 0 unsigned */
1706 /* Always trap */
1707 gen_op_set_T0(1);
1708 break;
1709 case OPC_TLT: /* rs < rs */
1710 case OPC_TLTI: /* r0 < 0 */
1711 case OPC_TLTU: /* rs < rs unsigned */
1712 case OPC_TLTIU: /* r0 < 0 unsigned */
1713 case OPC_TNE: /* rs != rs */
1714 case OPC_TNEI: /* r0 != 0 */
1715 /* Never trap: treat as NOP. */
1716 return;
1717 default:
1718 MIPS_INVAL("trap");
1719 generate_exception(ctx, EXCP_RI);
1720 return;
1721 }
1722 } else {
1723 switch (opc) {
1724 case OPC_TEQ:
1725 case OPC_TEQI:
1726 gen_op_eq();
1727 break;
1728 case OPC_TGE:
1729 case OPC_TGEI:
1730 gen_op_ge();
1731 break;
1732 case OPC_TGEU:
1733 case OPC_TGEIU:
1734 gen_op_geu();
1735 break;
1736 case OPC_TLT:
1737 case OPC_TLTI:
1738 gen_op_lt();
1739 break;
1740 case OPC_TLTU:
1741 case OPC_TLTIU:
1742 gen_op_ltu();
1743 break;
1744 case OPC_TNE:
1745 case OPC_TNEI:
1746 gen_op_ne();
1747 break;
1748 default:
1749 MIPS_INVAL("trap");
1750 generate_exception(ctx, EXCP_RI);
1751 return;
1752 }
1753 }
1754 save_cpu_state(ctx, 1);
1755 gen_op_trap();
1756 ctx->bstate = BS_STOP;
1757 }
1758
1759 static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1760 {
1761 TranslationBlock *tb;
1762 tb = ctx->tb;
1763 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1764 tcg_gen_goto_tb(n);
1765 gen_save_pc(dest);
1766 tcg_gen_exit_tb((long)tb + n);
1767 } else {
1768 gen_save_pc(dest);
1769 tcg_gen_exit_tb(0);
1770 }
1771 }
1772
1773 /* Branches (before delay slot) */
1774 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1775 int rs, int rt, int32_t offset)
1776 {
1777 target_ulong btarget = -1;
1778 int blink = 0;
1779 int bcond = 0;
1780
1781 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1782 #ifdef MIPS_DEBUG_DISAS
1783 if (loglevel & CPU_LOG_TB_IN_ASM) {
1784 fprintf(logfile,
1785 "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1786 ctx->pc);
1787 }
1788 #endif
1789 generate_exception(ctx, EXCP_RI);
1790 return;
1791 }
1792
1793 /* Load needed operands */
1794 switch (opc) {
1795 case OPC_BEQ:
1796 case OPC_BEQL:
1797 case OPC_BNE:
1798 case OPC_BNEL:
1799 /* Compare two registers */
1800 if (rs != rt) {
1801 GEN_LOAD_REG_T0(rs);
1802 GEN_LOAD_REG_T1(rt);
1803 bcond = 1;
1804 }
1805 btarget = ctx->pc + 4 + offset;
1806 break;
1807 case OPC_BGEZ:
1808 case OPC_BGEZAL:
1809 case OPC_BGEZALL:
1810 case OPC_BGEZL:
1811 case OPC_BGTZ:
1812 case OPC_BGTZL:
1813 case OPC_BLEZ:
1814 case OPC_BLEZL:
1815 case OPC_BLTZ:
1816 case OPC_BLTZAL:
1817 case OPC_BLTZALL:
1818 case OPC_BLTZL:
1819 /* Compare to zero */
1820 if (rs != 0) {
1821 gen_op_load_gpr_T0(rs);
1822 bcond = 1;
1823 }
1824 btarget = ctx->pc + 4 + offset;
1825 break;
1826 case OPC_J:
1827 case OPC_JAL:
1828 /* Jump to immediate */
1829 btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
1830 break;
1831 case OPC_JR:
1832 case OPC_JALR:
1833 /* Jump to register */
1834 if (offset != 0 && offset != 16) {
1835 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1836 others are reserved. */
1837 MIPS_INVAL("jump hint");
1838 generate_exception(ctx, EXCP_RI);
1839 return;
1840 }
1841 GEN_LOAD_REG_T2(rs);
1842 break;
1843 default:
1844 MIPS_INVAL("branch/jump");
1845 generate_exception(ctx, EXCP_RI);
1846 return;
1847 }
1848 if (bcond == 0) {
1849 /* No condition to be computed */
1850 switch (opc) {
1851 case OPC_BEQ: /* rx == rx */
1852 case OPC_BEQL: /* rx == rx likely */
1853 case OPC_BGEZ: /* 0 >= 0 */
1854 case OPC_BGEZL: /* 0 >= 0 likely */
1855 case OPC_BLEZ: /* 0 <= 0 */
1856 case OPC_BLEZL: /* 0 <= 0 likely */
1857 /* Always take */
1858 ctx->hflags |= MIPS_HFLAG_B;
1859 MIPS_DEBUG("balways");
1860 break;
1861 case OPC_BGEZAL: /* 0 >= 0 */
1862 case OPC_BGEZALL: /* 0 >= 0 likely */
1863 /* Always take and link */
1864 blink = 31;
1865 ctx->hflags |= MIPS_HFLAG_B;
1866 MIPS_DEBUG("balways and link");
1867 break;
1868 case OPC_BNE: /* rx != rx */
1869 case OPC_BGTZ: /* 0 > 0 */
1870 case OPC_BLTZ: /* 0 < 0 */
1871 /* Treat as NOP. */
1872 MIPS_DEBUG("bnever (NOP)");
1873 return;
1874 case OPC_BLTZAL: /* 0 < 0 */
1875 GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1876 gen_op_store_T0_gpr(31);
1877 MIPS_DEBUG("bnever and link");
1878 return;
1879 case OPC_BLTZALL: /* 0 < 0 likely */
1880 GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1881 gen_op_store_T0_gpr(31);
1882 /* Skip the instruction in the delay slot */
1883 MIPS_DEBUG("bnever, link and skip");
1884 ctx->pc += 4;
1885 return;
1886 case OPC_BNEL: /* rx != rx likely */
1887 case OPC_BGTZL: /* 0 > 0 likely */
1888 case OPC_BLTZL: /* 0 < 0 likely */
1889 /* Skip the instruction in the delay slot */
1890 MIPS_DEBUG("bnever and skip");
1891 ctx->pc += 4;
1892 return;
1893 case OPC_J:
1894 ctx->hflags |= MIPS_HFLAG_B;
1895 MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
1896 break;
1897 case OPC_JAL:
1898 blink = 31;
1899 ctx->hflags |= MIPS_HFLAG_B;
1900 MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
1901 break;
1902 case OPC_JR:
1903 ctx->hflags |= MIPS_HFLAG_BR;
1904 MIPS_DEBUG("jr %s", regnames[rs]);
1905 break;
1906 case OPC_JALR:
1907 blink = rt;
1908 ctx->hflags |= MIPS_HFLAG_BR;
1909 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1910 break;
1911 default:
1912 MIPS_INVAL("branch/jump");
1913 generate_exception(ctx, EXCP_RI);
1914 return;
1915 }
1916 } else {
1917 switch (opc) {
1918 case OPC_BEQ:
1919 gen_op_eq();
1920 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1921 regnames[rs], regnames[rt], btarget);
1922 goto not_likely;
1923 case OPC_BEQL:
1924 gen_op_eq();
1925 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1926 regnames[rs], regnames[rt], btarget);
1927 goto likely;
1928 case OPC_BNE:
1929 gen_op_ne();
1930 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1931 regnames[rs], regnames[rt], btarget);
1932 goto not_likely;
1933 case OPC_BNEL:
1934 gen_op_ne();
1935 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1936 regnames[rs], regnames[rt], btarget);
1937 goto likely;
1938 case OPC_BGEZ:
1939 gen_op_gez();
1940 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1941 goto not_likely;
1942 case OPC_BGEZL:
1943 gen_op_gez();
1944 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1945 goto likely;
1946 case OPC_BGEZAL:
1947 gen_op_gez();
1948 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1949 blink = 31;
1950 goto not_likely;
1951 case OPC_BGEZALL:
1952 gen_op_gez();
1953 blink = 31;
1954 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1955 goto likely;
1956 case OPC_BGTZ:
1957 gen_op_gtz();
1958 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1959 goto not_likely;
1960 case OPC_BGTZL:
1961 gen_op_gtz();
1962 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1963 goto likely;
1964 case OPC_BLEZ:
1965 gen_op_lez();
1966 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1967 goto not_likely;
1968 case OPC_BLEZL:
1969 gen_op_lez();
1970 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1971 goto likely;
1972 case OPC_BLTZ:
1973 gen_op_ltz();
1974 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1975 goto not_likely;
1976 case OPC_BLTZL:
1977 gen_op_ltz();
1978 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1979 goto likely;
1980 case OPC_BLTZAL:
1981 gen_op_ltz();
1982 blink = 31;
1983 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1984 not_likely:
1985 ctx->hflags |= MIPS_HFLAG_BC;
1986 gen_op_set_bcond();
1987 break;
1988 case OPC_BLTZALL:
1989 gen_op_ltz();
1990 blink = 31;
1991 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1992 likely:
1993 ctx->hflags |= MIPS_HFLAG_BL;
1994 gen_op_set_bcond();
1995 gen_op_save_bcond();
1996 break;
1997 default:
1998 MIPS_INVAL("conditional branch/jump");
1999 generate_exception(ctx, EXCP_RI);
2000 return;
2001 }
2002 }
2003 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2004 blink, ctx->hflags, btarget);
2005
2006 ctx->btarget = btarget;
2007 if (blink > 0) {
2008 GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
2009 gen_op_store_T0_gpr(blink);
2010 }
2011 }
2012
2013 /* special3 bitfield operations */
2014 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2015 int rs, int lsb, int msb)
2016 {
2017 GEN_LOAD_REG_T1(rs);
2018 switch (opc) {
2019 case OPC_EXT:
2020 if (lsb + msb > 31)
2021 goto fail;
2022 gen_op_ext(lsb, msb + 1);
2023 break;
2024 #if defined(TARGET_MIPS64)
2025 case OPC_DEXTM:
2026 if (lsb + msb > 63)
2027 goto fail;
2028 gen_op_dext(lsb, msb + 1 + 32);
2029 break;
2030 case OPC_DEXTU:
2031 if (lsb + msb > 63)
2032 goto fail;
2033 gen_op_dext(lsb + 32, msb + 1);
2034 break;
2035 case OPC_DEXT:
2036 if (lsb + msb > 63)
2037 goto fail;
2038 gen_op_dext(lsb, msb + 1);
2039 break;
2040 #endif
2041 case OPC_INS:
2042 if (lsb > msb)
2043 goto fail;
2044 GEN_LOAD_REG_T0(rt);
2045 gen_op_ins(lsb, msb - lsb + 1);
2046 break;
2047 #if defined(TARGET_MIPS64)
2048 case OPC_DINSM:
2049 if (lsb > msb)
2050 goto fail;
2051 GEN_LOAD_REG_T0(rt);
2052 gen_op_dins(lsb, msb - lsb + 1 + 32);
2053 break;
2054 case OPC_DINSU:
2055 if (lsb > msb)
2056 goto fail;
2057 GEN_LOAD_REG_T0(rt);
2058 gen_op_dins(lsb + 32, msb - lsb + 1);
2059 break;
2060 case OPC_DINS:
2061 if (lsb > msb)
2062 goto fail;
2063 GEN_LOAD_REG_T0(rt);
2064 gen_op_dins(lsb, msb - lsb + 1);
2065 break;
2066 #endif
2067 default:
2068 fail:
2069 MIPS_INVAL("bitops");
2070 generate_exception(ctx, EXCP_RI);
2071 return;
2072 }
2073 GEN_STORE_T0_REG(rt);
2074 }
2075
2076 /* CP0 (MMU and control) */
2077 static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2078 {
2079 const char *rn = "invalid";
2080
2081 if (sel != 0)
2082 check_insn(env, ctx, ISA_MIPS32);
2083
2084 switch (reg) {
2085 case 0:
2086 switch (sel) {
2087 case 0:
2088 gen_op_mfc0_index();
2089 rn = "Index";
2090 break;
2091 case 1:
2092 check_insn(env, ctx, ASE_MT);
2093 gen_op_mfc0_mvpcontrol();
2094 rn = "MVPControl";
2095 break;
2096 case 2:
2097 check_insn(env, ctx, ASE_MT);
2098 gen_op_mfc0_mvpconf0();
2099 rn = "MVPConf0";
2100 break;
2101 case 3:
2102 check_insn(env, ctx, ASE_MT);
2103 gen_op_mfc0_mvpconf1();
2104 rn = "MVPConf1";
2105 break;
2106 default:
2107 goto die;
2108 }
2109 break;
2110 case 1:
2111 switch (sel) {
2112 case 0:
2113 gen_op_mfc0_random();
2114 rn = "Random";
2115 break;
2116 case 1:
2117 check_insn(env, ctx, ASE_MT);
2118 gen_op_mfc0_vpecontrol();
2119 rn = "VPEControl";
2120 break;
2121 case 2:
2122 check_insn(env, ctx, ASE_MT);
2123 gen_op_mfc0_vpeconf0();
2124 rn = "VPEConf0";
2125 break;
2126 case 3:
2127 check_insn(env, ctx, ASE_MT);
2128 gen_op_mfc0_vpeconf1();
2129 rn = "VPEConf1";
2130 break;
2131 case 4:
2132 check_insn(env, ctx, ASE_MT);
2133 gen_op_mfc0_yqmask();
2134 rn = "YQMask";
2135 break;
2136 case 5:
2137 check_insn(env, ctx, ASE_MT);
2138 gen_op_mfc0_vpeschedule();
2139 rn = "VPESchedule";
2140 break;
2141 case 6:
2142 check_insn(env, ctx, ASE_MT);
2143 gen_op_mfc0_vpeschefback();
2144 rn = "VPEScheFBack";
2145 break;
2146 case 7:
2147 check_insn(env, ctx, ASE_MT);
2148 gen_op_mfc0_vpeopt();
2149 rn = "VPEOpt";
2150 break;
2151 default:
2152 goto die;
2153 }
2154 break;
2155 case 2:
2156 switch (sel) {
2157 case 0:
2158 gen_op_mfc0_entrylo0();
2159 rn = "EntryLo0";
2160 break;
2161 case 1:
2162 check_insn(env, ctx, ASE_MT);
2163 gen_op_mfc0_tcstatus();
2164 rn = "TCStatus";
2165 break;
2166 case 2:
2167 check_insn(env, ctx, ASE_MT);
2168 gen_op_mfc0_tcbind();
2169 rn = "TCBind";
2170 break;
2171 case 3:
2172 check_insn(env, ctx, ASE_MT);
2173 gen_op_mfc0_tcrestart();
2174 rn = "TCRestart";
2175 break;
2176 case 4:
2177 check_insn(env, ctx, ASE_MT);
2178 gen_op_mfc0_tchalt();
2179 rn = "TCHalt";
2180 break;
2181 case 5:
2182 check_insn(env, ctx, ASE_MT);
2183 gen_op_mfc0_tccontext();
2184 rn = "TCContext";
2185 break;
2186 case 6:
2187 check_insn(env, ctx, ASE_MT);
2188 gen_op_mfc0_tcschedule();
2189 rn = "TCSchedule";
2190 break;
2191 case 7:
2192 check_insn(env, ctx, ASE_MT);
2193 gen_op_mfc0_tcschefback();
2194 rn = "TCScheFBack";
2195 break;
2196 default:
2197 goto die;
2198 }
2199 break;
2200 case 3:
2201 switch (sel) {
2202 case 0:
2203 gen_op_mfc0_entrylo1();
2204 rn = "EntryLo1";
2205 break;
2206 default:
2207 goto die;
2208 }
2209 break;
2210 case 4:
2211 switch (sel) {
2212 case 0:
2213 gen_op_mfc0_context();
2214 rn = "Context";
2215 break;
2216 case 1:
2217 // gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2218 rn = "ContextConfig";
2219 // break;
2220 default:
2221 goto die;
2222 }
2223 break;
2224 case 5:
2225 switch (sel) {
2226 case 0:
2227 gen_op_mfc0_pagemask();
2228 rn = "PageMask";
2229 break;
2230 case 1:
2231 check_insn(env, ctx, ISA_MIPS32R2);
2232 gen_op_mfc0_pagegrain();
2233 rn = "PageGrain";
2234 break;
2235 default:
2236 goto die;
2237 }
2238 break;
2239 case 6:
2240 switch (sel) {
2241 case 0:
2242 gen_op_mfc0_wired();
2243 rn = "Wired";
2244 break;
2245 case 1:
2246 check_insn(env, ctx, ISA_MIPS32R2);
2247 gen_op_mfc0_srsconf0();
2248 rn = "SRSConf0";
2249 break;
2250 case 2:
2251 check_insn(env, ctx, ISA_MIPS32R2);
2252 gen_op_mfc0_srsconf1();
2253 rn = "SRSConf1";
2254 break;
2255 case 3:
2256 check_insn(env, ctx, ISA_MIPS32R2);
2257 gen_op_mfc0_srsconf2();
2258 rn = "SRSConf2";
2259 break;
2260 case 4:
2261 check_insn(env, ctx, ISA_MIPS32R2);
2262 gen_op_mfc0_srsconf3();
2263 rn = "SRSConf3";
2264 break;
2265 case 5:
2266 check_insn(env, ctx, ISA_MIPS32R2);
2267 gen_op_mfc0_srsconf4();
2268 rn = "SRSConf4";
2269 break;
2270 default:
2271 goto die;
2272 }
2273 break;
2274 case 7:
2275 switch (sel) {
2276 case 0:
2277 check_insn(env, ctx, ISA_MIPS32R2);
2278 gen_op_mfc0_hwrena();
2279 rn = "HWREna";
2280 break;
2281 default:
2282 goto die;
2283 }
2284 break;
2285 case 8:
2286 switch (sel) {
2287 case 0:
2288 gen_op_mfc0_badvaddr();
2289 rn = "BadVaddr";
2290 break;
2291 default:
2292 goto die;
2293 }
2294 break;
2295 case 9:
2296 switch (sel) {
2297 case 0:
2298 gen_op_mfc0_count();
2299 rn = "Count";
2300 break;
2301 /* 6,7 are implementation dependent */
2302 default:
2303 goto die;
2304 }
2305 break;
2306 case 10:
2307 switch (sel) {
2308 case 0:
2309 gen_op_mfc0_entryhi();
2310 rn = "EntryHi";
2311 break;
2312 default:
2313 goto die;
2314 }
2315 break;
2316 case 11:
2317 switch (sel) {
2318 case 0:
2319 gen_op_mfc0_compare();
2320 rn = "Compare";
2321 break;
2322 /* 6,7 are implementation dependent */
2323 default:
2324 goto die;
2325 }
2326 break;
2327 case 12:
2328 switch (sel) {
2329 case 0:
2330 gen_op_mfc0_status();
2331 rn = "Status";
2332 break;
2333 case 1:
2334 check_insn(env, ctx, ISA_MIPS32R2);
2335 gen_op_mfc0_intctl();
2336 rn = "IntCtl";
2337 break;
2338 case 2:
2339 check_insn(env, ctx, ISA_MIPS32R2);
2340 gen_op_mfc0_srsctl();
2341 rn = "SRSCtl";
2342 break;
2343 case 3:
2344 check_insn(env, ctx, ISA_MIPS32R2);
2345 gen_op_mfc0_srsmap();
2346 rn = "SRSMap";
2347 break;
2348 default:
2349 goto die;
2350 }
2351 break;
2352 case 13:
2353 switch (sel) {
2354 case 0:
2355 gen_op_mfc0_cause();
2356 rn = "Cause";
2357 break;
2358 default:
2359 goto die;
2360 }
2361 break;
2362 case 14:
2363 switch (sel) {
2364 case 0:
2365 gen_op_mfc0_epc();
2366 rn = "EPC";
2367 break;
2368 default:
2369 goto die;
2370 }
2371 break;
2372 case 15:
2373 switch (sel) {
2374 case 0:
2375 gen_op_mfc0_prid();
2376 rn = "PRid";
2377 break;
2378 case 1:
2379 check_insn(env, ctx, ISA_MIPS32R2);
2380 gen_op_mfc0_ebase();
2381 rn = "EBase";
2382 break;
2383 default:
2384 goto die;
2385 }
2386 break;
2387 case 16:
2388 switch (sel) {
2389 case 0:
2390 gen_op_mfc0_config0();
2391 rn = "Config";
2392 break;
2393 case 1:
2394 gen_op_mfc0_config1();
2395 rn = "Config1";
2396 break;
2397 case 2:
2398 gen_op_mfc0_config2();
2399 rn = "Config2";
2400 break;
2401 case 3:
2402 gen_op_mfc0_config3();
2403 rn = "Config3";
2404 break;
2405 /* 4,5 are reserved */
2406 /* 6,7 are implementation dependent */
2407 case 6:
2408 gen_op_mfc0_config6();
2409 rn = "Config6";
2410 break;
2411 case 7:
2412 gen_op_mfc0_config7();
2413 rn = "Config7";
2414 break;
2415 default:
2416 goto die;
2417 }
2418 break;
2419 case 17:
2420 switch (sel) {
2421 case 0:
2422 gen_op_mfc0_lladdr();
2423 rn = "LLAddr";
2424 break;
2425 default:
2426 goto die;
2427 }
2428 break;
2429 case 18:
2430 switch (sel) {
2431 case 0 ... 7:
2432 gen_op_mfc0_watchlo(sel);
2433 rn = "WatchLo";
2434 break;
2435 default:
2436 goto die;
2437 }
2438 break;
2439 case 19:
2440 switch (sel) {
2441 case 0 ...7:
2442 gen_op_mfc0_watchhi(sel);
2443 rn = "WatchHi";
2444 break;
2445 default:
2446 goto die;
2447 }
2448 break;
2449 case 20:
2450 switch (sel) {
2451 case 0:
2452 #if defined(TARGET_MIPS64)
2453 check_insn(env, ctx, ISA_MIPS3);
2454 gen_op_mfc0_xcontext();
2455 rn = "XContext";
2456 break;
2457 #endif
2458 default:
2459 goto die;
2460 }
2461 break;
2462 case 21:
2463 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2464 switch (sel) {
2465 case 0:
2466 gen_op_mfc0_framemask();
2467 rn = "Framemask";
2468 break;
2469 default:
2470 goto die;
2471 }
2472 break;
2473 case 22:
2474 /* ignored */
2475 rn = "'Diagnostic"; /* implementation dependent */
2476 break;
2477 case 23:
2478 switch (sel) {
2479 case 0:
2480 gen_op_mfc0_debug(); /* EJTAG support */
2481 rn = "Debug";
2482 break;
2483 case 1:
2484 // gen_op_mfc0_tracecontrol(); /* PDtrace support */
2485 rn = "TraceControl";
2486 // break;
2487 case 2:
2488 // gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2489 rn = "TraceControl2";
2490 // break;
2491 case 3:
2492 // gen_op_mfc0_usertracedata(); /* PDtrace support */
2493 rn = "UserTraceData";
2494 // break;
2495 case 4:
2496 // gen_op_mfc0_debug(); /* PDtrace support */
2497 rn = "TraceBPC";
2498 // break;
2499 default:
2500 goto die;
2501 }
2502 break;
2503 case 24:
2504 switch (sel) {
2505 case 0:
2506 gen_op_mfc0_depc(); /* EJTAG support */
2507 rn = "DEPC";
2508 break;
2509 default:
2510 goto die;
2511 }
2512 break;
2513 case 25:
2514 switch (sel) {
2515 case 0:
2516 gen_op_mfc0_performance0();
2517 rn = "Performance0";
2518 break;
2519 case 1:
2520 // gen_op_mfc0_performance1();
2521 rn = "Performance1";
2522 // break;
2523 case 2:
2524 // gen_op_mfc0_performance2();
2525 rn = "Performance2";
2526 // break;
2527 case 3:
2528 // gen_op_mfc0_performance3();
2529 rn = "Performance3";
2530 // break;
2531 case 4:
2532 // gen_op_mfc0_performance4();
2533 rn = "Performance4";
2534 // break;
2535 case 5:
2536 // gen_op_mfc0_performance5();
2537 rn = "Performance5";
2538 // break;
2539 case 6:
2540 // gen_op_mfc0_performance6();
2541 rn = "Performance6";
2542 // break;
2543 case 7:
2544 // gen_op_mfc0_performance7();
2545 rn = "Performance7";
2546 // break;
2547 default:
2548 goto die;
2549 }
2550 break;
2551 case 26:
2552 rn = "ECC";
2553 break;
2554 case 27:
2555 switch (sel) {
2556 /* ignored */
2557 case 0 ... 3:
2558 rn = "CacheErr";
2559 break;
2560 default:
2561 goto die;
2562 }
2563 break;
2564 case 28:
2565 switch (sel) {
2566 case 0:
2567 case 2:
2568 case 4:
2569 case 6:
2570 gen_op_mfc0_taglo();
2571 rn = "TagLo";
2572 break;
2573 case 1:
2574 case 3:
2575 case 5:
2576 case 7:
2577 gen_op_mfc0_datalo();
2578 rn = "DataLo";
2579 break;
2580 default:
2581 goto die;
2582 }
2583 break;
2584 case 29:
2585 switch (sel) {
2586 case 0:
2587 case 2:
2588 case 4:
2589 case 6:
2590 gen_op_mfc0_taghi();
2591 rn = "TagHi";
2592 break;
2593 case 1:
2594 case 3:
2595 case 5:
2596 case 7:
2597 gen_op_mfc0_datahi();
2598 rn = "DataHi";
2599 break;
2600 default:
2601 goto die;
2602 }
2603 break;
2604 case 30:
2605 switch (sel) {
2606 case 0:
2607 gen_op_mfc0_errorepc();
2608 rn = "ErrorEPC";
2609 break;
2610 default:
2611 goto die;
2612 }
2613 break;
2614 case 31:
2615 switch (sel) {
2616 case 0:
2617 gen_op_mfc0_desave(); /* EJTAG support */
2618 rn = "DESAVE";
2619 break;
2620 default:
2621 goto die;
2622 }
2623 break;
2624 default:
2625 goto die;
2626 }
2627 #if defined MIPS_DEBUG_DISAS
2628 if (loglevel & CPU_LOG_TB_IN_ASM) {
2629 fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2630 rn, reg, sel);
2631 }
2632 #endif
2633 return;
2634
2635 die:
2636 #if defined MIPS_DEBUG_DISAS
2637 if (loglevel & CPU_LOG_TB_IN_ASM) {
2638 fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2639 rn, reg, sel);
2640 }
2641 #endif
2642 generate_exception(ctx, EXCP_RI);
2643 }
2644
2645 static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2646 {
2647 const char *rn = "invalid";
2648
2649 if (sel != 0)
2650 check_insn(env, ctx, ISA_MIPS32);
2651
2652 switch (reg) {
2653 case 0:
2654 switch (sel) {
2655 case 0:
2656 gen_op_mtc0_index();
2657 rn = "Index";
2658 break;
2659 case 1:
2660 check_insn(env, ctx, ASE_MT);
2661 gen_op_mtc0_mvpcontrol();
2662 rn = "MVPControl";
2663 break;
2664 case 2:
2665 check_insn(env, ctx, ASE_MT);
2666 /* ignored */
2667 rn = "MVPConf0";
2668 break;
2669 case 3:
2670 check_insn(env, ctx, ASE_MT);
2671 /* ignored */
2672 rn = "MVPConf1";
2673 break;
2674 default:
2675 goto die;
2676 }
2677 break;
2678 case 1:
2679 switch (sel) {
2680 case 0:
2681 /* ignored */
2682 rn = "Random";
2683 break;
2684 case 1:
2685 check_insn(env, ctx, ASE_MT);
2686 gen_op_mtc0_vpecontrol();
2687 rn = "VPEControl";
2688 break;
2689 case 2:
2690 check_insn(env, ctx, ASE_MT);
2691 gen_op_mtc0_vpeconf0();
2692 rn = "VPEConf0";
2693 break;
2694 case 3:
2695 check_insn(env, ctx, ASE_MT);
2696 gen_op_mtc0_vpeconf1();
2697 rn = "VPEConf1";
2698 break;
2699 case 4:
2700 check_insn(env, ctx, ASE_MT);
2701 gen_op_mtc0_yqmask();
2702 rn = "YQMask";
2703 break;
2704 case 5:
2705 check_insn(env, ctx, ASE_MT);
2706 gen_op_mtc0_vpeschedule();
2707 rn = "VPESchedule";
2708 break;
2709 case 6:
2710 check_insn(env, ctx, ASE_MT);
2711 gen_op_mtc0_vpeschefback();
2712 rn = "VPEScheFBack";
2713 break;
2714 case 7:
2715 check_insn(env, ctx, ASE_MT);
2716 gen_op_mtc0_vpeopt();
2717 rn = "VPEOpt";
2718 break;
2719 default:
2720 goto die;
2721 }
2722 break;
2723 case 2:
2724 switch (sel) {
2725 case 0:
2726 gen_op_mtc0_entrylo0();
2727 rn = "EntryLo0";
2728 break;
2729 case 1:
2730 check_insn(env, ctx, ASE_MT);
2731 gen_op_mtc0_tcstatus();
2732 rn = "TCStatus";
2733 break;
2734 case 2:
2735 check_insn(env, ctx, ASE_MT);
2736 gen_op_mtc0_tcbind();
2737 rn = "TCBind";
2738 break;
2739 case 3:
2740 check_insn(env, ctx, ASE_MT);
2741 gen_op_mtc0_tcrestart();
2742 rn = "TCRestart";
2743 break;
2744 case 4:
2745 check_insn(env, ctx, ASE_MT);
2746 gen_op_mtc0_tchalt();
2747 rn = "TCHalt";
2748 break;
2749 case 5:
2750 check_insn(env, ctx, ASE_MT);
2751 gen_op_mtc0_tccontext();
2752 rn = "TCContext";
2753 break;
2754 case 6:
2755 check_insn(env, ctx, ASE_MT);
2756 gen_op_mtc0_tcschedule();
2757 rn = "TCSchedule";
2758 break;
2759 case 7:
2760 check_insn(env, ctx, ASE_MT);
2761 gen_op_mtc0_tcschefback();
2762 rn = "TCScheFBack";
2763 break;
2764 default:
2765 goto die;
2766 }
2767 break;
2768 case 3:
2769 switch (sel) {
2770 case 0:
2771 gen_op_mtc0_entrylo1();
2772 rn = "EntryLo1";
2773 break;
2774 default:
2775 goto die;
2776 }
2777 break;
2778 case 4:
2779 switch (sel) {
2780 case 0:
2781 gen_op_mtc0_context();
2782 rn = "Context";
2783 break;
2784 case 1:
2785 // gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2786 rn = "ContextConfig";
2787 // break;
2788 default:
2789 goto die;
2790 }
2791 break;
2792 case 5:
2793 switch (sel) {
2794 case 0:
2795 gen_op_mtc0_pagemask();
2796 rn = "PageMask";
2797 break;
2798 case 1:
2799 check_insn(env, ctx, ISA_MIPS32R2);
2800 gen_op_mtc0_pagegrain();
2801 rn = "PageGrain";
2802 break;
2803 default:
2804 goto die;
2805 }
2806 break;
2807 case 6:
2808 switch (sel) {
2809 case 0:
2810 gen_op_mtc0_wired();
2811 rn = "Wired";
2812 break;
2813 case 1:
2814 check_insn(env, ctx, ISA_MIPS32R2);
2815 gen_op_mtc0_srsconf0();
2816 rn = "SRSConf0";
2817 break;
2818 case 2:
2819 check_insn(env, ctx, ISA_MIPS32R2);
2820 gen_op_mtc0_srsconf1();
2821 rn = "SRSConf1";
2822 break;
2823 case 3:
2824 check_insn(env, ctx, ISA_MIPS32R2);
2825 gen_op_mtc0_srsconf2();
2826 rn = "SRSConf2";
2827 break;
2828 case 4:
2829 check_insn(env, ctx, ISA_MIPS32R2);
2830 gen_op_mtc0_srsconf3();
2831 rn = "SRSConf3";
2832 break;
2833 case 5:
2834 check_insn(env, ctx, ISA_MIPS32R2);
2835 gen_op_mtc0_srsconf4();
2836 rn = "SRSConf4";
2837 break;
2838 default:
2839 goto die;
2840 }
2841 break;
2842 case 7:
2843 switch (sel) {
2844 case 0:
2845 check_insn(env, ctx, ISA_MIPS32R2);
2846 gen_op_mtc0_hwrena();
2847 rn = "HWREna";
2848 break;
2849 default:
2850 goto die;
2851 }
2852 break;
2853 case 8:
2854 /* ignored */
2855 rn = "BadVaddr";
2856 break;
2857 case 9:
2858 switch (sel) {
2859 case 0:
2860 gen_op_mtc0_count();
2861 rn = "Count";
2862 break;
2863 /* 6,7 are implementation dependent */
2864 default:
2865 goto die;
2866 }
2867 /* Stop translation as we may have switched the execution mode */
2868 ctx->bstate = BS_STOP;
2869 break;
2870 case 10:
2871 switch (sel) {
2872 case 0:
2873 gen_op_mtc0_entryhi();
2874 rn = "EntryHi";
2875 break;
2876 default:
2877 goto die;
2878 }
2879 break;
2880 case 11:
2881 switch (sel) {
2882 case 0:
2883 gen_op_mtc0_compare();
2884 rn = "Compare";
2885 break;
2886 /* 6,7 are implementation dependent */
2887 default:
2888 goto die;
2889 }
2890 /* Stop translation as we may have switched the execution mode */
2891 ctx->bstate = BS_STOP;
2892 break;
2893 case 12:
2894 switch (sel) {
2895 case 0:
2896 gen_op_mtc0_status();
2897 /* BS_STOP isn't good enough here, hflags may have changed. */
2898 gen_save_pc(ctx->pc + 4);
2899 ctx->bstate = BS_EXCP;
2900 rn = "Status";
2901 break;
2902 case 1:
2903 check_insn(env, ctx, ISA_MIPS32R2);
2904 gen_op_mtc0_intctl();
2905 /* Stop translation as we may have switched the execution mode */
2906 ctx->bstate = BS_STOP;
2907 rn = "IntCtl";
2908 break;
2909 case 2:
2910 check_insn(env, ctx, ISA_MIPS32R2);
2911 gen_op_mtc0_srsctl();
2912 /* Stop translation as we may have switched the execution mode */
2913 ctx->bstate = BS_STOP;
2914 rn = "SRSCtl";
2915 break;
2916 case 3:
2917 check_insn(env, ctx, ISA_MIPS32R2);
2918 gen_op_mtc0_srsmap();
2919 /* Stop translation as we may have switched the execution mode */
2920 ctx->bstate = BS_STOP;
2921 rn = "SRSMap";
2922 break;
2923 default:
2924 goto die;
2925 }
2926 break;
2927 case 13:
2928 switch (sel) {
2929 case 0:
2930 gen_op_mtc0_cause();
2931 rn = "Cause";
2932 break;
2933 default:
2934 goto die;
2935 }
2936 /* Stop translation as we may have switched the execution mode */
2937 ctx->bstate = BS_STOP;
2938 break;
2939 case 14:
2940 switch (sel) {
2941 case 0:
2942 gen_op_mtc0_epc();
2943 rn = "EPC";
2944 break;
2945 default:
2946 goto die;
2947 }
2948 break;
2949 case 15:
2950 switch (sel) {
2951 case 0:
2952 /* ignored */
2953 rn = "PRid";
2954 break;
2955 case 1:
2956 check_insn(env, ctx, ISA_MIPS32R2);
2957 gen_op_mtc0_ebase();
2958 rn = "EBase";
2959 break;
2960 default:
2961 goto die;
2962 }
2963 break;
2964 case 16:
2965 switch (sel) {
2966 case 0:
2967 gen_op_mtc0_config0();
2968 rn = "Config";
2969 /* Stop translation as we may have switched the execution mode */
2970 ctx->bstate = BS_STOP;
2971 break;
2972 case 1:
2973 /* ignored, read only */
2974 rn = "Config1";
2975 break;
2976 case 2:
2977 gen_op_mtc0_config2();
2978 rn = "Config2";
2979 /* Stop translation as we may have switched the execution mode */
2980 ctx->bstate = BS_STOP;
2981 break;
2982 case 3:
2983 /* ignored, read only */
2984 rn = "Config3";
2985 break;
2986 /* 4,5 are reserved */
2987 /* 6,7 are implementation dependent */
2988 case 6:
2989 /* ignored */
2990 rn = "Config6";
2991 break;
2992 case 7:
2993 /* ignored */
2994 rn = "Config7";
2995 break;
2996 default:
2997 rn = "Invalid config selector";
2998 goto die;
2999 }
3000 break;
3001 case 17:
3002 switch (sel) {
3003 case 0:
3004 /* ignored */
3005 rn = "LLAddr";
3006 break;
3007 default:
3008 goto die;
3009 }
3010 break;
3011 case 18:
3012 switch (sel) {
3013 case 0 ... 7:
3014 gen_op_mtc0_watchlo(sel);
3015 rn = "WatchLo";
3016 break;
3017 default:
3018 goto die;
3019 }
3020 break;
3021 case 19:
3022 switch (sel) {
3023 case 0 ... 7:
3024 gen_op_mtc0_watchhi(sel);
3025 rn = "WatchHi";
3026 break;
3027 default:
3028 goto die;
3029 }
3030 break;
3031 case 20:
3032 switch (sel) {
3033 case 0:
3034 #if defined(TARGET_MIPS64)
3035 check_insn(env, ctx, ISA_MIPS3);
3036 gen_op_mtc0_xcontext();
3037 rn = "XContext";
3038 break;
3039 #endif
3040 default:
3041 goto die;
3042 }
3043 break;
3044 case 21:
3045 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3046 switch (sel) {
3047 case 0:
3048 gen_op_mtc0_framemask();
3049 rn = "Framemask";
3050 break;
3051 default:
3052 goto die;
3053 }
3054 break;
3055 case 22:
3056 /* ignored */
3057 rn = "Diagnostic"; /* implementation dependent */
3058 break;
3059 case 23:
3060 switch (sel) {
3061 case 0:
3062 gen_op_mtc0_debug(); /* EJTAG support */
3063 /* BS_STOP isn't good enough here, hflags may have changed. */
3064 gen_save_pc(ctx->pc + 4);
3065 ctx->bstate = BS_EXCP;
3066 rn = "Debug";
3067 break;
3068 case 1:
3069 // gen_op_mtc0_tracecontrol(); /* PDtrace support */
3070 rn = "TraceControl";
3071 /* Stop translation as we may have switched the execution mode */
3072 ctx->bstate = BS_STOP;
3073 // break;
3074 case 2:
3075 // gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3076 rn = "TraceControl2";
3077 /* Stop translation as we may have switched the execution mode */
3078 ctx->bstate = BS_STOP;
3079 // break;
3080 case 3:
3081 /* Stop translation as we may have switched the execution mode */
3082 ctx->bstate = BS_STOP;
3083 // gen_op_mtc0_usertracedata(); /* PDtrace support */
3084 rn = "UserTraceData";
3085 /* Stop translation as we may have switched the execution mode */
3086 ctx->bstate = BS_STOP;
3087 // break;
3088 case 4:
3089 // gen_op_mtc0_debug(); /* PDtrace support */
3090 /* Stop translation as we may have switched the execution mode */
3091 ctx->bstate = BS_STOP;
3092 rn = "TraceBPC";
3093 // break;
3094 default:
3095 goto die;
3096 }
3097 break;
3098 case 24:
3099 switch (sel) {
3100 case 0:
3101 gen_op_mtc0_depc(); /* EJTAG support */
3102 rn = "DEPC";
3103 break;
3104 default:
3105 goto die;
3106 }
3107 break;
3108 case 25:
3109 switch (sel) {
3110 case 0:
3111 gen_op_mtc0_performance0();
3112 rn = "Performance0";
3113 break;
3114 case 1:
3115 // gen_op_mtc0_performance1();
3116 rn = "Performance1";
3117 // break;
3118 case 2:
3119 // gen_op_mtc0_performance2();
3120 rn = "Performance2";
3121 // break;
3122 case 3:
3123 // gen_op_mtc0_performance3();
3124 rn = "Performance3";
3125 // break;
3126 case 4:
3127 // gen_op_mtc0_performance4();
3128 rn = "Performance4";
3129 // break;
3130 case 5:
3131 // gen_op_mtc0_performance5();
3132 rn = "Performance5";
3133 // break;
3134 case 6:
3135 // gen_op_mtc0_performance6();
3136 rn = "Performance6";
3137 // break;
3138 case 7:
3139 // gen_op_mtc0_performance7();
3140 rn = "Performance7";
3141 // break;
3142 default:
3143 goto die;
3144 }
3145 break;
3146 case 26:
3147 /* ignored */
3148 rn = "ECC";
3149 break;
3150 case 27:
3151 switch (sel) {
3152 case 0 ... 3:
3153 /* ignored */
3154 rn = "CacheErr";
3155 break;
3156 default:
3157 goto die;
3158 }
3159 break;
3160 case 28:
3161 switch (sel) {
3162 case 0:
3163 case 2:
3164 case 4:
3165 case 6:
3166 gen_op_mtc0_taglo();
3167 rn = "TagLo";
3168 break;
3169 case 1:
3170 case 3:
3171 case 5:
3172 case 7:
3173 gen_op_mtc0_datalo();
3174 rn = "DataLo";
3175 break;
3176 default:
3177 goto die;
3178 }
3179 break;
3180 case 29:
3181 switch (sel) {
3182 case 0:
3183 case 2:
3184 case 4:
3185 case 6:
3186 gen_op_mtc0_taghi();
3187 rn = "TagHi";
3188 break;
3189 case 1:
3190 case 3:
3191 case 5:
3192 case 7:
3193 gen_op_mtc0_datahi();
3194 rn = "DataHi";
3195 break;
3196 default:
3197 rn = "invalid sel";
3198 goto die;
3199 }
3200 break;
3201 case 30:
3202 switch (sel) {
3203 case 0:
3204 gen_op_mtc0_errorepc();
3205 rn = "ErrorEPC";
3206 break;
3207 default:
3208 goto die;
3209 }
3210 break;
3211 case 31:
3212 switch (sel) {
3213 case 0:
3214 gen_op_mtc0_desave(); /* EJTAG support */
3215 rn = "DESAVE";
3216 break;
3217 default:
3218 goto die;
3219 }
3220 /* Stop translation as we may have switched the execution mode */
3221 ctx->bstate = BS_STOP;
3222 break;
3223 default:
3224 goto die;
3225 }
3226 #if defined MIPS_DEBUG_DISAS
3227 if (loglevel & CPU_LOG_TB_IN_ASM) {
3228 fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3229 rn, reg, sel);
3230 }
3231 #endif
3232 return;
3233
3234 die:
3235 #if defined MIPS_DEBUG_DISAS
3236 if (loglevel & CPU_LOG_TB_IN_ASM) {
3237 fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3238 rn, reg, sel);
3239 }
3240 #endif
3241 generate_exception(ctx, EXCP_RI);
3242 }
3243
3244 #if defined(TARGET_MIPS64)
3245 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3246 {
3247 const char *rn = "invalid";
3248
3249 if (sel != 0)
3250 check_insn(env, ctx, ISA_MIPS64);
3251
3252 switch (reg) {
3253 case 0:
3254 switch (sel) {
3255 case 0:
3256 gen_op_mfc0_index();
3257 rn = "Index";
3258 break;
3259 case 1:
3260 check_insn(env, ctx, ASE_MT);
3261 gen_op_mfc0_mvpcontrol();
3262 rn = "MVPControl";
3263 break;
3264 case 2:
3265 check_insn(env, ctx, ASE_MT);
3266 gen_op_mfc0_mvpconf0();
3267 rn = "MVPConf0";
3268 break;
3269 case 3:
3270 check_insn(env, ctx, ASE_MT);
3271 gen_op_mfc0_mvpconf1();
3272 rn = "MVPConf1";
3273 break;
3274 default:
3275 goto die;
3276 }
3277 break;
3278 case 1:
3279 switch (sel) {
3280 case 0:
3281 gen_op_mfc0_random();
3282 rn = "Random";
3283 break;
3284 case 1:
3285 check_insn(env, ctx, ASE_MT);
3286 gen_op_mfc0_vpecontrol();
3287 rn = "VPEControl";
3288 break;
3289 case 2:
3290 check_insn(env, ctx, ASE_MT);
3291 gen_op_mfc0_vpeconf0();
3292 rn = "VPEConf0";
3293 break;
3294 case 3:
3295 check_insn(env, ctx, ASE_MT);
3296 gen_op_mfc0_vpeconf1();
3297 rn = "VPEConf1";
3298 break;
3299 case 4:
3300 check_insn(env, ctx, ASE_MT);
3301 gen_op_dmfc0_yqmask();
3302 rn = "YQMask";
3303 break;
3304 case 5:
3305 check_insn(env, ctx, ASE_MT);
3306 gen_op_dmfc0_vpeschedule();
3307 rn = "VPESchedule";
3308 break;
3309 case 6:
3310 check_insn(env, ctx, ASE_MT);
3311 gen_op_dmfc0_vpeschefback();
3312 rn = "VPEScheFBack";
3313 break;
3314 case 7:
3315 check_insn(env, ctx, ASE_MT);
3316 gen_op_mfc0_vpeopt();
3317 rn = "VPEOpt";
3318 break;
3319 default:
3320 goto die;
3321 }
3322 break;
3323 case 2:
3324 switch (sel) {
3325 case 0:
3326 gen_op_dmfc0_entrylo0();
3327 rn = "EntryLo0";
3328 break;
3329 case 1:
3330 check_insn(env, ctx, ASE_MT);
3331 gen_op_mfc0_tcstatus();
3332 rn = "TCStatus";
3333 break;
3334 case 2:
3335 check_insn(env, ctx, ASE_MT);
3336 gen_op_mfc0_tcbind();
3337 rn = "TCBind";
3338 break;
3339 case 3:
3340 check_insn(env, ctx, ASE_MT);
3341 gen_op_dmfc0_tcrestart();
3342 rn = "TCRestart";
3343 break;
3344 case 4:
3345 check_insn(env, ctx, ASE_MT);
3346 gen_op_dmfc0_tchalt();
3347 rn = "TCHalt";
3348 break;
3349 case 5:
3350 check_insn(env, ctx, ASE_MT);
3351 gen_op_dmfc0_tccontext();
3352 rn = "TCContext";
3353 break;
3354 case 6:
3355 check_insn(env, ctx, ASE_MT);
3356 gen_op_dmfc0_tcschedule();
3357 rn = "TCSchedule";
3358 break;
3359 case 7:
3360 check_insn(env, ctx, ASE_MT);
3361 gen_op_dmfc0_tcschefback();
3362 rn = "TCScheFBack";
3363 break;
3364 default:
3365 goto die;
3366 }
3367 break;
3368 case 3:
3369 switch (sel) {
3370 case 0:
3371 gen_op_dmfc0_entrylo1();
3372 rn = "EntryLo1";
3373 break;
3374 default:
3375 goto die;
3376 }
3377 break;
3378 case 4:
3379 switch (sel) {
3380 case 0:
3381 gen_op_dmfc0_context();
3382 rn = "Context";
3383 break;
3384 case 1:
3385 // gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3386 rn = "ContextConfig";
3387 // break;
3388 default:
3389 goto die;
3390 }
3391 break;
3392 case 5:
3393 switch (sel) {
3394 case 0:
3395 gen_op_mfc0_pagemask();
3396 rn = "PageMask";
3397 break;
3398 case 1:
3399 check_insn(env, ctx, ISA_MIPS32R2);
3400 gen_op_mfc0_pagegrain();
3401 rn = "PageGrain";
3402 break;
3403 default:
3404 goto die;
3405 }
3406 break;
3407 case 6:
3408 switch (sel) {
3409 case 0:
3410 gen_op_mfc0_wired();
3411 rn = "Wired";
3412 break;
3413 case 1:
3414 check_insn(env, ctx, ISA_MIPS32R2);
3415 gen_op_mfc0_srsconf0();
3416 rn = "SRSConf0";
3417 break;
3418 case 2:
3419 check_insn(env, ctx, ISA_MIPS32R2);
3420 gen_op_mfc0_srsconf1();
3421 rn = "SRSConf1";
3422 break;
3423 case 3:
3424 check_insn(env, ctx, ISA_MIPS32R2);
3425 gen_op_mfc0_srsconf2();
3426 rn = "SRSConf2";
3427 break;
3428 case 4:
3429 check_insn(env, ctx, ISA_MIPS32R2);
3430 gen_op_mfc0_srsconf3();
3431 rn = "SRSConf3";
3432 break;
3433 case 5:
3434 check_insn(env, ctx, ISA_MIPS32R2);
3435 gen_op_mfc0_srsconf4();
3436 rn = "SRSConf4";
3437 break;
3438 default:
3439 goto die;
3440 }
3441 break;
3442 case 7:
3443 switch (sel) {
3444 case 0:
3445 check_insn(env, ctx, ISA_MIPS32R2);
3446 gen_op_mfc0_hwrena();
3447 rn = "HWREna";
3448 break;
3449 default:
3450 goto die;
3451 }
3452 break;
3453 case 8:
3454 switch (sel) {
3455 case 0:
3456 gen_op_dmfc0_badvaddr();
3457 rn = "BadVaddr";
3458 break;
3459 default:
3460 goto die;
3461 }
3462 break;
3463 case 9:
3464 switch (sel) {
3465 case 0:
3466 gen_op_mfc0_count();
3467 rn = "Count";
3468 break;
3469 /* 6,7 are implementation dependent */
3470 default:
3471 goto die;
3472 }
3473 break;
3474 case 10:
3475 switch (sel) {
3476 case 0:
3477 gen_op_dmfc0_entryhi();
3478 rn = "EntryHi";
3479 break;
3480 default:
3481 goto die;
3482 }
3483 break;
3484 case 11:
3485 switch (sel) {
3486 case 0:
3487 gen_op_mfc0_compare();
3488 rn = "Compare";
3489 break;
3490 /* 6,7 are implementation dependent */
3491 default:
3492 goto die;
3493 }
3494 break;
3495 case 12:
3496 switch (sel) {
3497 case 0:
3498 gen_op_mfc0_status();
3499 rn = "Status";
3500 break;
3501 case 1:
3502 check_insn(env, ctx, ISA_MIPS32R2);
3503 gen_op_mfc0_intctl();
3504 rn = "IntCtl";
3505 break;
3506 case 2:
3507 check_insn(env, ctx, ISA_MIPS32R2);
3508 gen_op_mfc0_srsctl();
3509 rn = "SRSCtl";
3510 break;
3511 case 3:
3512 check_insn(env, ctx, ISA_MIPS32R2);
3513 gen_op_mfc0_srsmap();
3514 rn = "SRSMap";
3515 break;
3516 default:
3517 goto die;
3518 }
3519 break;
3520 case 13:
3521 switch (sel) {
3522 case 0:
3523 gen_op_mfc0_cause();
3524 rn = "Cause";
3525 break;
3526 default:
3527 goto die;
3528 }
3529 break;
3530 case 14:
3531 switch (sel) {
3532 case 0:
3533 gen_op_dmfc0_epc();
3534 rn = "EPC";
3535 break;
3536 default:
3537 goto die;
3538 }
3539 break;
3540 case 15:
3541 switch (sel) {
3542 case 0:
3543 gen_op_mfc0_prid();
3544 rn = "PRid";
3545 break;
3546 case 1:
3547 check_insn(env, ctx, ISA_MIPS32R2);
3548 gen_op_mfc0_ebase();
3549 rn = "EBase";
3550 break;
3551 default:
3552 goto die;
3553 }
3554 break;
3555 case 16:
3556 switch (sel) {
3557 case 0:
3558 gen_op_mfc0_config0();
3559 rn = "Config";
3560 break;
3561 case 1:
3562 gen_op_mfc0_config1();
3563 rn = "Config1";
3564 break;
3565 case 2:
3566 gen_op_mfc0_config2();
3567 rn = "Config2";
3568 break;
3569 case 3:
3570 gen_op_mfc0_config3();
3571 rn = "Config3";
3572 break;
3573 /* 6,7 are implementation dependent */
3574 default:
3575 goto die;
3576 }
3577 break;
3578 case 17:
3579 switch (sel) {
3580 case 0:
3581 gen_op_dmfc0_lladdr();
3582 rn = "LLAddr";
3583 break;
3584 default:
3585 goto die;
3586 }
3587 break;
3588 case 18:
3589 switch (sel) {
3590 case 0 ... 7:
3591 gen_op_dmfc0_watchlo(sel);
3592 rn = "WatchLo";
3593 break;
3594 default:
3595 goto die;
3596 }
3597 break;
3598 case 19:
3599 switch (sel) {
3600 case 0 ... 7:
3601 gen_op_mfc0_watchhi(sel);
3602 rn = "WatchHi";
3603 break;
3604 default:
3605 goto die;
3606 }
3607 break;
3608 case 20:
3609 switch (sel) {
3610 case 0:
3611 check_insn(env, ctx, ISA_MIPS3);
3612 gen_op_dmfc0_xcontext();
3613 rn = "XContext";
3614 break;
3615 default:
3616 goto die;
3617 }
3618 break;
3619 case 21:
3620 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3621 switch (sel) {
3622 case 0:
3623 gen_op_mfc0_framemask();
3624 rn = "Framemask";
3625 break;
3626 default:
3627 goto die;
3628 }
3629 break;
3630 case 22:
3631 /* ignored */
3632 rn = "'Diagnostic"; /* implementation dependent */
3633 break;
3634 case 23:
3635 switch (sel) {
3636 case 0:
3637 gen_op_mfc0_debug(); /* EJTAG support */
3638 rn = "Debug";
3639 break;
3640 case 1:
3641 // gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3642 rn = "TraceControl";
3643 // break;
3644 case 2:
3645 // gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3646 rn = "TraceControl2";
3647 // break;
3648 case 3:
3649 // gen_op_dmfc0_usertracedata(); /* PDtrace support */
3650 rn = "UserTraceData";
3651 // break;
3652 case 4:
3653 // gen_op_dmfc0_debug(); /* PDtrace support */
3654 rn = "TraceBPC";
3655 // break;
3656 default:
3657 goto die;
3658 }
3659 break;
3660 case 24:
3661 switch (sel) {
3662 case 0:
3663 gen_op_dmfc0_depc(); /* EJTAG support */
3664 rn = "DEPC";
3665 break;
3666 default:
3667 goto die;
3668 }
3669 break;
3670 case 25:
3671 switch (sel) {
3672 case 0:
3673 gen_op_mfc0_performance0();
3674 rn = "Performance0";
3675 break;
3676 case 1:
3677 // gen_op_dmfc0_performance1();
3678 rn = "Performance1";
3679 // break;
3680 case 2:
3681 // gen_op_dmfc0_performance2();
3682 rn = "Performance2";
3683 // break;
3684 case 3:
3685 // gen_op_dmfc0_performance3();
3686 rn = "Performance3";
3687 // break;
3688 case 4:
3689 // gen_op_dmfc0_performance4();
3690 rn = "Performance4";
3691 // break;
3692 case 5:
3693 // gen_op_dmfc0_performance5();
3694 rn = "Performance5";
3695 // break;
3696 case 6:
3697 // gen_op_dmfc0_performance6();
3698 rn = "Performance6";
3699 // break;
3700 case 7:
3701 // gen_op_dmfc0_performance7();
3702 rn = "Performance7";
3703 // break;
3704 default:
3705 goto die;
3706 }
3707 break;
3708 case 26:
3709 rn = "ECC";
3710 break;
3711 case 27:
3712 switch (sel) {
3713 /* ignored */
3714 case 0 ... 3:
3715 rn = "CacheErr";
3716 break;
3717 default:
3718 goto die;
3719 }
3720 break;
3721 case 28:
3722 switch (sel) {
3723 case 0:
3724 case 2:
3725 case 4:
3726 case 6:
3727 gen_op_mfc0_taglo();
3728 rn = "TagLo";
3729 break;
3730 case 1:
3731 case 3:
3732 case 5:
3733 case 7:
3734 gen_op_mfc0_datalo();
3735 rn = "DataLo";
3736 break;
3737 default:
3738 goto die;
3739 }
3740 break;
3741 case 29:
3742 switch (sel) {
3743 case 0:
3744 case 2:
3745 case 4:
3746 case 6:
3747 gen_op_mfc0_taghi();
3748 rn = "TagHi";
3749 break;
3750 case 1:
3751 case 3:
3752 case 5:
3753 case 7:
3754 gen_op_mfc0_datahi();
3755 rn = "DataHi";
3756 break;
3757 default:
3758 goto die;
3759 }
3760 break;
3761 case 30:
3762 switch (sel) {
3763 case 0:
3764 gen_op_dmfc0_errorepc();
3765 rn = "ErrorEPC";
3766 break;
3767 default:
3768 goto die;
3769 }
3770 break;
3771 case 31:
3772 switch (sel) {
3773 case 0:
3774 gen_op_mfc0_desave(); /* EJTAG support */
3775 rn = "DESAVE";
3776 break;
3777 default:
3778 goto die;
3779 }
3780 break;
3781 default:
3782 goto die;
3783 }
3784 #if defined MIPS_DEBUG_DISAS
3785 if (loglevel & CPU_LOG_TB_IN_ASM) {
3786 fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3787 rn, reg, sel);
3788 }
3789 #endif
3790 return;
3791
3792 die:
3793 #if defined MIPS_DEBUG_DISAS
3794 if (loglevel & CPU_LOG_TB_IN_ASM) {
3795 fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3796 rn, reg, sel);
3797 }
3798 #endif
3799 generate_exception(ctx, EXCP_RI);
3800 }
3801
3802 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3803 {
3804 const char *rn = "invalid";
3805
3806 if (sel != 0)
3807 check_insn(env, ctx, ISA_MIPS64);
3808
3809 switch (reg) {
3810 case 0:
3811 switch (sel) {
3812 case 0:
3813 gen_op_mtc0_index();
3814 rn = "Index";
3815 break;
3816 case 1:
3817 check_insn(env, ctx, ASE_MT);
3818 gen_op_mtc0_mvpcontrol();
3819 rn = "MVPControl";
3820 break;
3821 case 2:
3822 check_insn(env, ctx, ASE_MT);
3823 /* ignored */
3824 rn = "MVPConf0";
3825 break;
3826 case 3:
3827 check_insn(env, ctx, ASE_MT);
3828 /* ignored */
3829 rn = "MVPConf1";
3830 break;
3831 default:
3832 goto die;
3833 }
3834 break;
3835 case 1:
3836 switch (sel) {
3837 case 0:
3838 /* ignored */
3839 rn = "Random";
3840 break;
3841 case 1:
3842 check_insn(env, ctx, ASE_MT);
3843 gen_op_mtc0_vpecontrol();
3844 rn = "VPEControl";
3845 break;
3846 case 2:
3847 check_insn(env, ctx, ASE_MT);
3848 gen_op_mtc0_vpeconf0();
3849 rn = "VPEConf0";
3850 break;
3851 case 3:
3852 check_insn(env, ctx, ASE_MT);
3853 gen_op_mtc0_vpeconf1();
3854 rn = "VPEConf1";
3855 break;
3856 case 4:
3857 check_insn(env, ctx, ASE_MT);
3858 gen_op_mtc0_yqmask();
3859 rn = "YQMask";
3860 break;
3861 case 5:
3862 check_insn(env, ctx, ASE_MT);
3863 gen_op_mtc0_vpeschedule();
3864 rn = "VPESchedule";
3865 break;
3866 case 6:
3867 check_insn(env, ctx, ASE_MT);
3868 gen_op_mtc0_vpeschefback();
3869 rn = "VPEScheFBack";
3870 break;
3871 case 7:
3872 check_insn(env, ctx, ASE_MT);
3873 gen_op_mtc0_vpeopt();
3874 rn = "VPEOpt";
3875 break;
3876 default:
3877 goto die;
3878 }
3879 break;
3880 case 2:
3881 switch (sel) {
3882 case 0:
3883 gen_op_mtc0_entrylo0();
3884 rn = "EntryLo0";
3885 break;
3886 case 1:
3887 check_insn(env, ctx, ASE_MT);
3888 gen_op_mtc0_tcstatus();
3889 rn = "TCStatus";
3890 break;
3891 case 2:
3892 check_insn(env, ctx, ASE_MT);
3893 gen_op_mtc0_tcbind();
3894 rn = "TCBind";
3895 break;
3896 case 3:
3897 check_insn(env, ctx, ASE_MT);
3898 gen_op_mtc0_tcrestart();
3899 rn = "TCRestart";
3900 break;
3901 case 4:
3902 check_insn(env, ctx, ASE_MT);
3903 gen_op_mtc0_tchalt();
3904 rn = "TCHalt";
3905 break;
3906 case 5:
3907 check_insn(env, ctx, ASE_MT);
3908 gen_op_mtc0_tccontext();
3909 rn = "TCContext";
3910 break;
3911 case 6:
3912 check_insn(env, ctx, ASE_MT);
3913 gen_op_mtc0_tcschedule();
3914 rn = "TCSchedule";
3915 break;
3916 case 7:
3917 check_insn(env, ctx, ASE_MT);
3918 gen_op_mtc0_tcschefback();
3919 rn = "TCScheFBack";
3920 break;
3921 default:
3922 goto die;
3923 }
3924 break;
3925 case 3:
3926 switch (sel) {
3927 case 0:
3928 gen_op_mtc0_entrylo1();
3929 rn = "EntryLo1";
3930 break;
3931 default:
3932 goto die;
3933 }
3934 break;
3935 case 4:
3936 switch (sel) {
3937 case 0:
3938 gen_op_mtc0_context();
3939 rn = "Context";
3940 break;
3941 case 1:
3942 // gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3943 rn = "ContextConfig";
3944 // break;
3945 default:
3946 goto die;
3947 }
3948 break;
3949 case 5:
3950 switch (sel) {
3951 case 0:
3952 gen_op_mtc0_pagemask();
3953 rn = "PageMask";
3954 break;
3955 case 1:
3956 check_insn(env, ctx, ISA_MIPS32R2);
3957 gen_op_mtc0_pagegrain();
3958 rn = "PageGrain";
3959 break;
3960 default:
3961 goto die;
3962 }
3963 break;
3964 case 6:
3965 switch (sel) {
3966 case 0:
3967 gen_op_mtc0_wired();
3968 rn = "Wired";
3969 break;
3970 case 1:
3971 check_insn(env, ctx, ISA_MIPS32R2);
3972 gen_op_mtc0_srsconf0();
3973 rn = "SRSConf0";
3974 break;
3975 case 2:
3976 check_insn(env, ctx, ISA_MIPS32R2);
3977 gen_op_mtc0_srsconf1();
3978 rn = "SRSConf1";
3979 break;
3980 case 3:
3981 check_insn(env, ctx, ISA_MIPS32R2);
3982 gen_op_mtc0_srsconf2();
3983 rn = "SRSConf2";
3984 break;
3985 case 4:
3986 check_insn(env, ctx, ISA_MIPS32R2);
3987 gen_op_mtc0_srsconf3();
3988 rn = "SRSConf3";
3989 break;
3990 case 5:
3991 check_insn(env, ctx, ISA_MIPS32R2);
3992 gen_op_mtc0_srsconf4();
3993 rn = "SRSConf4";
3994 break;
3995 default:
3996 goto die;
3997 }
3998 break;
3999 case 7:
4000 switch (sel) {
4001 case 0:
4002 check_insn(env, ctx, ISA_MIPS32R2);
4003 gen_op_mtc0_hwrena();
4004 rn = "HWREna";
4005 break;
4006 default:
4007 goto die;
4008 }
4009 break;
4010 case 8:
4011 /* ignored */
4012 rn = "BadVaddr";
4013 break;
4014 case 9:
4015 switch (sel) {
4016 case 0:
4017 gen_op_mtc0_count();
4018 rn = "Count";
4019 break;
4020 /* 6,7 are implementation dependent */
4021 default:
4022 goto die;
4023 }
4024 /* Stop translation as we may have switched the execution mode */
4025 ctx->bstate = BS_STOP;
4026 break;
4027 case 10:
4028 switch (sel) {
4029 case 0:
4030 gen_op_mtc0_entryhi();
4031 rn = "EntryHi";
4032 break;
4033 default:
4034 goto die;
4035 }
4036 break;
4037 case 11:
4038 switch (sel) {
4039 case 0:
4040 gen_op_mtc0_compare();
4041 rn = "Compare";
4042 break;
4043 /* 6,7 are implementation dependent */
4044 default:
4045 goto die;
4046 }
4047 /* Stop translation as we may have switched the execution mode */
4048 ctx->bstate = BS_STOP;
4049 break;
4050 case 12:
4051 switch (sel) {
4052 case 0:
4053 gen_op_mtc0_status();
4054 /* BS_STOP isn't good enough here, hflags may have changed. */
4055 gen_save_pc(ctx->pc + 4);
4056 ctx->bstate = BS_EXCP;
4057 rn = "Status";
4058 break;
4059 case 1:
4060 check_insn(env, ctx, ISA_MIPS32R2);
4061 gen_op_mtc0_intctl();
4062 /* Stop translation as we may have switched the execution mode */
4063 ctx->bstate = BS_STOP;
4064 rn = "IntCtl";
4065 break;
4066 case 2:
4067 check_insn(env, ctx, ISA_MIPS32R2);
4068 gen_op_mtc0_srsctl();
4069 /* Stop translation as we may have switched the execution mode */
4070 ctx->bstate = BS_STOP;
4071 rn = "SRSCtl";
4072 break;
4073 case 3:
4074 check_insn(env, ctx, ISA_MIPS32R2);
4075 gen_op_mtc0_srsmap();
4076 /* Stop translation as we may have switched the execution mode */
4077 ctx->bstate = BS_STOP;
4078 rn = "SRSMap";
4079 break;
4080 default:
4081 goto die;
4082 }
4083 break;
4084 case 13:
4085 switch (sel) {
4086 case 0:
4087 gen_op_mtc0_cause();
4088 rn = "Cause";
4089 break;
4090 default:
4091 goto die;
4092 }
4093 /* Stop translation as we may have switched the execution mode */
4094 ctx->bstate = BS_STOP;
4095 break;
4096 case 14:
4097 switch (sel) {
4098 case 0:
4099 gen_op_mtc0_epc();
4100 rn = "EPC";
4101 break;
4102 default:
4103 goto die;
4104 }
4105 break;
4106 case 15:
4107 switch (sel) {
4108 case 0:
4109 /* ignored */
4110 rn = "PRid";
4111 break;
4112 case 1:
4113 check_insn(env, ctx, ISA_MIPS32R2);
4114 gen_op_mtc0_ebase();
4115 rn = "EBase";
4116 break;
4117 default:
4118 goto die;
4119 }
4120 break;
4121 case 16:
4122 switch (sel) {
4123 case 0:
4124 gen_op_mtc0_config0();
4125 rn = "Config";
4126 /* Stop translation as we may have switched the execution mode */
4127 ctx->bstate = BS_STOP;
4128 break;
4129 case 1:
4130 /* ignored */
4131 rn = "Config1";
4132 break;
4133 case 2:
4134 gen_op_mtc0_config2();
4135 rn = "Config2";
4136 /* Stop translation as we may have switched the execution mode */
4137 ctx->bstate = BS_STOP;
4138 break;
4139 case 3:
4140 /* ignored */
4141 rn = "Config3";
4142 break;
4143 /* 6,7 are implementation dependent */
4144 default:
4145 rn = "Invalid config selector";
4146 goto die;
4147 }
4148 break;
4149 case 17:
4150 switch (sel) {
4151 case 0:
4152 /* ignored */
4153 rn = "LLAddr";
4154 break;
4155 default:
4156 goto die;
4157 }
4158 break;
4159 case 18:
4160 switch (sel) {
4161 case 0 ... 7:
4162 gen_op_mtc0_watchlo(sel);
4163 rn = "WatchLo";
4164 break;
4165 default:
4166 goto die;
4167 }
4168 break;
4169 case 19:
4170 switch (sel) {
4171 case 0 ... 7:
4172 gen_op_mtc0_watchhi(sel);
4173 rn = "WatchHi";
4174 break;
4175 default:
4176 goto die;
4177 }
4178 break;
4179 case 20:
4180 switch (sel) {
4181 case 0:
4182 check_insn(env, ctx, ISA_MIPS3);
4183 gen_op_mtc0_xcontext();
4184 rn = "XContext";
4185 break;
4186 default:
4187 goto die;
4188 }
4189 break;
4190 case 21:
4191 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4192 switch (sel) {
4193 case 0:
4194 gen_op_mtc0_framemask();
4195 rn = "Framemask";
4196 break;
4197 default:
4198 goto die;
4199 }
4200 break;
4201 case 22:
4202 /* ignored */
4203 rn = "Diagnostic"; /* implementation dependent */
4204 break;
4205 case 23:
4206 switch (sel) {
4207 case 0:
4208 gen_op_mtc0_debug(); /* EJTAG support */
4209 /* BS_STOP isn't good enough here, hflags may have changed. */
4210 gen_save_pc(ctx->pc + 4);
4211 ctx->bstate = BS_EXCP;
4212 rn = "Debug";
4213 break;
4214 case 1:
4215 // gen_op_mtc0_tracecontrol(); /* PDtrace support */
4216 /* Stop translation as we may have switched the execution mode */
4217 ctx->bstate = BS_STOP;
4218 rn = "TraceControl";
4219 // break;
4220 case 2:
4221 // gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4222 /* Stop translation as we may have switched the execution mode */
4223 ctx->bstate = BS_STOP;
4224 rn = "TraceControl2";
4225 // break;
4226 case 3:
4227 // gen_op_mtc0_usertracedata(); /* PDtrace support */
4228 /* Stop translation as we may have switched the execution mode */
4229 ctx->bstate = BS_STOP;
4230 rn = "UserTraceData";
4231 // break;
4232 case 4:
4233 // gen_op_mtc0_debug(); /* PDtrace support */
4234 /* Stop translation as we may have switched the execution mode */
4235 ctx->bstate = BS_STOP;
4236 rn = "TraceBPC";
4237 // break;
4238 default:
4239 goto die;
4240 }
4241 break;
4242 case 24:
4243 switch (sel) {
4244 case 0:
4245 gen_op_mtc0_depc(); /* EJTAG support */
4246 rn = "DEPC";
4247 break;
4248 default:
4249 goto die;
4250 }
4251 break;
4252 case 25:
4253 switch (sel) {
4254 case 0:
4255 gen_op_mtc0_performance0();
4256 rn = "Performance0";
4257 break;
4258 case 1:
4259 // gen_op_mtc0_performance1();
4260 rn = "Performance1";
4261 // break;
4262 case 2:
4263 // gen_op_mtc0_performance2();
4264 rn = "Performance2";
4265 // break;
4266 case 3:
4267 // gen_op_mtc0_performance3();
4268 rn = "Performance3";
4269 // break;
4270 case 4:
4271 // gen_op_mtc0_performance4();
4272 rn = "Performance4";
4273 // break;
4274 case 5:
4275 // gen_op_mtc0_performance5();
4276 rn = "Performance5";
4277 // break;
4278 case 6:
4279 // gen_op_mtc0_performance6();
4280 rn = "Performance6";
4281 // break;
4282 case 7:
4283 // gen_op_mtc0_performance7();
4284 rn = "Performance7";
4285 // break;
4286 default:
4287 goto die;
4288 }
4289 break;
4290 case 26:
4291 /* ignored */
4292 rn = "ECC";
4293 break;
4294 case 27:
4295 switch (sel) {
4296 case 0 ... 3:
4297 /* ignored */
4298 rn = "CacheErr";
4299 break;
4300 default:
4301 goto die;
4302 }
4303 break;
4304 case 28:
4305 switch (sel) {
4306 case 0:
4307 case 2:
4308 case 4:
4309 case 6:
4310 gen_op_mtc0_taglo();
4311 rn = "TagLo";
4312 break;
4313 case 1:
4314 case 3:
4315 case 5:
4316 case 7:
4317 gen_op_mtc0_datalo();
4318 rn = "DataLo";
4319 break;
4320 default:
4321 goto die;
4322 }
4323 break;
4324 case 29:
4325 switch (sel) {
4326 case 0:
4327 case 2:
4328 case 4:
4329 case 6:
4330 gen_op_mtc0_taghi();
4331 rn = "TagHi";
4332 break;
4333 case 1:
4334 case 3:
4335 case 5:
4336 case 7:
4337 gen_op_mtc0_datahi();
4338 rn = "DataHi";
4339 break;
4340 default:
4341 rn = "invalid sel";
4342 goto die;
4343 }
4344 break;
4345 case 30:
4346 switch (sel) {
4347 case 0:
4348 gen_op_mtc0_errorepc();
4349 rn = "ErrorEPC";
4350 break;
4351 default:
4352 goto die;
4353 }
4354 break;
4355 case 31:
4356 switch (sel) {
4357 case 0:
4358 gen_op_mtc0_desave(); /* EJTAG support */
4359 rn = "DESAVE";
4360 break;
4361 default:
4362 goto die;
4363 }
4364 /* Stop translation as we may have switched the execution mode */
4365 ctx->bstate = BS_STOP;
4366 break;
4367 default:
4368 goto die;
4369 }
4370 #if defined MIPS_DEBUG_DISAS
4371 if (loglevel & CPU_LOG_TB_IN_ASM) {
4372 fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4373 rn, reg, sel);
4374 }
4375 #endif
4376 return;
4377
4378 die:
4379 #if defined MIPS_DEBUG_DISAS
4380 if (loglevel & CPU_LOG_TB_IN_ASM) {
4381 fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4382 rn, reg, sel);
4383 }
4384 #endif
4385 generate_exception(ctx, EXCP_RI);
4386 }
4387 #endif /* TARGET_MIPS64 */
4388
4389 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4390 int u, int sel, int h)
4391 {
4392 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4393
4394 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4395 ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4396 (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4397 gen_op_set_T0(-1);
4398 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4399 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4400 gen_op_set_T0(-1);
4401 else if (u == 0) {
4402 switch (rt) {
4403 case 2:
4404 switch (sel) {
4405 case 1:
4406 gen_op_mftc0_tcstatus();
4407 break;
4408 case 2:
4409 gen_op_mftc0_tcbind();
4410 break;
4411 case 3:
4412 gen_op_mftc0_tcrestart();
4413 break;
4414 case 4:
4415 gen_op_mftc0_tchalt();
4416 break;
4417 case 5:
4418 gen_op_mftc0_tccontext();
4419 break;
4420 case 6:
4421 gen_op_mftc0_tcschedule();
4422 break;
4423 case 7:
4424 gen_op_mftc0_tcschefback();
4425 break;
4426 default:
4427 gen_mfc0(env, ctx, rt, sel);
4428 break;
4429 }
4430 break;
4431 case 10:
4432 switch (sel) {
4433 case 0:
4434 gen_op_mftc0_entryhi();
4435 break;
4436 default:
4437 gen_mfc0(env, ctx, rt, sel);
4438 break;
4439 }
4440 case 12:
4441 switch (sel) {
4442 case 0:
4443 gen_op_mftc0_status();
4444 break;
4445 default:
4446 gen_mfc0(env, ctx, rt, sel);
4447 break;
4448 }
4449 case 23:
4450 switch (sel) {
4451 case 0:
4452 gen_op_mftc0_debug();
4453 break;
4454 default:
4455 gen_mfc0(env, ctx, rt, sel);
4456 break;
4457 }
4458 break;
4459 default:
4460 gen_mfc0(env, ctx, rt, sel);
4461 }
4462 } else switch (sel) {
4463 /* GPR registers. */
4464 case 0:
4465 gen_op_mftgpr(rt);
4466 break;
4467 /* Auxiliary CPU registers */
4468 case 1:
4469 switch (rt) {
4470 case 0:
4471 gen_op_mftlo(0);
4472 break;
4473 case 1:
4474 gen_op_mfthi(0);
4475 break;
4476 case 2:
4477 gen_op_mftacx(0);
4478 break;
4479 case 4:
4480 gen_op_mftlo(1);
4481 break;
4482 case 5:
4483 gen_op_mfthi(1);
4484 break;
4485 case 6:
4486 gen_op_mftacx(1);
4487 break;
4488 case 8:
4489 gen_op_mftlo(2);
4490 break;
4491 case 9:
4492 gen_op_mfthi(2);
4493 break;
4494 case 10:
4495 gen_op_mftacx(2);
4496 break;
4497 case 12:
4498 gen_op_mftlo(3);
4499 break;
4500 case 13:
4501 gen_op_mfthi(3);
4502 break;
4503 case 14:
4504 gen_op_mftacx(3);
4505 break;
4506 case 16:
4507 gen_op_mftdsp();
4508 break;
4509 default:
4510 goto die;
4511 }
4512 break;
4513 /* Floating point (COP1). */
4514 case 2:
4515 /* XXX: For now we support only a single FPU context. */
4516 if (h == 0) {
4517 GEN_LOAD_FREG_FTN(WT0, rt);
4518 gen_op_mfc1();
4519 } else {
4520 GEN_LOAD_FREG_FTN(WTH0, rt);
4521 gen_op_mfhc1();
4522 }
4523 break;
4524 case 3:
4525 /* XXX: For now we support only a single FPU context. */
4526 gen_op_cfc1(rt);
4527 break;
4528 /* COP2: Not implemented. */
4529 case 4:
4530 case 5:
4531 /* fall through */
4532 default:
4533 goto die;
4534 }
4535 #if defined MIPS_DEBUG_DISAS
4536 if (loglevel & CPU_LOG_TB_IN_ASM) {
4537 fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4538 rt, u, sel, h);
4539 }
4540 #endif
4541 return;
4542
4543 die:
4544 #if defined MIPS_DEBUG_DISAS
4545 if (loglevel & CPU_LOG_TB_IN_ASM) {
4546 fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4547 rt, u, sel, h);
4548 }
4549 #endif
4550 generate_exception(ctx, EXCP_RI);
4551 }
4552
4553 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4554 int u, int sel, int h)
4555 {
4556 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4557
4558 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4559 ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4560 (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4561 /* NOP */ ;
4562 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4563 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4564 /* NOP */ ;
4565 else if (u == 0) {
4566 switch (rd) {
4567 case 2:
4568 switch (sel) {
4569 case 1:
4570 gen_op_mttc0_tcstatus();
4571 break;
4572 case 2:
4573 gen_op_mttc0_tcbind();
4574 break;
4575 case 3:
4576 gen_op_mttc0_tcrestart();
4577 break;
4578 case 4:
4579 gen_op_mttc0_tchalt();
4580 break;
4581 case 5:
4582 gen_op_mttc0_tccontext();
4583 break;
4584 case 6:
4585 gen_op_mttc0_tcschedule();
4586 break;
4587 case 7:
4588 gen_op_mttc0_tcschefback();
4589 break;
4590 default:
4591 gen_mtc0(env, ctx, rd, sel);
4592 break;
4593 }
4594 break;
4595 case 10:
4596 switch (sel) {
4597 case 0:
4598 gen_op_mttc0_entryhi();
4599 break;
4600 default:
4601 gen_mtc0(env, ctx, rd, sel);
4602 break;
4603 }
4604 case 12:
4605 switch (sel) {
4606 case 0:
4607 gen_op_mttc0_status();
4608 break;
4609 default:
4610 gen_mtc0(env, ctx, rd, sel);
4611 break;
4612 }
4613 case 23:
4614 switch (sel) {
4615 case 0:
4616 gen_op_mttc0_debug();
4617 break;
4618 default:
4619 gen_mtc0(env, ctx, rd, sel);
4620 break;
4621 }
4622 break;
4623 default:
4624 gen_mtc0(env, ctx, rd, sel);
4625 }
4626 } else switch (sel) {
4627 /* GPR registers. */
4628 case 0:
4629 gen_op_mttgpr(rd);
4630 break;
4631 /* Auxiliary CPU registers */
4632 case 1:
4633 switch (rd) {
4634 case 0:
4635 gen_op_mttlo(0);
4636 break;
4637 case 1:
4638 gen_op_mtthi(0);
4639 break;
4640 case 2:
4641 gen_op_mttacx(0);
4642 break;
4643 case 4:
4644 gen_op_mttlo(1);
4645 break;
4646 case 5:
4647 gen_op_mtthi(1);
4648 break;
4649 case 6:
4650 gen_op_mttacx(1);
4651 break;
4652 case 8:
4653 gen_op_mttlo(2);
4654 break;
4655 case 9:
4656 gen_op_mtthi(2);
4657 break;
4658 case 10:
4659 gen_op_mttacx(2);
4660 break;
4661 case 12:
4662 gen_op_mttlo(3);
4663 break;
4664 case 13:
4665 gen_op_mtthi(3);
4666 break;
4667 case 14:
4668 gen_op_mttacx(3);
4669 break;
4670 case 16:
4671 gen_op_mttdsp();
4672 break;
4673 default:
4674 goto die;
4675 }
4676 break;
4677 /* Floating point (COP1). */
4678 case 2:
4679 /* XXX: For now we support only a single FPU context. */
4680 if (h == 0) {
4681 gen_op_mtc1();
4682 GEN_STORE_FTN_FREG(rd, WT0);
4683 } else {
4684 gen_op_mthc1();
4685 GEN_STORE_FTN_FREG(rd, WTH0);
4686 }
4687 break;
4688 case 3:
4689 /* XXX: For now we support only a single FPU context. */
4690 gen_op_ctc1(rd);
4691 break;
4692 /* COP2: Not implemented. */
4693 case 4:
4694 case 5:
4695 /* fall through */
4696 default:
4697 goto die;
4698 }
4699 #if defined MIPS_DEBUG_DISAS
4700 if (loglevel & CPU_LOG_TB_IN_ASM) {
4701 fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4702 rd, u, sel, h);
4703 }
4704 #endif
4705 return;
4706
4707 die:
4708 #if defined MIPS_DEBUG_DISAS
4709 if (loglevel & CPU_LOG_TB_IN_ASM) {
4710 fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4711 rd, u, sel, h);
4712 }
4713 #endif
4714 generate_exception(ctx, EXCP_RI);
4715 }
4716
4717 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4718 {
4719 const char *opn = "ldst";
4720
4721 switch (opc) {
4722 case OPC_MFC0:
4723 if (rt == 0) {
4724 /* Treat as NOP. */
4725 return;
4726 }
4727 gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4728 gen_op_store_T0_gpr(rt);
4729 opn = "mfc0";
4730 break;
4731 case OPC_MTC0:
4732 GEN_LOAD_REG_T0(rt);
4733 save_cpu_state(ctx, 1);
4734 gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4735 opn = "mtc0";
4736 break;
4737 #if defined(TARGET_MIPS64)
4738 case OPC_DMFC0:
4739 check_insn(env, ctx, ISA_MIPS3);
4740 if (rt == 0) {
4741 /* Treat as NOP. */
4742 return;
4743 }
4744 gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4745 gen_op_store_T0_gpr(rt);
4746 opn = "dmfc0";
4747 break;
4748 case OPC_DMTC0:
4749 check_insn(env, ctx, ISA_MIPS3);
4750 GEN_LOAD_REG_T0(rt);
4751 save_cpu_state(ctx, 1);
4752 gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4753 opn = "dmtc0";
4754 break;
4755 #endif
4756 case OPC_MFTR:
4757 check_insn(env, ctx, ASE_MT);
4758 if (rd == 0) {
4759 /* Treat as NOP. */
4760 return;
4761 }
4762 gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4763 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4764 gen_op_store_T0_gpr(rd);
4765 opn = "mftr";
4766 break;
4767 case OPC_MTTR:
4768 check_insn(env, ctx, ASE_MT);
4769 GEN_LOAD_REG_T0(rt);
4770 gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4771 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4772 opn = "mttr";
4773 break;
4774 case OPC_TLBWI:
4775 opn = "tlbwi";
4776 if (!env->tlb->do_tlbwi)
4777 goto die;
4778 gen_op_tlbwi();
4779 break;
4780 case OPC_TLBWR:
4781 opn = "tlbwr";
4782 if (!env->tlb->do_tlbwr)
4783 goto die;
4784 gen_op_tlbwr();
4785 break;
4786 case OPC_TLBP:
4787 opn = "tlbp";
4788 if (!env->tlb->do_tlbp)
4789 goto die;
4790 gen_op_tlbp();
4791 break;
4792 case OPC_TLBR:
4793 opn = "tlbr";
4794 if (!env->tlb->do_tlbr)
4795 goto die;
4796 gen_op_tlbr();
4797 break;
4798 case OPC_ERET:
4799 opn = "eret";
4800 check_insn(env, ctx, ISA_MIPS2);
4801 save_cpu_state(ctx, 1);
4802 gen_op_eret();
4803 ctx->bstate = BS_EXCP;
4804 break;
4805 case OPC_DERET:
4806 opn = "deret";
4807 check_insn(env, ctx, ISA_MIPS32);
4808 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4809 MIPS_INVAL(opn);
4810 generate_exception(ctx, EXCP_RI);
4811 } else {
4812 save_cpu_state(ctx, 1);
4813 gen_op_deret();
4814 ctx->bstate = BS_EXCP;
4815 }
4816 break;
4817 case OPC_WAIT:
4818 opn = "wait";
4819 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4820 /* If we get an exception, we want to restart at next instruction */
4821 ctx->pc += 4;
4822 save_cpu_state(ctx, 1);
4823 ctx->pc -= 4;
4824 gen_op_wait();
4825 ctx->bstate = BS_EXCP;
4826 break;
4827 default:
4828 die:
4829 MIPS_INVAL(opn);
4830 generate_exception(ctx, EXCP_RI);
4831 return;
4832 }
4833 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4834 }
4835
4836 /* CP1 Branches (before delay slot) */
4837 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4838 int32_t cc, int32_t offset)
4839 {
4840 target_ulong btarget;
4841 const char *opn = "cp1 cond branch";
4842
4843 if (cc != 0)
4844 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
4845
4846 btarget = ctx->pc + 4 + offset;
4847
4848 switch (op) {
4849 case OPC_BC1F:
4850 gen_op_bc1f(cc);
4851 opn = "bc1f";
4852 goto not_likely;
4853 case OPC_BC1FL:
4854 gen_op_bc1f(cc);
4855 opn = "bc1fl";
4856 goto likely;
4857 case OPC_BC1T:
4858 gen_op_bc1t(cc);
4859 opn = "bc1t";
4860 goto not_likely;
4861 case OPC_BC1TL:
4862 gen_op_bc1t(cc);
4863 opn = "bc1tl";
4864 likely:
4865 ctx->hflags |= MIPS_HFLAG_BL;
4866 gen_op_set_bcond();
4867 gen_op_save_bcond();
4868 break;
4869 case OPC_BC1FANY2:
4870 gen_op_bc1any2f(cc);
4871 opn = "bc1any2f";
4872 goto not_likely;
4873 case OPC_BC1TANY2:
4874 gen_op_bc1any2t(cc);
4875 opn = "bc1any2t";
4876 goto not_likely;
4877 case OPC_BC1FANY4:
4878 gen_op_bc1any4f(cc);
4879 opn = "bc1any4f";
4880 goto not_likely;
4881 case OPC_BC1TANY4:
4882 gen_op_bc1any4t(cc);
4883 opn = "bc1any4t";
4884 not_likely:
4885 ctx->hflags |= MIPS_HFLAG_BC;
4886 gen_op_set_bcond();
4887 break;
4888 default:
4889 MIPS_INVAL(opn);
4890 generate_exception (ctx, EXCP_RI);
4891 return;
4892 }
4893 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4894 ctx->hflags, btarget);
4895 ctx->btarget = btarget;
4896 }
4897
4898 /* Coprocessor 1 (FPU) */
4899
4900 #define FOP(func, fmt) (((fmt) << 21) | (func))
4901
4902 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4903 {
4904 const char *opn = "cp1 move";
4905
4906 switch (opc) {
4907 case OPC_MFC1:
4908 GEN_LOAD_FREG_FTN(WT0, fs);
4909 gen_op_mfc1();
4910 GEN_STORE_T0_REG(rt);
4911 opn = "mfc1";
4912 break;
4913 case OPC_MTC1:
4914 GEN_LOAD_REG_T0(rt);
4915 gen_op_mtc1();
4916 GEN_STORE_FTN_FREG(fs, WT0);
4917 opn = "mtc1";
4918 break;
4919 case OPC_CFC1:
4920 gen_op_cfc1(fs);
4921 GEN_STORE_T0_REG(rt);
4922 opn = "cfc1";
4923 break;
4924 case OPC_CTC1:
4925 GEN_LOAD_REG_T0(rt);
4926 gen_op_ctc1(fs);
4927 opn = "ctc1";
4928 break;
4929 case OPC_DMFC1:
4930 GEN_LOAD_FREG_FTN(DT0, fs);
4931 gen_op_dmfc1();
4932 GEN_STORE_T0_REG(rt);
4933 opn = "dmfc1";
4934 break;
4935 case OPC_DMTC1:
4936 GEN_LOAD_REG_T0(rt);
4937 gen_op_dmtc1();
4938 GEN_STORE_FTN_FREG(fs, DT0);
4939 opn = "dmtc1";
4940 break;
4941 case OPC_MFHC1:
4942 GEN_LOAD_FREG_FTN(WTH0, fs);
4943 gen_op_mfhc1();
4944 GEN_STORE_T0_REG(rt);
4945 opn = "mfhc1";
4946 break;
4947 case OPC_MTHC1:
4948 GEN_LOAD_REG_T0(rt);
4949 gen_op_mthc1();
4950 GEN_STORE_FTN_FREG(fs, WTH0);
4951 opn = "mthc1";
4952 break;
4953 default:
4954 MIPS_INVAL(opn);
4955 generate_exception (ctx, EXCP_RI);
4956 return;
4957 }
4958 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4959 }
4960
4961 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4962 {
4963 uint32_t ccbit;
4964
4965 GEN_LOAD_REG_T0(rd);
4966 GEN_LOAD_REG_T1(rs);
4967 if (cc) {
4968 ccbit = 1 << (24 + cc);
4969 } else
4970 ccbit = 1 << 23;
4971 if (!tf)
4972 gen_op_movf(ccbit);
4973 else
4974 gen_op_movt(ccbit);
4975 GEN_STORE_T0_REG(rd);
4976 }
4977
4978 #define GEN_MOVCF(fmt) \
4979 static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4980 { \
4981 uint32_t ccbit; \
4982 \
4983 if (cc) { \
4984 ccbit = 1 << (24 + cc); \
4985 } else \
4986 ccbit = 1 << 23; \
4987 if (!tf) \
4988 glue(gen_op_float_movf_, fmt)(ccbit); \
4989 else \
4990 glue(gen_op_float_movt_, fmt)(ccbit); \
4991 }
4992 GEN_MOVCF(d);
4993 GEN_MOVCF(s);
4994 GEN_MOVCF(ps);
4995 #undef GEN_MOVCF
4996
4997 static void gen_farith (DisasContext *ctx, uint32_t op1,
4998 int ft, int fs, int fd, int cc)
4999 {
5000 const char *opn = "farith";
5001 const char *condnames[] = {
5002 "c.f",
5003 "c.un",
5004 "c.eq",
5005 "c.ueq",
5006 "c.olt",
5007 "c.ult",
5008 "c.ole",
5009 "c.ule",
5010 "c.sf",
5011 "c.ngle",
5012 "c.seq",
5013 "c.ngl",
5014 "c.lt",
5015 "c.nge",
5016 "c.le",
5017 "c.ngt",
5018 };
5019 const char *condnames_abs[] = {
5020 "cabs.f",
5021 "cabs.un",
5022 "cabs.eq",
5023 "cabs.ueq",
5024 "cabs.olt",
5025 "cabs.ult",
5026 "cabs.ole",
5027 "cabs.ule",
5028 "cabs.sf",
5029 "cabs.ngle",
5030 "cabs.seq",
5031 "cabs.ngl",
5032 "cabs.lt",
5033 "cabs.nge",
5034 "cabs.le",
5035 "cabs.ngt",
5036 };
5037 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5038 uint32_t func = ctx->opcode & 0x3f;
5039
5040 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5041 case FOP(0, 16):
5042 GEN_LOAD_FREG_FTN(WT0, fs);
5043 GEN_LOAD_FREG_FTN(WT1, ft);
5044 gen_op_float_add_s();
5045 GEN_STORE_FTN_FREG(fd, WT2);
5046 opn = "add.s";
5047 optype = BINOP;
5048 break;
5049 case FOP(1, 16):
5050 GEN_LOAD_FREG_FTN(WT0, fs);
5051 GEN_LOAD_FREG_FTN(WT1, ft);
5052 gen_op_float_sub_s();
5053 GEN_STORE_FTN_FREG(fd, WT2);
5054 opn = "sub.s";
5055 optype = BINOP;
5056 break;
5057 case FOP(2, 16):
5058 GEN_LOAD_FREG_FTN(WT0, fs);
5059 GEN_LOAD_FREG_FTN(WT1, ft);
5060 gen_op_float_mul_s();
5061 GEN_STORE_FTN_FREG(fd, WT2);
5062 opn = "mul.s";
5063 optype = BINOP;
5064 break;
5065 case FOP(3, 16):
5066 GEN_LOAD_FREG_FTN(WT0, fs);
5067 GEN_LOAD_FREG_FTN(WT1, ft);
5068 gen_op_float_div_s();
5069 GEN_STORE_FTN_FREG(fd, WT2);
5070 opn = "div.s";
5071 optype = BINOP;
5072 break;
5073 case FOP(4, 16):
5074 GEN_LOAD_FREG_FTN(WT0, fs);
5075 gen_op_float_sqrt_s();
5076 GEN_STORE_FTN_FREG(fd, WT2);
5077 opn = "sqrt.s";
5078 break;
5079 case FOP(5, 16):
5080 GEN_LOAD_FREG_FTN(WT0, fs);
5081 gen_op_float_abs_s();
5082 GEN_STORE_FTN_FREG(fd, WT2);
5083 opn = "abs.s";
5084 break;
5085 case FOP(6, 16):
5086 GEN_LOAD_FREG_FTN(WT0, fs);
5087 gen_op_float_mov_s();
5088 GEN_STORE_FTN_FREG(fd, WT2);
5089 opn = "mov.s";
5090 break;
5091 case FOP(7, 16):
5092 GEN_LOAD_FREG_FTN(WT0, fs);
5093 gen_op_float_chs_s();
5094 GEN_STORE_FTN_FREG(fd, WT2);
5095 opn = "neg.s";
5096 break;
5097 case FOP(8, 16):
5098 check_cp1_64bitmode(ctx);
5099 GEN_LOAD_FREG_FTN(WT0, fs);
5100 gen_op_float_roundl_s();
5101 GEN_STORE_FTN_FREG(fd, DT2);
5102 opn = "round.l.s";
5103 break;
5104 case FOP(9, 16):
5105 check_cp1_64bitmode(ctx);
5106 GEN_LOAD_FREG_FTN(WT0, fs);
5107 gen_op_float_truncl_s();
5108 GEN_STORE_FTN_FREG(fd, DT2);
5109 opn = "trunc.l.s";
5110 break;
5111 case FOP(10, 16):
5112 check_cp1_64bitmode(ctx);
5113 GEN_LOAD_FREG_FTN(WT0, fs);
5114 gen_op_float_ceill_s();
5115 GEN_STORE_FTN_FREG(fd, DT2);
5116 opn = "ceil.l.s";
5117 break;
5118 case FOP(11, 16):
5119 check_cp1_64bitmode(ctx);
5120 GEN_LOAD_FREG_FTN(WT0, fs);
5121 gen_op_float_floorl_s();
5122 GEN_STORE_FTN_FREG(fd, DT2);
5123 opn = "floor.l.s";
5124 break;
5125 case FOP(12, 16):
5126 GEN_LOAD_FREG_FTN(WT0, fs);
5127 gen_op_float_roundw_s();
5128 GEN_STORE_FTN_FREG(fd, WT2);
5129 opn = "round.w.s";
5130 break;
5131 case FOP(13, 16):
5132 GEN_LOAD_FREG_FTN(WT0, fs);
5133 gen_op_float_truncw_s();
5134 GEN_STORE_FTN_FREG(fd, WT2);
5135 opn = "trunc.w.s";
5136 break;
5137 case FOP(14, 16):
5138 GEN_LOAD_FREG_FTN(WT0, fs);
5139 gen_op_float_ceilw_s();
5140 GEN_STORE_FTN_FREG(fd, WT2);
5141 opn = "ceil.w.s";
5142 break;
5143 case FOP(15, 16):
5144 GEN_LOAD_FREG_FTN(WT0, fs);
5145 gen_op_float_floorw_s();
5146 GEN_STORE_FTN_FREG(fd, WT2);
5147 opn = "floor.w.s";
5148 break;
5149 case FOP(17, 16):
5150 GEN_LOAD_REG_T0(ft);
5151 GEN_LOAD_FREG_FTN(WT0, fs);
5152 GEN_LOAD_FREG_FTN(WT2, fd);
5153 gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5154 GEN_STORE_FTN_FREG(fd, WT2);
5155 opn = "movcf.s";
5156 break;
5157 case FOP(18, 16):
5158 GEN_LOAD_REG_T0(ft);
5159 GEN_LOAD_FREG_FTN(WT0, fs);
5160 GEN_LOAD_FREG_FTN(WT2, fd);
5161 gen_op_float_movz_s();
5162 GEN_STORE_FTN_FREG(fd, WT2);
5163 opn = "movz.s";
5164 break;
5165 case FOP(19, 16):
5166 GEN_LOAD_REG_T0(ft);
5167 GEN_LOAD_FREG_FTN(WT0, fs);
5168 GEN_LOAD_FREG_FTN(WT2, fd);
5169 gen_op_float_movn_s();
5170 GEN_STORE_FTN_FREG(fd, WT2);
5171 opn = "movn.s";
5172 break;
5173 case FOP(21, 16):
5174 check_cop1x(ctx);
5175 GEN_LOAD_FREG_FTN(WT0, fs);
5176 gen_op_float_recip_s();
5177 GEN_STORE_FTN_FREG(fd, WT2);
5178 opn = "recip.s";
5179 break;
5180 case FOP(22, 16):
5181 check_cop1x(ctx);
5182 GEN_LOAD_FREG_FTN(WT0, fs);
5183 gen_op_float_rsqrt_s();
5184 GEN_STORE_FTN_FREG(fd, WT2);
5185 opn = "rsqrt.s";
5186 break;
5187 case FOP(28, 16):
5188 check_cp1_64bitmode(ctx);
5189 GEN_LOAD_FREG_FTN(WT0, fs);
5190 GEN_LOAD_FREG_FTN(WT2, fd);
5191 gen_op_float_recip2_s();
5192 GEN_STORE_FTN_FREG(fd, WT2);
5193 opn = "recip2.s";
5194 break;
5195 case FOP(29, 16):
5196 check_cp1_64bitmode(ctx);
5197 GEN_LOAD_FREG_FTN(WT0, fs);
5198 gen_op_float_recip1_s();
5199 GEN_STORE_FTN_FREG(fd, WT2);
5200 opn = "recip1.s";
5201 break;
5202 case FOP(30, 16):
5203 check_cp1_64bitmode(ctx);
5204 GEN_LOAD_FREG_FTN(WT0, fs);
5205 gen_op_float_rsqrt1_s();
5206 GEN_STORE_FTN_FREG(fd, WT2);
5207 opn = "rsqrt1.s";
5208 break;
5209 case FOP(31, 16):
5210 check_cp1_64bitmode(ctx);
5211 GEN_LOAD_FREG_FTN(WT0, fs);
5212 GEN_LOAD_FREG_FTN(WT2, ft);
5213 gen_op_float_rsqrt2_s();
5214 GEN_STORE_FTN_FREG(fd, WT2);
5215 opn = "rsqrt2.s";
5216 break;
5217 case FOP(33, 16):
5218 check_cp1_registers(ctx, fd);
5219 GEN_LOAD_FREG_FTN(WT0, fs);
5220 gen_op_float_cvtd_s();
5221 GEN_STORE_FTN_FREG(fd, DT2);
5222 opn = "cvt.d.s";
5223 break;
5224 case FOP(36, 16):
5225 GEN_LOAD_FREG_FTN(WT0, fs);
5226 gen_op_float_cvtw_s();
5227 GEN_STORE_FTN_FREG(fd, WT2);
5228 opn = "cvt.w.s";
5229 break;
5230 case FOP(37, 16):
5231 check_cp1_64bitmode(ctx);
5232 GEN_LOAD_FREG_FTN(WT0, fs);
5233 gen_op_float_cvtl_s();
5234 GEN_STORE_FTN_FREG(fd, DT2);
5235 opn = "cvt.l.s";
5236 break;
5237 case FOP(38, 16):
5238 check_cp1_64bitmode(ctx);
5239 GEN_LOAD_FREG_FTN(WT1, fs);
5240 GEN_LOAD_FREG_FTN(WT0, ft);
5241 gen_op_float_cvtps_s();
5242 GEN_STORE_FTN_FREG(fd, DT2);
5243 opn = "cvt.ps.s";
5244 break;
5245 case FOP(48, 16):
5246 case FOP(49, 16):
5247 case FOP(50, 16):
5248 case FOP(51, 16):
5249 case FOP(52, 16):
5250 case FOP(53, 16):
5251 case FOP(54, 16):
5252 case FOP(55, 16):
5253 case FOP(56, 16):
5254 case FOP(57, 16):
5255 case FOP(58, 16):
5256 case FOP(59, 16):
5257 case FOP(60, 16):
5258 case FOP(61, 16):
5259 case FOP(62, 16):
5260 case FOP(63, 16):
5261 GEN_LOAD_FREG_FTN(WT0, fs);
5262 GEN_LOAD_FREG_FTN(WT1, ft);
5263 if (ctx->opcode & (1 << 6)) {
5264 check_cop1x(ctx);
5265 gen_cmpabs_s(func-48, cc);
5266 opn = condnames_abs[func-48];
5267 } else {
5268 gen_cmp_s(func-48, cc);
5269 opn = condnames[func-48];
5270 }
5271 break;
5272 case FOP(0, 17):
5273 check_cp1_registers(ctx, fs | ft | fd);
5274 GEN_LOAD_FREG_FTN(DT0, fs);
5275 GEN_LOAD_FREG_FTN(DT1, ft);
5276 gen_op_float_add_d();
5277 GEN_STORE_FTN_FREG(fd, DT2);
5278 opn = "add.d";
5279 optype = BINOP;
5280 break;
5281 case FOP(1, 17):
5282 check_cp1_registers(ctx, fs | ft | fd);
5283 GEN_LOAD_FREG_FTN(DT0, fs);
5284 GEN_LOAD_FREG_FTN(DT1, ft);
5285 gen_op_float_sub_d();
5286 GEN_STORE_FTN_FREG(fd, DT2);
5287 opn = "sub.d";
5288 optype = BINOP;
5289 break;
5290 case FOP(2, 17):
5291 check_cp1_registers(ctx, fs | ft | fd);
5292 GEN_LOAD_FREG_FTN(DT0, fs);
5293 GEN_LOAD_FREG_FTN(DT1, ft);
5294 gen_op_float_mul_d();
5295 GEN_STORE_FTN_FREG(fd, DT2);
5296 opn = "mul.d";
5297 optype = BINOP;
5298 break;
5299 case FOP(3, 17):
5300 check_cp1_registers(ctx, fs | ft | fd);
5301 GEN_LOAD_FREG_FTN(DT0, fs);
5302 GEN_LOAD_FREG_FTN(DT1, ft);
5303 gen_op_float_div_d();
5304 GEN_STORE_FTN_FREG(fd, DT2);
5305 opn = "div.d";
5306 optype = BINOP;
5307 break;
5308 case FOP(4, 17):
5309 check_cp1_registers(ctx, fs | fd);
5310 GEN_LOAD_FREG_FTN(DT0, fs);
5311 gen_op_float_sqrt_d();
5312 GEN_STORE_FTN_FREG(fd, DT2);
5313 opn = "sqrt.d";
5314 break;
5315 case FOP(5, 17):
5316 check_cp1_registers(ctx, fs | fd);
5317 GEN_LOAD_FREG_FTN(DT0, fs);
5318 gen_op_float_abs_d();
5319 GEN_STORE_FTN_FREG(fd, DT2);
5320 opn = "abs.d";
5321 break;
5322 case FOP(6, 17):
5323 check_cp1_registers(ctx, fs | fd);
5324 GEN_LOAD_FREG_FTN(DT0, fs);
5325 gen_op_float_mov_d();
5326 GEN_STORE_FTN_FREG(fd, DT2);
5327 opn = "mov.d";
5328 break;
5329 case FOP(7, 17):
5330 check_cp1_registers(ctx, fs | fd);
5331 GEN_LOAD_FREG_FTN(DT0, fs);
5332 gen_op_float_chs_d();
5333 GEN_STORE_FTN_FREG(fd, DT2);
5334 opn = "neg.d";
5335 break;
5336 case FOP(8, 17):
5337 check_cp1_64bitmode(ctx);
5338 GEN_LOAD_FREG_FTN(DT0, fs);
5339 gen_op_float_roundl_d();
5340 GEN_STORE_FTN_FREG(fd, DT2);
5341 opn = "round.l.d";
5342 break;
5343 case FOP(9, 17):
5344 check_cp1_64bitmode(ctx);
5345 GEN_LOAD_FREG_FTN(DT0, fs);
5346 gen_op_float_truncl_d();
5347 GEN_STORE_FTN_FREG(fd, DT2);
5348 opn = "trunc.l.d";
5349 break;
5350 case FOP(10, 17):
5351 check_cp1_64bitmode(ctx);
5352 GEN_LOAD_FREG_FTN(DT0, fs);
5353 gen_op_float_ceill_d();
5354 GEN_STORE_FTN_FREG(fd, DT2);
5355 opn = "ceil.l.d";
5356 break;
5357 case FOP(11, 17):
5358 check_cp1_64bitmode(ctx);
5359 GEN_LOAD_FREG_FTN(DT0, fs);
5360 gen_op_float_floorl_d();
5361 GEN_STORE_FTN_FREG(fd, DT2);
5362 opn = "floor.l.d";
5363 break;
5364 case FOP(12, 17):
5365 check_cp1_registers(ctx, fs);
5366 GEN_LOAD_FREG_FTN(DT0, fs);
5367 gen_op_float_roundw_d();
5368 GEN_STORE_FTN_FREG(fd, WT2);
5369 opn = "round.w.d";
5370 break;
5371 case FOP(13, 17):
5372 check_cp1_registers(ctx, fs);
5373 GEN_LOAD_FREG_FTN(DT0, fs);
5374 gen_op_float_truncw_d();
5375 GEN_STORE_FTN_FREG(fd, WT2);
5376 opn = "trunc.w.d";
5377 break;
5378 case FOP(14, 17):
5379 check_cp1_registers(ctx, fs);
5380 GEN_LOAD_FREG_FTN(DT0, fs);
5381 gen_op_float_ceilw_d();
5382 GEN_STORE_FTN_FREG(fd, WT2);
5383 opn = "ceil.w.d";
5384 break;
5385 case FOP(15, 17):
5386 check_cp1_registers(ctx, fs);
5387 GEN_LOAD_FREG_FTN(DT0, fs);
5388 gen_op_float_floorw_d();
5389 GEN_STORE_FTN_FREG(fd, WT2);
5390 opn = "floor.w.d";
5391 break;
5392 case FOP(17, 17):
5393 GEN_LOAD_REG_T0(ft);
5394 GEN_LOAD_FREG_FTN(DT0, fs);
5395 GEN_LOAD_FREG_FTN(DT2, fd);
5396 gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5397 GEN_STORE_FTN_FREG(fd, DT2);
5398 opn = "movcf.d";
5399 break;
5400 case FOP(18, 17):
5401 GEN_LOAD_REG_T0(ft);
5402 GEN_LOAD_FREG_FTN(DT0, fs);
5403 GEN_LOAD_FREG_FTN(DT2, fd);
5404 gen_op_float_movz_d();
5405 GEN_STORE_FTN_FREG(fd, DT2);
5406 opn = "movz.d";
5407 break;
5408 case FOP(19, 17):
5409 GEN_LOAD_REG_T0(ft);
5410 GEN_LOAD_FREG_FTN(DT0, fs);
5411 GEN_LOAD_FREG_FTN(DT2, fd);
5412 gen_op_float_movn_d();
5413 GEN_STORE_FTN_FREG(fd, DT2);
5414 opn = "movn.d";
5415 break;
5416 case FOP(21, 17):
5417 check_cp1_64bitmode(ctx);
5418 GEN_LOAD_FREG_FTN(DT0, fs);
5419 gen_op_float_recip_d();
5420 GEN_STORE_FTN_FREG(fd, DT2);
5421 opn = "recip.d";
5422 break;
5423 case FOP(22, 17):
5424 check_cp1_64bitmode(ctx);
5425 GEN_LOAD_FREG_FTN(DT0, fs);
5426 gen_op_float_rsqrt_d();
5427 GEN_STORE_FTN_FREG(fd, DT2);
5428 opn = "rsqrt.d";
5429 break;
5430 case FOP(28, 17):
5431 check_cp1_64bitmode(ctx);
5432 GEN_LOAD_FREG_FTN(DT0, fs);
5433 GEN_LOAD_FREG_FTN(DT2, ft);
5434 gen_op_float_recip2_d();
5435 GEN_STORE_FTN_FREG(fd, DT2);
5436 opn = "recip2.d";
5437 break;
5438 case FOP(29, 17):
5439 check_cp1_64bitmode(ctx);
5440 GEN_LOAD_FREG_FTN(DT0, fs);
5441 gen_op_float_recip1_d();
5442 GEN_STORE_FTN_FREG(fd, DT2);
5443 opn = "recip1.d";
5444 break;
5445 case FOP(30, 17):
5446 check_cp1_64bitmode(ctx);
5447 GEN_LOAD_FREG_FTN(DT0, fs);
5448 gen_op_float_rsqrt1_d();
5449 GEN_STORE_FTN_FREG(fd, DT2);
5450 opn = "rsqrt1.d";
5451 break;
5452 case FOP(31, 17):
5453 check_cp1_64bitmode(ctx);
5454 GEN_LOAD_FREG_FTN(DT0, fs);
5455 GEN_LOAD_FREG_FTN(DT2, ft);
5456 gen_op_float_rsqrt2_d();
5457 GEN_STORE_FTN_FREG(fd, DT2);
5458 opn = "rsqrt2.d";
5459 break;
5460 case FOP(48, 17):
5461 case FOP(49, 17):
5462 case FOP(50, 17):
5463 case FOP(51, 17):
5464 case FOP(52, 17):
5465 case FOP(53, 17):
5466 case FOP(54, 17):
5467 case FOP(55, 17):
5468 case FOP(56, 17):
5469 case FOP(57, 17):
5470 case FOP(58, 17):
5471 case FOP(59, 17):
5472 case FOP(60, 17):
5473 case FOP(61, 17):
5474 case FOP(62, 17):
5475 case FOP(63, 17):
5476 GEN_LOAD_FREG_FTN(DT0, fs);
5477 GEN_LOAD_FREG_FTN(DT1, ft);
5478 if (ctx->opcode & (1 << 6)) {
5479 check_cop1x(ctx);
5480 check_cp1_registers(ctx, fs | ft);
5481 gen_cmpabs_d(func-48, cc);
5482 opn = condnames_abs[func-48];
5483 } else {
5484 check_cp1_registers(ctx, fs | ft);
5485 gen_cmp_d(func-48, cc);
5486 opn = condnames[func-48];
5487 }
5488 break;
5489 case FOP(32, 17):
5490 check_cp1_registers(ctx, fs);
5491 GEN_LOAD_FREG_FTN(DT0, fs);
5492 gen_op_float_cvts_d();
5493 GEN_STORE_FTN_FREG(fd, WT2);
5494 opn = "cvt.s.d";
5495 break;
5496 case FOP(36, 17):
5497 check_cp1_registers(ctx, fs);
5498 GEN_LOAD_FREG_FTN(DT0, fs);
5499 gen_op_float_cvtw_d();
5500 GEN_STORE_FTN_FREG(fd, WT2);
5501 opn = "cvt.w.d";
5502 break;
5503 case FOP(37, 17):
5504 check_cp1_64bitmode(ctx);
5505 GEN_LOAD_FREG_FTN(DT0, fs);
5506 gen_op_float_cvtl_d();
5507 GEN_STORE_FTN_FREG(fd, DT2);
5508 opn = "cvt.l.d";
5509 break;
5510 case FOP(32, 20):
5511 GEN_LOAD_FREG_FTN(WT0, fs);
5512 gen_op_float_cvts_w();
5513 GEN_STORE_FTN_FREG(fd, WT2);
5514 opn = "cvt.s.w";
5515 break;
5516 case FOP(33, 20):
5517 check_cp1_registers(ctx, fd);
5518 GEN_LOAD_FREG_FTN(WT0, fs);
5519 gen_op_float_cvtd_w();
5520 GEN_STORE_FTN_FREG(fd, DT2);
5521 opn = "cvt.d.w";
5522 break;
5523 case FOP(32, 21):
5524 check_cp1_64bitmode(ctx);
5525 GEN_LOAD_FREG_FTN(DT0, fs);
5526 gen_op_float_cvts_l();
5527 GEN_STORE_FTN_FREG(fd, WT2);
5528 opn = "cvt.s.l";
5529 break;
5530 case FOP(33, 21):
5531 check_cp1_64bitmode(ctx);
5532 GEN_LOAD_FREG_FTN(DT0, fs);
5533 gen_op_float_cvtd_l();
5534 GEN_STORE_FTN_FREG(fd, DT2);
5535 opn = "cvt.d.l";
5536 break;
5537 case FOP(38, 20):
5538 check_cp1_64bitmode(ctx);
5539 GEN_LOAD_FREG_FTN(WT0, fs);
5540 GEN_LOAD_FREG_FTN(WTH0, fs);
5541 gen_op_float_cvtps_pw();
5542 GEN_STORE_FTN_FREG(fd, WT2);
5543 GEN_STORE_FTN_FREG(fd, WTH2);
5544 opn = "cvt.ps.pw";
5545 break;
5546 case FOP(0, 22):
5547 check_cp1_64bitmode(ctx);
5548 GEN_LOAD_FREG_FTN(WT0, fs);
5549 GEN_LOAD_FREG_FTN(WTH0, fs);
5550 GEN_LOAD_FREG_FTN(WT1, ft);
5551 GEN_LOAD_FREG_FTN(WTH1, ft);
5552 gen_op_float_add_ps();
5553 GEN_STORE_FTN_FREG(fd, WT2);
5554 GEN_STORE_FTN_FREG(fd, WTH2);
5555 opn = "add.ps";
5556 break;
5557 case FOP(1, 22):
5558 check_cp1_64bitmode(ctx);
5559 GEN_LOAD_FREG_FTN(WT0, fs);
5560 GEN_LOAD_FREG_FTN(WTH0, fs);
5561 GEN_LOAD_FREG_FTN(WT1, ft);
5562 GEN_LOAD_FREG_FTN(WTH1, ft);
5563 gen_op_float_sub_ps();
5564 GEN_STORE_FTN_FREG(fd, WT2);
5565 GEN_STORE_FTN_FREG(fd, WTH2);
5566 opn = "sub.ps";
5567 break;
5568 case FOP(2, 22):
5569 check_cp1_64bitmode(ctx);
5570 GEN_LOAD_FREG_FTN(WT0, fs);
5571 GEN_LOAD_FREG_FTN(WTH0, fs);
5572 GEN_LOAD_FREG_FTN(WT1, ft);
5573 GEN_LOAD_FREG_FTN(WTH1, ft);
5574 gen_op_float_mul_ps();
5575 GEN_STORE_FTN_FREG(fd, WT2);
5576 GEN_STORE_FTN_FREG(fd, WTH2);
5577 opn = "mul.ps";
5578 break;
5579 case FOP(5, 22):
5580 check_cp1_64bitmode(ctx);
5581 GEN_LOAD_FREG_FTN(WT0, fs);
5582 GEN_LOAD_FREG_FTN(WTH0, fs);
5583 gen_op_float_abs_ps();
5584 GEN_STORE_FTN_FREG(fd, WT2);
5585 GEN_STORE_FTN_FREG(fd, WTH2);
5586 opn = "abs.ps";
5587 break;
5588 case FOP(6, 22):
5589 check_cp1_64bitmode(ctx);
5590 GEN_LOAD_FREG_FTN(WT0, fs);
5591 GEN_LOAD_FREG_FTN(WTH0, fs);
5592 gen_op_float_mov_ps();
5593 GEN_STORE_FTN_FREG(fd, WT2);
5594 GEN_STORE_FTN_FREG(fd, WTH2);
5595 opn = "mov.ps";
5596 break;
5597 case FOP(7, 22):
5598 check_cp1_64bitmode(ctx);
5599 GEN_LOAD_FREG_FTN(WT0, fs);
5600 GEN_LOAD_FREG_FTN(WTH0, fs);
5601 gen_op_float_chs_ps();
5602 GEN_STORE_FTN_FREG(fd, WT2);
5603 GEN_STORE_FTN_FREG(fd, WTH2);
5604 opn = "neg.ps";
5605 break;
5606 case FOP(17, 22):
5607 check_cp1_64bitmode(ctx);
5608 GEN_LOAD_REG_T0(ft);
5609 GEN_LOAD_FREG_FTN(WT0, fs);
5610 GEN_LOAD_FREG_FTN(WTH0, fs);
5611 GEN_LOAD_FREG_FTN(WT2, fd);
5612 GEN_LOAD_FREG_FTN(WTH2, fd);
5613 gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
5614 GEN_STORE_FTN_FREG(fd, WT2);
5615 GEN_STORE_FTN_FREG(fd, WTH2);
5616 opn = "movcf.ps";
5617 break;
5618 case FOP(18, 22):
5619 check_cp1_64bitmode(ctx);
5620 GEN_LOAD_REG_T0(ft);
5621 GEN_LOAD_FREG_FTN(WT0, fs);
5622 GEN_LOAD_FREG_FTN(WTH0, fs);
5623 GEN_LOAD_FREG_FTN(WT2, fd);
5624 GEN_LOAD_FREG_FTN(WTH2, fd);
5625 gen_op_float_movz_ps();
5626 GEN_STORE_FTN_FREG(fd, WT2);
5627 GEN_STORE_FTN_FREG(fd, WTH2);
5628 opn = "movz.ps";
5629 break;
5630 case FOP(19, 22):
5631 check_cp1_64bitmode(ctx);
5632 GEN_LOAD_REG_T0(ft);
5633 GEN_LOAD_FREG_FTN(WT0, fs);
5634 GEN_LOAD_FREG_FTN(WTH0, fs);
5635 GEN_LOAD_FREG_FTN(WT2, fd);
5636 GEN_LOAD_FREG_FTN(WTH2, fd);
5637 gen_op_float_movn_ps();
5638 GEN_STORE_FTN_FREG(fd, WT2);
5639 GEN_STORE_FTN_FREG(fd, WTH2);
5640 opn = "movn.ps";
5641 break;
5642 case FOP(24, 22):
5643 check_cp1_64bitmode(ctx);
5644 GEN_LOAD_FREG_FTN(WT0, ft);
5645 GEN_LOAD_FREG_FTN(WTH0, ft);
5646 GEN_LOAD_FREG_FTN(WT1, fs);
5647 GEN_LOAD_FREG_FTN(WTH1, fs);
5648 gen_op_float_addr_ps();
5649 GEN_STORE_FTN_FREG(fd, WT2);
5650 GEN_STORE_FTN_FREG(fd, WTH2);
5651 opn = "addr.ps";
5652 break;
5653 case FOP(26, 22):
5654 check_cp1_64bitmode(ctx);
5655 GEN_LOAD_FREG_FTN(WT0, ft);
5656 GEN_LOAD_FREG_FTN(WTH0, ft);
5657 GEN_LOAD_FREG_FTN(WT1, fs);
5658 GEN_LOAD_FREG_FTN(WTH1, fs);
5659 gen_op_float_mulr_ps();
5660 GEN_STORE_FTN_FREG(fd, WT2);
5661 GEN_STORE_FTN_FREG(fd, WTH2);
5662 opn = "mulr.ps";
5663 break;
5664 case FOP(28, 22):
5665 check_cp1_64bitmode(ctx);
5666 GEN_LOAD_FREG_FTN(WT0, fs);
5667 GEN_LOAD_FREG_FTN(WTH0, fs);
5668 GEN_LOAD_FREG_FTN(WT2, fd);
5669 GEN_LOAD_FREG_FTN(WTH2, fd);
5670 gen_op_float_recip2_ps();
5671 GEN_STORE_FTN_FREG(fd, WT2);
5672 GEN_STORE_FTN_FREG(fd, WTH2);
5673 opn = "recip2.ps";
5674 break;
5675 case FOP(29, 22):
5676 check_cp1_64bitmode(ctx);
5677 GEN_LOAD_FREG_FTN(WT0, fs);
5678 GEN_LOAD_FREG_FTN(WTH0, fs);
5679 gen_op_float_recip1_ps();
5680 GEN_STORE_FTN_FREG(fd, WT2);
5681 GEN_STORE_FTN_FREG(fd, WTH2);
5682 opn = "recip1.ps";
5683 break;
5684 case FOP(30, 22):
5685 check_cp1_64bitmode(ctx);
5686 GEN_LOAD_FREG_FTN(WT0, fs);
5687 GEN_LOAD_FREG_FTN(WTH0, fs);
5688 gen_op_float_rsqrt1_ps();
5689 GEN_STORE_FTN_FREG(fd, WT2);
5690 GEN_STORE_FTN_FREG(fd, WTH2);
5691 opn = "rsqrt1.ps";
5692 break;
5693 case FOP(31, 22):
5694 check_cp1_64bitmode(ctx);
5695 GEN_LOAD_FREG_FTN(WT0, fs);
5696 GEN_LOAD_FREG_FTN(WTH0, fs);
5697 GEN_LOAD_FREG_FTN(WT2, ft);
5698 GEN_LOAD_FREG_FTN(WTH2, ft);
5699 gen_op_float_rsqrt2_ps();
5700 GEN_STORE_FTN_FREG(fd, WT2);
5701 GEN_STORE_FTN_FREG(fd, WTH2);
5702 opn = "rsqrt2.ps";
5703 break;
5704 case FOP(32, 22):
5705 check_cp1_64bitmode(ctx);
5706 GEN_LOAD_FREG_FTN(WTH0, fs);
5707 gen_op_float_cvts_pu();
5708 GEN_STORE_FTN_FREG(fd, WT2);
5709 opn = "cvt.s.pu";
5710 break;
5711 case FOP(36, 22):
5712 check_cp1_64bitmode(ctx);
5713 GEN_LOAD_FREG_FTN(WT0, fs);
5714 GEN_LOAD_FREG_FTN(WTH0, fs);
5715 gen_op_float_cvtpw_ps();
5716 GEN_STORE_FTN_FREG(fd, WT2);
5717 GEN_STORE_FTN_FREG(fd, WTH2);
5718 opn = "cvt.pw.ps";
5719 break;
5720 case FOP(40, 22):
5721 check_cp1_64bitmode(ctx);
5722 GEN_LOAD_FREG_FTN(WT0, fs);
5723 gen_op_float_cvts_pl();
5724 GEN_STORE_FTN_FREG(fd, WT2);
5725 opn = "cvt.s.pl";
5726 break;
5727 case FOP(44, 22):
5728 check_cp1_64bitmode(ctx);
5729 GEN_LOAD_FREG_FTN(WT0, fs);
5730 GEN_LOAD_FREG_FTN(WT1, ft);
5731 gen_op_float_pll_ps();
5732 GEN_STORE_FTN_FREG(fd, DT2);
5733 opn = "pll.ps";
5734 break;
5735 case FOP(45, 22):
5736 check_cp1_64bitmode(ctx);
5737 GEN_LOAD_FREG_FTN(WT0, fs);
5738 GEN_LOAD_FREG_FTN(WTH1, ft);
5739 gen_op_float_plu_ps();
5740 GEN_STORE_FTN_FREG(fd, DT2);
5741 opn = "plu.ps";
5742 break;
5743 case FOP(46, 22):
5744 check_cp1_64bitmode(ctx);
5745 GEN_LOAD_FREG_FTN(WTH0, fs);
5746 GEN_LOAD_FREG_FTN(WT1, ft);
5747 gen_op_float_pul_ps();
5748 GEN_STORE_FTN_FREG(fd, DT2);
5749 opn = "pul.ps";
5750 break;
5751 case FOP(47, 22):
5752 check_cp1_64bitmode(ctx);
5753 GEN_LOAD_FREG_FTN(WTH0, fs);
5754 GEN_LOAD_FREG_FTN(WTH1, ft);
5755 gen_op_float_puu_ps();
5756 GEN_STORE_FTN_FREG(fd, DT2);
5757 opn = "puu.ps";
5758 break;
5759 case FOP(48, 22):
5760 case FOP(49, 22):
5761 case FOP(50, 22):
5762 case FOP(51, 22):
5763 case FOP(52, 22):
5764 case FOP(53, 22):
5765 case FOP(54, 22):
5766 case FOP(55, 22):
5767 case FOP(56, 22):
5768 case FOP(57, 22):
5769 case FOP(58, 22):
5770 case FOP(59, 22):
5771 case FOP(60, 22):
5772 case FOP(61, 22):
5773 case FOP(62, 22):
5774 case FOP(63, 22):
5775 check_cp1_64bitmode(ctx);
5776 GEN_LOAD_FREG_FTN(WT0, fs);
5777 GEN_LOAD_FREG_FTN(WTH0, fs);
5778 GEN_LOAD_FREG_FTN(WT1, ft);
5779 GEN_LOAD_FREG_FTN(WTH1, ft);
5780 if (ctx->opcode & (1 << 6)) {
5781 gen_cmpabs_ps(func-48, cc);
5782 opn = condnames_abs[func-48];
5783 } else {
5784 gen_cmp_ps(func-48, cc);
5785 opn = condnames[func-48];
5786 }
5787 break;
5788 default:
5789 MIPS_INVAL(opn);
5790 generate_exception (ctx, EXCP_RI);
5791 return;
5792 }
5793 switch (optype) {
5794 case BINOP:
5795 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5796 break;
5797 case CMPOP:
5798 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5799 break;
5800 default:
5801 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5802 break;
5803 }
5804 }
5805
5806 /* Coprocessor 3 (FPU) */
5807 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5808 int fd, int fs, int base, int index)
5809 {
5810 const char *opn = "extended float load/store";
5811 int store = 0;
5812
5813 if (base == 0) {
5814 if (index == 0)
5815 gen_op_reset_T0();
5816 else
5817 GEN_LOAD_REG_T0(index);
5818 } else if (index == 0) {
5819 GEN_LOAD_REG_T0(base);
5820 } else {
5821 GEN_LOAD_REG_T0(base);
5822 GEN_LOAD_REG_T1(index);
5823 gen_op_addr_add();
5824 }
5825 /* Don't do NOP if destination is zero: we must perform the actual
5826 memory access. */
5827 switch (opc) {
5828 case OPC_LWXC1:
5829 check_cop1x(ctx);
5830 op_ldst(lwc1);
5831 GEN_STORE_FTN_FREG(fd, WT0);
5832 opn = "lwxc1";
5833 break;
5834 case OPC_LDXC1:
5835 check_cop1x(ctx);
5836 check_cp1_registers(ctx, fd);
5837 op_ldst(ldc1);
5838 GEN_STORE_FTN_FREG(fd, DT0);
5839 opn = "ldxc1";
5840 break;
5841 case OPC_LUXC1:
5842 check_cp1_64bitmode(ctx);
5843 op_ldst(luxc1);
5844 GEN_STORE_FTN_FREG(fd, DT0);
5845 opn = "luxc1";
5846 break;
5847 case OPC_SWXC1:
5848 check_cop1x(ctx);
5849 GEN_LOAD_FREG_FTN(WT0, fs);
5850 op_ldst(swc1);
5851 opn = "swxc1";
5852 store = 1;
5853 break;
5854 case OPC_SDXC1:
5855 check_cop1x(ctx);
5856 check_cp1_registers(ctx, fs);
5857 GEN_LOAD_FREG_FTN(DT0, fs);
5858 op_ldst(sdc1);
5859 opn = "sdxc1";
5860 store = 1;
5861 break;
5862 case OPC_SUXC1:
5863 check_cp1_64bitmode(ctx);
5864 GEN_LOAD_FREG_FTN(DT0, fs);
5865 op_ldst(suxc1);
5866 opn = "suxc1";
5867 store = 1;
5868 break;
5869 default:
5870 MIPS_INVAL(opn);
5871 generate_exception(ctx, EXCP_RI);
5872 return;
5873 }
5874 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5875 regnames[index], regnames[base]);
5876 }
5877
5878 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5879 int fd, int fr, int fs, int ft)
5880 {
5881 const char *opn = "flt3_arith";
5882
5883 switch (opc) {
5884 case OPC_ALNV_PS:
5885 check_cp1_64bitmode(ctx);
5886 GEN_LOAD_REG_T0(fr);
5887 GEN_LOAD_FREG_FTN(DT0, fs);
5888 GEN_LOAD_FREG_FTN(DT1, ft);
5889 gen_op_float_alnv_ps();
5890 GEN_STORE_FTN_FREG(fd, DT2);
5891 opn = "alnv.ps";
5892 break;
5893 case OPC_MADD_S:
5894 check_cop1x(ctx);
5895 GEN_LOAD_FREG_FTN(WT0, fs);
5896 GEN_LOAD_FREG_FTN(WT1, ft);
5897 GEN_LOAD_FREG_FTN(WT2, fr);
5898 gen_op_float_muladd_s();
5899 GEN_STORE_FTN_FREG(fd, WT2);
5900 opn = "madd.s";
5901 break;
5902 case OPC_MADD_D:
5903 check_cop1x(ctx);
5904 check_cp1_registers(ctx, fd | fs | ft | fr);
5905 GEN_LOAD_FREG_FTN(DT0, fs);
5906 GEN_LOAD_FREG_FTN(DT1, ft);
5907 GEN_LOAD_FREG_FTN(DT2, fr);
5908 gen_op_float_muladd_d();
5909 GEN_STORE_FTN_FREG(fd, DT2);
5910 opn = "madd.d";
5911 break;
5912 case OPC_MADD_PS:
5913 check_cp1_64bitmode(ctx);
5914 GEN_LOAD_FREG_FTN(WT0, fs);
5915 GEN_LOAD_FREG_FTN(WTH0, fs);
5916 GEN_LOAD_FREG_FTN(WT1, ft);
5917 GEN_LOAD_FREG_FTN(WTH1, ft);
5918 GEN_LOAD_FREG_FTN(WT2, fr);
5919 GEN_LOAD_FREG_FTN(WTH2, fr);
5920 gen_op_float_muladd_ps();
5921 GEN_STORE_FTN_FREG(fd, WT2);
5922 GEN_STORE_FTN_FREG(fd, WTH2);
5923 opn = "madd.ps";
5924 break;
5925 case OPC_MSUB_S:
5926 check_cop1x(ctx);
5927 GEN_LOAD_FREG_FTN(WT0, fs);
5928 GEN_LOAD_FREG_FTN(WT1, ft);
5929 GEN_LOAD_FREG_FTN(WT2, fr);
5930 gen_op_float_mulsub_s();
5931 GEN_STORE_FTN_FREG(fd, WT2);
5932 opn = "msub.s";
5933 break;
5934 case OPC_MSUB_D:
5935 check_cop1x(ctx);
5936 check_cp1_registers(ctx, fd | fs | ft | fr);
5937 GEN_LOAD_FREG_FTN(DT0, fs);
5938 GEN_LOAD_FREG_FTN(DT1, ft);
5939 GEN_LOAD_FREG_FTN(DT2, fr);
5940 gen_op_float_mulsub_d();
5941 GEN_STORE_FTN_FREG(fd, DT2);
5942 opn = "msub.d";
5943 break;
5944 case OPC_MSUB_PS:
5945 check_cp1_64bitmode(ctx);
5946 GEN_LOAD_FREG_FTN(WT0, fs);
5947 GEN_LOAD_FREG_FTN(WTH0, fs);
5948 GEN_LOAD_FREG_FTN(WT1, ft);
5949 GEN_LOAD_FREG_FTN(WTH1, ft);
5950 GEN_LOAD_FREG_FTN(WT2, fr);
5951 GEN_LOAD_FREG_FTN(WTH2, fr);
5952 gen_op_float_mulsub_ps();
5953 GEN_STORE_FTN_FREG(fd, WT2);
5954 GEN_STORE_FTN_FREG(fd, WTH2);
5955 opn = "msub.ps";
5956 break;
5957 case OPC_NMADD_S:
5958 check_cop1x(ctx);
5959 GEN_LOAD_FREG_FTN(WT0, fs);
5960 GEN_LOAD_FREG_FTN(WT1, ft);
5961 GEN_LOAD_FREG_FTN(WT2, fr);
5962 gen_op_float_nmuladd_s();
5963 GEN_STORE_FTN_FREG(fd, WT2);
5964 opn = "nmadd.s";
5965 break;
5966 case OPC_NMADD_D:
5967 check_cop1x(ctx);
5968 check_cp1_registers(ctx, fd | fs | ft | fr);
5969 GEN_LOAD_FREG_FTN(DT0, fs);
5970 GEN_LOAD_FREG_FTN(DT1, ft);
5971 GEN_LOAD_FREG_FTN(DT2, fr);
5972 gen_op_float_nmuladd_d();
5973 GEN_STORE_FTN_FREG(fd, DT2);
5974 opn = "nmadd.d";
5975 break;
5976 case OPC_NMADD_PS:
5977 check_cp1_64bitmode(ctx);
5978 GEN_LOAD_FREG_FTN(WT0, fs);
5979 GEN_LOAD_FREG_FTN(WTH0, fs);
5980 GEN_LOAD_FREG_FTN(WT1, ft);
5981 GEN_LOAD_FREG_FTN(WTH1, ft);
5982 GEN_LOAD_FREG_FTN(WT2, fr);
5983 GEN_LOAD_FREG_FTN(WTH2, fr);
5984 gen_op_float_nmuladd_ps();
5985 GEN_STORE_FTN_FREG(fd, WT2);
5986 GEN_STORE_FTN_FREG(fd, WTH2);
5987 opn = "nmadd.ps";
5988 break;
5989 case OPC_NMSUB_S:
5990 check_cop1x(ctx);
5991 GEN_LOAD_FREG_FTN(WT0, fs);
5992 GEN_LOAD_FREG_FTN(WT1, ft);
5993 GEN_LOAD_FREG_FTN(WT2, fr);
5994 gen_op_float_nmulsub_s();
5995 GEN_STORE_FTN_FREG(fd, WT2);
5996 opn = "nmsub.s";
5997 break;
5998 case OPC_NMSUB_D:
5999 check_cop1x(ctx);
6000 check_cp1_registers(ctx, fd | fs | ft | fr);
6001 GEN_LOAD_FREG_FTN(DT0, fs);
6002 GEN_LOAD_FREG_FTN(DT1, ft);
6003 GEN_LOAD_FREG_FTN(DT2, fr);
6004 gen_op_float_nmulsub_d();
6005 GEN_STORE_FTN_FREG(fd, DT2);
6006 opn = "nmsub.d";
6007 break;
6008 case OPC_NMSUB_PS:
6009 check_cp1_64bitmode(ctx);
6010 GEN_LOAD_FREG_FTN(WT0, fs);
6011 GEN_LOAD_FREG_FTN(WTH0, fs);
6012 GEN_LOAD_FREG_FTN(WT1, ft);
6013 GEN_LOAD_FREG_FTN(WTH1, ft);
6014 GEN_LOAD_FREG_FTN(WT2, fr);
6015 GEN_LOAD_FREG_FTN(WTH2, fr);
6016 gen_op_float_nmulsub_ps();
6017 GEN_STORE_FTN_FREG(fd, WT2);
6018 GEN_STORE_FTN_FREG(fd, WTH2);
6019 opn = "nmsub.ps";
6020 break;
6021 default:
6022 MIPS_INVAL(opn);
6023 generate_exception (ctx, EXCP_RI);
6024 return;
6025 }
6026 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6027 fregnames[fs], fregnames[ft]);
6028 }
6029
6030 /* ISA extensions (ASEs) */
6031 /* MIPS16 extension to MIPS32 */
6032 /* SmartMIPS extension to MIPS32 */
6033
6034 #if defined(TARGET_MIPS64)
6035
6036 /* MDMX extension to MIPS64 */
6037
6038 #endif
6039
6040 static void decode_opc (CPUState *env, DisasContext *ctx)
6041 {
6042 int32_t offset;
6043 int rs, rt, rd, sa;
6044 uint32_t op, op1, op2;
6045 int16_t imm;
6046
6047 /* make sure instructions are on a word boundary */
6048 if (ctx->pc & 0x3) {
6049 env->CP0_BadVAddr = ctx->pc;
6050 generate_exception(ctx, EXCP_AdEL);
6051 return;
6052 }
6053
6054 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6055 int l1;
6056 /* Handle blikely not taken case */
6057 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6058 l1 = gen_new_label();
6059 gen_op_jnz_T2(l1);
6060 gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6061 gen_goto_tb(ctx, 1, ctx->pc + 4);
6062 gen_set_label(l1);
6063 }
6064 op = MASK_OP_MAJOR(ctx->opcode);
6065 rs = (ctx->opcode >> 21) & 0x1f;
6066 rt = (ctx->opcode >> 16) & 0x1f;
6067 rd = (ctx->opcode >> 11) & 0x1f;
6068 sa = (ctx->opcode >> 6) & 0x1f;
6069 imm = (int16_t)ctx->opcode;
6070 switch (op) {
6071 case OPC_SPECIAL:
6072 op1 = MASK_SPECIAL(ctx->opcode);
6073 switch (op1) {
6074 case OPC_SLL: /* Arithmetic with immediate */
6075 case OPC_SRL ... OPC_SRA:
6076 gen_arith_imm(env, ctx, op1, rd, rt, sa);
6077 break;
6078 case OPC_MOVZ ... OPC_MOVN:
6079 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6080 case OPC_SLLV: /* Arithmetic */
6081 case OPC_SRLV ... OPC_SRAV:
6082 case OPC_ADD ... OPC_NOR:
6083 case OPC_SLT ... OPC_SLTU:
6084 gen_arith(env, ctx, op1, rd, rs, rt);
6085 break;
6086 case OPC_MULT ... OPC_DIVU:
6087 if (sa) {
6088 check_insn(env, ctx, INSN_VR54XX);
6089 op1 = MASK_MUL_VR54XX(ctx->opcode);
6090 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6091 } else
6092 gen_muldiv(ctx, op1, rs, rt);
6093 break;
6094 case OPC_JR ... OPC_JALR:
6095 gen_compute_branch(ctx, op1, rs, rd, sa);
6096 return;
6097 case OPC_TGE ... OPC_TEQ: /* Traps */
6098 case OPC_TNE:
6099 gen_trap(ctx, op1, rs, rt, -1);
6100 break;
6101 case OPC_MFHI: /* Move from HI/LO */
6102 case OPC_MFLO:
6103 gen_HILO(ctx, op1, rd);
6104 break;
6105 case OPC_MTHI:
6106 case OPC_MTLO: /* Move to HI/LO */
6107 gen_HILO(ctx, op1, rs);
6108 break;
6109 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
6110 #ifdef MIPS_STRICT_STANDARD
6111 MIPS_INVAL("PMON / selsl");
6112 generate_exception(ctx, EXCP_RI);
6113 #else
6114 gen_op_pmon(sa);
6115 #endif
6116 break;
6117 case OPC_SYSCALL:
6118 generate_exception(ctx, EXCP_SYSCALL);
6119 break;
6120 case OPC_BREAK:
6121 generate_exception(ctx, EXCP_BREAK);
6122 break;
6123 case OPC_SPIM:
6124 #ifdef MIPS_STRICT_STANDARD
6125 MIPS_INVAL("SPIM");
6126 generate_exception(ctx, EXCP_RI);
6127 #else
6128 /* Implemented as RI exception for now. */
6129 MIPS_INVAL("spim (unofficial)");
6130 generate_exception(ctx, EXCP_RI);
6131 #endif
6132 break;
6133 case OPC_SYNC:
6134 /* Treat as NOP. */
6135 break;
6136
6137 case OPC_MOVCI:
6138 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6139 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6140 save_cpu_state(ctx, 1);
6141 check_cp1_enabled(ctx);
6142 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6143 (ctx->opcode >> 16) & 1);
6144 } else {
6145 generate_exception_err(ctx, EXCP_CpU, 1);
6146 }
6147 break;
6148
6149 #if defined(TARGET_MIPS64)
6150 /* MIPS64 specific opcodes */
6151 case OPC_DSLL:
6152 case OPC_DSRL ... OPC_DSRA:
6153 case OPC_DSLL32:
6154 case OPC_DSRL32 ... OPC_DSRA32:
6155 check_insn(env, ctx, ISA_MIPS3);
6156 check_mips_64(ctx);
6157 gen_arith_imm(env, ctx, op1, rd, rt, sa);
6158 break;
6159 case OPC_DSLLV:
6160 case OPC_DSRLV ... OPC_DSRAV:
6161 case OPC_DADD ... OPC_DSUBU:
6162 check_insn(env, ctx, ISA_MIPS3);
6163 check_mips_64(ctx);
6164 gen_arith(env, ctx, op1, rd, rs, rt);
6165 break;
6166 case OPC_DMULT ... OPC_DDIVU:
6167 check_insn(env, ctx, ISA_MIPS3);
6168 check_mips_64(ctx);
6169 gen_muldiv(ctx, op1, rs, rt);
6170 break;
6171 #endif
6172 default: /* Invalid */
6173 MIPS_INVAL("special");
6174 generate_exception(ctx, EXCP_RI);
6175 break;
6176 }
6177 break;
6178 case OPC_SPECIAL2:
6179 op1 = MASK_SPECIAL2(ctx->opcode);
6180 switch (op1) {
6181 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6182 case OPC_MSUB ... OPC_MSUBU:
6183 check_insn(env, ctx, ISA_MIPS32);
6184 gen_muldiv(ctx, op1, rs, rt);
6185 break;
6186 case OPC_MUL:
6187 gen_arith(env, ctx, op1, rd, rs, rt);
6188 break;
6189 case OPC_CLZ ... OPC_CLO:
6190 check_insn(env, ctx, ISA_MIPS32);
6191 gen_cl(ctx, op1, rd, rs);
6192 break;
6193 case OPC_SDBBP:
6194 /* XXX: not clear which exception should be raised
6195 * when in debug mode...
6196 */
6197 check_insn(env, ctx, ISA_MIPS32);
6198 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6199 generate_exception(ctx, EXCP_DBp);
6200 } else {
6201 generate_exception(ctx, EXCP_DBp);
6202 }
6203 /* Treat as NOP. */
6204 break;
6205 #if defined(TARGET_MIPS64)
6206 case OPC_DCLZ ... OPC_DCLO:
6207 check_insn(env, ctx, ISA_MIPS64);
6208 check_mips_64(ctx);
6209 gen_cl(ctx, op1, rd, rs);
6210 break;
6211 #endif
6212 default: /* Invalid */
6213 MIPS_INVAL("special2");
6214 generate_exception(ctx, EXCP_RI);
6215 break;
6216 }
6217 break;
6218 case OPC_SPECIAL3:
6219 op1 = MASK_SPECIAL3(ctx->opcode);
6220 switch (op1) {
6221 case OPC_EXT:
6222 case OPC_INS:
6223 check_insn(env, ctx, ISA_MIPS32R2);
6224 gen_bitops(ctx, op1, rt, rs, sa, rd);
6225 break;
6226 case OPC_BSHFL:
6227 check_insn(env, ctx, ISA_MIPS32R2);
6228 op2 = MASK_BSHFL(ctx->opcode);
6229 switch (op2) {
6230 case OPC_WSBH:
6231 GEN_LOAD_REG_T1(rt);
6232 gen_op_wsbh();
6233 break;
6234 case OPC_SEB:
6235 GEN_LOAD_REG_T1(rt);
6236 gen_op_seb();
6237 break;
6238 case OPC_SEH:
6239 GEN_LOAD_REG_T1(rt);
6240 gen_op_seh();
6241 break;
6242 default: /* Invalid */
6243 MIPS_INVAL("bshfl");
6244 generate_exception(ctx, EXCP_RI);
6245 break;
6246 }
6247 GEN_STORE_T0_REG(rd);
6248 break;
6249 case OPC_RDHWR:
6250 check_insn(env, ctx, ISA_MIPS32R2);
6251 switch (rd) {
6252 case 0:
6253 save_cpu_state(ctx, 1);
6254 gen_op_rdhwr_cpunum();
6255 break;
6256 case 1:
6257 save_cpu_state(ctx, 1);
6258 gen_op_rdhwr_synci_step();
6259 break;
6260 case 2:
6261 save_cpu_state(ctx, 1);
6262 gen_op_rdhwr_cc();
6263 break;
6264 case 3:
6265 save_cpu_state(ctx, 1);
6266 gen_op_rdhwr_ccres();
6267 break;
6268 case 29:
6269 #if defined (CONFIG_USER_ONLY)
6270 gen_op_tls_value();
6271 break;
6272 #endif
6273 default: /* Invalid */
6274 MIPS_INVAL("rdhwr");
6275 generate_exception(ctx, EXCP_RI);
6276 break;
6277 }
6278 GEN_STORE_T0_REG(rt);
6279 break;
6280 case OPC_FORK:
6281 check_insn(env, ctx, ASE_MT);
6282 GEN_LOAD_REG_T0(rt);
6283 GEN_LOAD_REG_T1(rs);
6284 gen_op_fork();
6285 break;
6286 case OPC_YIELD:
6287 check_insn(env, ctx, ASE_MT);
6288 GEN_LOAD_REG_T0(rs);
6289 gen_op_yield();
6290 GEN_STORE_T0_REG(rd);
6291 break;
6292 #if defined(TARGET_MIPS64)
6293 case OPC_DEXTM ... OPC_DEXT:
6294 case OPC_DINSM ... OPC_DINS:
6295 check_insn(env, ctx, ISA_MIPS64R2);
6296 check_mips_64(ctx);
6297 gen_bitops(ctx, op1, rt, rs, sa, rd);
6298 break;
6299 case OPC_DBSHFL:
6300 check_insn(env, ctx, ISA_MIPS64R2);
6301 check_mips_64(ctx);
6302 op2 = MASK_DBSHFL(ctx->opcode);
6303 switch (op2) {
6304 case OPC_DSBH:
6305 GEN_LOAD_REG_T1(rt);
6306 gen_op_dsbh();
6307 break;
6308 case OPC_DSHD:
6309 GEN_LOAD_REG_T1(rt);
6310 gen_op_dshd();
6311 break;
6312 default: /* Invalid */
6313 MIPS_INVAL("dbshfl");
6314 generate_exception(ctx, EXCP_RI);
6315 break;
6316 }
6317 GEN_STORE_T0_REG(rd);
6318 break;
6319 #endif
6320 default: /* Invalid */
6321 MIPS_INVAL("special3");
6322 generate_exception(ctx, EXCP_RI);
6323 break;
6324 }
6325 break;
6326 case OPC_REGIMM:
6327 op1 = MASK_REGIMM(ctx->opcode);
6328 switch (op1) {
6329 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6330 case OPC_BLTZAL ... OPC_BGEZALL:
6331 gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6332 return;
6333 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6334 case OPC_TNEI:
6335 gen_trap(ctx, op1, rs, -1, imm);
6336 break;
6337 case OPC_SYNCI:
6338 check_insn(env, ctx, ISA_MIPS32R2);
6339 /* Treat as NOP. */
6340 break;
6341 default: /* Invalid */
6342 MIPS_INVAL("regimm");
6343 generate_exception(ctx, EXCP_RI);
6344 break;
6345 }
6346 break;
6347 case OPC_CP0:
6348 check_cp0_enabled(ctx);
6349 op1 = MASK_CP0(ctx->opcode);
6350 switch (op1) {
6351 case OPC_MFC0:
6352 case OPC_MTC0:
6353 case OPC_MFTR:
6354 case OPC_MTTR:
6355 #if defined(TARGET_MIPS64)
6356 case OPC_DMFC0:
6357 case OPC_DMTC0:
6358 #endif
6359 gen_cp0(env, ctx, op1, rt, rd);
6360 break;
6361 case OPC_C0_FIRST ... OPC_C0_LAST:
6362 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6363 break;
6364 case OPC_MFMC0:
6365 op2 = MASK_MFMC0(ctx->opcode);
6366 switch (op2) {
6367 case OPC_DMT:
6368 check_insn(env, ctx, ASE_MT);
6369 gen_op_dmt();
6370 break;
6371 case OPC_EMT:
6372 check_insn(env, ctx, ASE_MT);
6373 gen_op_emt();
6374 break;
6375 case OPC_DVPE:
6376 check_insn(env, ctx, ASE_MT);
6377 gen_op_dvpe();
6378 break;
6379 case OPC_EVPE:
6380 check_insn(env, ctx, ASE_MT);
6381 gen_op_evpe();
6382 break;
6383 case OPC_DI:
6384 check_insn(env, ctx, ISA_MIPS32R2);
6385 save_cpu_state(ctx, 1);
6386 gen_op_di();
6387 /* Stop translation as we may have switched the execution mode */
6388 ctx->bstate = BS_STOP;
6389 break;
6390 case OPC_EI:
6391 check_insn(env, ctx, ISA_MIPS32R2);
6392 save_cpu_state(ctx, 1);
6393 gen_op_ei();
6394 /* Stop translation as we may have switched the execution mode */
6395 ctx->bstate = BS_STOP;
6396 break;
6397 default: /* Invalid */
6398 MIPS_INVAL("mfmc0");
6399 generate_exception(ctx, EXCP_RI);
6400 break;
6401 }
6402 GEN_STORE_T0_REG(rt);
6403 break;
6404 case OPC_RDPGPR:
6405 check_insn(env, ctx, ISA_MIPS32R2);
6406 GEN_LOAD_SRSREG_TN(T0, rt);
6407 GEN_STORE_T0_REG(rd);
6408 break;
6409 case OPC_WRPGPR:
6410 check_insn(env, ctx, ISA_MIPS32R2);
6411 GEN_LOAD_REG_T0(rt);
6412 GEN_STORE_TN_SRSREG(rd, T0);
6413 break;
6414 default:
6415 MIPS_INVAL("cp0");
6416 generate_exception(ctx, EXCP_RI);
6417 break;
6418 }
6419 break;
6420 case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6421 gen_arith_imm(env, ctx, op, rt, rs, imm);
6422 break;
6423 case OPC_J ... OPC_JAL: /* Jump */
6424 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6425 gen_compute_branch(ctx, op, rs, rt, offset);
6426 return;
6427 case OPC_BEQ ... OPC_BGTZ: /* Branch */
6428 case OPC_BEQL ... OPC_BGTZL:
6429 gen_compute_branch(ctx, op, rs, rt, imm << 2);
6430 return;
6431 case OPC_LB ... OPC_LWR: /* Load and stores */
6432 case OPC_SB ... OPC_SW:
6433 case OPC_SWR:
6434 case OPC_LL:
6435 case OPC_SC:
6436 gen_ldst(ctx, op, rt, rs, imm);
6437 break;
6438 case OPC_CACHE:
6439 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6440 /* Treat as NOP. */
6441 break;
6442 case OPC_PREF:
6443 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6444 /* Treat as NOP. */
6445 break;
6446
6447 /* Floating point (COP1). */
6448 case OPC_LWC1:
6449 case OPC_LDC1:
6450 case OPC_SWC1:
6451 case OPC_SDC1:
6452 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6453 save_cpu_state(ctx, 1);
6454 check_cp1_enabled(ctx);
6455 gen_flt_ldst(ctx, op, rt, rs, imm);
6456 } else {
6457 generate_exception_err(ctx, EXCP_CpU, 1);
6458 }
6459 break;
6460
6461 case OPC_CP1:
6462 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6463 save_cpu_state(ctx, 1);
6464 check_cp1_enabled(ctx);
6465 op1 = MASK_CP1(ctx->opcode);
6466 switch (op1) {
6467 case OPC_MFHC1:
6468 case OPC_MTHC1:
6469 check_insn(env, ctx, ISA_MIPS32R2);
6470 case OPC_MFC1:
6471 case OPC_CFC1:
6472 case OPC_MTC1:
6473 case OPC_CTC1:
6474 gen_cp1(ctx, op1, rt, rd);
6475 break;
6476 #if defined(TARGET_MIPS64)
6477 case OPC_DMFC1:
6478 case OPC_DMTC1:
6479 check_insn(env, ctx, ISA_MIPS3);
6480 gen_cp1(ctx, op1, rt, rd);
6481 break;
6482 #endif
6483 case OPC_BC1ANY2:
6484 case OPC_BC1ANY4:
6485 check_cop1x(ctx);
6486 check_insn(env, ctx, ASE_MIPS3D);
6487 /* fall through */
6488 case OPC_BC1:
6489 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6490 (rt >> 2) & 0x7, imm << 2);
6491 return;
6492 case OPC_S_FMT:
6493 case OPC_D_FMT:
6494 case OPC_W_FMT:
6495 case OPC_L_FMT:
6496 case OPC_PS_FMT:
6497 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
6498 (imm >> 8) & 0x7);
6499 break;
6500 default:
6501 MIPS_INVAL("cp1");
6502 generate_exception (ctx, EXCP_RI);
6503 break;
6504 }
6505 } else {
6506 generate_exception_err(ctx, EXCP_CpU, 1);
6507 }
6508 break;
6509
6510 /* COP2. */
6511 case OPC_LWC2:
6512 case OPC_LDC2:
6513 case OPC_SWC2:
6514 case OPC_SDC2:
6515 case OPC_CP2:
6516 /* COP2: Not implemented. */
6517 generate_exception_err(ctx, EXCP_CpU, 2);
6518 break;
6519
6520 case OPC_CP3:
6521 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6522 save_cpu_state(ctx, 1);
6523 check_cp1_enabled(ctx);
6524 op1 = MASK_CP3(ctx->opcode);
6525 switch (op1) {
6526 case OPC_LWXC1:
6527 case OPC_LDXC1:
6528 case OPC_LUXC1:
6529 case OPC_SWXC1:
6530 case OPC_SDXC1:
6531 case OPC_SUXC1:
6532 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
6533 break;
6534 case OPC_PREFX:
6535 /* Treat as NOP. */
6536 break;
6537 case OPC_ALNV_PS:
6538 case OPC_MADD_S:
6539 case OPC_MADD_D:
6540 case OPC_MADD_PS:
6541 case OPC_MSUB_S:
6542 case OPC_MSUB_D:
6543 case OPC_MSUB_PS:
6544 case OPC_NMADD_S:
6545 case OPC_NMADD_D:
6546 case OPC_NMADD_PS:
6547 case OPC_NMSUB_S:
6548 case OPC_NMSUB_D:
6549 case OPC_NMSUB_PS:
6550 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
6551 break;
6552 default:
6553 MIPS_INVAL("cp3");
6554 generate_exception (ctx, EXCP_RI);
6555 break;
6556 }
6557 } else {
6558 generate_exception_err(ctx, EXCP_CpU, 1);
6559 }
6560 break;
6561
6562 #if defined(TARGET_MIPS64)
6563 /* MIPS64 opcodes */
6564 case OPC_LWU:
6565 case OPC_LDL ... OPC_LDR:
6566 case OPC_SDL ... OPC_SDR:
6567 case OPC_LLD:
6568 case OPC_LD:
6569 case OPC_SCD:
6570 case OPC_SD:
6571 check_insn(env, ctx, ISA_MIPS3);
6572 check_mips_64(ctx);
6573 gen_ldst(ctx, op, rt, rs, imm);
6574 break;
6575 case OPC_DADDI ... OPC_DADDIU:
6576 check_insn(env, ctx, ISA_MIPS3);
6577 check_mips_64(ctx);
6578 gen_arith_imm(env, ctx, op, rt, rs, imm);
6579 break;
6580 #endif
6581 case OPC_JALX:
6582 check_insn(env, ctx, ASE_MIPS16);
6583 /* MIPS16: Not implemented. */
6584 case OPC_MDMX:
6585 check_insn(env, ctx, ASE_MDMX);
6586 /* MDMX: Not implemented. */
6587 default: /* Invalid */
6588 MIPS_INVAL("major opcode");
6589 generate_exception(ctx, EXCP_RI);
6590 break;
6591 }
6592 if (ctx->hflags & MIPS_HFLAG_BMASK) {
6593 int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6594 /* Branches completion */
6595 ctx->hflags &= ~MIPS_HFLAG_BMASK;
6596 ctx->bstate = BS_BRANCH;
6597 save_cpu_state(ctx, 0);
6598 switch (hflags) {
6599 case MIPS_HFLAG_B:
6600 /* unconditional branch */
6601 MIPS_DEBUG("unconditional branch");
6602 gen_goto_tb(ctx, 0, ctx->btarget);
6603 break;
6604 case MIPS_HFLAG_BL:
6605 /* blikely taken case */
6606 MIPS_DEBUG("blikely branch taken");
6607 gen_goto_tb(ctx, 0, ctx->btarget);
6608 break;
6609 case MIPS_HFLAG_BC:
6610 /* Conditional branch */
6611 MIPS_DEBUG("conditional branch");
6612 {
6613 int l1;
6614 l1 = gen_new_label();
6615 gen_op_jnz_T2(l1);
6616 gen_goto_tb(ctx, 1, ctx->pc + 4);
6617 gen_set_label(l1);
6618 gen_goto_tb(ctx, 0, ctx->btarget);
6619 }
6620 break;
6621 case MIPS_HFLAG_BR:
6622 /* unconditional branch to register */
6623 MIPS_DEBUG("branch to register");
6624 gen_op_breg();
6625 tcg_gen_exit_tb(0);
6626 break;
6627 default:
6628 MIPS_DEBUG("unknown branch");
6629 break;
6630 }
6631 }
6632 }
6633
6634 static always_inline int
6635 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
6636 int search_pc)
6637 {
6638 DisasContext ctx;
6639 target_ulong pc_start;
6640 uint16_t *gen_opc_end;
6641 int j, lj = -1;
6642
6643 if (search_pc && loglevel)
6644 fprintf (logfile, "search pc %d\n", search_pc);
6645
6646 pc_start = tb->pc;
6647 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6648 ctx.pc = pc_start;
6649 ctx.saved_pc = -1;
6650 ctx.tb = tb;
6651 ctx.bstate = BS_NONE;
6652 /* Restore delay slot state from the tb context. */
6653 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
6654 restore_cpu_state(env, &ctx);
6655 #if defined(CONFIG_USER_ONLY)
6656 ctx.mem_idx = MIPS_HFLAG_UM;
6657 #else
6658 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
6659 #endif
6660 #ifdef DEBUG_DISAS
6661 if (loglevel & CPU_LOG_TB_CPU) {
6662 fprintf(logfile, "------------------------------------------------\n");
6663 /* FIXME: This may print out stale hflags from env... */
6664 cpu_dump_state(env, logfile, fprintf, 0);
6665 }
6666 #endif
6667 #ifdef MIPS_DEBUG_DISAS
6668 if (loglevel & CPU_LOG_TB_IN_ASM)
6669 fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
6670 tb, ctx.mem_idx, ctx.hflags);
6671 #endif
6672 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
6673 if (env->nb_breakpoints > 0) {
6674 for(j = 0; j < env->nb_breakpoints; j++) {
6675 if (env->breakpoints[j] == ctx.pc) {
6676 save_cpu_state(&ctx, 1);
6677 ctx.bstate = BS_BRANCH;
6678 gen_op_debug();
6679 /* Include the breakpoint location or the tb won't
6680 * be flushed when it must be. */
6681 ctx.pc += 4;
6682 goto done_generating;
6683 }
6684 }
6685 }
6686
6687 if (search_pc) {
6688 j = gen_opc_ptr - gen_opc_buf;
6689 if (lj < j) {
6690 lj++;
6691 while (lj < j)
6692 gen_opc_instr_start[lj++] = 0;
6693 }
6694 gen_opc_pc[lj] = ctx.pc;
6695 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
6696 gen_opc_instr_start[lj] = 1;
6697 }
6698 ctx.opcode = ldl_code(ctx.pc);
6699 decode_opc(env, &ctx);
6700 ctx.pc += 4;
6701
6702 if (env->singlestep_enabled)
6703 break;
6704
6705 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
6706 break;
6707
6708 #if defined (MIPS_SINGLE_STEP)
6709 break;
6710 #endif
6711 }
6712 if (env->singlestep_enabled) {
6713 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
6714 gen_op_debug();
6715 } else {
6716 switch (ctx.bstate) {
6717 case BS_STOP:
6718 gen_op_interrupt_restart();
6719 gen_goto_tb(&ctx, 0, ctx.pc);
6720 break;
6721 case BS_NONE:
6722 save_cpu_state(&ctx, 0);
6723 gen_goto_tb(&ctx, 0, ctx.pc);
6724 break;
6725 case BS_EXCP:
6726 gen_op_interrupt_restart();
6727 tcg_gen_exit_tb(0);
6728 break;
6729 case BS_BRANCH:
6730 default:
6731 break;
6732 }
6733 }
6734 done_generating:
6735 ctx.last_T0_store = NULL;
6736 *gen_opc_ptr = INDEX_op_end;
6737 if (search_pc) {
6738 j = gen_opc_ptr - gen_opc_buf;
6739 lj++;
6740 while (lj <= j)
6741 gen_opc_instr_start[lj++] = 0;
6742 } else {
6743 tb->size = ctx.pc - pc_start;
6744 }
6745 #ifdef DEBUG_DISAS
6746 #if defined MIPS_DEBUG_DISAS
6747 if (loglevel & CPU_LOG_TB_IN_ASM)
6748 fprintf(logfile, "\n");
6749 #endif
6750 if (loglevel & CPU_LOG_TB_IN_ASM) {
6751 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6752 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6753 fprintf(logfile, "\n");
6754 }
6755 if (loglevel & CPU_LOG_TB_CPU) {
6756 fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6757 }
6758 #endif
6759
6760 return 0;
6761 }
6762
6763 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6764 {
6765 return gen_intermediate_code_internal(env, tb, 0);
6766 }
6767
6768 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6769 {
6770 return gen_intermediate_code_internal(env, tb, 1);
6771 }
6772
6773 void fpu_dump_state(CPUState *env, FILE *f,
6774 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6775 int flags)
6776 {
6777 int i;
6778 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6779
6780 #define printfpr(fp) \
6781 do { \
6782 if (is_fpu64) \
6783 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n", \
6784 (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd, \
6785 (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6786 else { \
6787 fpr_t tmp; \
6788 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
6789 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
6790 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n", \
6791 tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd, \
6792 tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]); \
6793 } \
6794 } while(0)
6795
6796
6797 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
6798 env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
6799 get_float_exception_flags(&env->fpu->fp_status));
6800 fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
6801 fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
6802 fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
6803 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6804 fpu_fprintf(f, "%3s: ", fregnames[i]);
6805 printfpr(&env->fpu->fpr[i]);
6806 }
6807
6808 #undef printfpr
6809 }
6810
6811 void dump_fpu (CPUState *env)
6812 {
6813 if (loglevel) {
6814 fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6815 env->PC[env->current_tc], env->HI[env->current_tc][0], env->LO[env->current_tc][0], env->hflags, env->btarget, env->bcond);
6816 fpu_dump_state(env, logfile, fprintf, 0);
6817 }
6818 }
6819
6820 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6821 /* Debug help: The architecture requires 32bit code to maintain proper
6822 sign-extened values on 64bit machines. */
6823
6824 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6825
6826 void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6827 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6828 int flags)
6829 {
6830 int i;
6831
6832 if (!SIGN_EXT_P(env->PC[env->current_tc]))
6833 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
6834 if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
6835 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
6836 if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
6837 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
6838 if (!SIGN_EXT_P(env->btarget))
6839 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6840
6841 for (i = 0; i < 32; i++) {
6842 if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
6843 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
6844 }
6845
6846 if (!SIGN_EXT_P(env->CP0_EPC))
6847 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6848 if (!SIGN_EXT_P(env->CP0_LLAddr))
6849 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6850 }
6851 #endif
6852
6853 void cpu_dump_state (CPUState *env, FILE *f,
6854 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6855 int flags)
6856 {
6857 int i;
6858
6859 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",
6860 env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
6861 for (i = 0; i < 32; i++) {
6862 if ((i & 3) == 0)
6863 cpu_fprintf(f, "GPR%02d:", i);
6864 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
6865 if ((i & 3) == 3)
6866 cpu_fprintf(f, "\n");
6867 }
6868
6869 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
6870 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6871 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6872 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6873 if (env->hflags & MIPS_HFLAG_FPU)
6874 fpu_dump_state(env, f, cpu_fprintf, flags);
6875 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6876 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6877 #endif
6878 }
6879
6880 #include "translate_init.c"
6881
6882 CPUMIPSState *cpu_mips_init (const char *cpu_model)
6883 {
6884 CPUMIPSState *env;
6885 const mips_def_t *def;
6886
6887 def = cpu_mips_find_by_name(cpu_model);
6888 if (!def)
6889 return NULL;
6890 env = qemu_mallocz(sizeof(CPUMIPSState));
6891 if (!env)
6892 return NULL;
6893 env->cpu_model = def;
6894
6895 cpu_exec_init(env);
6896 env->cpu_model_str = cpu_model;
6897 cpu_reset(env);
6898 return env;
6899 }
6900
6901 void cpu_reset (CPUMIPSState *env)
6902 {
6903 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6904
6905 tlb_flush(env, 1);
6906
6907 /* Minimal init */
6908 #if !defined(CONFIG_USER_ONLY)
6909 if (env->hflags & MIPS_HFLAG_BMASK) {
6910 /* If the exception was raised from a delay slot,
6911 * come back to the jump. */
6912 env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
6913 } else {
6914 env->CP0_ErrorEPC = env->PC[env->current_tc];
6915 }
6916 env->PC[env->current_tc] = (int32_t)0xBFC00000;
6917 env->CP0_Wired = 0;
6918 /* SMP not implemented */
6919 env->CP0_EBase = 0x80000000;
6920 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6921 /* vectored interrupts not implemented, timer on int 7,
6922 no performance counters. */
6923 env->CP0_IntCtl = 0xe0000000;
6924 {
6925 int i;
6926
6927 for (i = 0; i < 7; i++) {
6928 env->CP0_WatchLo[i] = 0;
6929 env->CP0_WatchHi[i] = 0x80000000;
6930 }
6931 env->CP0_WatchLo[7] = 0;
6932 env->CP0_WatchHi[7] = 0;
6933 }
6934 /* Count register increments in debug mode, EJTAG version 1 */
6935 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6936 #endif
6937 env->exception_index = EXCP_NONE;
6938 #if defined(CONFIG_USER_ONLY)
6939 env->hflags = MIPS_HFLAG_UM;
6940 env->user_mode_only = 1;
6941 #else
6942 env->hflags = MIPS_HFLAG_CP0;
6943 #endif
6944 cpu_mips_register(env, env->cpu_model);
6945 }