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