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