Statistics
| Branch: | Revision:

root / target-mips / translate.c @ fcb4a419

History | View | Annotate | Download (144.4 kB)

1 6af0bf9c bellard
/*
2 6af0bf9c bellard
 *  MIPS32 emulation for qemu: main translation routines.
3 6af0bf9c bellard
 * 
4 6af0bf9c bellard
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5 6ea83fed bellard
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6 bb8a53ad ths
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 6af0bf9c bellard
 *
8 6af0bf9c bellard
 * This library is free software; you can redistribute it and/or
9 6af0bf9c bellard
 * modify it under the terms of the GNU Lesser General Public
10 6af0bf9c bellard
 * License as published by the Free Software Foundation; either
11 6af0bf9c bellard
 * version 2 of the License, or (at your option) any later version.
12 6af0bf9c bellard
 *
13 6af0bf9c bellard
 * This library is distributed in the hope that it will be useful,
14 6af0bf9c bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 6af0bf9c bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 6af0bf9c bellard
 * Lesser General Public License for more details.
17 6af0bf9c bellard
 *
18 6af0bf9c bellard
 * You should have received a copy of the GNU Lesser General Public
19 6af0bf9c bellard
 * License along with this library; if not, write to the Free Software
20 6af0bf9c bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 6af0bf9c bellard
 */
22 6af0bf9c bellard
23 6af0bf9c bellard
#include <stdarg.h>
24 6af0bf9c bellard
#include <stdlib.h>
25 6af0bf9c bellard
#include <stdio.h>
26 6af0bf9c bellard
#include <string.h>
27 6af0bf9c bellard
#include <inttypes.h>
28 6af0bf9c bellard
29 6af0bf9c bellard
#include "cpu.h"
30 6af0bf9c bellard
#include "exec-all.h"
31 6af0bf9c bellard
#include "disas.h"
32 6af0bf9c bellard
33 eeef26cd bellard
//#define MIPS_DEBUG_DISAS
34 c570fd16 ths
//#define MIPS_DEBUG_SIGN_EXTENSIONS
35 6af0bf9c bellard
//#define MIPS_SINGLE_STEP
36 6af0bf9c bellard
37 c53be334 bellard
#ifdef USE_DIRECT_JUMP
38 c53be334 bellard
#define TBPARAM(x)
39 c53be334 bellard
#else
40 c53be334 bellard
#define TBPARAM(x) (long)(x)
41 c53be334 bellard
#endif
42 c53be334 bellard
43 6af0bf9c bellard
enum {
44 6af0bf9c bellard
#define DEF(s, n, copy_size) INDEX_op_ ## s,
45 6af0bf9c bellard
#include "opc.h"
46 6af0bf9c bellard
#undef DEF
47 6af0bf9c bellard
    NB_OPS,
48 6af0bf9c bellard
};
49 6af0bf9c bellard
50 6af0bf9c bellard
static uint16_t *gen_opc_ptr;
51 6af0bf9c bellard
static uint32_t *gen_opparam_ptr;
52 6af0bf9c bellard
53 6af0bf9c bellard
#include "gen-op.h"
54 6af0bf9c bellard
55 7a387fff ths
/* MIPS major opcodes */
56 7a387fff ths
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
57 e37e863f bellard
58 e37e863f bellard
enum {
59 e37e863f bellard
    /* indirect opcode tables */
60 7a387fff ths
    OPC_SPECIAL  = (0x00 << 26),
61 7a387fff ths
    OPC_REGIMM   = (0x01 << 26),
62 7a387fff ths
    OPC_CP0      = (0x10 << 26),
63 7a387fff ths
    OPC_CP1      = (0x11 << 26),
64 7a387fff ths
    OPC_CP2      = (0x12 << 26),
65 7a387fff ths
    OPC_CP3      = (0x13 << 26),
66 7a387fff ths
    OPC_SPECIAL2 = (0x1C << 26),
67 7a387fff ths
    OPC_SPECIAL3 = (0x1F << 26),
68 e37e863f bellard
    /* arithmetic with immediate */
69 7a387fff ths
    OPC_ADDI     = (0x08 << 26),
70 7a387fff ths
    OPC_ADDIU    = (0x09 << 26),
71 7a387fff ths
    OPC_SLTI     = (0x0A << 26),
72 7a387fff ths
    OPC_SLTIU    = (0x0B << 26),
73 7a387fff ths
    OPC_ANDI     = (0x0C << 26),
74 7a387fff ths
    OPC_ORI      = (0x0D << 26),
75 7a387fff ths
    OPC_XORI     = (0x0E << 26),
76 7a387fff ths
    OPC_LUI      = (0x0F << 26),
77 7a387fff ths
    OPC_DADDI    = (0x18 << 26),
78 7a387fff ths
    OPC_DADDIU   = (0x19 << 26),
79 e37e863f bellard
    /* Jump and branches */
80 7a387fff ths
    OPC_J        = (0x02 << 26),
81 7a387fff ths
    OPC_JAL      = (0x03 << 26),
82 7a387fff ths
    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
83 7a387fff ths
    OPC_BEQL     = (0x14 << 26),
84 7a387fff ths
    OPC_BNE      = (0x05 << 26),
85 7a387fff ths
    OPC_BNEL     = (0x15 << 26),
86 7a387fff ths
    OPC_BLEZ     = (0x06 << 26),
87 7a387fff ths
    OPC_BLEZL    = (0x16 << 26),
88 7a387fff ths
    OPC_BGTZ     = (0x07 << 26),
89 7a387fff ths
    OPC_BGTZL    = (0x17 << 26),
90 7a387fff ths
    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
91 e37e863f bellard
    /* Load and stores */
92 7a387fff ths
    OPC_LDL      = (0x1A << 26),
93 7a387fff ths
    OPC_LDR      = (0x1B << 26),
94 7a387fff ths
    OPC_LB       = (0x20 << 26),
95 7a387fff ths
    OPC_LH       = (0x21 << 26),
96 7a387fff ths
    OPC_LWL      = (0x22 << 26),
97 7a387fff ths
    OPC_LW       = (0x23 << 26),
98 7a387fff ths
    OPC_LBU      = (0x24 << 26),
99 7a387fff ths
    OPC_LHU      = (0x25 << 26),
100 7a387fff ths
    OPC_LWR      = (0x26 << 26),
101 7a387fff ths
    OPC_LWU      = (0x27 << 26),
102 7a387fff ths
    OPC_SB       = (0x28 << 26),
103 7a387fff ths
    OPC_SH       = (0x29 << 26),
104 7a387fff ths
    OPC_SWL      = (0x2A << 26),
105 7a387fff ths
    OPC_SW       = (0x2B << 26),
106 7a387fff ths
    OPC_SDL      = (0x2C << 26),
107 7a387fff ths
    OPC_SDR      = (0x2D << 26),
108 7a387fff ths
    OPC_SWR      = (0x2E << 26),
109 7a387fff ths
    OPC_LL       = (0x30 << 26),
110 7a387fff ths
    OPC_LLD      = (0x34 << 26),
111 7a387fff ths
    OPC_LD       = (0x37 << 26),
112 7a387fff ths
    OPC_SC       = (0x38 << 26),
113 7a387fff ths
    OPC_SCD      = (0x3C << 26),
114 7a387fff ths
    OPC_SD       = (0x3F << 26),
115 e37e863f bellard
    /* Floating point load/store */
116 7a387fff ths
    OPC_LWC1     = (0x31 << 26),
117 7a387fff ths
    OPC_LWC2     = (0x32 << 26),
118 7a387fff ths
    OPC_LDC1     = (0x35 << 26),
119 7a387fff ths
    OPC_LDC2     = (0x36 << 26),
120 7a387fff ths
    OPC_SWC1     = (0x39 << 26),
121 7a387fff ths
    OPC_SWC2     = (0x3A << 26),
122 7a387fff ths
    OPC_SDC1     = (0x3D << 26),
123 7a387fff ths
    OPC_SDC2     = (0x3E << 26),
124 7a387fff ths
    /* MDMX ASE specific */
125 7a387fff ths
    OPC_MDMX     = (0x1E << 26),
126 e37e863f bellard
    /* Cache and prefetch */
127 7a387fff ths
    OPC_CACHE    = (0x2F << 26),
128 7a387fff ths
    OPC_PREF     = (0x33 << 26),
129 7a387fff ths
    /* Reserved major opcode */
130 7a387fff ths
    OPC_MAJOR3B_RESERVED = (0x3B << 26),
131 e37e863f bellard
};
132 e37e863f bellard
133 e37e863f bellard
/* MIPS special opcodes */
134 7a387fff ths
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
135 7a387fff ths
136 e37e863f bellard
enum {
137 e37e863f bellard
    /* Shifts */
138 7a387fff ths
    OPC_SLL      = 0x00 | OPC_SPECIAL,
139 e37e863f bellard
    /* NOP is SLL r0, r0, 0   */
140 e37e863f bellard
    /* SSNOP is SLL r0, r0, 1 */
141 7a387fff ths
    /* EHB is SLL r0, r0, 3 */
142 7a387fff ths
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
143 7a387fff ths
    OPC_SRA      = 0x03 | OPC_SPECIAL,
144 7a387fff ths
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
145 7a387fff ths
    OPC_SRLV     = 0x06 | OPC_SPECIAL,
146 7a387fff ths
    OPC_SRAV     = 0x07 | OPC_SPECIAL,
147 7a387fff ths
    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
148 7a387fff ths
    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
149 7a387fff ths
    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
150 7a387fff ths
    OPC_DSLL     = 0x38 | OPC_SPECIAL,
151 7a387fff ths
    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
152 7a387fff ths
    OPC_DSRA     = 0x3B | OPC_SPECIAL,
153 7a387fff ths
    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
154 7a387fff ths
    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
155 7a387fff ths
    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
156 e37e863f bellard
    /* Multiplication / division */
157 7a387fff ths
    OPC_MULT     = 0x18 | OPC_SPECIAL,
158 7a387fff ths
    OPC_MULTU    = 0x19 | OPC_SPECIAL,
159 7a387fff ths
    OPC_DIV      = 0x1A | OPC_SPECIAL,
160 7a387fff ths
    OPC_DIVU     = 0x1B | OPC_SPECIAL,
161 7a387fff ths
    OPC_DMULT    = 0x1C | OPC_SPECIAL,
162 7a387fff ths
    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
163 7a387fff ths
    OPC_DDIV     = 0x1E | OPC_SPECIAL,
164 7a387fff ths
    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
165 e37e863f bellard
    /* 2 registers arithmetic / logic */
166 7a387fff ths
    OPC_ADD      = 0x20 | OPC_SPECIAL,
167 7a387fff ths
    OPC_ADDU     = 0x21 | OPC_SPECIAL,
168 7a387fff ths
    OPC_SUB      = 0x22 | OPC_SPECIAL,
169 7a387fff ths
    OPC_SUBU     = 0x23 | OPC_SPECIAL,
170 7a387fff ths
    OPC_AND      = 0x24 | OPC_SPECIAL,
171 7a387fff ths
    OPC_OR       = 0x25 | OPC_SPECIAL,
172 7a387fff ths
    OPC_XOR      = 0x26 | OPC_SPECIAL,
173 7a387fff ths
    OPC_NOR      = 0x27 | OPC_SPECIAL,
174 7a387fff ths
    OPC_SLT      = 0x2A | OPC_SPECIAL,
175 7a387fff ths
    OPC_SLTU     = 0x2B | OPC_SPECIAL,
176 7a387fff ths
    OPC_DADD     = 0x2C | OPC_SPECIAL,
177 7a387fff ths
    OPC_DADDU    = 0x2D | OPC_SPECIAL,
178 7a387fff ths
    OPC_DSUB     = 0x2E | OPC_SPECIAL,
179 7a387fff ths
    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
180 e37e863f bellard
    /* Jumps */
181 7a387fff ths
    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
182 7a387fff ths
    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
183 e37e863f bellard
    /* Traps */
184 7a387fff ths
    OPC_TGE      = 0x30 | OPC_SPECIAL,
185 7a387fff ths
    OPC_TGEU     = 0x31 | OPC_SPECIAL,
186 7a387fff ths
    OPC_TLT      = 0x32 | OPC_SPECIAL,
187 7a387fff ths
    OPC_TLTU     = 0x33 | OPC_SPECIAL,
188 7a387fff ths
    OPC_TEQ      = 0x34 | OPC_SPECIAL,
189 7a387fff ths
    OPC_TNE      = 0x36 | OPC_SPECIAL,
190 e37e863f bellard
    /* HI / LO registers load & stores */
191 7a387fff ths
    OPC_MFHI     = 0x10 | OPC_SPECIAL,
192 7a387fff ths
    OPC_MTHI     = 0x11 | OPC_SPECIAL,
193 7a387fff ths
    OPC_MFLO     = 0x12 | OPC_SPECIAL,
194 7a387fff ths
    OPC_MTLO     = 0x13 | OPC_SPECIAL,
195 e37e863f bellard
    /* Conditional moves */
196 7a387fff ths
    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
197 7a387fff ths
    OPC_MOVN     = 0x0B | OPC_SPECIAL,
198 e37e863f bellard
199 7a387fff ths
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200 e37e863f bellard
201 e37e863f bellard
    /* Special */
202 7a387fff ths
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
203 7a387fff ths
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
204 7a387fff ths
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
205 7a387fff ths
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
206 7a387fff ths
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
207 7a387fff ths
208 7a387fff ths
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
209 7a387fff ths
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
210 7a387fff ths
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
211 7a387fff ths
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
212 7a387fff ths
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
213 7a387fff ths
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
214 7a387fff ths
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
215 7a387fff ths
};
216 7a387fff ths
217 7a387fff ths
/* REGIMM (rt field) opcodes */
218 7a387fff ths
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
219 7a387fff ths
220 7a387fff ths
enum {
221 7a387fff ths
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
222 7a387fff ths
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
223 7a387fff ths
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
224 7a387fff ths
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
225 7a387fff ths
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
226 7a387fff ths
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
227 7a387fff ths
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
228 7a387fff ths
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
229 7a387fff ths
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
230 7a387fff ths
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
231 7a387fff ths
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
232 7a387fff ths
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
233 7a387fff ths
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
234 7a387fff ths
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
235 7a387fff ths
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
236 e37e863f bellard
};
237 e37e863f bellard
238 7a387fff ths
/* Special2 opcodes */
239 7a387fff ths
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
240 7a387fff ths
241 e37e863f bellard
enum {
242 7a387fff ths
    /* Multiply & xxx operations */
243 7a387fff ths
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
244 7a387fff ths
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
245 7a387fff ths
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
246 7a387fff ths
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
247 7a387fff ths
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
248 e37e863f bellard
    /* Misc */
249 7a387fff ths
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
250 7a387fff ths
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
251 7a387fff ths
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
252 7a387fff ths
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
253 e37e863f bellard
    /* Special */
254 7a387fff ths
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
255 7a387fff ths
};
256 7a387fff ths
257 7a387fff ths
/* Special3 opcodes */
258 7a387fff ths
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
259 7a387fff ths
260 7a387fff ths
enum {
261 7a387fff ths
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
262 7a387fff ths
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
263 7a387fff ths
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
264 7a387fff ths
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
265 7a387fff ths
    OPC_INS      = 0x04 | OPC_SPECIAL3,
266 7a387fff ths
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
267 7a387fff ths
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
268 7a387fff ths
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
269 7a387fff ths
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
270 7a387fff ths
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
271 7a387fff ths
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
272 e37e863f bellard
};
273 e37e863f bellard
274 7a387fff ths
/* BSHFL opcodes */
275 7a387fff ths
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
276 7a387fff ths
277 e37e863f bellard
enum {
278 7a387fff ths
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
279 7a387fff ths
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
280 7a387fff ths
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
281 e37e863f bellard
};
282 e37e863f bellard
283 7a387fff ths
/* DBSHFL opcodes */
284 7a387fff ths
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
285 7a387fff ths
286 e37e863f bellard
enum {
287 7a387fff ths
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
288 7a387fff ths
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
289 e37e863f bellard
};
290 e37e863f bellard
291 7a387fff ths
/* Coprocessor 0 (rs field) */
292 7a387fff ths
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
293 7a387fff ths
294 6ea83fed bellard
enum {
295 7a387fff ths
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
296 7a387fff ths
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
297 7a387fff ths
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
298 7a387fff ths
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
299 7a387fff ths
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
300 7a387fff ths
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
301 7a387fff ths
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
302 7a387fff ths
    OPC_C0       = (0x10 << 21) | OPC_CP0,
303 7a387fff ths
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
304 7a387fff ths
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
305 6ea83fed bellard
};
306 7a387fff ths
307 7a387fff ths
/* MFMC0 opcodes */
308 b48cfdff ths
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
309 7a387fff ths
310 7a387fff ths
enum {
311 7a387fff ths
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
312 7a387fff ths
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
313 7a387fff ths
};
314 7a387fff ths
315 7a387fff ths
/* Coprocessor 0 (with rs == C0) */
316 7a387fff ths
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
317 7a387fff ths
318 7a387fff ths
enum {
319 7a387fff ths
    OPC_TLBR     = 0x01 | OPC_C0,
320 7a387fff ths
    OPC_TLBWI    = 0x02 | OPC_C0,
321 7a387fff ths
    OPC_TLBWR    = 0x06 | OPC_C0,
322 7a387fff ths
    OPC_TLBP     = 0x08 | OPC_C0,
323 7a387fff ths
    OPC_RFE      = 0x10 | OPC_C0,
324 7a387fff ths
    OPC_ERET     = 0x18 | OPC_C0,
325 7a387fff ths
    OPC_DERET    = 0x1F | OPC_C0,
326 7a387fff ths
    OPC_WAIT     = 0x20 | OPC_C0,
327 7a387fff ths
};
328 7a387fff ths
329 7a387fff ths
/* Coprocessor 1 (rs field) */
330 7a387fff ths
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
331 7a387fff ths
332 7a387fff ths
enum {
333 7a387fff ths
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
334 7a387fff ths
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
335 7a387fff ths
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
336 7a387fff ths
    OPC_MFHCI    = (0x03 << 21) | OPC_CP1,
337 7a387fff ths
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
338 7a387fff ths
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
339 7a387fff ths
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
340 7a387fff ths
    OPC_MTHCI    = (0x07 << 21) | OPC_CP1,
341 7a387fff ths
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
342 7a387fff ths
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
343 7a387fff ths
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
344 7a387fff ths
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
345 7a387fff ths
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
346 7a387fff ths
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
347 7a387fff ths
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
348 7a387fff ths
};
349 7a387fff ths
350 7a387fff ths
enum {
351 7a387fff ths
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
352 7a387fff ths
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
353 7a387fff ths
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
354 7a387fff ths
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
355 7a387fff ths
};
356 7a387fff ths
357 e1449664 ths
#define MASK_CP1_BCOND(op)      MASK_CP1(op) | (op & (0x3 << 16))
358 e1449664 ths
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
359 7a387fff ths
360 7a387fff ths
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
361 e0c84da7 ths
362 e0c84da7 ths
enum {
363 e0c84da7 ths
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
364 e0c84da7 ths
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
365 e0c84da7 ths
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
366 e0c84da7 ths
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
367 e0c84da7 ths
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
368 e0c84da7 ths
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
369 e0c84da7 ths
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
370 e0c84da7 ths
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
371 e0c84da7 ths
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
372 e0c84da7 ths
};
373 e0c84da7 ths
374 e0c84da7 ths
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
375 e0c84da7 ths
376 e0c84da7 ths
enum {
377 e0c84da7 ths
    OPC_LWXC1   = 0x00 | OPC_CP3,
378 e0c84da7 ths
    OPC_LDXC1   = 0x01 | OPC_CP3,
379 e0c84da7 ths
    OPC_LUXC1   = 0x05 | OPC_CP3,
380 e0c84da7 ths
    OPC_SWXC1   = 0x08 | OPC_CP3,
381 e0c84da7 ths
    OPC_SDXC1   = 0x09 | OPC_CP3,
382 e0c84da7 ths
    OPC_SUXC1   = 0x0D | OPC_CP3,
383 e0c84da7 ths
    OPC_PREFX   = 0x0F | OPC_CP3,
384 e0c84da7 ths
    OPC_ALNV_PS = 0x1E | OPC_CP3,
385 e0c84da7 ths
    OPC_MADD_S  = 0x20 | OPC_CP3,
386 e0c84da7 ths
    OPC_MADD_D  = 0x21 | OPC_CP3,
387 e0c84da7 ths
    OPC_MADD_PS = 0x26 | OPC_CP3,
388 e0c84da7 ths
    OPC_MSUB_S  = 0x28 | OPC_CP3,
389 e0c84da7 ths
    OPC_MSUB_D  = 0x29 | OPC_CP3,
390 e0c84da7 ths
    OPC_MSUB_PS = 0x2E | OPC_CP3,
391 e0c84da7 ths
    OPC_NMADD_S = 0x30 | OPC_CP3,
392 e0c84da7 ths
    OPC_NMADD_D = 0x32 | OPC_CP3,
393 e0c84da7 ths
    OPC_NMADD_PS= 0x36 | OPC_CP3,
394 e0c84da7 ths
    OPC_NMSUB_S = 0x38 | OPC_CP3,
395 e0c84da7 ths
    OPC_NMSUB_D = 0x39 | OPC_CP3,
396 e0c84da7 ths
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
397 e0c84da7 ths
};
398 e0c84da7 ths
399 6ea83fed bellard
400 6af0bf9c bellard
const unsigned char *regnames[] =
401 6af0bf9c bellard
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
402 6af0bf9c bellard
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
403 6af0bf9c bellard
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
404 6af0bf9c bellard
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
405 6af0bf9c bellard
406 6af0bf9c bellard
/* Warning: no function for r0 register (hard wired to zero) */
407 6af0bf9c bellard
#define GEN32(func, NAME) \
408 6af0bf9c bellard
static GenOpFunc *NAME ## _table [32] = {                                     \
409 6af0bf9c bellard
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,                                  \
410 6af0bf9c bellard
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,                                  \
411 6af0bf9c bellard
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,                                \
412 6af0bf9c bellard
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
413 6af0bf9c bellard
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
414 6af0bf9c bellard
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
415 6af0bf9c bellard
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
416 6af0bf9c bellard
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
417 6af0bf9c bellard
};                                                                            \
418 6af0bf9c bellard
static inline void func(int n)                                                \
419 6af0bf9c bellard
{                                                                             \
420 6af0bf9c bellard
    NAME ## _table[n]();                                                      \
421 6af0bf9c bellard
}
422 6af0bf9c bellard
423 6af0bf9c bellard
/* General purpose registers moves */
424 6af0bf9c bellard
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
425 6af0bf9c bellard
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
426 6af0bf9c bellard
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
427 6af0bf9c bellard
428 6af0bf9c bellard
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
429 6af0bf9c bellard
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
430 6af0bf9c bellard
431 7a387fff ths
static const char *fregnames[] =
432 6ea83fed bellard
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
433 6ea83fed bellard
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
434 6ea83fed bellard
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
435 6ea83fed bellard
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
436 6ea83fed bellard
437 6ea83fed bellard
# define SFGEN32(func, NAME) \
438 6ea83fed bellard
static GenOpFunc *NAME ## _table [32] = {                                     \
439 6ea83fed bellard
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,                                \
440 6ea83fed bellard
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,                                \
441 6ea83fed bellard
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,                               \
442 6ea83fed bellard
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
443 6ea83fed bellard
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
444 6ea83fed bellard
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
445 6ea83fed bellard
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
446 6ea83fed bellard
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
447 6ea83fed bellard
};                                                                            \
448 6ea83fed bellard
static inline void func(int n)                                                \
449 6ea83fed bellard
{                                                                             \
450 6ea83fed bellard
    NAME ## _table[n]();                                                      \
451 6ea83fed bellard
}
452 6ea83fed bellard
453 6ea83fed bellard
# define DFGEN32(func, NAME) \
454 6ea83fed bellard
static GenOpFunc *NAME ## _table [32] = {                                     \
455 6ea83fed bellard
NAME ## 0,  0, NAME ## 2,  0,                                                 \
456 6ea83fed bellard
NAME ## 4,  0, NAME ## 6,  0,                                                 \
457 6ea83fed bellard
NAME ## 8,  0, NAME ## 10, 0,                                                 \
458 6ea83fed bellard
NAME ## 12, 0, NAME ## 14, 0,                                                 \
459 6ea83fed bellard
NAME ## 16, 0, NAME ## 18, 0,                                                 \
460 6ea83fed bellard
NAME ## 20, 0, NAME ## 22, 0,                                                 \
461 6ea83fed bellard
NAME ## 24, 0, NAME ## 26, 0,                                                 \
462 6ea83fed bellard
NAME ## 28, 0, NAME ## 30, 0,                                                 \
463 6ea83fed bellard
};                                                                            \
464 6ea83fed bellard
static inline void func(int n)                                                \
465 6ea83fed bellard
{                                                                             \
466 6ea83fed bellard
    NAME ## _table[n]();                                                      \
467 6ea83fed bellard
}
468 6ea83fed bellard
469 6ea83fed bellard
SFGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
470 6ea83fed bellard
SFGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
471 6ea83fed bellard
472 6ea83fed bellard
SFGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
473 6ea83fed bellard
SFGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
474 6ea83fed bellard
475 6ea83fed bellard
SFGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
476 6ea83fed bellard
SFGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
477 6ea83fed bellard
478 6ea83fed bellard
DFGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
479 6ea83fed bellard
DFGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
480 6ea83fed bellard
481 6ea83fed bellard
DFGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
482 6ea83fed bellard
DFGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
483 6ea83fed bellard
484 6ea83fed bellard
DFGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
485 6ea83fed bellard
DFGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
486 6ea83fed bellard
487 6ea83fed bellard
#define FOP_CONDS(fmt) \
488 6ea83fed bellard
static GenOpFunc * cond_ ## fmt ## _table[16] = {                       \
489 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _f,                                           \
490 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _un,                                          \
491 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _eq,                                          \
492 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ueq,                                         \
493 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _olt,                                         \
494 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ult,                                         \
495 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ole,                                         \
496 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ule,                                         \
497 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _sf,                                          \
498 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ngle,                                        \
499 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _seq,                                         \
500 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ngl,                                         \
501 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _lt,                                          \
502 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _nge,                                         \
503 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _le,                                          \
504 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ngt,                                         \
505 6ea83fed bellard
};                                                                      \
506 6ea83fed bellard
static inline void gen_cmp_ ## fmt(int n)                               \
507 6ea83fed bellard
{                                                                       \
508 6ea83fed bellard
    cond_ ## fmt ## _table[n]();                                        \
509 6ea83fed bellard
}
510 6ea83fed bellard
511 6ea83fed bellard
FOP_CONDS(d)
512 6ea83fed bellard
FOP_CONDS(s)
513 6ea83fed bellard
514 6af0bf9c bellard
typedef struct DisasContext {
515 6af0bf9c bellard
    struct TranslationBlock *tb;
516 6af0bf9c bellard
    target_ulong pc, saved_pc;
517 6af0bf9c bellard
    uint32_t opcode;
518 6af0bf9c bellard
    /* Routine used to access memory */
519 6af0bf9c bellard
    int mem_idx;
520 6af0bf9c bellard
    uint32_t hflags, saved_hflags;
521 6af0bf9c bellard
    uint32_t CP0_Status;
522 6af0bf9c bellard
    int bstate;
523 6af0bf9c bellard
    target_ulong btarget;
524 6af0bf9c bellard
} DisasContext;
525 6af0bf9c bellard
526 6af0bf9c bellard
enum {
527 6af0bf9c bellard
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
528 6af0bf9c bellard
                      * exception condition
529 6af0bf9c bellard
                      */
530 6af0bf9c bellard
    BS_STOP     = 1, /* We want to stop translation for any reason */
531 6af0bf9c bellard
    BS_BRANCH   = 2, /* We reached a branch condition     */
532 6af0bf9c bellard
    BS_EXCP     = 3, /* We reached an exception condition */
533 6af0bf9c bellard
};
534 6af0bf9c bellard
535 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
536 6af0bf9c bellard
#define MIPS_DEBUG(fmt, args...)                                              \
537 6af0bf9c bellard
do {                                                                          \
538 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
539 3594c774 ths
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
540 6af0bf9c bellard
                ctx->pc, ctx->opcode , ##args);                               \
541 6af0bf9c bellard
    }                                                                         \
542 6af0bf9c bellard
} while (0)
543 6af0bf9c bellard
#else
544 6af0bf9c bellard
#define MIPS_DEBUG(fmt, args...) do { } while(0)
545 6af0bf9c bellard
#endif
546 6af0bf9c bellard
547 6af0bf9c bellard
#define MIPS_INVAL(op)                                                        \
548 6af0bf9c bellard
do {                                                                          \
549 6af0bf9c bellard
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
550 6af0bf9c bellard
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
551 6af0bf9c bellard
} while (0)
552 6af0bf9c bellard
553 6af0bf9c bellard
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
554 6af0bf9c bellard
do {                                                                          \
555 6af0bf9c bellard
    if (Rn == 0) {                                                            \
556 6af0bf9c bellard
        glue(gen_op_reset_, Tn)();                                            \
557 6af0bf9c bellard
    } else {                                                                  \
558 6af0bf9c bellard
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
559 6af0bf9c bellard
    }                                                                         \
560 6af0bf9c bellard
} while (0)
561 6af0bf9c bellard
562 6af0bf9c bellard
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
563 6af0bf9c bellard
do {                                                                          \
564 6af0bf9c bellard
    if (Imm == 0) {                                                           \
565 6af0bf9c bellard
        glue(gen_op_reset_, Tn)();                                            \
566 6af0bf9c bellard
    } else {                                                                  \
567 6af0bf9c bellard
        glue(gen_op_set_, Tn)(Imm);                                           \
568 6af0bf9c bellard
    }                                                                         \
569 6af0bf9c bellard
} while (0)
570 6af0bf9c bellard
571 6af0bf9c bellard
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
572 6af0bf9c bellard
do {                                                                          \
573 6af0bf9c bellard
    if (Rn != 0) {                                                            \
574 6af0bf9c bellard
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
575 6af0bf9c bellard
    }                                                                         \
576 6af0bf9c bellard
} while (0)
577 6af0bf9c bellard
578 7a387fff ths
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
579 6ea83fed bellard
do {                                                                          \
580 6ea83fed bellard
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
581 6ea83fed bellard
} while (0)
582 6ea83fed bellard
583 6ea83fed bellard
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
584 6ea83fed bellard
do {                                                                          \
585 6ea83fed bellard
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
586 6ea83fed bellard
} while (0)
587 6ea83fed bellard
588 6af0bf9c bellard
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
589 6af0bf9c bellard
{
590 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
591 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
592 6af0bf9c bellard
            fprintf(logfile, "hflags %08x saved %08x\n",
593 6af0bf9c bellard
                    ctx->hflags, ctx->saved_hflags);
594 6af0bf9c bellard
    }
595 6af0bf9c bellard
#endif
596 6af0bf9c bellard
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
597 6af0bf9c bellard
        gen_op_save_pc(ctx->pc);
598 6af0bf9c bellard
        ctx->saved_pc = ctx->pc;
599 6af0bf9c bellard
    }
600 6af0bf9c bellard
    if (ctx->hflags != ctx->saved_hflags) {
601 6af0bf9c bellard
        gen_op_save_state(ctx->hflags);
602 6af0bf9c bellard
        ctx->saved_hflags = ctx->hflags;
603 6af0bf9c bellard
        if (ctx->hflags & MIPS_HFLAG_BR) {
604 6af0bf9c bellard
            gen_op_save_breg_target();
605 6af0bf9c bellard
        } else if (ctx->hflags & MIPS_HFLAG_B) {
606 6af0bf9c bellard
            gen_op_save_btarget(ctx->btarget);
607 6af0bf9c bellard
        } else if (ctx->hflags & MIPS_HFLAG_BMASK) {
608 6af0bf9c bellard
            gen_op_save_bcond();
609 6af0bf9c bellard
            gen_op_save_btarget(ctx->btarget);
610 6af0bf9c bellard
        }
611 6af0bf9c bellard
    }
612 6af0bf9c bellard
}
613 6af0bf9c bellard
614 4ad40f36 bellard
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
615 6af0bf9c bellard
{
616 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
617 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
618 6af0bf9c bellard
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
619 6af0bf9c bellard
#endif
620 6af0bf9c bellard
    save_cpu_state(ctx, 1);
621 4ad40f36 bellard
    if (err == 0)
622 4ad40f36 bellard
        gen_op_raise_exception(excp);
623 4ad40f36 bellard
    else
624 4ad40f36 bellard
        gen_op_raise_exception_err(excp, err);
625 6af0bf9c bellard
    ctx->bstate = BS_EXCP;
626 6af0bf9c bellard
}
627 6af0bf9c bellard
628 4ad40f36 bellard
static inline void generate_exception (DisasContext *ctx, int excp)
629 4ad40f36 bellard
{
630 4ad40f36 bellard
    generate_exception_err (ctx, excp, 0);
631 4ad40f36 bellard
}
632 4ad40f36 bellard
633 6af0bf9c bellard
#if defined(CONFIG_USER_ONLY)
634 6af0bf9c bellard
#define op_ldst(name)        gen_op_##name##_raw()
635 6af0bf9c bellard
#define OP_LD_TABLE(width)
636 6af0bf9c bellard
#define OP_ST_TABLE(width)
637 6af0bf9c bellard
#else
638 6af0bf9c bellard
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
639 6af0bf9c bellard
#define OP_LD_TABLE(width)                                                    \
640 6af0bf9c bellard
static GenOpFunc *gen_op_l##width[] = {                                       \
641 6af0bf9c bellard
    &gen_op_l##width##_user,                                                  \
642 6af0bf9c bellard
    &gen_op_l##width##_kernel,                                                \
643 6af0bf9c bellard
}
644 6af0bf9c bellard
#define OP_ST_TABLE(width)                                                    \
645 6af0bf9c bellard
static GenOpFunc *gen_op_s##width[] = {                                       \
646 6af0bf9c bellard
    &gen_op_s##width##_user,                                                  \
647 6af0bf9c bellard
    &gen_op_s##width##_kernel,                                                \
648 6af0bf9c bellard
}
649 6af0bf9c bellard
#endif
650 6af0bf9c bellard
651 60aa19ab ths
#ifdef TARGET_MIPS64
652 6af0bf9c bellard
OP_LD_TABLE(d);
653 6af0bf9c bellard
OP_LD_TABLE(dl);
654 6af0bf9c bellard
OP_LD_TABLE(dr);
655 6af0bf9c bellard
OP_ST_TABLE(d);
656 6af0bf9c bellard
OP_ST_TABLE(dl);
657 6af0bf9c bellard
OP_ST_TABLE(dr);
658 c570fd16 ths
OP_LD_TABLE(ld);
659 c570fd16 ths
OP_ST_TABLE(cd);
660 6af0bf9c bellard
#endif
661 6af0bf9c bellard
OP_LD_TABLE(w);
662 d796321b bellard
OP_LD_TABLE(wu);
663 6af0bf9c bellard
OP_LD_TABLE(wl);
664 6af0bf9c bellard
OP_LD_TABLE(wr);
665 6af0bf9c bellard
OP_ST_TABLE(w);
666 6af0bf9c bellard
OP_ST_TABLE(wl);
667 6af0bf9c bellard
OP_ST_TABLE(wr);
668 6af0bf9c bellard
OP_LD_TABLE(h);
669 6af0bf9c bellard
OP_LD_TABLE(hu);
670 6af0bf9c bellard
OP_ST_TABLE(h);
671 6af0bf9c bellard
OP_LD_TABLE(b);
672 6af0bf9c bellard
OP_LD_TABLE(bu);
673 6af0bf9c bellard
OP_ST_TABLE(b);
674 6af0bf9c bellard
OP_LD_TABLE(l);
675 6af0bf9c bellard
OP_ST_TABLE(c);
676 6ea83fed bellard
OP_LD_TABLE(wc1);
677 6ea83fed bellard
OP_ST_TABLE(wc1);
678 6ea83fed bellard
OP_LD_TABLE(dc1);
679 6ea83fed bellard
OP_ST_TABLE(dc1);
680 6af0bf9c bellard
681 6af0bf9c bellard
/* Load and store */
682 7a387fff ths
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
683 6af0bf9c bellard
                      int base, int16_t offset)
684 6af0bf9c bellard
{
685 7a387fff ths
    const char *opn = "unk";
686 6af0bf9c bellard
687 6af0bf9c bellard
    if (base == 0) {
688 6af0bf9c bellard
        GEN_LOAD_IMM_TN(T0, offset);
689 6af0bf9c bellard
    } else if (offset == 0) {
690 6af0bf9c bellard
        gen_op_load_gpr_T0(base);
691 6af0bf9c bellard
    } else {
692 6af0bf9c bellard
        gen_op_load_gpr_T0(base);
693 6af0bf9c bellard
        gen_op_set_T1(offset);
694 6af0bf9c bellard
        gen_op_add();
695 6af0bf9c bellard
    }
696 6af0bf9c bellard
    /* Don't do NOP if destination is zero: we must perform the actual
697 6af0bf9c bellard
     * memory access
698 6af0bf9c bellard
     */
699 6af0bf9c bellard
    switch (opc) {
700 60aa19ab ths
#ifdef TARGET_MIPS64
701 6af0bf9c bellard
    case OPC_LD:
702 6af0bf9c bellard
        op_ldst(ld);
703 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
704 6af0bf9c bellard
        opn = "ld";
705 6af0bf9c bellard
        break;
706 7a387fff ths
    case OPC_LLD:
707 7a387fff ths
        op_ldst(lld);
708 7a387fff ths
        GEN_STORE_TN_REG(rt, T0);
709 7a387fff ths
        opn = "lld";
710 7a387fff ths
        break;
711 6af0bf9c bellard
    case OPC_SD:
712 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
713 6af0bf9c bellard
        op_ldst(sd);
714 6af0bf9c bellard
        opn = "sd";
715 6af0bf9c bellard
        break;
716 7a387fff ths
    case OPC_SCD:
717 62c5609a ths
        save_cpu_state(ctx, 1);
718 7a387fff ths
        GEN_LOAD_REG_TN(T1, rt);
719 7a387fff ths
        op_ldst(scd);
720 7a387fff ths
        opn = "scd";
721 7a387fff ths
        break;
722 6af0bf9c bellard
    case OPC_LDL:
723 6af0bf9c bellard
        op_ldst(ldl);
724 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
725 6af0bf9c bellard
        opn = "ldl";
726 6af0bf9c bellard
        break;
727 6af0bf9c bellard
    case OPC_SDL:
728 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
729 6af0bf9c bellard
        op_ldst(sdl);
730 6af0bf9c bellard
        opn = "sdl";
731 6af0bf9c bellard
        break;
732 6af0bf9c bellard
    case OPC_LDR:
733 6af0bf9c bellard
        op_ldst(ldr);
734 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
735 6af0bf9c bellard
        opn = "ldr";
736 6af0bf9c bellard
        break;
737 6af0bf9c bellard
    case OPC_SDR:
738 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
739 6af0bf9c bellard
        op_ldst(sdr);
740 6af0bf9c bellard
        opn = "sdr";
741 6af0bf9c bellard
        break;
742 6af0bf9c bellard
#endif
743 6af0bf9c bellard
    case OPC_LW:
744 6af0bf9c bellard
        op_ldst(lw);
745 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
746 6af0bf9c bellard
        opn = "lw";
747 6af0bf9c bellard
        break;
748 d796321b bellard
    case OPC_LWU:
749 d796321b bellard
        op_ldst(lwu);
750 d796321b bellard
        GEN_STORE_TN_REG(rt, T0);
751 d796321b bellard
        opn = "lwu";
752 d796321b bellard
        break;
753 6af0bf9c bellard
    case OPC_SW:
754 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
755 6af0bf9c bellard
        op_ldst(sw);
756 6af0bf9c bellard
        opn = "sw";
757 6af0bf9c bellard
        break;
758 6af0bf9c bellard
    case OPC_LH:
759 6af0bf9c bellard
        op_ldst(lh);
760 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
761 6af0bf9c bellard
        opn = "lh";
762 6af0bf9c bellard
        break;
763 6af0bf9c bellard
    case OPC_SH:
764 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
765 6af0bf9c bellard
        op_ldst(sh);
766 6af0bf9c bellard
        opn = "sh";
767 6af0bf9c bellard
        break;
768 6af0bf9c bellard
    case OPC_LHU:
769 6af0bf9c bellard
        op_ldst(lhu);
770 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
771 6af0bf9c bellard
        opn = "lhu";
772 6af0bf9c bellard
        break;
773 6af0bf9c bellard
    case OPC_LB:
774 6af0bf9c bellard
        op_ldst(lb);
775 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
776 6af0bf9c bellard
        opn = "lb";
777 6af0bf9c bellard
        break;
778 6af0bf9c bellard
    case OPC_SB:
779 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
780 6af0bf9c bellard
        op_ldst(sb);
781 6af0bf9c bellard
        opn = "sb";
782 6af0bf9c bellard
        break;
783 6af0bf9c bellard
    case OPC_LBU:
784 6af0bf9c bellard
        op_ldst(lbu);
785 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
786 6af0bf9c bellard
        opn = "lbu";
787 6af0bf9c bellard
        break;
788 6af0bf9c bellard
    case OPC_LWL:
789 9d1d106a bellard
        GEN_LOAD_REG_TN(T1, rt);
790 6af0bf9c bellard
        op_ldst(lwl);
791 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
792 6af0bf9c bellard
        opn = "lwl";
793 6af0bf9c bellard
        break;
794 6af0bf9c bellard
    case OPC_SWL:
795 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
796 6af0bf9c bellard
        op_ldst(swl);
797 6af0bf9c bellard
        opn = "swr";
798 6af0bf9c bellard
        break;
799 6af0bf9c bellard
    case OPC_LWR:
800 9d1d106a bellard
        GEN_LOAD_REG_TN(T1, rt);
801 6af0bf9c bellard
        op_ldst(lwr);
802 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
803 6af0bf9c bellard
        opn = "lwr";
804 6af0bf9c bellard
        break;
805 6af0bf9c bellard
    case OPC_SWR:
806 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
807 6af0bf9c bellard
        op_ldst(swr);
808 6af0bf9c bellard
        opn = "swr";
809 6af0bf9c bellard
        break;
810 6af0bf9c bellard
    case OPC_LL:
811 6af0bf9c bellard
        op_ldst(ll);
812 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
813 6af0bf9c bellard
        opn = "ll";
814 6af0bf9c bellard
        break;
815 6af0bf9c bellard
    case OPC_SC:
816 62c5609a ths
        save_cpu_state(ctx, 1);
817 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
818 6af0bf9c bellard
        op_ldst(sc);
819 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
820 6af0bf9c bellard
        opn = "sc";
821 6af0bf9c bellard
        break;
822 6af0bf9c bellard
    default:
823 6af0bf9c bellard
        MIPS_INVAL("load/store");
824 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
825 6af0bf9c bellard
        return;
826 6af0bf9c bellard
    }
827 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
828 6af0bf9c bellard
}
829 6af0bf9c bellard
830 6ea83fed bellard
/* Load and store */
831 7a387fff ths
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
832 6ea83fed bellard
                      int base, int16_t offset)
833 6ea83fed bellard
{
834 7a387fff ths
    const char *opn = "unk";
835 6ea83fed bellard
836 6ea83fed bellard
    if (base == 0) {
837 6ea83fed bellard
        GEN_LOAD_IMM_TN(T0, offset);
838 6ea83fed bellard
    } else if (offset == 0) {
839 6ea83fed bellard
        gen_op_load_gpr_T0(base);
840 6ea83fed bellard
    } else {
841 6ea83fed bellard
        gen_op_load_gpr_T0(base);
842 6ea83fed bellard
        gen_op_set_T1(offset);
843 6ea83fed bellard
        gen_op_add();
844 6ea83fed bellard
    }
845 6ea83fed bellard
    /* Don't do NOP if destination is zero: we must perform the actual
846 6ea83fed bellard
     * memory access
847 6ea83fed bellard
     */
848 6ea83fed bellard
    switch (opc) {
849 6ea83fed bellard
    case OPC_LWC1:
850 6ea83fed bellard
        op_ldst(lwc1);
851 6ea83fed bellard
        GEN_STORE_FTN_FREG(ft, WT0);
852 6ea83fed bellard
        opn = "lwc1";
853 6ea83fed bellard
        break;
854 6ea83fed bellard
    case OPC_SWC1:
855 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, ft);
856 6ea83fed bellard
        op_ldst(swc1);
857 6ea83fed bellard
        opn = "swc1";
858 6ea83fed bellard
        break;
859 6ea83fed bellard
    case OPC_LDC1:
860 6ea83fed bellard
        op_ldst(ldc1);
861 6ea83fed bellard
        GEN_STORE_FTN_FREG(ft, DT0);
862 6ea83fed bellard
        opn = "ldc1";
863 6ea83fed bellard
        break;
864 6ea83fed bellard
    case OPC_SDC1:
865 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, ft);
866 6ea83fed bellard
        op_ldst(sdc1);
867 6ea83fed bellard
        opn = "sdc1";
868 6ea83fed bellard
        break;
869 6ea83fed bellard
    default:
870 6ea83fed bellard
        MIPS_INVAL("float load/store");
871 e397ee33 ths
        generate_exception(ctx, EXCP_RI);
872 6ea83fed bellard
        return;
873 6ea83fed bellard
    }
874 6ea83fed bellard
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
875 6ea83fed bellard
}
876 6ea83fed bellard
877 6af0bf9c bellard
/* Arithmetic with immediate operand */
878 7a387fff ths
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
879 6af0bf9c bellard
                           int rs, int16_t imm)
880 6af0bf9c bellard
{
881 6af0bf9c bellard
    uint32_t uimm;
882 7a387fff ths
    const char *opn = "unk";
883 6af0bf9c bellard
884 7a387fff ths
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
885 6af0bf9c bellard
        /* if no destination, treat it as a NOP 
886 6af0bf9c bellard
         * For addi, we must generate the overflow exception when needed.
887 6af0bf9c bellard
         */
888 6af0bf9c bellard
        MIPS_DEBUG("NOP");
889 6af0bf9c bellard
        return;
890 6af0bf9c bellard
    }
891 5a63bcb2 ths
    uimm = (uint16_t)imm;
892 5a63bcb2 ths
    switch (opc) {
893 5a63bcb2 ths
    case OPC_ADDI:
894 5a63bcb2 ths
    case OPC_ADDIU:
895 5a63bcb2 ths
#ifdef TARGET_MIPS64
896 5a63bcb2 ths
    case OPC_DADDI:
897 5a63bcb2 ths
    case OPC_DADDIU:
898 5a63bcb2 ths
#endif
899 5a63bcb2 ths
    case OPC_SLTI:
900 5a63bcb2 ths
    case OPC_SLTIU:
901 7a387fff ths
        uimm = (int32_t)imm; /* Sign extend to 32 bits */
902 5a63bcb2 ths
        /* Fall through. */
903 5a63bcb2 ths
    case OPC_ANDI:
904 5a63bcb2 ths
    case OPC_ORI:
905 5a63bcb2 ths
    case OPC_XORI:
906 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, rs);
907 6af0bf9c bellard
        GEN_LOAD_IMM_TN(T1, uimm);
908 5a63bcb2 ths
        break;
909 5a63bcb2 ths
    case OPC_LUI:
910 5a63bcb2 ths
        uimm <<= 16;
911 6af0bf9c bellard
        GEN_LOAD_IMM_TN(T0, uimm);
912 5a63bcb2 ths
        break;
913 5a63bcb2 ths
    case OPC_SLL:
914 5a63bcb2 ths
    case OPC_SRA:
915 5a63bcb2 ths
    case OPC_SRL:
916 5a63bcb2 ths
#ifdef TARGET_MIPS64
917 5a63bcb2 ths
    case OPC_DSLL:
918 5a63bcb2 ths
    case OPC_DSRA:
919 5a63bcb2 ths
    case OPC_DSRL:
920 5a63bcb2 ths
    case OPC_DSLL32:
921 5a63bcb2 ths
    case OPC_DSRA32:
922 5a63bcb2 ths
    case OPC_DSRL32:
923 5a63bcb2 ths
#endif
924 5a63bcb2 ths
        uimm &= 0x1f;
925 5a63bcb2 ths
        GEN_LOAD_REG_TN(T0, rs);
926 5a63bcb2 ths
        GEN_LOAD_IMM_TN(T1, uimm);
927 5a63bcb2 ths
        break;
928 6af0bf9c bellard
    }
929 6af0bf9c bellard
    switch (opc) {
930 6af0bf9c bellard
    case OPC_ADDI:
931 6af0bf9c bellard
        save_cpu_state(ctx, 1);
932 6af0bf9c bellard
        gen_op_addo();
933 6af0bf9c bellard
        opn = "addi";
934 6af0bf9c bellard
        break;
935 6af0bf9c bellard
    case OPC_ADDIU:
936 6af0bf9c bellard
        gen_op_add();
937 6af0bf9c bellard
        opn = "addiu";
938 6af0bf9c bellard
        break;
939 60aa19ab ths
#ifdef TARGET_MIPS64
940 7a387fff ths
    case OPC_DADDI:
941 7a387fff ths
        save_cpu_state(ctx, 1);
942 7a387fff ths
        gen_op_daddo();
943 7a387fff ths
        opn = "daddi";
944 7a387fff ths
        break;
945 7a387fff ths
    case OPC_DADDIU:
946 7a387fff ths
        gen_op_dadd();
947 7a387fff ths
        opn = "daddiu";
948 7a387fff ths
        break;
949 7a387fff ths
#endif
950 6af0bf9c bellard
    case OPC_SLTI:
951 6af0bf9c bellard
        gen_op_lt();
952 6af0bf9c bellard
        opn = "slti";
953 6af0bf9c bellard
        break;
954 6af0bf9c bellard
    case OPC_SLTIU:
955 6af0bf9c bellard
        gen_op_ltu();
956 6af0bf9c bellard
        opn = "sltiu";
957 6af0bf9c bellard
        break;
958 6af0bf9c bellard
    case OPC_ANDI:
959 6af0bf9c bellard
        gen_op_and();
960 6af0bf9c bellard
        opn = "andi";
961 6af0bf9c bellard
        break;
962 6af0bf9c bellard
    case OPC_ORI:
963 6af0bf9c bellard
        gen_op_or();
964 6af0bf9c bellard
        opn = "ori";
965 6af0bf9c bellard
        break;
966 6af0bf9c bellard
    case OPC_XORI:
967 6af0bf9c bellard
        gen_op_xor();
968 6af0bf9c bellard
        opn = "xori";
969 6af0bf9c bellard
        break;
970 6af0bf9c bellard
    case OPC_LUI:
971 6af0bf9c bellard
        opn = "lui";
972 6af0bf9c bellard
        break;
973 6af0bf9c bellard
    case OPC_SLL:
974 6af0bf9c bellard
        gen_op_sll();
975 6af0bf9c bellard
        opn = "sll";
976 6af0bf9c bellard
        break;
977 6af0bf9c bellard
    case OPC_SRA:
978 6af0bf9c bellard
        gen_op_sra();
979 6af0bf9c bellard
        opn = "sra";
980 6af0bf9c bellard
        break;
981 6af0bf9c bellard
    case OPC_SRL:
982 5a63bcb2 ths
        switch ((ctx->opcode >> 21) & 0x1f) {
983 5a63bcb2 ths
        case 0:
984 7a387fff ths
            gen_op_srl();
985 7a387fff ths
            opn = "srl";
986 5a63bcb2 ths
            break;
987 5a63bcb2 ths
        case 1:
988 5a63bcb2 ths
            gen_op_rotr();
989 5a63bcb2 ths
            opn = "rotr";
990 5a63bcb2 ths
            break;
991 5a63bcb2 ths
        default:
992 5a63bcb2 ths
            MIPS_INVAL("invalid srl flag");
993 5a63bcb2 ths
            generate_exception(ctx, EXCP_RI);
994 5a63bcb2 ths
            break;
995 5a63bcb2 ths
        }
996 7a387fff ths
        break;
997 60aa19ab ths
#ifdef TARGET_MIPS64
998 7a387fff ths
    case OPC_DSLL:
999 7a387fff ths
        gen_op_dsll();
1000 7a387fff ths
        opn = "dsll";
1001 7a387fff ths
        break;
1002 7a387fff ths
    case OPC_DSRA:
1003 7a387fff ths
        gen_op_dsra();
1004 7a387fff ths
        opn = "dsra";
1005 7a387fff ths
        break;
1006 7a387fff ths
    case OPC_DSRL:
1007 5a63bcb2 ths
        switch ((ctx->opcode >> 21) & 0x1f) {
1008 5a63bcb2 ths
        case 0:
1009 7a387fff ths
            gen_op_dsrl();
1010 7a387fff ths
            opn = "dsrl";
1011 5a63bcb2 ths
            break;
1012 5a63bcb2 ths
        case 1:
1013 5a63bcb2 ths
            gen_op_drotr();
1014 5a63bcb2 ths
            opn = "drotr";
1015 5a63bcb2 ths
            break;
1016 5a63bcb2 ths
        default:
1017 5a63bcb2 ths
            MIPS_INVAL("invalid dsrl flag");
1018 5a63bcb2 ths
            generate_exception(ctx, EXCP_RI);
1019 5a63bcb2 ths
            break;
1020 5a63bcb2 ths
        }
1021 7a387fff ths
        break;
1022 7a387fff ths
    case OPC_DSLL32:
1023 7a387fff ths
        gen_op_dsll32();
1024 7a387fff ths
        opn = "dsll32";
1025 7a387fff ths
        break;
1026 7a387fff ths
    case OPC_DSRA32:
1027 7a387fff ths
        gen_op_dsra32();
1028 7a387fff ths
        opn = "dsra32";
1029 7a387fff ths
        break;
1030 7a387fff ths
    case OPC_DSRL32:
1031 5a63bcb2 ths
        switch ((ctx->opcode >> 21) & 0x1f) {
1032 5a63bcb2 ths
        case 0:
1033 7a387fff ths
            gen_op_dsrl32();
1034 7a387fff ths
            opn = "dsrl32";
1035 5a63bcb2 ths
            break;
1036 5a63bcb2 ths
        case 1:
1037 5a63bcb2 ths
            gen_op_drotr32();
1038 5a63bcb2 ths
            opn = "drotr32";
1039 5a63bcb2 ths
            break;
1040 5a63bcb2 ths
        default:
1041 5a63bcb2 ths
            MIPS_INVAL("invalid dsrl32 flag");
1042 5a63bcb2 ths
            generate_exception(ctx, EXCP_RI);
1043 5a63bcb2 ths
            break;
1044 5a63bcb2 ths
        }
1045 6af0bf9c bellard
        break;
1046 7a387fff ths
#endif
1047 6af0bf9c bellard
    default:
1048 6af0bf9c bellard
        MIPS_INVAL("imm arith");
1049 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1050 6af0bf9c bellard
        return;
1051 6af0bf9c bellard
    }
1052 6af0bf9c bellard
    GEN_STORE_TN_REG(rt, T0);
1053 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
1054 6af0bf9c bellard
}
1055 6af0bf9c bellard
1056 6af0bf9c bellard
/* Arithmetic */
1057 7a387fff ths
static void gen_arith (DisasContext *ctx, uint32_t opc,
1058 6af0bf9c bellard
                       int rd, int rs, int rt)
1059 6af0bf9c bellard
{
1060 7a387fff ths
    const char *opn = "unk";
1061 6af0bf9c bellard
1062 7a387fff ths
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1063 7a387fff ths
       && opc != OPC_DADD && opc != OPC_DSUB) {
1064 6af0bf9c bellard
        /* if no destination, treat it as a NOP 
1065 6af0bf9c bellard
         * For add & sub, we must generate the overflow exception when needed.
1066 6af0bf9c bellard
         */
1067 6af0bf9c bellard
        MIPS_DEBUG("NOP");
1068 6af0bf9c bellard
        return;
1069 6af0bf9c bellard
    }
1070 6af0bf9c bellard
    GEN_LOAD_REG_TN(T0, rs);
1071 6af0bf9c bellard
    GEN_LOAD_REG_TN(T1, rt);
1072 6af0bf9c bellard
    switch (opc) {
1073 6af0bf9c bellard
    case OPC_ADD:
1074 6af0bf9c bellard
        save_cpu_state(ctx, 1);
1075 6af0bf9c bellard
        gen_op_addo();
1076 6af0bf9c bellard
        opn = "add";
1077 6af0bf9c bellard
        break;
1078 6af0bf9c bellard
    case OPC_ADDU:
1079 6af0bf9c bellard
        gen_op_add();
1080 6af0bf9c bellard
        opn = "addu";
1081 6af0bf9c bellard
        break;
1082 6af0bf9c bellard
    case OPC_SUB:
1083 6af0bf9c bellard
        save_cpu_state(ctx, 1);
1084 6af0bf9c bellard
        gen_op_subo();
1085 6af0bf9c bellard
        opn = "sub";
1086 6af0bf9c bellard
        break;
1087 6af0bf9c bellard
    case OPC_SUBU:
1088 6af0bf9c bellard
        gen_op_sub();
1089 6af0bf9c bellard
        opn = "subu";
1090 6af0bf9c bellard
        break;
1091 60aa19ab ths
#ifdef TARGET_MIPS64
1092 7a387fff ths
    case OPC_DADD:
1093 7a387fff ths
        save_cpu_state(ctx, 1);
1094 7a387fff ths
        gen_op_daddo();
1095 7a387fff ths
        opn = "dadd";
1096 7a387fff ths
        break;
1097 7a387fff ths
    case OPC_DADDU:
1098 7a387fff ths
        gen_op_dadd();
1099 7a387fff ths
        opn = "daddu";
1100 7a387fff ths
        break;
1101 7a387fff ths
    case OPC_DSUB:
1102 7a387fff ths
        save_cpu_state(ctx, 1);
1103 7a387fff ths
        gen_op_dsubo();
1104 7a387fff ths
        opn = "dsub";
1105 7a387fff ths
        break;
1106 7a387fff ths
    case OPC_DSUBU:
1107 7a387fff ths
        gen_op_dsub();
1108 7a387fff ths
        opn = "dsubu";
1109 7a387fff ths
        break;
1110 7a387fff ths
#endif
1111 6af0bf9c bellard
    case OPC_SLT:
1112 6af0bf9c bellard
        gen_op_lt();
1113 6af0bf9c bellard
        opn = "slt";
1114 6af0bf9c bellard
        break;
1115 6af0bf9c bellard
    case OPC_SLTU:
1116 6af0bf9c bellard
        gen_op_ltu();
1117 6af0bf9c bellard
        opn = "sltu";
1118 6af0bf9c bellard
        break;
1119 6af0bf9c bellard
    case OPC_AND:
1120 6af0bf9c bellard
        gen_op_and();
1121 6af0bf9c bellard
        opn = "and";
1122 6af0bf9c bellard
        break;
1123 6af0bf9c bellard
    case OPC_NOR:
1124 6af0bf9c bellard
        gen_op_nor();
1125 6af0bf9c bellard
        opn = "nor";
1126 6af0bf9c bellard
        break;
1127 6af0bf9c bellard
    case OPC_OR:
1128 6af0bf9c bellard
        gen_op_or();
1129 6af0bf9c bellard
        opn = "or";
1130 6af0bf9c bellard
        break;
1131 6af0bf9c bellard
    case OPC_XOR:
1132 6af0bf9c bellard
        gen_op_xor();
1133 6af0bf9c bellard
        opn = "xor";
1134 6af0bf9c bellard
        break;
1135 6af0bf9c bellard
    case OPC_MUL:
1136 6af0bf9c bellard
        gen_op_mul();
1137 6af0bf9c bellard
        opn = "mul";
1138 6af0bf9c bellard
        break;
1139 6af0bf9c bellard
    case OPC_MOVN:
1140 6af0bf9c bellard
        gen_op_movn(rd);
1141 6af0bf9c bellard
        opn = "movn";
1142 6af0bf9c bellard
        goto print;
1143 6af0bf9c bellard
    case OPC_MOVZ:
1144 6af0bf9c bellard
        gen_op_movz(rd);
1145 6af0bf9c bellard
        opn = "movz";
1146 6af0bf9c bellard
        goto print;
1147 6af0bf9c bellard
    case OPC_SLLV:
1148 6af0bf9c bellard
        gen_op_sllv();
1149 6af0bf9c bellard
        opn = "sllv";
1150 6af0bf9c bellard
        break;
1151 6af0bf9c bellard
    case OPC_SRAV:
1152 6af0bf9c bellard
        gen_op_srav();
1153 6af0bf9c bellard
        opn = "srav";
1154 6af0bf9c bellard
        break;
1155 6af0bf9c bellard
    case OPC_SRLV:
1156 5a63bcb2 ths
        switch ((ctx->opcode >> 6) & 0x1f) {
1157 5a63bcb2 ths
        case 0:
1158 7a387fff ths
            gen_op_srlv();
1159 7a387fff ths
            opn = "srlv";
1160 5a63bcb2 ths
            break;
1161 5a63bcb2 ths
        case 1:
1162 5a63bcb2 ths
            gen_op_rotrv();
1163 5a63bcb2 ths
            opn = "rotrv";
1164 5a63bcb2 ths
            break;
1165 5a63bcb2 ths
        default:
1166 5a63bcb2 ths
            MIPS_INVAL("invalid srlv flag");
1167 5a63bcb2 ths
            generate_exception(ctx, EXCP_RI);
1168 5a63bcb2 ths
            break;
1169 5a63bcb2 ths
        }
1170 7a387fff ths
        break;
1171 60aa19ab ths
#ifdef TARGET_MIPS64
1172 7a387fff ths
    case OPC_DSLLV:
1173 7a387fff ths
        gen_op_dsllv();
1174 7a387fff ths
        opn = "dsllv";
1175 7a387fff ths
        break;
1176 7a387fff ths
    case OPC_DSRAV:
1177 7a387fff ths
        gen_op_dsrav();
1178 7a387fff ths
        opn = "dsrav";
1179 7a387fff ths
        break;
1180 7a387fff ths
    case OPC_DSRLV:
1181 5a63bcb2 ths
        switch ((ctx->opcode >> 6) & 0x1f) {
1182 5a63bcb2 ths
        case 0:
1183 7a387fff ths
            gen_op_dsrlv();
1184 7a387fff ths
            opn = "dsrlv";
1185 5a63bcb2 ths
            break;
1186 5a63bcb2 ths
        case 1:
1187 5a63bcb2 ths
            gen_op_drotrv();
1188 5a63bcb2 ths
            opn = "drotrv";
1189 5a63bcb2 ths
            break;
1190 5a63bcb2 ths
        default:
1191 5a63bcb2 ths
            MIPS_INVAL("invalid dsrlv flag");
1192 5a63bcb2 ths
            generate_exception(ctx, EXCP_RI);
1193 5a63bcb2 ths
            break;
1194 5a63bcb2 ths
        }
1195 6af0bf9c bellard
        break;
1196 7a387fff ths
#endif
1197 6af0bf9c bellard
    default:
1198 6af0bf9c bellard
        MIPS_INVAL("arith");
1199 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1200 6af0bf9c bellard
        return;
1201 6af0bf9c bellard
    }
1202 6af0bf9c bellard
    GEN_STORE_TN_REG(rd, T0);
1203 6af0bf9c bellard
 print:
1204 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1205 6af0bf9c bellard
}
1206 6af0bf9c bellard
1207 6af0bf9c bellard
/* Arithmetic on HI/LO registers */
1208 7a387fff ths
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1209 6af0bf9c bellard
{
1210 7a387fff ths
    const char *opn = "unk";
1211 6af0bf9c bellard
1212 6af0bf9c bellard
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1213 6af0bf9c bellard
        /* Treat as a NOP */
1214 6af0bf9c bellard
        MIPS_DEBUG("NOP");
1215 6af0bf9c bellard
        return;
1216 6af0bf9c bellard
    }
1217 6af0bf9c bellard
    switch (opc) {
1218 6af0bf9c bellard
    case OPC_MFHI:
1219 6af0bf9c bellard
        gen_op_load_HI();
1220 6af0bf9c bellard
        GEN_STORE_TN_REG(reg, T0);
1221 6af0bf9c bellard
        opn = "mfhi";
1222 6af0bf9c bellard
        break;
1223 6af0bf9c bellard
    case OPC_MFLO:
1224 6af0bf9c bellard
        gen_op_load_LO();
1225 6af0bf9c bellard
        GEN_STORE_TN_REG(reg, T0);
1226 6af0bf9c bellard
        opn = "mflo";
1227 6af0bf9c bellard
        break;
1228 6af0bf9c bellard
    case OPC_MTHI:
1229 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, reg);
1230 6af0bf9c bellard
        gen_op_store_HI();
1231 6af0bf9c bellard
        opn = "mthi";
1232 6af0bf9c bellard
        break;
1233 6af0bf9c bellard
    case OPC_MTLO:
1234 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, reg);
1235 6af0bf9c bellard
        gen_op_store_LO();
1236 6af0bf9c bellard
        opn = "mtlo";
1237 6af0bf9c bellard
        break;
1238 6af0bf9c bellard
    default:
1239 6af0bf9c bellard
        MIPS_INVAL("HILO");
1240 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1241 6af0bf9c bellard
        return;
1242 6af0bf9c bellard
    }
1243 6af0bf9c bellard
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1244 6af0bf9c bellard
}
1245 6af0bf9c bellard
1246 7a387fff ths
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1247 6af0bf9c bellard
                        int rs, int rt)
1248 6af0bf9c bellard
{
1249 7a387fff ths
    const char *opn = "unk";
1250 6af0bf9c bellard
1251 6af0bf9c bellard
    GEN_LOAD_REG_TN(T0, rs);
1252 6af0bf9c bellard
    GEN_LOAD_REG_TN(T1, rt);
1253 6af0bf9c bellard
    switch (opc) {
1254 6af0bf9c bellard
    case OPC_DIV:
1255 6af0bf9c bellard
        gen_op_div();
1256 6af0bf9c bellard
        opn = "div";
1257 6af0bf9c bellard
        break;
1258 6af0bf9c bellard
    case OPC_DIVU:
1259 6af0bf9c bellard
        gen_op_divu();
1260 6af0bf9c bellard
        opn = "divu";
1261 6af0bf9c bellard
        break;
1262 6af0bf9c bellard
    case OPC_MULT:
1263 6af0bf9c bellard
        gen_op_mult();
1264 6af0bf9c bellard
        opn = "mult";
1265 6af0bf9c bellard
        break;
1266 6af0bf9c bellard
    case OPC_MULTU:
1267 6af0bf9c bellard
        gen_op_multu();
1268 6af0bf9c bellard
        opn = "multu";
1269 6af0bf9c bellard
        break;
1270 60aa19ab ths
#ifdef TARGET_MIPS64
1271 7a387fff ths
    case OPC_DDIV:
1272 7a387fff ths
        gen_op_ddiv();
1273 7a387fff ths
        opn = "ddiv";
1274 7a387fff ths
        break;
1275 7a387fff ths
    case OPC_DDIVU:
1276 7a387fff ths
        gen_op_ddivu();
1277 7a387fff ths
        opn = "ddivu";
1278 7a387fff ths
        break;
1279 7a387fff ths
    case OPC_DMULT:
1280 7a387fff ths
        gen_op_dmult();
1281 7a387fff ths
        opn = "dmult";
1282 7a387fff ths
        break;
1283 7a387fff ths
    case OPC_DMULTU:
1284 7a387fff ths
        gen_op_dmultu();
1285 7a387fff ths
        opn = "dmultu";
1286 7a387fff ths
        break;
1287 7a387fff ths
#endif
1288 6af0bf9c bellard
    case OPC_MADD:
1289 6af0bf9c bellard
        gen_op_madd();
1290 6af0bf9c bellard
        opn = "madd";
1291 6af0bf9c bellard
        break;
1292 6af0bf9c bellard
    case OPC_MADDU:
1293 6af0bf9c bellard
        gen_op_maddu();
1294 6af0bf9c bellard
        opn = "maddu";
1295 6af0bf9c bellard
        break;
1296 6af0bf9c bellard
    case OPC_MSUB:
1297 6af0bf9c bellard
        gen_op_msub();
1298 6af0bf9c bellard
        opn = "msub";
1299 6af0bf9c bellard
        break;
1300 6af0bf9c bellard
    case OPC_MSUBU:
1301 6af0bf9c bellard
        gen_op_msubu();
1302 6af0bf9c bellard
        opn = "msubu";
1303 6af0bf9c bellard
        break;
1304 6af0bf9c bellard
    default:
1305 6af0bf9c bellard
        MIPS_INVAL("mul/div");
1306 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1307 6af0bf9c bellard
        return;
1308 6af0bf9c bellard
    }
1309 6af0bf9c bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1310 6af0bf9c bellard
}
1311 6af0bf9c bellard
1312 7a387fff ths
static void gen_cl (DisasContext *ctx, uint32_t opc,
1313 6af0bf9c bellard
                    int rd, int rs)
1314 6af0bf9c bellard
{
1315 7a387fff ths
    const char *opn = "unk";
1316 6af0bf9c bellard
    if (rd == 0) {
1317 6af0bf9c bellard
        /* Treat as a NOP */
1318 6af0bf9c bellard
        MIPS_DEBUG("NOP");
1319 6af0bf9c bellard
        return;
1320 6af0bf9c bellard
    }
1321 6af0bf9c bellard
    GEN_LOAD_REG_TN(T0, rs);
1322 6af0bf9c bellard
    switch (opc) {
1323 6af0bf9c bellard
    case OPC_CLO:
1324 6af0bf9c bellard
        gen_op_clo();
1325 6af0bf9c bellard
        opn = "clo";
1326 6af0bf9c bellard
        break;
1327 6af0bf9c bellard
    case OPC_CLZ:
1328 6af0bf9c bellard
        gen_op_clz();
1329 6af0bf9c bellard
        opn = "clz";
1330 6af0bf9c bellard
        break;
1331 60aa19ab ths
#ifdef TARGET_MIPS64
1332 7a387fff ths
    case OPC_DCLO:
1333 7a387fff ths
        gen_op_dclo();
1334 7a387fff ths
        opn = "dclo";
1335 7a387fff ths
        break;
1336 7a387fff ths
    case OPC_DCLZ:
1337 7a387fff ths
        gen_op_dclz();
1338 7a387fff ths
        opn = "dclz";
1339 7a387fff ths
        break;
1340 7a387fff ths
#endif
1341 6af0bf9c bellard
    default:
1342 6af0bf9c bellard
        MIPS_INVAL("CLx");
1343 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1344 6af0bf9c bellard
        return;
1345 6af0bf9c bellard
    }
1346 6af0bf9c bellard
    gen_op_store_T0_gpr(rd);
1347 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1348 6af0bf9c bellard
}
1349 6af0bf9c bellard
1350 6af0bf9c bellard
/* Traps */
1351 7a387fff ths
static void gen_trap (DisasContext *ctx, uint32_t opc,
1352 6af0bf9c bellard
                      int rs, int rt, int16_t imm)
1353 6af0bf9c bellard
{
1354 6af0bf9c bellard
    int cond;
1355 6af0bf9c bellard
1356 6af0bf9c bellard
    cond = 0;
1357 6af0bf9c bellard
    /* Load needed operands */
1358 6af0bf9c bellard
    switch (opc) {
1359 6af0bf9c bellard
    case OPC_TEQ:
1360 6af0bf9c bellard
    case OPC_TGE:
1361 6af0bf9c bellard
    case OPC_TGEU:
1362 6af0bf9c bellard
    case OPC_TLT:
1363 6af0bf9c bellard
    case OPC_TLTU:
1364 6af0bf9c bellard
    case OPC_TNE:
1365 6af0bf9c bellard
        /* Compare two registers */
1366 6af0bf9c bellard
        if (rs != rt) {
1367 6af0bf9c bellard
            GEN_LOAD_REG_TN(T0, rs);
1368 6af0bf9c bellard
            GEN_LOAD_REG_TN(T1, rt);
1369 6af0bf9c bellard
            cond = 1;
1370 6af0bf9c bellard
        }
1371 179e32bb ths
        break;
1372 6af0bf9c bellard
    case OPC_TEQI:
1373 6af0bf9c bellard
    case OPC_TGEI:
1374 6af0bf9c bellard
    case OPC_TGEIU:
1375 6af0bf9c bellard
    case OPC_TLTI:
1376 6af0bf9c bellard
    case OPC_TLTIU:
1377 6af0bf9c bellard
    case OPC_TNEI:
1378 6af0bf9c bellard
        /* Compare register to immediate */
1379 6af0bf9c bellard
        if (rs != 0 || imm != 0) {
1380 6af0bf9c bellard
            GEN_LOAD_REG_TN(T0, rs);
1381 6af0bf9c bellard
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1382 6af0bf9c bellard
            cond = 1;
1383 6af0bf9c bellard
        }
1384 6af0bf9c bellard
        break;
1385 6af0bf9c bellard
    }
1386 6af0bf9c bellard
    if (cond == 0) {
1387 6af0bf9c bellard
        switch (opc) {
1388 6af0bf9c bellard
        case OPC_TEQ:   /* rs == rs */
1389 6af0bf9c bellard
        case OPC_TEQI:  /* r0 == 0  */
1390 6af0bf9c bellard
        case OPC_TGE:   /* rs >= rs */
1391 6af0bf9c bellard
        case OPC_TGEI:  /* r0 >= 0  */
1392 6af0bf9c bellard
        case OPC_TGEU:  /* rs >= rs unsigned */
1393 6af0bf9c bellard
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1394 6af0bf9c bellard
            /* Always trap */
1395 6af0bf9c bellard
            gen_op_set_T0(1);
1396 6af0bf9c bellard
            break;
1397 6af0bf9c bellard
        case OPC_TLT:   /* rs < rs           */
1398 6af0bf9c bellard
        case OPC_TLTI:  /* r0 < 0            */
1399 6af0bf9c bellard
        case OPC_TLTU:  /* rs < rs unsigned  */
1400 6af0bf9c bellard
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1401 6af0bf9c bellard
        case OPC_TNE:   /* rs != rs          */
1402 6af0bf9c bellard
        case OPC_TNEI:  /* r0 != 0           */
1403 6af0bf9c bellard
            /* Never trap: treat as NOP */
1404 6af0bf9c bellard
            return;
1405 6af0bf9c bellard
        default:
1406 6af0bf9c bellard
            MIPS_INVAL("TRAP");
1407 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1408 6af0bf9c bellard
            return;
1409 6af0bf9c bellard
        }
1410 6af0bf9c bellard
    } else {
1411 6af0bf9c bellard
        switch (opc) {
1412 6af0bf9c bellard
        case OPC_TEQ:
1413 6af0bf9c bellard
        case OPC_TEQI:
1414 6af0bf9c bellard
            gen_op_eq();
1415 6af0bf9c bellard
            break;
1416 6af0bf9c bellard
        case OPC_TGE:
1417 6af0bf9c bellard
        case OPC_TGEI:
1418 6af0bf9c bellard
            gen_op_ge();
1419 6af0bf9c bellard
            break;
1420 6af0bf9c bellard
        case OPC_TGEU:
1421 6af0bf9c bellard
        case OPC_TGEIU:
1422 6af0bf9c bellard
            gen_op_geu();
1423 6af0bf9c bellard
            break;
1424 6af0bf9c bellard
        case OPC_TLT:
1425 6af0bf9c bellard
        case OPC_TLTI:
1426 6af0bf9c bellard
            gen_op_lt();
1427 6af0bf9c bellard
            break;
1428 6af0bf9c bellard
        case OPC_TLTU:
1429 6af0bf9c bellard
        case OPC_TLTIU:
1430 6af0bf9c bellard
            gen_op_ltu();
1431 6af0bf9c bellard
            break;
1432 6af0bf9c bellard
        case OPC_TNE:
1433 6af0bf9c bellard
        case OPC_TNEI:
1434 6af0bf9c bellard
            gen_op_ne();
1435 6af0bf9c bellard
            break;
1436 6af0bf9c bellard
        default:
1437 6af0bf9c bellard
            MIPS_INVAL("TRAP");
1438 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1439 6af0bf9c bellard
            return;
1440 6af0bf9c bellard
        }
1441 6af0bf9c bellard
    }
1442 6af0bf9c bellard
    save_cpu_state(ctx, 1);
1443 6af0bf9c bellard
    gen_op_trap();
1444 6af0bf9c bellard
    ctx->bstate = BS_STOP;
1445 6af0bf9c bellard
}
1446 6af0bf9c bellard
1447 6e256c93 bellard
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1448 c53be334 bellard
{
1449 6e256c93 bellard
    TranslationBlock *tb;
1450 6e256c93 bellard
    tb = ctx->tb;
1451 6e256c93 bellard
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1452 6e256c93 bellard
        if (n == 0)
1453 6e256c93 bellard
            gen_op_goto_tb0(TBPARAM(tb));
1454 6e256c93 bellard
        else
1455 6e256c93 bellard
            gen_op_goto_tb1(TBPARAM(tb));
1456 6e256c93 bellard
        gen_op_save_pc(dest);
1457 6e256c93 bellard
        gen_op_set_T0((long)tb + n);
1458 6e256c93 bellard
    } else {
1459 6e256c93 bellard
        gen_op_save_pc(dest);
1460 9898128f ths
        gen_op_reset_T0();
1461 6e256c93 bellard
    }
1462 9898128f ths
    gen_op_exit_tb();
1463 c53be334 bellard
}
1464 c53be334 bellard
1465 6af0bf9c bellard
/* Branches (before delay slot) */
1466 7a387fff ths
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1467 6af0bf9c bellard
                                int rs, int rt, int32_t offset)
1468 6af0bf9c bellard
{
1469 3ad4bb2d ths
    target_ulong btarget = -1;
1470 3ad4bb2d ths
    int blink = 0;
1471 3ad4bb2d ths
    int bcond = 0;
1472 3ad4bb2d ths
1473 3ad4bb2d ths
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1474 3ad4bb2d ths
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1475 3ad4bb2d ths
            fprintf(logfile,
1476 38121543 ths
                    "undefined branch in delay slot at PC " TARGET_FMT_lx "\n",
1477 38121543 ths
                    ctx->pc);
1478 3ad4bb2d ths
        }
1479 3ad4bb2d ths
        MIPS_INVAL("branch/jump in bdelay slot");
1480 3ad4bb2d ths
        generate_exception(ctx, EXCP_RI);
1481 3ad4bb2d ths
        return;
1482 3ad4bb2d ths
    }
1483 6af0bf9c bellard
1484 6af0bf9c bellard
    /* Load needed operands */
1485 6af0bf9c bellard
    switch (opc) {
1486 6af0bf9c bellard
    case OPC_BEQ:
1487 6af0bf9c bellard
    case OPC_BEQL:
1488 6af0bf9c bellard
    case OPC_BNE:
1489 6af0bf9c bellard
    case OPC_BNEL:
1490 6af0bf9c bellard
        /* Compare two registers */
1491 6af0bf9c bellard
        if (rs != rt) {
1492 6af0bf9c bellard
            GEN_LOAD_REG_TN(T0, rs);
1493 6af0bf9c bellard
            GEN_LOAD_REG_TN(T1, rt);
1494 6af0bf9c bellard
            bcond = 1;
1495 6af0bf9c bellard
        }
1496 6af0bf9c bellard
        btarget = ctx->pc + 4 + offset;
1497 6af0bf9c bellard
        break;
1498 6af0bf9c bellard
    case OPC_BGEZ:
1499 6af0bf9c bellard
    case OPC_BGEZAL:
1500 6af0bf9c bellard
    case OPC_BGEZALL:
1501 6af0bf9c bellard
    case OPC_BGEZL:
1502 6af0bf9c bellard
    case OPC_BGTZ:
1503 6af0bf9c bellard
    case OPC_BGTZL:
1504 6af0bf9c bellard
    case OPC_BLEZ:
1505 6af0bf9c bellard
    case OPC_BLEZL:
1506 6af0bf9c bellard
    case OPC_BLTZ:
1507 6af0bf9c bellard
    case OPC_BLTZAL:
1508 6af0bf9c bellard
    case OPC_BLTZALL:
1509 6af0bf9c bellard
    case OPC_BLTZL:
1510 6af0bf9c bellard
        /* Compare to zero */
1511 6af0bf9c bellard
        if (rs != 0) {
1512 6af0bf9c bellard
            gen_op_load_gpr_T0(rs);
1513 6af0bf9c bellard
            bcond = 1;
1514 6af0bf9c bellard
        }
1515 6af0bf9c bellard
        btarget = ctx->pc + 4 + offset;
1516 6af0bf9c bellard
        break;
1517 6af0bf9c bellard
    case OPC_J:
1518 6af0bf9c bellard
    case OPC_JAL:
1519 6af0bf9c bellard
        /* Jump to immediate */
1520 5dc4b744 ths
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset;
1521 6af0bf9c bellard
        break;
1522 6af0bf9c bellard
    case OPC_JR:
1523 6af0bf9c bellard
    case OPC_JALR:
1524 6af0bf9c bellard
        /* Jump to register */
1525 7a387fff ths
        if (offset != 0 && offset != 16) {
1526 7a387fff ths
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1527 cbeb0857 ths
               others are reserved. */
1528 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1529 6af0bf9c bellard
            return;
1530 6af0bf9c bellard
        }
1531 6af0bf9c bellard
        GEN_LOAD_REG_TN(T2, rs);
1532 6af0bf9c bellard
        break;
1533 6af0bf9c bellard
    default:
1534 6af0bf9c bellard
        MIPS_INVAL("branch/jump");
1535 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1536 6af0bf9c bellard
        return;
1537 6af0bf9c bellard
    }
1538 6af0bf9c bellard
    if (bcond == 0) {
1539 6af0bf9c bellard
        /* No condition to be computed */
1540 6af0bf9c bellard
        switch (opc) {
1541 6af0bf9c bellard
        case OPC_BEQ:     /* rx == rx        */
1542 6af0bf9c bellard
        case OPC_BEQL:    /* rx == rx likely */
1543 6af0bf9c bellard
        case OPC_BGEZ:    /* 0 >= 0          */
1544 6af0bf9c bellard
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1545 6af0bf9c bellard
        case OPC_BLEZ:    /* 0 <= 0          */
1546 6af0bf9c bellard
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1547 6af0bf9c bellard
            /* Always take */
1548 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1549 6af0bf9c bellard
            MIPS_DEBUG("balways");
1550 6af0bf9c bellard
            break;
1551 6af0bf9c bellard
        case OPC_BGEZAL:  /* 0 >= 0          */
1552 6af0bf9c bellard
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1553 6af0bf9c bellard
            /* Always take and link */
1554 6af0bf9c bellard
            blink = 31;
1555 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1556 6af0bf9c bellard
            MIPS_DEBUG("balways and link");
1557 6af0bf9c bellard
            break;
1558 6af0bf9c bellard
        case OPC_BNE:     /* rx != rx        */
1559 6af0bf9c bellard
        case OPC_BGTZ:    /* 0 > 0           */
1560 6af0bf9c bellard
        case OPC_BLTZ:    /* 0 < 0           */
1561 6af0bf9c bellard
            /* Treated as NOP */
1562 6af0bf9c bellard
            MIPS_DEBUG("bnever (NOP)");
1563 6af0bf9c bellard
            return;
1564 eeef26cd bellard
        case OPC_BLTZAL:  /* 0 < 0           */
1565 eeef26cd bellard
            gen_op_set_T0(ctx->pc + 8);
1566 eeef26cd bellard
            gen_op_store_T0_gpr(31);
1567 9898128f ths
            MIPS_DEBUG("bnever and link");
1568 eeef26cd bellard
            return;
1569 eeef26cd bellard
        case OPC_BLTZALL: /* 0 < 0 likely */
1570 eeef26cd bellard
            gen_op_set_T0(ctx->pc + 8);
1571 eeef26cd bellard
            gen_op_store_T0_gpr(31);
1572 9898128f ths
            /* Skip the instruction in the delay slot */
1573 9898128f ths
            MIPS_DEBUG("bnever, link and skip");
1574 9898128f ths
            ctx->pc += 4;
1575 eeef26cd bellard
            return;
1576 6af0bf9c bellard
        case OPC_BNEL:    /* rx != rx likely */
1577 6af0bf9c bellard
        case OPC_BGTZL:   /* 0 > 0 likely */
1578 6af0bf9c bellard
        case OPC_BLTZL:   /* 0 < 0 likely */
1579 6af0bf9c bellard
            /* Skip the instruction in the delay slot */
1580 6af0bf9c bellard
            MIPS_DEBUG("bnever and skip");
1581 9898128f ths
            ctx->pc += 4;
1582 6af0bf9c bellard
            return;
1583 6af0bf9c bellard
        case OPC_J:
1584 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1585 6af0bf9c bellard
            MIPS_DEBUG("j %08x", btarget);
1586 6af0bf9c bellard
            break;
1587 6af0bf9c bellard
        case OPC_JAL:
1588 6af0bf9c bellard
            blink = 31;
1589 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1590 6af0bf9c bellard
            MIPS_DEBUG("jal %08x", btarget);
1591 6af0bf9c bellard
            break;
1592 6af0bf9c bellard
        case OPC_JR:
1593 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
1594 6af0bf9c bellard
            MIPS_DEBUG("jr %s", regnames[rs]);
1595 6af0bf9c bellard
            break;
1596 6af0bf9c bellard
        case OPC_JALR:
1597 6af0bf9c bellard
            blink = rt;
1598 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
1599 6af0bf9c bellard
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1600 6af0bf9c bellard
            break;
1601 6af0bf9c bellard
        default:
1602 6af0bf9c bellard
            MIPS_INVAL("branch/jump");
1603 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1604 6af0bf9c bellard
            return;
1605 6af0bf9c bellard
        }
1606 6af0bf9c bellard
    } else {
1607 6af0bf9c bellard
        switch (opc) {
1608 6af0bf9c bellard
        case OPC_BEQ:
1609 6af0bf9c bellard
            gen_op_eq();
1610 6af0bf9c bellard
            MIPS_DEBUG("beq %s, %s, %08x",
1611 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1612 6af0bf9c bellard
            goto not_likely;
1613 6af0bf9c bellard
        case OPC_BEQL:
1614 6af0bf9c bellard
            gen_op_eq();
1615 6af0bf9c bellard
            MIPS_DEBUG("beql %s, %s, %08x",
1616 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1617 6af0bf9c bellard
            goto likely;
1618 6af0bf9c bellard
        case OPC_BNE:
1619 6af0bf9c bellard
            gen_op_ne();
1620 6af0bf9c bellard
            MIPS_DEBUG("bne %s, %s, %08x",
1621 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1622 6af0bf9c bellard
            goto not_likely;
1623 6af0bf9c bellard
        case OPC_BNEL:
1624 6af0bf9c bellard
            gen_op_ne();
1625 6af0bf9c bellard
            MIPS_DEBUG("bnel %s, %s, %08x",
1626 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1627 6af0bf9c bellard
            goto likely;
1628 6af0bf9c bellard
        case OPC_BGEZ:
1629 6af0bf9c bellard
            gen_op_gez();
1630 6af0bf9c bellard
            MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget);
1631 6af0bf9c bellard
            goto not_likely;
1632 6af0bf9c bellard
        case OPC_BGEZL:
1633 6af0bf9c bellard
            gen_op_gez();
1634 6af0bf9c bellard
            MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget);
1635 6af0bf9c bellard
            goto likely;
1636 6af0bf9c bellard
        case OPC_BGEZAL:
1637 6af0bf9c bellard
            gen_op_gez();
1638 6af0bf9c bellard
            MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget);
1639 6af0bf9c bellard
            blink = 31;
1640 6af0bf9c bellard
            goto not_likely;
1641 6af0bf9c bellard
        case OPC_BGEZALL:
1642 6af0bf9c bellard
            gen_op_gez();
1643 6af0bf9c bellard
            blink = 31;
1644 6af0bf9c bellard
            MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget);
1645 6af0bf9c bellard
            goto likely;
1646 6af0bf9c bellard
        case OPC_BGTZ:
1647 6af0bf9c bellard
            gen_op_gtz();
1648 6af0bf9c bellard
            MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget);
1649 6af0bf9c bellard
            goto not_likely;
1650 6af0bf9c bellard
        case OPC_BGTZL:
1651 6af0bf9c bellard
            gen_op_gtz();
1652 6af0bf9c bellard
            MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget);
1653 6af0bf9c bellard
            goto likely;
1654 6af0bf9c bellard
        case OPC_BLEZ:
1655 6af0bf9c bellard
            gen_op_lez();
1656 6af0bf9c bellard
            MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget);
1657 6af0bf9c bellard
            goto not_likely;
1658 6af0bf9c bellard
        case OPC_BLEZL:
1659 6af0bf9c bellard
            gen_op_lez();
1660 6af0bf9c bellard
            MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget);
1661 6af0bf9c bellard
            goto likely;
1662 6af0bf9c bellard
        case OPC_BLTZ:
1663 6af0bf9c bellard
            gen_op_ltz();
1664 6af0bf9c bellard
            MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget);
1665 6af0bf9c bellard
            goto not_likely;
1666 6af0bf9c bellard
        case OPC_BLTZL:
1667 6af0bf9c bellard
            gen_op_ltz();
1668 6af0bf9c bellard
            MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget);
1669 6af0bf9c bellard
            goto likely;
1670 6af0bf9c bellard
        case OPC_BLTZAL:
1671 6af0bf9c bellard
            gen_op_ltz();
1672 6af0bf9c bellard
            blink = 31;
1673 6af0bf9c bellard
            MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
1674 6af0bf9c bellard
        not_likely:
1675 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BC;
1676 6af0bf9c bellard
            break;
1677 6af0bf9c bellard
        case OPC_BLTZALL:
1678 6af0bf9c bellard
            gen_op_ltz();
1679 6af0bf9c bellard
            blink = 31;
1680 6af0bf9c bellard
            MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
1681 6af0bf9c bellard
        likely:
1682 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BL;
1683 6af0bf9c bellard
            break;
1684 c53f4a62 ths
        default:
1685 c53f4a62 ths
            MIPS_INVAL("conditional branch/jump");
1686 c53f4a62 ths
            generate_exception(ctx, EXCP_RI);
1687 c53f4a62 ths
            return;
1688 6af0bf9c bellard
        }
1689 6af0bf9c bellard
        gen_op_set_bcond();
1690 6af0bf9c bellard
    }
1691 6af0bf9c bellard
    MIPS_DEBUG("enter ds: link %d cond %02x target %08x",
1692 6af0bf9c bellard
               blink, ctx->hflags, btarget);
1693 6af0bf9c bellard
    ctx->btarget = btarget;
1694 6af0bf9c bellard
    if (blink > 0) {
1695 6af0bf9c bellard
        gen_op_set_T0(ctx->pc + 8);
1696 6af0bf9c bellard
        gen_op_store_T0_gpr(blink);
1697 6af0bf9c bellard
    }
1698 6af0bf9c bellard
}
1699 6af0bf9c bellard
1700 7a387fff ths
/* special3 bitfield operations */
1701 7a387fff ths
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1702 7a387fff ths
                       int rs, int lsb, int msb)
1703 7a387fff ths
{
1704 7a387fff ths
    GEN_LOAD_REG_TN(T1, rs);
1705 7a387fff ths
    switch (opc) {
1706 7a387fff ths
    case OPC_EXT:
1707 7a387fff ths
        if (lsb + msb > 31)
1708 7a387fff ths
            goto fail;
1709 7a387fff ths
        gen_op_ext(lsb, msb + 1);
1710 7a387fff ths
        break;
1711 7a387fff ths
    case OPC_DEXTM:
1712 7a387fff ths
        if (lsb + msb > 63)
1713 7a387fff ths
            goto fail;
1714 7a387fff ths
        gen_op_ext(lsb, msb + 1 + 32);
1715 7a387fff ths
        break;
1716 7a387fff ths
    case OPC_DEXTU:
1717 7a387fff ths
        if (lsb + msb > 63)
1718 7a387fff ths
            goto fail;
1719 7a387fff ths
        gen_op_ext(lsb + 32, msb + 1);
1720 7a387fff ths
        break;
1721 7a387fff ths
    case OPC_DEXT:
1722 7a387fff ths
        gen_op_ext(lsb, msb + 1);
1723 7a387fff ths
        break;
1724 7a387fff ths
    case OPC_INS:
1725 7a387fff ths
        if (lsb > msb)
1726 7a387fff ths
            goto fail;
1727 171b31e7 ths
        GEN_LOAD_REG_TN(T0, rt);
1728 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1);
1729 7a387fff ths
        break;
1730 7a387fff ths
    case OPC_DINSM:
1731 7a387fff ths
        if (lsb > msb)
1732 7a387fff ths
            goto fail;
1733 171b31e7 ths
        GEN_LOAD_REG_TN(T0, rt);
1734 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1735 7a387fff ths
        break;
1736 7a387fff ths
    case OPC_DINSU:
1737 7a387fff ths
        if (lsb > msb)
1738 7a387fff ths
            goto fail;
1739 171b31e7 ths
        GEN_LOAD_REG_TN(T0, rt);
1740 7a387fff ths
        gen_op_ins(lsb + 32, msb - lsb + 1);
1741 7a387fff ths
        break;
1742 7a387fff ths
    case OPC_DINS:
1743 7a387fff ths
        if (lsb > msb)
1744 7a387fff ths
            goto fail;
1745 171b31e7 ths
        GEN_LOAD_REG_TN(T0, rt);
1746 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1);
1747 7a387fff ths
        break;
1748 7a387fff ths
    default:
1749 7a387fff ths
fail:
1750 7a387fff ths
        MIPS_INVAL("bitops");
1751 7a387fff ths
        generate_exception(ctx, EXCP_RI);
1752 7a387fff ths
        return;
1753 7a387fff ths
    }
1754 7a387fff ths
    GEN_STORE_TN_REG(rt, T0);
1755 7a387fff ths
}
1756 7a387fff ths
1757 6af0bf9c bellard
/* CP0 (MMU and control) */
1758 873eb012 ths
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1759 873eb012 ths
{
1760 7a387fff ths
    const char *rn = "invalid";
1761 873eb012 ths
1762 873eb012 ths
    switch (reg) {
1763 873eb012 ths
    case 0:
1764 7a387fff ths
        switch (sel) {
1765 7a387fff ths
        case 0:
1766 2423f660 ths
            gen_op_mfc0_index();
1767 7a387fff ths
            rn = "Index";
1768 7a387fff ths
            break;
1769 7a387fff ths
        case 1:
1770 2423f660 ths
//            gen_op_mfc0_mvpcontrol(); /* MT ASE */
1771 7a387fff ths
            rn = "MVPControl";
1772 2423f660 ths
//            break;
1773 7a387fff ths
        case 2:
1774 2423f660 ths
//            gen_op_mfc0_mvpconf0(); /* MT ASE */
1775 7a387fff ths
            rn = "MVPConf0";
1776 2423f660 ths
//            break;
1777 7a387fff ths
        case 3:
1778 2423f660 ths
//            gen_op_mfc0_mvpconf1(); /* MT ASE */
1779 7a387fff ths
            rn = "MVPConf1";
1780 2423f660 ths
//            break;
1781 7a387fff ths
        default:
1782 7a387fff ths
            goto die;
1783 7a387fff ths
        }
1784 873eb012 ths
        break;
1785 873eb012 ths
    case 1:
1786 7a387fff ths
        switch (sel) {
1787 7a387fff ths
        case 0:
1788 7a387fff ths
            gen_op_mfc0_random();
1789 7a387fff ths
            rn = "Random";
1790 2423f660 ths
            break;
1791 7a387fff ths
        case 1:
1792 2423f660 ths
//            gen_op_mfc0_vpecontrol(); /* MT ASE */
1793 7a387fff ths
            rn = "VPEControl";
1794 2423f660 ths
//            break;
1795 7a387fff ths
        case 2:
1796 2423f660 ths
//            gen_op_mfc0_vpeconf0(); /* MT ASE */
1797 7a387fff ths
            rn = "VPEConf0";
1798 2423f660 ths
//            break;
1799 7a387fff ths
        case 3:
1800 2423f660 ths
//            gen_op_mfc0_vpeconf1(); /* MT ASE */
1801 7a387fff ths
            rn = "VPEConf1";
1802 2423f660 ths
//            break;
1803 7a387fff ths
        case 4:
1804 2423f660 ths
//            gen_op_mfc0_YQMask(); /* MT ASE */
1805 7a387fff ths
            rn = "YQMask";
1806 2423f660 ths
//            break;
1807 7a387fff ths
        case 5:
1808 2423f660 ths
//            gen_op_mfc0_vpeschedule(); /* MT ASE */
1809 7a387fff ths
            rn = "VPESchedule";
1810 2423f660 ths
//            break;
1811 7a387fff ths
        case 6:
1812 2423f660 ths
//            gen_op_mfc0_vpeschefback(); /* MT ASE */
1813 7a387fff ths
            rn = "VPEScheFBack";
1814 2423f660 ths
//            break;
1815 7a387fff ths
        case 7:
1816 2423f660 ths
//            gen_op_mfc0_vpeopt(); /* MT ASE */
1817 7a387fff ths
            rn = "VPEOpt";
1818 2423f660 ths
//            break;
1819 7a387fff ths
        default:
1820 7a387fff ths
            goto die;
1821 7a387fff ths
        }
1822 873eb012 ths
        break;
1823 873eb012 ths
    case 2:
1824 7a387fff ths
        switch (sel) {
1825 7a387fff ths
        case 0:
1826 2423f660 ths
            gen_op_mfc0_entrylo0();
1827 2423f660 ths
            rn = "EntryLo0";
1828 2423f660 ths
            break;
1829 7a387fff ths
        case 1:
1830 2423f660 ths
//            gen_op_mfc0_tcstatus(); /* MT ASE */
1831 2423f660 ths
            rn = "TCStatus";
1832 2423f660 ths
//            break;
1833 7a387fff ths
        case 2:
1834 2423f660 ths
//            gen_op_mfc0_tcbind(); /* MT ASE */
1835 2423f660 ths
            rn = "TCBind";
1836 2423f660 ths
//            break;
1837 7a387fff ths
        case 3:
1838 2423f660 ths
//            gen_op_mfc0_tcrestart(); /* MT ASE */
1839 2423f660 ths
            rn = "TCRestart";
1840 2423f660 ths
//            break;
1841 7a387fff ths
        case 4:
1842 2423f660 ths
//            gen_op_mfc0_tchalt(); /* MT ASE */
1843 2423f660 ths
            rn = "TCHalt";
1844 2423f660 ths
//            break;
1845 7a387fff ths
        case 5:
1846 2423f660 ths
//            gen_op_mfc0_tccontext(); /* MT ASE */
1847 2423f660 ths
            rn = "TCContext";
1848 2423f660 ths
//            break;
1849 7a387fff ths
        case 6:
1850 2423f660 ths
//            gen_op_mfc0_tcschedule(); /* MT ASE */
1851 2423f660 ths
            rn = "TCSchedule";
1852 2423f660 ths
//            break;
1853 7a387fff ths
        case 7:
1854 2423f660 ths
//            gen_op_mfc0_tcschefback(); /* MT ASE */
1855 2423f660 ths
            rn = "TCScheFBack";
1856 2423f660 ths
//            break;
1857 7a387fff ths
        default:
1858 7a387fff ths
            goto die;
1859 7a387fff ths
        }
1860 873eb012 ths
        break;
1861 873eb012 ths
    case 3:
1862 7a387fff ths
        switch (sel) {
1863 7a387fff ths
        case 0:
1864 2423f660 ths
            gen_op_mfc0_entrylo1();
1865 2423f660 ths
            rn = "EntryLo1";
1866 2423f660 ths
            break;
1867 7a387fff ths
        default:
1868 7a387fff ths
            goto die;
1869 1579a72e ths
        }
1870 873eb012 ths
        break;
1871 873eb012 ths
    case 4:
1872 7a387fff ths
        switch (sel) {
1873 7a387fff ths
        case 0:
1874 2423f660 ths
            gen_op_mfc0_context();
1875 2423f660 ths
            rn = "Context";
1876 2423f660 ths
            break;
1877 7a387fff ths
        case 1:
1878 2423f660 ths
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
1879 2423f660 ths
            rn = "ContextConfig";
1880 2423f660 ths
//            break;
1881 7a387fff ths
        default:
1882 7a387fff ths
            goto die;
1883 1579a72e ths
        }
1884 873eb012 ths
        break;
1885 873eb012 ths
    case 5:
1886 7a387fff ths
        switch (sel) {
1887 7a387fff ths
        case 0:
1888 2423f660 ths
            gen_op_mfc0_pagemask();
1889 2423f660 ths
            rn = "PageMask";
1890 2423f660 ths
            break;
1891 7a387fff ths
        case 1:
1892 2423f660 ths
            gen_op_mfc0_pagegrain();
1893 2423f660 ths
            rn = "PageGrain";
1894 2423f660 ths
            break;
1895 7a387fff ths
        default:
1896 7a387fff ths
            goto die;
1897 1579a72e ths
        }
1898 873eb012 ths
        break;
1899 873eb012 ths
    case 6:
1900 7a387fff ths
        switch (sel) {
1901 7a387fff ths
        case 0:
1902 2423f660 ths
            gen_op_mfc0_wired();
1903 2423f660 ths
            rn = "Wired";
1904 2423f660 ths
            break;
1905 7a387fff ths
        case 1:
1906 2423f660 ths
//            gen_op_mfc0_srsconf0(); /* shadow registers */
1907 2423f660 ths
            rn = "SRSConf0";
1908 2423f660 ths
//            break;
1909 7a387fff ths
        case 2:
1910 2423f660 ths
//            gen_op_mfc0_srsconf1(); /* shadow registers */
1911 2423f660 ths
            rn = "SRSConf1";
1912 2423f660 ths
//            break;
1913 7a387fff ths
        case 3:
1914 2423f660 ths
//            gen_op_mfc0_srsconf2(); /* shadow registers */
1915 2423f660 ths
            rn = "SRSConf2";
1916 2423f660 ths
//            break;
1917 7a387fff ths
        case 4:
1918 2423f660 ths
//            gen_op_mfc0_srsconf3(); /* shadow registers */
1919 2423f660 ths
            rn = "SRSConf3";
1920 2423f660 ths
//            break;
1921 7a387fff ths
        case 5:
1922 2423f660 ths
//            gen_op_mfc0_srsconf4(); /* shadow registers */
1923 2423f660 ths
            rn = "SRSConf4";
1924 2423f660 ths
//            break;
1925 7a387fff ths
        default:
1926 7a387fff ths
            goto die;
1927 1579a72e ths
        }
1928 873eb012 ths
        break;
1929 8c0fdd85 ths
    case 7:
1930 7a387fff ths
        switch (sel) {
1931 7a387fff ths
        case 0:
1932 2423f660 ths
            gen_op_mfc0_hwrena();
1933 2423f660 ths
            rn = "HWREna";
1934 2423f660 ths
            break;
1935 7a387fff ths
        default:
1936 7a387fff ths
            goto die;
1937 1579a72e ths
        }
1938 8c0fdd85 ths
        break;
1939 873eb012 ths
    case 8:
1940 7a387fff ths
        switch (sel) {
1941 7a387fff ths
        case 0:
1942 2423f660 ths
            gen_op_mfc0_badvaddr();
1943 2423f660 ths
            rn = "BadVaddr";
1944 2423f660 ths
            break;
1945 7a387fff ths
        default:
1946 7a387fff ths
            goto die;
1947 7a387fff ths
       }
1948 873eb012 ths
        break;
1949 873eb012 ths
    case 9:
1950 7a387fff ths
        switch (sel) {
1951 7a387fff ths
        case 0:
1952 2423f660 ths
            gen_op_mfc0_count();
1953 2423f660 ths
            rn = "Count";
1954 2423f660 ths
            break;
1955 2423f660 ths
        /* 6,7 are implementation dependent */
1956 7a387fff ths
        default:
1957 7a387fff ths
            goto die;
1958 2423f660 ths
        }
1959 873eb012 ths
        break;
1960 873eb012 ths
    case 10:
1961 7a387fff ths
        switch (sel) {
1962 7a387fff ths
        case 0:
1963 2423f660 ths
            gen_op_mfc0_entryhi();
1964 2423f660 ths
            rn = "EntryHi";
1965 2423f660 ths
            break;
1966 7a387fff ths
        default:
1967 7a387fff ths
            goto die;
1968 1579a72e ths
        }
1969 873eb012 ths
        break;
1970 873eb012 ths
    case 11:
1971 7a387fff ths
        switch (sel) {
1972 7a387fff ths
        case 0:
1973 2423f660 ths
            gen_op_mfc0_compare();
1974 2423f660 ths
            rn = "Compare";
1975 2423f660 ths
            break;
1976 2423f660 ths
        /* 6,7 are implementation dependent */
1977 7a387fff ths
        default:
1978 7a387fff ths
            goto die;
1979 2423f660 ths
        }
1980 873eb012 ths
        break;
1981 873eb012 ths
    case 12:
1982 7a387fff ths
        switch (sel) {
1983 7a387fff ths
        case 0:
1984 2423f660 ths
            gen_op_mfc0_status();
1985 2423f660 ths
            rn = "Status";
1986 2423f660 ths
            break;
1987 7a387fff ths
        case 1:
1988 2423f660 ths
            gen_op_mfc0_intctl();
1989 2423f660 ths
            rn = "IntCtl";
1990 2423f660 ths
            break;
1991 7a387fff ths
        case 2:
1992 2423f660 ths
            gen_op_mfc0_srsctl();
1993 2423f660 ths
            rn = "SRSCtl";
1994 2423f660 ths
            break;
1995 7a387fff ths
        case 3:
1996 2423f660 ths
//            gen_op_mfc0_srsmap(); /* shadow registers */
1997 2423f660 ths
            rn = "SRSMap";
1998 2423f660 ths
//            break;
1999 7a387fff ths
        default:
2000 7a387fff ths
            goto die;
2001 7a387fff ths
       }
2002 873eb012 ths
        break;
2003 873eb012 ths
    case 13:
2004 7a387fff ths
        switch (sel) {
2005 7a387fff ths
        case 0:
2006 2423f660 ths
            gen_op_mfc0_cause();
2007 2423f660 ths
            rn = "Cause";
2008 2423f660 ths
            break;
2009 7a387fff ths
        default:
2010 7a387fff ths
            goto die;
2011 7a387fff ths
       }
2012 873eb012 ths
        break;
2013 873eb012 ths
    case 14:
2014 7a387fff ths
        switch (sel) {
2015 7a387fff ths
        case 0:
2016 2423f660 ths
            gen_op_mfc0_epc();
2017 2423f660 ths
            rn = "EPC";
2018 2423f660 ths
            break;
2019 7a387fff ths
        default:
2020 7a387fff ths
            goto die;
2021 1579a72e ths
        }
2022 873eb012 ths
        break;
2023 873eb012 ths
    case 15:
2024 7a387fff ths
        switch (sel) {
2025 7a387fff ths
        case 0:
2026 2423f660 ths
            gen_op_mfc0_prid();
2027 2423f660 ths
            rn = "PRid";
2028 2423f660 ths
            break;
2029 7a387fff ths
        case 1:
2030 2423f660 ths
            gen_op_mfc0_ebase();
2031 2423f660 ths
            rn = "EBase";
2032 2423f660 ths
            break;
2033 7a387fff ths
        default:
2034 7a387fff ths
            goto die;
2035 7a387fff ths
       }
2036 873eb012 ths
        break;
2037 873eb012 ths
    case 16:
2038 873eb012 ths
        switch (sel) {
2039 873eb012 ths
        case 0:
2040 e397ee33 ths
            gen_op_mfc0_config0();
2041 873eb012 ths
            rn = "Config";
2042 873eb012 ths
            break;
2043 873eb012 ths
        case 1:
2044 e397ee33 ths
            gen_op_mfc0_config1();
2045 873eb012 ths
            rn = "Config1";
2046 873eb012 ths
            break;
2047 7a387fff ths
        case 2:
2048 e397ee33 ths
            gen_op_mfc0_config2();
2049 7a387fff ths
            rn = "Config2";
2050 7a387fff ths
            break;
2051 7a387fff ths
        case 3:
2052 e397ee33 ths
            gen_op_mfc0_config3();
2053 7a387fff ths
            rn = "Config3";
2054 7a387fff ths
            break;
2055 e397ee33 ths
        /* 4,5 are reserved */
2056 e397ee33 ths
        /* 6,7 are implementation dependent */
2057 e397ee33 ths
        case 6:
2058 e397ee33 ths
            gen_op_mfc0_config6();
2059 e397ee33 ths
            rn = "Config6";
2060 e397ee33 ths
            break;
2061 e397ee33 ths
        case 7:
2062 e397ee33 ths
            gen_op_mfc0_config7();
2063 e397ee33 ths
            rn = "Config7";
2064 e397ee33 ths
            break;
2065 873eb012 ths
        default:
2066 873eb012 ths
            goto die;
2067 873eb012 ths
        }
2068 873eb012 ths
        break;
2069 873eb012 ths
    case 17:
2070 7a387fff ths
        switch (sel) {
2071 7a387fff ths
        case 0:
2072 2423f660 ths
            gen_op_mfc0_lladdr();
2073 2423f660 ths
            rn = "LLAddr";
2074 2423f660 ths
            break;
2075 7a387fff ths
        default:
2076 7a387fff ths
            goto die;
2077 7a387fff ths
        }
2078 873eb012 ths
        break;
2079 873eb012 ths
    case 18:
2080 7a387fff ths
        switch (sel) {
2081 7a387fff ths
        case 0:
2082 2423f660 ths
            gen_op_mfc0_watchlo0();
2083 2423f660 ths
            rn = "WatchLo";
2084 2423f660 ths
            break;
2085 7a387fff ths
        case 1:
2086 2423f660 ths
//            gen_op_mfc0_watchlo1();
2087 2423f660 ths
            rn = "WatchLo1";
2088 2423f660 ths
//            break;
2089 7a387fff ths
        case 2:
2090 2423f660 ths
//            gen_op_mfc0_watchlo2();
2091 2423f660 ths
            rn = "WatchLo2";
2092 2423f660 ths
//            break;
2093 7a387fff ths
        case 3:
2094 2423f660 ths
//            gen_op_mfc0_watchlo3();
2095 2423f660 ths
            rn = "WatchLo3";
2096 2423f660 ths
//            break;
2097 7a387fff ths
        case 4:
2098 2423f660 ths
//            gen_op_mfc0_watchlo4();
2099 2423f660 ths
            rn = "WatchLo4";
2100 2423f660 ths
//            break;
2101 7a387fff ths
        case 5:
2102 2423f660 ths
//            gen_op_mfc0_watchlo5();
2103 2423f660 ths
            rn = "WatchLo5";
2104 2423f660 ths
//            break;
2105 7a387fff ths
        case 6:
2106 2423f660 ths
//            gen_op_mfc0_watchlo6();
2107 2423f660 ths
            rn = "WatchLo6";
2108 2423f660 ths
//            break;
2109 7a387fff ths
        case 7:
2110 2423f660 ths
//            gen_op_mfc0_watchlo7();
2111 2423f660 ths
            rn = "WatchLo7";
2112 2423f660 ths
//            break;
2113 7a387fff ths
        default:
2114 7a387fff ths
            goto die;
2115 7a387fff ths
        }
2116 873eb012 ths
        break;
2117 873eb012 ths
    case 19:
2118 7a387fff ths
        switch (sel) {
2119 7a387fff ths
        case 0:
2120 2423f660 ths
            gen_op_mfc0_watchhi0();
2121 2423f660 ths
            rn = "WatchHi";
2122 2423f660 ths
            break;
2123 7a387fff ths
        case 1:
2124 2423f660 ths
//            gen_op_mfc0_watchhi1();
2125 2423f660 ths
            rn = "WatchHi1";
2126 2423f660 ths
//            break;
2127 7a387fff ths
        case 2:
2128 2423f660 ths
//            gen_op_mfc0_watchhi2();
2129 2423f660 ths
            rn = "WatchHi2";
2130 2423f660 ths
//            break;
2131 7a387fff ths
        case 3:
2132 2423f660 ths
//            gen_op_mfc0_watchhi3();
2133 2423f660 ths
            rn = "WatchHi3";
2134 2423f660 ths
//            break;
2135 7a387fff ths
        case 4:
2136 2423f660 ths
//            gen_op_mfc0_watchhi4();
2137 2423f660 ths
            rn = "WatchHi4";
2138 2423f660 ths
//            break;
2139 7a387fff ths
        case 5:
2140 2423f660 ths
//            gen_op_mfc0_watchhi5();
2141 2423f660 ths
            rn = "WatchHi5";
2142 2423f660 ths
//            break;
2143 7a387fff ths
        case 6:
2144 2423f660 ths
//            gen_op_mfc0_watchhi6();
2145 2423f660 ths
            rn = "WatchHi6";
2146 2423f660 ths
//            break;
2147 7a387fff ths
        case 7:
2148 2423f660 ths
//            gen_op_mfc0_watchhi7();
2149 2423f660 ths
            rn = "WatchHi7";
2150 2423f660 ths
//            break;
2151 7a387fff ths
        default:
2152 7a387fff ths
            goto die;
2153 7a387fff ths
        }
2154 873eb012 ths
        break;
2155 8c0fdd85 ths
    case 20:
2156 7a387fff ths
        switch (sel) {
2157 7a387fff ths
        case 0:
2158 2423f660 ths
            /* 64 bit MMU only */
2159 2423f660 ths
            gen_op_mfc0_xcontext();
2160 2423f660 ths
            rn = "XContext";
2161 2423f660 ths
            break;
2162 7a387fff ths
        default:
2163 7a387fff ths
            goto die;
2164 7a387fff ths
        }
2165 8c0fdd85 ths
        break;
2166 8c0fdd85 ths
    case 21:
2167 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2168 7a387fff ths
        switch (sel) {
2169 7a387fff ths
        case 0:
2170 2423f660 ths
            gen_op_mfc0_framemask();
2171 2423f660 ths
            rn = "Framemask";
2172 2423f660 ths
            break;
2173 7a387fff ths
        default:
2174 7a387fff ths
            goto die;
2175 7a387fff ths
        }
2176 8c0fdd85 ths
        break;
2177 8c0fdd85 ths
    case 22:
2178 2423f660 ths
        /* ignored */
2179 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
2180 2423f660 ths
        break;
2181 873eb012 ths
    case 23:
2182 7a387fff ths
        switch (sel) {
2183 7a387fff ths
        case 0:
2184 2423f660 ths
            gen_op_mfc0_debug(); /* EJTAG support */
2185 2423f660 ths
            rn = "Debug";
2186 2423f660 ths
            break;
2187 7a387fff ths
        case 1:
2188 2423f660 ths
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2189 2423f660 ths
            rn = "TraceControl";
2190 2423f660 ths
//            break;
2191 7a387fff ths
        case 2:
2192 2423f660 ths
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2193 2423f660 ths
            rn = "TraceControl2";
2194 2423f660 ths
//            break;
2195 7a387fff ths
        case 3:
2196 2423f660 ths
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2197 2423f660 ths
            rn = "UserTraceData";
2198 2423f660 ths
//            break;
2199 7a387fff ths
        case 4:
2200 2423f660 ths
//            gen_op_mfc0_debug(); /* PDtrace support */
2201 2423f660 ths
            rn = "TraceBPC";
2202 2423f660 ths
//            break;
2203 7a387fff ths
        default:
2204 7a387fff ths
            goto die;
2205 7a387fff ths
        }
2206 873eb012 ths
        break;
2207 873eb012 ths
    case 24:
2208 7a387fff ths
        switch (sel) {
2209 7a387fff ths
        case 0:
2210 2423f660 ths
            gen_op_mfc0_depc(); /* EJTAG support */
2211 2423f660 ths
            rn = "DEPC";
2212 2423f660 ths
            break;
2213 7a387fff ths
        default:
2214 7a387fff ths
            goto die;
2215 7a387fff ths
        }
2216 873eb012 ths
        break;
2217 8c0fdd85 ths
    case 25:
2218 7a387fff ths
        switch (sel) {
2219 7a387fff ths
        case 0:
2220 2423f660 ths
            gen_op_mfc0_performance0();
2221 2423f660 ths
            rn = "Performance0";
2222 7a387fff ths
            break;
2223 7a387fff ths
        case 1:
2224 2423f660 ths
//            gen_op_mfc0_performance1();
2225 2423f660 ths
            rn = "Performance1";
2226 2423f660 ths
//            break;
2227 7a387fff ths
        case 2:
2228 2423f660 ths
//            gen_op_mfc0_performance2();
2229 2423f660 ths
            rn = "Performance2";
2230 2423f660 ths
//            break;
2231 7a387fff ths
        case 3:
2232 2423f660 ths
//            gen_op_mfc0_performance3();
2233 2423f660 ths
            rn = "Performance3";
2234 2423f660 ths
//            break;
2235 7a387fff ths
        case 4:
2236 2423f660 ths
//            gen_op_mfc0_performance4();
2237 2423f660 ths
            rn = "Performance4";
2238 2423f660 ths
//            break;
2239 7a387fff ths
        case 5:
2240 2423f660 ths
//            gen_op_mfc0_performance5();
2241 2423f660 ths
            rn = "Performance5";
2242 2423f660 ths
//            break;
2243 7a387fff ths
        case 6:
2244 2423f660 ths
//            gen_op_mfc0_performance6();
2245 2423f660 ths
            rn = "Performance6";
2246 2423f660 ths
//            break;
2247 7a387fff ths
        case 7:
2248 2423f660 ths
//            gen_op_mfc0_performance7();
2249 2423f660 ths
            rn = "Performance7";
2250 2423f660 ths
//            break;
2251 7a387fff ths
        default:
2252 7a387fff ths
            goto die;
2253 7a387fff ths
        }
2254 8c0fdd85 ths
        break;
2255 8c0fdd85 ths
    case 26:
2256 7a387fff ths
       rn = "ECC";
2257 7a387fff ths
       break;
2258 8c0fdd85 ths
    case 27:
2259 7a387fff ths
        switch (sel) {
2260 7a387fff ths
        /* ignored */
2261 7a387fff ths
        case 0 ... 3:
2262 2423f660 ths
            rn = "CacheErr";
2263 2423f660 ths
            break;
2264 7a387fff ths
        default:
2265 7a387fff ths
            goto die;
2266 7a387fff ths
        }
2267 8c0fdd85 ths
        break;
2268 873eb012 ths
    case 28:
2269 873eb012 ths
        switch (sel) {
2270 873eb012 ths
        case 0:
2271 7a387fff ths
        case 2:
2272 7a387fff ths
        case 4:
2273 7a387fff ths
        case 6:
2274 873eb012 ths
            gen_op_mfc0_taglo();
2275 873eb012 ths
            rn = "TagLo";
2276 873eb012 ths
            break;
2277 873eb012 ths
        case 1:
2278 7a387fff ths
        case 3:
2279 7a387fff ths
        case 5:
2280 7a387fff ths
        case 7:
2281 873eb012 ths
            gen_op_mfc0_datalo();
2282 873eb012 ths
            rn = "DataLo";
2283 873eb012 ths
            break;
2284 873eb012 ths
        default:
2285 873eb012 ths
            goto die;
2286 873eb012 ths
        }
2287 873eb012 ths
        break;
2288 8c0fdd85 ths
    case 29:
2289 7a387fff ths
        switch (sel) {
2290 7a387fff ths
        case 0:
2291 7a387fff ths
        case 2:
2292 7a387fff ths
        case 4:
2293 7a387fff ths
        case 6:
2294 7a387fff ths
            gen_op_mfc0_taghi();
2295 7a387fff ths
            rn = "TagHi";
2296 7a387fff ths
            break;
2297 7a387fff ths
        case 1:
2298 7a387fff ths
        case 3:
2299 7a387fff ths
        case 5:
2300 7a387fff ths
        case 7:
2301 7a387fff ths
            gen_op_mfc0_datahi();
2302 7a387fff ths
            rn = "DataHi";
2303 7a387fff ths
            break;
2304 7a387fff ths
        default:
2305 7a387fff ths
            goto die;
2306 7a387fff ths
        }
2307 8c0fdd85 ths
        break;
2308 873eb012 ths
    case 30:
2309 7a387fff ths
        switch (sel) {
2310 7a387fff ths
        case 0:
2311 2423f660 ths
            gen_op_mfc0_errorepc();
2312 2423f660 ths
            rn = "ErrorEPC";
2313 2423f660 ths
            break;
2314 7a387fff ths
        default:
2315 7a387fff ths
            goto die;
2316 7a387fff ths
        }
2317 873eb012 ths
        break;
2318 873eb012 ths
    case 31:
2319 7a387fff ths
        switch (sel) {
2320 7a387fff ths
        case 0:
2321 2423f660 ths
            gen_op_mfc0_desave(); /* EJTAG support */
2322 2423f660 ths
            rn = "DESAVE";
2323 2423f660 ths
            break;
2324 7a387fff ths
        default:
2325 7a387fff ths
            goto die;
2326 7a387fff ths
        }
2327 873eb012 ths
        break;
2328 873eb012 ths
    default:
2329 873eb012 ths
       goto die;
2330 873eb012 ths
    }
2331 873eb012 ths
#if defined MIPS_DEBUG_DISAS
2332 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2333 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2334 7a387fff ths
                rn, reg, sel);
2335 873eb012 ths
    }
2336 873eb012 ths
#endif
2337 873eb012 ths
    return;
2338 873eb012 ths
2339 873eb012 ths
die:
2340 873eb012 ths
#if defined MIPS_DEBUG_DISAS
2341 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2342 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2343 7a387fff ths
                rn, reg, sel);
2344 873eb012 ths
    }
2345 873eb012 ths
#endif
2346 873eb012 ths
    generate_exception(ctx, EXCP_RI);
2347 873eb012 ths
}
2348 873eb012 ths
2349 8c0fdd85 ths
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2350 8c0fdd85 ths
{
2351 7a387fff ths
    const char *rn = "invalid";
2352 7a387fff ths
2353 8c0fdd85 ths
    switch (reg) {
2354 8c0fdd85 ths
    case 0:
2355 7a387fff ths
        switch (sel) {
2356 7a387fff ths
        case 0:
2357 7a387fff ths
           gen_op_mtc0_index();
2358 7a387fff ths
            rn = "Index";
2359 7a387fff ths
            break;
2360 7a387fff ths
        case 1:
2361 2423f660 ths
//            gen_op_mtc0_mvpcontrol(); /* MT ASE */
2362 7a387fff ths
            rn = "MVPControl";
2363 2423f660 ths
//            break;
2364 7a387fff ths
        case 2:
2365 2423f660 ths
//            gen_op_mtc0_mvpconf0(); /* MT ASE */
2366 7a387fff ths
            rn = "MVPConf0";
2367 2423f660 ths
//            break;
2368 7a387fff ths
        case 3:
2369 2423f660 ths
//            gen_op_mtc0_mvpconf1(); /* MT ASE */
2370 7a387fff ths
            rn = "MVPConf1";
2371 2423f660 ths
//            break;
2372 7a387fff ths
        default:
2373 7a387fff ths
            goto die;
2374 7a387fff ths
        }
2375 8c0fdd85 ths
        break;
2376 8c0fdd85 ths
    case 1:
2377 7a387fff ths
        switch (sel) {
2378 7a387fff ths
        case 0:
2379 2423f660 ths
            /* ignored */
2380 7a387fff ths
            rn = "Random";
2381 2423f660 ths
            break;
2382 7a387fff ths
        case 1:
2383 2423f660 ths
//            gen_op_mtc0_vpecontrol(); /* MT ASE */
2384 7a387fff ths
            rn = "VPEControl";
2385 2423f660 ths
//            break;
2386 7a387fff ths
        case 2:
2387 2423f660 ths
//            gen_op_mtc0_vpeconf0(); /* MT ASE */
2388 7a387fff ths
            rn = "VPEConf0";
2389 2423f660 ths
//            break;
2390 7a387fff ths
        case 3:
2391 2423f660 ths
//            gen_op_mtc0_vpeconf1(); /* MT ASE */
2392 7a387fff ths
            rn = "VPEConf1";
2393 2423f660 ths
//            break;
2394 7a387fff ths
        case 4:
2395 2423f660 ths
//            gen_op_mtc0_YQMask(); /* MT ASE */
2396 7a387fff ths
            rn = "YQMask";
2397 2423f660 ths
//            break;
2398 7a387fff ths
        case 5:
2399 2423f660 ths
//            gen_op_mtc0_vpeschedule(); /* MT ASE */
2400 7a387fff ths
            rn = "VPESchedule";
2401 2423f660 ths
//            break;
2402 7a387fff ths
        case 6:
2403 2423f660 ths
//            gen_op_mtc0_vpeschefback(); /* MT ASE */
2404 7a387fff ths
            rn = "VPEScheFBack";
2405 2423f660 ths
//            break;
2406 7a387fff ths
        case 7:
2407 2423f660 ths
//            gen_op_mtc0_vpeopt(); /* MT ASE */
2408 7a387fff ths
            rn = "VPEOpt";
2409 2423f660 ths
//            break;
2410 7a387fff ths
        default:
2411 7a387fff ths
            goto die;
2412 7a387fff ths
        }
2413 8c0fdd85 ths
        break;
2414 8c0fdd85 ths
    case 2:
2415 7a387fff ths
        switch (sel) {
2416 7a387fff ths
        case 0:
2417 2423f660 ths
            gen_op_mtc0_entrylo0();
2418 2423f660 ths
            rn = "EntryLo0";
2419 2423f660 ths
            break;
2420 7a387fff ths
        case 1:
2421 2423f660 ths
//            gen_op_mtc0_tcstatus(); /* MT ASE */
2422 2423f660 ths
            rn = "TCStatus";
2423 2423f660 ths
//            break;
2424 7a387fff ths
        case 2:
2425 2423f660 ths
//            gen_op_mtc0_tcbind(); /* MT ASE */
2426 2423f660 ths
            rn = "TCBind";
2427 2423f660 ths
//            break;
2428 7a387fff ths
        case 3:
2429 2423f660 ths
//            gen_op_mtc0_tcrestart(); /* MT ASE */
2430 2423f660 ths
            rn = "TCRestart";
2431 2423f660 ths
//            break;
2432 7a387fff ths
        case 4:
2433 2423f660 ths
//            gen_op_mtc0_tchalt(); /* MT ASE */
2434 2423f660 ths
            rn = "TCHalt";
2435 2423f660 ths
//            break;
2436 7a387fff ths
        case 5:
2437 2423f660 ths
//            gen_op_mtc0_tccontext(); /* MT ASE */
2438 2423f660 ths
            rn = "TCContext";
2439 2423f660 ths
//            break;
2440 7a387fff ths
        case 6:
2441 2423f660 ths
//            gen_op_mtc0_tcschedule(); /* MT ASE */
2442 2423f660 ths
            rn = "TCSchedule";
2443 2423f660 ths
//            break;
2444 7a387fff ths
        case 7:
2445 2423f660 ths
//            gen_op_mtc0_tcschefback(); /* MT ASE */
2446 2423f660 ths
            rn = "TCScheFBack";
2447 2423f660 ths
//            break;
2448 7a387fff ths
        default:
2449 7a387fff ths
            goto die;
2450 7a387fff ths
        }
2451 8c0fdd85 ths
        break;
2452 8c0fdd85 ths
    case 3:
2453 7a387fff ths
        switch (sel) {
2454 7a387fff ths
        case 0:
2455 2423f660 ths
            gen_op_mtc0_entrylo1();
2456 2423f660 ths
            rn = "EntryLo1";
2457 2423f660 ths
            break;
2458 7a387fff ths
        default:
2459 7a387fff ths
            goto die;
2460 876d4b07 ths
        }
2461 8c0fdd85 ths
        break;
2462 8c0fdd85 ths
    case 4:
2463 7a387fff ths
        switch (sel) {
2464 7a387fff ths
        case 0:
2465 2423f660 ths
            gen_op_mtc0_context();
2466 2423f660 ths
            rn = "Context";
2467 2423f660 ths
            break;
2468 7a387fff ths
        case 1:
2469 2423f660 ths
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2470 2423f660 ths
            rn = "ContextConfig";
2471 2423f660 ths
//            break;
2472 7a387fff ths
        default:
2473 7a387fff ths
            goto die;
2474 876d4b07 ths
        }
2475 8c0fdd85 ths
        break;
2476 8c0fdd85 ths
    case 5:
2477 7a387fff ths
        switch (sel) {
2478 7a387fff ths
        case 0:
2479 2423f660 ths
            gen_op_mtc0_pagemask();
2480 2423f660 ths
            rn = "PageMask";
2481 2423f660 ths
            break;
2482 7a387fff ths
        case 1:
2483 2423f660 ths
            gen_op_mtc0_pagegrain();
2484 2423f660 ths
            rn = "PageGrain";
2485 2423f660 ths
            break;
2486 7a387fff ths
        default:
2487 7a387fff ths
            goto die;
2488 876d4b07 ths
        }
2489 8c0fdd85 ths
        break;
2490 8c0fdd85 ths
    case 6:
2491 7a387fff ths
        switch (sel) {
2492 7a387fff ths
        case 0:
2493 2423f660 ths
            gen_op_mtc0_wired();
2494 2423f660 ths
            rn = "Wired";
2495 2423f660 ths
            break;
2496 7a387fff ths
        case 1:
2497 2423f660 ths
//            gen_op_mtc0_srsconf0(); /* shadow registers */
2498 2423f660 ths
            rn = "SRSConf0";
2499 2423f660 ths
//            break;
2500 7a387fff ths
        case 2:
2501 2423f660 ths
//            gen_op_mtc0_srsconf1(); /* shadow registers */
2502 2423f660 ths
            rn = "SRSConf1";
2503 2423f660 ths
//            break;
2504 7a387fff ths
        case 3:
2505 2423f660 ths
//            gen_op_mtc0_srsconf2(); /* shadow registers */
2506 2423f660 ths
            rn = "SRSConf2";
2507 2423f660 ths
//            break;
2508 7a387fff ths
        case 4:
2509 2423f660 ths
//            gen_op_mtc0_srsconf3(); /* shadow registers */
2510 2423f660 ths
            rn = "SRSConf3";
2511 2423f660 ths
//            break;
2512 7a387fff ths
        case 5:
2513 2423f660 ths
//            gen_op_mtc0_srsconf4(); /* shadow registers */
2514 2423f660 ths
            rn = "SRSConf4";
2515 2423f660 ths
//            break;
2516 7a387fff ths
        default:
2517 7a387fff ths
            goto die;
2518 876d4b07 ths
        }
2519 8c0fdd85 ths
        break;
2520 8c0fdd85 ths
    case 7:
2521 7a387fff ths
        switch (sel) {
2522 7a387fff ths
        case 0:
2523 2423f660 ths
            gen_op_mtc0_hwrena();
2524 2423f660 ths
            rn = "HWREna";
2525 2423f660 ths
            break;
2526 7a387fff ths
        default:
2527 7a387fff ths
            goto die;
2528 876d4b07 ths
        }
2529 8c0fdd85 ths
        break;
2530 8c0fdd85 ths
    case 8:
2531 7a387fff ths
        /* ignored */
2532 8c0fdd85 ths
        rn = "BadVaddr";
2533 8c0fdd85 ths
        break;
2534 8c0fdd85 ths
    case 9:
2535 7a387fff ths
        switch (sel) {
2536 7a387fff ths
        case 0:
2537 2423f660 ths
            gen_op_mtc0_count();
2538 2423f660 ths
            rn = "Count";
2539 2423f660 ths
            break;
2540 876d4b07 ths
        /* 6,7 are implementation dependent */
2541 7a387fff ths
        default:
2542 7a387fff ths
            goto die;
2543 876d4b07 ths
        }
2544 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
2545 876d4b07 ths
        ctx->bstate = BS_STOP;
2546 8c0fdd85 ths
        break;
2547 8c0fdd85 ths
    case 10:
2548 7a387fff ths
        switch (sel) {
2549 7a387fff ths
        case 0:
2550 2423f660 ths
            gen_op_mtc0_entryhi();
2551 2423f660 ths
            rn = "EntryHi";
2552 2423f660 ths
            break;
2553 7a387fff ths
        default:
2554 7a387fff ths
            goto die;
2555 876d4b07 ths
        }
2556 8c0fdd85 ths
        break;
2557 8c0fdd85 ths
    case 11:
2558 7a387fff ths
        switch (sel) {
2559 7a387fff ths
        case 0:
2560 2423f660 ths
            gen_op_mtc0_compare();
2561 2423f660 ths
            rn = "Compare";
2562 2423f660 ths
            break;
2563 2423f660 ths
        /* 6,7 are implementation dependent */
2564 7a387fff ths
        default:
2565 7a387fff ths
            goto die;
2566 876d4b07 ths
        }
2567 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
2568 876d4b07 ths
        ctx->bstate = BS_STOP;
2569 8c0fdd85 ths
        break;
2570 8c0fdd85 ths
    case 12:
2571 7a387fff ths
        switch (sel) {
2572 7a387fff ths
        case 0:
2573 2423f660 ths
            gen_op_mtc0_status();
2574 2423f660 ths
            rn = "Status";
2575 2423f660 ths
            break;
2576 7a387fff ths
        case 1:
2577 2423f660 ths
            gen_op_mtc0_intctl();
2578 2423f660 ths
            rn = "IntCtl";
2579 2423f660 ths
            break;
2580 7a387fff ths
        case 2:
2581 2423f660 ths
            gen_op_mtc0_srsctl();
2582 2423f660 ths
            rn = "SRSCtl";
2583 2423f660 ths
            break;
2584 7a387fff ths
        case 3:
2585 2423f660 ths
//            gen_op_mtc0_srsmap(); /* shadow registers */
2586 2423f660 ths
            rn = "SRSMap";
2587 2423f660 ths
//            break;
2588 7a387fff ths
        default:
2589 7a387fff ths
            goto die;
2590 876d4b07 ths
        }
2591 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
2592 876d4b07 ths
        ctx->bstate = BS_STOP;
2593 8c0fdd85 ths
        break;
2594 8c0fdd85 ths
    case 13:
2595 7a387fff ths
        switch (sel) {
2596 7a387fff ths
        case 0:
2597 2423f660 ths
            gen_op_mtc0_cause();
2598 2423f660 ths
            rn = "Cause";
2599 2423f660 ths
            break;
2600 7a387fff ths
        default:
2601 7a387fff ths
            goto die;
2602 876d4b07 ths
        }
2603 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
2604 876d4b07 ths
        ctx->bstate = BS_STOP;
2605 8c0fdd85 ths
        break;
2606 8c0fdd85 ths
    case 14:
2607 7a387fff ths
        switch (sel) {
2608 7a387fff ths
        case 0:
2609 2423f660 ths
            gen_op_mtc0_epc();
2610 2423f660 ths
            rn = "EPC";
2611 2423f660 ths
            break;
2612 7a387fff ths
        default:
2613 7a387fff ths
            goto die;
2614 876d4b07 ths
        }
2615 8c0fdd85 ths
        break;
2616 8c0fdd85 ths
    case 15:
2617 7a387fff ths
        switch (sel) {
2618 7a387fff ths
        case 0:
2619 2423f660 ths
            /* ignored */
2620 2423f660 ths
            rn = "PRid";
2621 2423f660 ths
            break;
2622 7a387fff ths
        case 1:
2623 2423f660 ths
            gen_op_mtc0_ebase();
2624 2423f660 ths
            rn = "EBase";
2625 2423f660 ths
            break;
2626 7a387fff ths
        default:
2627 7a387fff ths
            goto die;
2628 1579a72e ths
        }
2629 8c0fdd85 ths
        break;
2630 8c0fdd85 ths
    case 16:
2631 8c0fdd85 ths
        switch (sel) {
2632 8c0fdd85 ths
        case 0:
2633 e397ee33 ths
            gen_op_mtc0_config0();
2634 7a387fff ths
            rn = "Config";
2635 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
2636 2423f660 ths
            ctx->bstate = BS_STOP;
2637 7a387fff ths
            break;
2638 7a387fff ths
        case 1:
2639 e397ee33 ths
            /* ignored, read only */
2640 7a387fff ths
            rn = "Config1";
2641 7a387fff ths
            break;
2642 7a387fff ths
        case 2:
2643 e397ee33 ths
            gen_op_mtc0_config2();
2644 7a387fff ths
            rn = "Config2";
2645 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
2646 2423f660 ths
            ctx->bstate = BS_STOP;
2647 8c0fdd85 ths
            break;
2648 7a387fff ths
        case 3:
2649 e397ee33 ths
            /* ignored, read only */
2650 7a387fff ths
            rn = "Config3";
2651 7a387fff ths
            break;
2652 e397ee33 ths
        /* 4,5 are reserved */
2653 e397ee33 ths
        /* 6,7 are implementation dependent */
2654 e397ee33 ths
        case 6:
2655 e397ee33 ths
            /* ignored */
2656 e397ee33 ths
            rn = "Config6";
2657 e397ee33 ths
            break;
2658 e397ee33 ths
        case 7:
2659 e397ee33 ths
            /* ignored */
2660 e397ee33 ths
            rn = "Config7";
2661 e397ee33 ths
            break;
2662 8c0fdd85 ths
        default:
2663 8c0fdd85 ths
            rn = "Invalid config selector";
2664 8c0fdd85 ths
            goto die;
2665 8c0fdd85 ths
        }
2666 8c0fdd85 ths
        break;
2667 8c0fdd85 ths
    case 17:
2668 7a387fff ths
        switch (sel) {
2669 7a387fff ths
        case 0:
2670 2423f660 ths
            /* ignored */
2671 2423f660 ths
            rn = "LLAddr";
2672 2423f660 ths
            break;
2673 7a387fff ths
        default:
2674 7a387fff ths
            goto die;
2675 7a387fff ths
        }
2676 8c0fdd85 ths
        break;
2677 8c0fdd85 ths
    case 18:
2678 7a387fff ths
        switch (sel) {
2679 7a387fff ths
        case 0:
2680 2423f660 ths
            gen_op_mtc0_watchlo0();
2681 2423f660 ths
            rn = "WatchLo";
2682 2423f660 ths
            break;
2683 7a387fff ths
        case 1:
2684 2423f660 ths
//            gen_op_mtc0_watchlo1();
2685 2423f660 ths
            rn = "WatchLo1";
2686 2423f660 ths
//            break;
2687 7a387fff ths
        case 2:
2688 2423f660 ths
//            gen_op_mtc0_watchlo2();
2689 2423f660 ths
            rn = "WatchLo2";
2690 2423f660 ths
//            break;
2691 7a387fff ths
        case 3:
2692 2423f660 ths
//            gen_op_mtc0_watchlo3();
2693 2423f660 ths
            rn = "WatchLo3";
2694 2423f660 ths
//            break;
2695 7a387fff ths
        case 4:
2696 2423f660 ths
//            gen_op_mtc0_watchlo4();
2697 2423f660 ths
            rn = "WatchLo4";
2698 2423f660 ths
//            break;
2699 7a387fff ths
        case 5:
2700 2423f660 ths
//            gen_op_mtc0_watchlo5();
2701 2423f660 ths
            rn = "WatchLo5";
2702 2423f660 ths
//            break;
2703 7a387fff ths
        case 6:
2704 2423f660 ths
//            gen_op_mtc0_watchlo6();
2705 2423f660 ths
            rn = "WatchLo6";
2706 2423f660 ths
//            break;
2707 7a387fff ths
        case 7:
2708 2423f660 ths
//            gen_op_mtc0_watchlo7();
2709 2423f660 ths
            rn = "WatchLo7";
2710 2423f660 ths
//            break;
2711 7a387fff ths
        default:
2712 7a387fff ths
            goto die;
2713 7a387fff ths
        }
2714 8c0fdd85 ths
        break;
2715 8c0fdd85 ths
    case 19:
2716 7a387fff ths
        switch (sel) {
2717 7a387fff ths
        case 0:
2718 2423f660 ths
            gen_op_mtc0_watchhi0();
2719 2423f660 ths
            rn = "WatchHi";
2720 2423f660 ths
            break;
2721 7a387fff ths
        case 1:
2722 2423f660 ths
//            gen_op_mtc0_watchhi1();
2723 2423f660 ths
            rn = "WatchHi1";
2724 2423f660 ths
//            break;
2725 7a387fff ths
        case 2:
2726 2423f660 ths
//            gen_op_mtc0_watchhi2();
2727 2423f660 ths
            rn = "WatchHi2";
2728 2423f660 ths
//            break;
2729 7a387fff ths
        case 3:
2730 2423f660 ths
//            gen_op_mtc0_watchhi3();
2731 2423f660 ths
            rn = "WatchHi3";
2732 2423f660 ths
//            break;
2733 7a387fff ths
        case 4:
2734 2423f660 ths
//            gen_op_mtc0_watchhi4();
2735 2423f660 ths
            rn = "WatchHi4";
2736 2423f660 ths
//            break;
2737 7a387fff ths
        case 5:
2738 2423f660 ths
//            gen_op_mtc0_watchhi5();
2739 2423f660 ths
            rn = "WatchHi5";
2740 2423f660 ths
//            break;
2741 7a387fff ths
        case 6:
2742 2423f660 ths
//            gen_op_mtc0_watchhi6();
2743 2423f660 ths
            rn = "WatchHi6";
2744 2423f660 ths
//            break;
2745 7a387fff ths
        case 7:
2746 2423f660 ths
//            gen_op_mtc0_watchhi7();
2747 2423f660 ths
            rn = "WatchHi7";
2748 2423f660 ths
//            break;
2749 7a387fff ths
        default:
2750 7a387fff ths
            goto die;
2751 7a387fff ths
        }
2752 8c0fdd85 ths
        break;
2753 8c0fdd85 ths
    case 20:
2754 7a387fff ths
        switch (sel) {
2755 7a387fff ths
        case 0:
2756 2423f660 ths
            /* 64 bit MMU only */
2757 2423f660 ths
            /* Nothing writable in lower 32 bits */
2758 2423f660 ths
            rn = "XContext";
2759 2423f660 ths
            break;
2760 7a387fff ths
        default:
2761 7a387fff ths
            goto die;
2762 7a387fff ths
        }
2763 8c0fdd85 ths
        break;
2764 8c0fdd85 ths
    case 21:
2765 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2766 7a387fff ths
        switch (sel) {
2767 7a387fff ths
        case 0:
2768 2423f660 ths
            gen_op_mtc0_framemask();
2769 2423f660 ths
            rn = "Framemask";
2770 2423f660 ths
            break;
2771 7a387fff ths
        default:
2772 7a387fff ths
            goto die;
2773 7a387fff ths
        }
2774 7a387fff ths
        break;
2775 8c0fdd85 ths
    case 22:
2776 7a387fff ths
        /* ignored */
2777 7a387fff ths
        rn = "Diagnostic"; /* implementation dependent */
2778 2423f660 ths
        break;
2779 8c0fdd85 ths
    case 23:
2780 7a387fff ths
        switch (sel) {
2781 7a387fff ths
        case 0:
2782 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
2783 2423f660 ths
            rn = "Debug";
2784 2423f660 ths
            break;
2785 7a387fff ths
        case 1:
2786 2423f660 ths
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
2787 2423f660 ths
            rn = "TraceControl";
2788 2423f660 ths
//            break;
2789 7a387fff ths
        case 2:
2790 2423f660 ths
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2791 2423f660 ths
            rn = "TraceControl2";
2792 2423f660 ths
//            break;
2793 7a387fff ths
        case 3:
2794 2423f660 ths
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
2795 2423f660 ths
            rn = "UserTraceData";
2796 2423f660 ths
//            break;
2797 7a387fff ths
        case 4:
2798 2423f660 ths
//            gen_op_mtc0_debug(); /* PDtrace support */
2799 2423f660 ths
            rn = "TraceBPC";
2800 2423f660 ths
//            break;
2801 7a387fff ths
        default:
2802 7a387fff ths
            goto die;
2803 7a387fff ths
        }
2804 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
2805 2423f660 ths
        ctx->bstate = BS_STOP;
2806 8c0fdd85 ths
        break;
2807 8c0fdd85 ths
    case 24:
2808 7a387fff ths
        switch (sel) {
2809 7a387fff ths
        case 0:
2810 2423f660 ths
            gen_op_mtc0_depc(); /* EJTAG support */
2811 2423f660 ths
            rn = "DEPC";
2812 2423f660 ths
            break;
2813 7a387fff ths
        default:
2814 7a387fff ths
            goto die;
2815 7a387fff ths
        }
2816 8c0fdd85 ths
        break;
2817 8c0fdd85 ths
    case 25:
2818 7a387fff ths
        switch (sel) {
2819 7a387fff ths
        case 0:
2820 2423f660 ths
            gen_op_mtc0_performance0();
2821 2423f660 ths
            rn = "Performance0";
2822 2423f660 ths
            break;
2823 7a387fff ths
        case 1:
2824 2423f660 ths
//            gen_op_mtc0_performance1();
2825 2423f660 ths
            rn = "Performance1";
2826 2423f660 ths
//            break;
2827 7a387fff ths
        case 2:
2828 2423f660 ths
//            gen_op_mtc0_performance2();
2829 2423f660 ths
            rn = "Performance2";
2830 2423f660 ths
//            break;
2831 7a387fff ths
        case 3:
2832 2423f660 ths
//            gen_op_mtc0_performance3();
2833 2423f660 ths
            rn = "Performance3";
2834 2423f660 ths
//            break;
2835 7a387fff ths
        case 4:
2836 2423f660 ths
//            gen_op_mtc0_performance4();
2837 2423f660 ths
            rn = "Performance4";
2838 2423f660 ths
//            break;
2839 7a387fff ths
        case 5:
2840 2423f660 ths
//            gen_op_mtc0_performance5();
2841 2423f660 ths
            rn = "Performance5";
2842 2423f660 ths
//            break;
2843 7a387fff ths
        case 6:
2844 2423f660 ths
//            gen_op_mtc0_performance6();
2845 2423f660 ths
            rn = "Performance6";
2846 2423f660 ths
//            break;
2847 7a387fff ths
        case 7:
2848 2423f660 ths
//            gen_op_mtc0_performance7();
2849 2423f660 ths
            rn = "Performance7";
2850 2423f660 ths
//            break;
2851 7a387fff ths
        default:
2852 7a387fff ths
            goto die;
2853 7a387fff ths
        }
2854 8c0fdd85 ths
       break;
2855 8c0fdd85 ths
    case 26:
2856 2423f660 ths
        /* ignored */
2857 8c0fdd85 ths
        rn = "ECC";
2858 2423f660 ths
        break;
2859 8c0fdd85 ths
    case 27:
2860 7a387fff ths
        switch (sel) {
2861 7a387fff ths
        case 0 ... 3:
2862 2423f660 ths
            /* ignored */
2863 2423f660 ths
            rn = "CacheErr";
2864 2423f660 ths
            break;
2865 7a387fff ths
        default:
2866 7a387fff ths
            goto die;
2867 7a387fff ths
        }
2868 8c0fdd85 ths
       break;
2869 8c0fdd85 ths
    case 28:
2870 8c0fdd85 ths
        switch (sel) {
2871 8c0fdd85 ths
        case 0:
2872 7a387fff ths
        case 2:
2873 7a387fff ths
        case 4:
2874 7a387fff ths
        case 6:
2875 8c0fdd85 ths
            gen_op_mtc0_taglo();
2876 8c0fdd85 ths
            rn = "TagLo";
2877 8c0fdd85 ths
            break;
2878 7a387fff ths
        case 1:
2879 7a387fff ths
        case 3:
2880 7a387fff ths
        case 5:
2881 7a387fff ths
        case 7:
2882 2423f660 ths
            gen_op_mtc0_datalo();
2883 7a387fff ths
            rn = "DataLo";
2884 7a387fff ths
            break;
2885 8c0fdd85 ths
        default:
2886 8c0fdd85 ths
            goto die;
2887 8c0fdd85 ths
        }
2888 8c0fdd85 ths
        break;
2889 8c0fdd85 ths
    case 29:
2890 7a387fff ths
        switch (sel) {
2891 7a387fff ths
        case 0:
2892 7a387fff ths
        case 2:
2893 7a387fff ths
        case 4:
2894 7a387fff ths
        case 6:
2895 7a387fff ths
            gen_op_mtc0_taghi();
2896 7a387fff ths
            rn = "TagHi";
2897 7a387fff ths
            break;
2898 7a387fff ths
        case 1:
2899 7a387fff ths
        case 3:
2900 7a387fff ths
        case 5:
2901 7a387fff ths
        case 7:
2902 2423f660 ths
            gen_op_mtc0_datahi();
2903 7a387fff ths
            rn = "DataHi";
2904 7a387fff ths
            break;
2905 7a387fff ths
        default:
2906 7a387fff ths
            rn = "invalid sel";
2907 7a387fff ths
            goto die;
2908 7a387fff ths
        }
2909 8c0fdd85 ths
       break;
2910 8c0fdd85 ths
    case 30:
2911 7a387fff ths
        switch (sel) {
2912 7a387fff ths
        case 0:
2913 2423f660 ths
            gen_op_mtc0_errorepc();
2914 2423f660 ths
            rn = "ErrorEPC";
2915 2423f660 ths
            break;
2916 7a387fff ths
        default:
2917 7a387fff ths
            goto die;
2918 7a387fff ths
        }
2919 8c0fdd85 ths
        break;
2920 8c0fdd85 ths
    case 31:
2921 7a387fff ths
        switch (sel) {
2922 7a387fff ths
        case 0:
2923 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
2924 2423f660 ths
            rn = "DESAVE";
2925 2423f660 ths
            break;
2926 7a387fff ths
        default:
2927 7a387fff ths
            goto die;
2928 7a387fff ths
        }
2929 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
2930 2423f660 ths
        ctx->bstate = BS_STOP;
2931 8c0fdd85 ths
        break;
2932 8c0fdd85 ths
    default:
2933 8c0fdd85 ths
       goto die;
2934 8c0fdd85 ths
    }
2935 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
2936 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2937 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2938 7a387fff ths
                rn, reg, sel);
2939 8c0fdd85 ths
    }
2940 8c0fdd85 ths
#endif
2941 8c0fdd85 ths
    return;
2942 8c0fdd85 ths
2943 8c0fdd85 ths
die:
2944 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
2945 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2946 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2947 7a387fff ths
                rn, reg, sel);
2948 8c0fdd85 ths
    }
2949 8c0fdd85 ths
#endif
2950 8c0fdd85 ths
    generate_exception(ctx, EXCP_RI);
2951 8c0fdd85 ths
}
2952 8c0fdd85 ths
2953 534ce69f ths
#ifdef TARGET_MIPS64
2954 9c2149c8 ths
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2955 9c2149c8 ths
{
2956 9c2149c8 ths
    const char *rn = "invalid";
2957 9c2149c8 ths
2958 9c2149c8 ths
    switch (reg) {
2959 9c2149c8 ths
    case 0:
2960 9c2149c8 ths
        switch (sel) {
2961 9c2149c8 ths
        case 0:
2962 2423f660 ths
            gen_op_mfc0_index();
2963 9c2149c8 ths
            rn = "Index";
2964 9c2149c8 ths
            break;
2965 9c2149c8 ths
        case 1:
2966 2423f660 ths
//            gen_op_dmfc0_mvpcontrol(); /* MT ASE */
2967 9c2149c8 ths
            rn = "MVPControl";
2968 2423f660 ths
//            break;
2969 9c2149c8 ths
        case 2:
2970 2423f660 ths
//            gen_op_dmfc0_mvpconf0(); /* MT ASE */
2971 9c2149c8 ths
            rn = "MVPConf0";
2972 2423f660 ths
//            break;
2973 9c2149c8 ths
        case 3:
2974 2423f660 ths
//            gen_op_dmfc0_mvpconf1(); /* MT ASE */
2975 9c2149c8 ths
            rn = "MVPConf1";
2976 2423f660 ths
//            break;
2977 9c2149c8 ths
        default:
2978 9c2149c8 ths
            goto die;
2979 9c2149c8 ths
        }
2980 9c2149c8 ths
        break;
2981 9c2149c8 ths
    case 1:
2982 9c2149c8 ths
        switch (sel) {
2983 9c2149c8 ths
        case 0:
2984 9c2149c8 ths
            gen_op_mfc0_random();
2985 9c2149c8 ths
            rn = "Random";
2986 2423f660 ths
            break;
2987 9c2149c8 ths
        case 1:
2988 2423f660 ths
//            gen_op_dmfc0_vpecontrol(); /* MT ASE */
2989 9c2149c8 ths
            rn = "VPEControl";
2990 2423f660 ths
//            break;
2991 9c2149c8 ths
        case 2:
2992 2423f660 ths
//            gen_op_dmfc0_vpeconf0(); /* MT ASE */
2993 9c2149c8 ths
            rn = "VPEConf0";
2994 2423f660 ths
//            break;
2995 9c2149c8 ths
        case 3:
2996 2423f660 ths
//            gen_op_dmfc0_vpeconf1(); /* MT ASE */
2997 9c2149c8 ths
            rn = "VPEConf1";
2998 2423f660 ths
//            break;
2999 9c2149c8 ths
        case 4:
3000 2423f660 ths
//            gen_op_dmfc0_YQMask(); /* MT ASE */
3001 9c2149c8 ths
            rn = "YQMask";
3002 2423f660 ths
//            break;
3003 9c2149c8 ths
        case 5:
3004 2423f660 ths
//            gen_op_dmfc0_vpeschedule(); /* MT ASE */
3005 9c2149c8 ths
            rn = "VPESchedule";
3006 2423f660 ths
//            break;
3007 9c2149c8 ths
        case 6:
3008 2423f660 ths
//            gen_op_dmfc0_vpeschefback(); /* MT ASE */
3009 9c2149c8 ths
            rn = "VPEScheFBack";
3010 2423f660 ths
//            break;
3011 9c2149c8 ths
        case 7:
3012 2423f660 ths
//            gen_op_dmfc0_vpeopt(); /* MT ASE */
3013 9c2149c8 ths
            rn = "VPEOpt";
3014 2423f660 ths
//            break;
3015 9c2149c8 ths
        default:
3016 9c2149c8 ths
            goto die;
3017 9c2149c8 ths
        }
3018 9c2149c8 ths
        break;
3019 9c2149c8 ths
    case 2:
3020 9c2149c8 ths
        switch (sel) {
3021 9c2149c8 ths
        case 0:
3022 2423f660 ths
            gen_op_dmfc0_entrylo0();
3023 2423f660 ths
            rn = "EntryLo0";
3024 2423f660 ths
            break;
3025 9c2149c8 ths
        case 1:
3026 2423f660 ths
//            gen_op_dmfc0_tcstatus(); /* MT ASE */
3027 2423f660 ths
            rn = "TCStatus";
3028 2423f660 ths
//            break;
3029 9c2149c8 ths
        case 2:
3030 2423f660 ths
//            gen_op_dmfc0_tcbind(); /* MT ASE */
3031 2423f660 ths
            rn = "TCBind";
3032 2423f660 ths
//            break;
3033 9c2149c8 ths
        case 3:
3034 2423f660 ths
//            gen_op_dmfc0_tcrestart(); /* MT ASE */
3035 2423f660 ths
            rn = "TCRestart";
3036 2423f660 ths
//            break;
3037 9c2149c8 ths
        case 4:
3038 2423f660 ths
//            gen_op_dmfc0_tchalt(); /* MT ASE */
3039 2423f660 ths
            rn = "TCHalt";
3040 2423f660 ths
//            break;
3041 9c2149c8 ths
        case 5:
3042 2423f660 ths
//            gen_op_dmfc0_tccontext(); /* MT ASE */
3043 2423f660 ths
            rn = "TCContext";
3044 2423f660 ths
//            break;
3045 9c2149c8 ths
        case 6:
3046 2423f660 ths
//            gen_op_dmfc0_tcschedule(); /* MT ASE */
3047 2423f660 ths
            rn = "TCSchedule";
3048 2423f660 ths
//            break;
3049 9c2149c8 ths
        case 7:
3050 2423f660 ths
//            gen_op_dmfc0_tcschefback(); /* MT ASE */
3051 2423f660 ths
            rn = "TCScheFBack";
3052 2423f660 ths
//            break;
3053 9c2149c8 ths
        default:
3054 9c2149c8 ths
            goto die;
3055 9c2149c8 ths
        }
3056 9c2149c8 ths
        break;
3057 9c2149c8 ths
    case 3:
3058 9c2149c8 ths
        switch (sel) {
3059 9c2149c8 ths
        case 0:
3060 2423f660 ths
            gen_op_dmfc0_entrylo1();
3061 2423f660 ths
            rn = "EntryLo1";
3062 2423f660 ths
            break;
3063 9c2149c8 ths
        default:
3064 9c2149c8 ths
            goto die;
3065 1579a72e ths
        }
3066 9c2149c8 ths
        break;
3067 9c2149c8 ths
    case 4:
3068 9c2149c8 ths
        switch (sel) {
3069 9c2149c8 ths
        case 0:
3070 2423f660 ths
            gen_op_dmfc0_context();
3071 2423f660 ths
            rn = "Context";
3072 2423f660 ths
            break;
3073 9c2149c8 ths
        case 1:
3074 2423f660 ths
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3075 2423f660 ths
            rn = "ContextConfig";
3076 2423f660 ths
//            break;
3077 9c2149c8 ths
        default:
3078 9c2149c8 ths
            goto die;
3079 876d4b07 ths
        }
3080 9c2149c8 ths
        break;
3081 9c2149c8 ths
    case 5:
3082 9c2149c8 ths
        switch (sel) {
3083 9c2149c8 ths
        case 0:
3084 2423f660 ths
            gen_op_mfc0_pagemask();
3085 2423f660 ths
            rn = "PageMask";
3086 2423f660 ths
            break;
3087 9c2149c8 ths
        case 1:
3088 2423f660 ths
            gen_op_mfc0_pagegrain();
3089 2423f660 ths
            rn = "PageGrain";
3090 2423f660 ths
            break;
3091 9c2149c8 ths
        default:
3092 9c2149c8 ths
            goto die;
3093 876d4b07 ths
        }
3094 9c2149c8 ths
        break;
3095 9c2149c8 ths
    case 6:
3096 9c2149c8 ths
        switch (sel) {
3097 9c2149c8 ths
        case 0:
3098 2423f660 ths
            gen_op_mfc0_wired();
3099 2423f660 ths
            rn = "Wired";
3100 2423f660 ths
            break;
3101 9c2149c8 ths
        case 1:
3102 2423f660 ths
//            gen_op_dmfc0_srsconf0(); /* shadow registers */
3103 2423f660 ths
            rn = "SRSConf0";
3104 2423f660 ths
//            break;
3105 9c2149c8 ths
        case 2:
3106 2423f660 ths
//            gen_op_dmfc0_srsconf1(); /* shadow registers */
3107 2423f660 ths
            rn = "SRSConf1";
3108 2423f660 ths
//            break;
3109 9c2149c8 ths
        case 3:
3110 2423f660 ths
//            gen_op_dmfc0_srsconf2(); /* shadow registers */
3111 2423f660 ths
            rn = "SRSConf2";
3112 2423f660 ths
//            break;
3113 9c2149c8 ths
        case 4:
3114 2423f660 ths
//            gen_op_dmfc0_srsconf3(); /* shadow registers */
3115 2423f660 ths
            rn = "SRSConf3";
3116 2423f660 ths
//            break;
3117 9c2149c8 ths
        case 5:
3118 2423f660 ths
//            gen_op_dmfc0_srsconf4(); /* shadow registers */
3119 2423f660 ths
            rn = "SRSConf4";
3120 2423f660 ths
//            break;
3121 9c2149c8 ths
        default:
3122 9c2149c8 ths
            goto die;
3123 876d4b07 ths
        }
3124 9c2149c8 ths
        break;
3125 9c2149c8 ths
    case 7:
3126 9c2149c8 ths
        switch (sel) {
3127 9c2149c8 ths
        case 0:
3128 2423f660 ths
            gen_op_mfc0_hwrena();
3129 2423f660 ths
            rn = "HWREna";
3130 2423f660 ths
            break;
3131 9c2149c8 ths
        default:
3132 9c2149c8 ths
            goto die;
3133 876d4b07 ths
        }
3134 9c2149c8 ths
        break;
3135 9c2149c8 ths
    case 8:
3136 9c2149c8 ths
        switch (sel) {
3137 9c2149c8 ths
        case 0:
3138 2423f660 ths
            gen_op_dmfc0_badvaddr();
3139 2423f660 ths
            rn = "BadVaddr";
3140 2423f660 ths
            break;
3141 9c2149c8 ths
        default:
3142 9c2149c8 ths
            goto die;
3143 876d4b07 ths
        }
3144 9c2149c8 ths
        break;
3145 9c2149c8 ths
    case 9:
3146 9c2149c8 ths
        switch (sel) {
3147 9c2149c8 ths
        case 0:
3148 2423f660 ths
            gen_op_mfc0_count();
3149 2423f660 ths
            rn = "Count";
3150 2423f660 ths
            break;
3151 2423f660 ths
        /* 6,7 are implementation dependent */
3152 9c2149c8 ths
        default:
3153 9c2149c8 ths
            goto die;
3154 876d4b07 ths
        }
3155 9c2149c8 ths
        break;
3156 9c2149c8 ths
    case 10:
3157 9c2149c8 ths
        switch (sel) {
3158 9c2149c8 ths
        case 0:
3159 2423f660 ths
            gen_op_dmfc0_entryhi();
3160 2423f660 ths
            rn = "EntryHi";
3161 2423f660 ths
            break;
3162 9c2149c8 ths
        default:
3163 9c2149c8 ths
            goto die;
3164 876d4b07 ths
        }
3165 9c2149c8 ths
        break;
3166 9c2149c8 ths
    case 11:
3167 9c2149c8 ths
        switch (sel) {
3168 9c2149c8 ths
        case 0:
3169 2423f660 ths
            gen_op_mfc0_compare();
3170 2423f660 ths
            rn = "Compare";
3171 2423f660 ths
            break;
3172 876d4b07 ths
        /* 6,7 are implementation dependent */
3173 9c2149c8 ths
        default:
3174 9c2149c8 ths
            goto die;
3175 876d4b07 ths
        }
3176 9c2149c8 ths
        break;
3177 9c2149c8 ths
    case 12:
3178 9c2149c8 ths
        switch (sel) {
3179 9c2149c8 ths
        case 0:
3180 2423f660 ths
            gen_op_mfc0_status();
3181 2423f660 ths
            rn = "Status";
3182 2423f660 ths
            break;
3183 9c2149c8 ths
        case 1:
3184 2423f660 ths
            gen_op_mfc0_intctl();
3185 2423f660 ths
            rn = "IntCtl";
3186 2423f660 ths
            break;
3187 9c2149c8 ths
        case 2:
3188 2423f660 ths
            gen_op_mfc0_srsctl();
3189 2423f660 ths
            rn = "SRSCtl";
3190 2423f660 ths
            break;
3191 9c2149c8 ths
        case 3:
3192 2423f660 ths
            gen_op_mfc0_srsmap(); /* shadow registers */
3193 2423f660 ths
            rn = "SRSMap";
3194 2423f660 ths
            break;
3195 9c2149c8 ths
        default:
3196 9c2149c8 ths
            goto die;
3197 876d4b07 ths
        }
3198 9c2149c8 ths
        break;
3199 9c2149c8 ths
    case 13:
3200 9c2149c8 ths
        switch (sel) {
3201 9c2149c8 ths
        case 0:
3202 2423f660 ths
            gen_op_mfc0_cause();
3203 2423f660 ths
            rn = "Cause";
3204 2423f660 ths
            break;
3205 9c2149c8 ths
        default:
3206 9c2149c8 ths
            goto die;
3207 876d4b07 ths
        }
3208 9c2149c8 ths
        break;
3209 9c2149c8 ths
    case 14:
3210 9c2149c8 ths
        switch (sel) {
3211 9c2149c8 ths
        case 0:
3212 2423f660 ths
            gen_op_dmfc0_epc();
3213 2423f660 ths
            rn = "EPC";
3214 2423f660 ths
            break;
3215 9c2149c8 ths
        default:
3216 9c2149c8 ths
            goto die;
3217 876d4b07 ths
        }
3218 9c2149c8 ths
        break;
3219 9c2149c8 ths
    case 15:
3220 9c2149c8 ths
        switch (sel) {
3221 9c2149c8 ths
        case 0:
3222 2423f660 ths
            gen_op_mfc0_prid();
3223 2423f660 ths
            rn = "PRid";
3224 2423f660 ths
            break;
3225 9c2149c8 ths
        case 1:
3226 2423f660 ths
            gen_op_mfc0_ebase();
3227 2423f660 ths
            rn = "EBase";
3228 2423f660 ths
            break;
3229 9c2149c8 ths
        default:
3230 9c2149c8 ths
            goto die;
3231 876d4b07 ths
        }
3232 9c2149c8 ths
        break;
3233 9c2149c8 ths
    case 16:
3234 9c2149c8 ths
        switch (sel) {
3235 9c2149c8 ths
        case 0:
3236 2423f660 ths
            gen_op_mfc0_config0();
3237 9c2149c8 ths
            rn = "Config";
3238 9c2149c8 ths
            break;
3239 9c2149c8 ths
        case 1:
3240 2423f660 ths
            gen_op_mfc0_config1();
3241 9c2149c8 ths
            rn = "Config1";
3242 9c2149c8 ths
            break;
3243 9c2149c8 ths
        case 2:
3244 2423f660 ths
            gen_op_mfc0_config2();
3245 9c2149c8 ths
            rn = "Config2";
3246 9c2149c8 ths
            break;
3247 9c2149c8 ths
        case 3:
3248 2423f660 ths
            gen_op_mfc0_config3();
3249 9c2149c8 ths
            rn = "Config3";
3250 9c2149c8 ths
            break;
3251 9c2149c8 ths
       /* 6,7 are implementation dependent */
3252 9c2149c8 ths
        default:
3253 9c2149c8 ths
            goto die;
3254 9c2149c8 ths
        }
3255 9c2149c8 ths
        break;
3256 9c2149c8 ths
    case 17:
3257 9c2149c8 ths
        switch (sel) {
3258 9c2149c8 ths
        case 0:
3259 2423f660 ths
            gen_op_dmfc0_lladdr();
3260 2423f660 ths
            rn = "LLAddr";
3261 2423f660 ths
            break;
3262 9c2149c8 ths
        default:
3263 9c2149c8 ths
            goto die;
3264 9c2149c8 ths
        }
3265 9c2149c8 ths
        break;
3266 9c2149c8 ths
    case 18:
3267 9c2149c8 ths
        switch (sel) {
3268 9c2149c8 ths
        case 0:
3269 2423f660 ths
            gen_op_dmfc0_watchlo0();
3270 2423f660 ths
            rn = "WatchLo";
3271 2423f660 ths
            break;
3272 9c2149c8 ths
        case 1:
3273 2423f660 ths
//            gen_op_dmfc0_watchlo1();
3274 2423f660 ths
            rn = "WatchLo1";
3275 2423f660 ths
//            break;
3276 9c2149c8 ths
        case 2:
3277 2423f660 ths
//            gen_op_dmfc0_watchlo2();
3278 2423f660 ths
            rn = "WatchLo2";
3279 2423f660 ths
//            break;
3280 9c2149c8 ths
        case 3:
3281 2423f660 ths
//            gen_op_dmfc0_watchlo3();
3282 2423f660 ths
            rn = "WatchLo3";
3283 2423f660 ths
//            break;
3284 9c2149c8 ths
        case 4:
3285 2423f660 ths
//            gen_op_dmfc0_watchlo4();
3286 2423f660 ths
            rn = "WatchLo4";
3287 2423f660 ths
//            break;
3288 9c2149c8 ths
        case 5:
3289 2423f660 ths
//            gen_op_dmfc0_watchlo5();
3290 2423f660 ths
            rn = "WatchLo5";
3291 2423f660 ths
//            break;
3292 9c2149c8 ths
        case 6:
3293 2423f660 ths
//            gen_op_dmfc0_watchlo6();
3294 2423f660 ths
            rn = "WatchLo6";
3295 2423f660 ths
//            break;
3296 9c2149c8 ths
        case 7:
3297 2423f660 ths
//            gen_op_dmfc0_watchlo7();
3298 2423f660 ths
            rn = "WatchLo7";
3299 2423f660 ths
//            break;
3300 9c2149c8 ths
        default:
3301 9c2149c8 ths
            goto die;
3302 9c2149c8 ths
        }
3303 9c2149c8 ths
        break;
3304 9c2149c8 ths
    case 19:
3305 9c2149c8 ths
        switch (sel) {
3306 9c2149c8 ths
        case 0:
3307 2423f660 ths
            gen_op_mfc0_watchhi0();
3308 2423f660 ths
            rn = "WatchHi";
3309 2423f660 ths
            break;
3310 9c2149c8 ths
        case 1:
3311 2423f660 ths
//            gen_op_mfc0_watchhi1();
3312 2423f660 ths
            rn = "WatchHi1";
3313 2423f660 ths
//            break;
3314 9c2149c8 ths
        case 2:
3315 2423f660 ths
//            gen_op_mfc0_watchhi2();
3316 2423f660 ths
            rn = "WatchHi2";
3317 2423f660 ths
//            break;
3318 9c2149c8 ths
        case 3:
3319 2423f660 ths
//            gen_op_mfc0_watchhi3();
3320 2423f660 ths
            rn = "WatchHi3";
3321 2423f660 ths
//            break;
3322 9c2149c8 ths
        case 4:
3323 2423f660 ths
//            gen_op_mfc0_watchhi4();
3324 2423f660 ths
            rn = "WatchHi4";
3325 2423f660 ths
//            break;
3326 9c2149c8 ths
        case 5:
3327 2423f660 ths
//            gen_op_mfc0_watchhi5();
3328 2423f660 ths
            rn = "WatchHi5";
3329 2423f660 ths
//            break;
3330 9c2149c8 ths
        case 6:
3331 2423f660 ths
//            gen_op_mfc0_watchhi6();
3332 2423f660 ths
            rn = "WatchHi6";
3333 2423f660 ths
//            break;
3334 9c2149c8 ths
        case 7:
3335 2423f660 ths
//            gen_op_mfc0_watchhi7();
3336 2423f660 ths
            rn = "WatchHi7";
3337 2423f660 ths
//            break;
3338 9c2149c8 ths
        default:
3339 9c2149c8 ths
            goto die;
3340 9c2149c8 ths
        }
3341 9c2149c8 ths
        break;
3342 9c2149c8 ths
    case 20:
3343 9c2149c8 ths
        switch (sel) {
3344 9c2149c8 ths
        case 0:
3345 2423f660 ths
            /* 64 bit MMU only */
3346 2423f660 ths
            gen_op_dmfc0_xcontext();
3347 2423f660 ths
            rn = "XContext";
3348 2423f660 ths
            break;
3349 9c2149c8 ths
        default:
3350 9c2149c8 ths
            goto die;
3351 9c2149c8 ths
        }
3352 9c2149c8 ths
        break;
3353 9c2149c8 ths
    case 21:
3354 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3355 9c2149c8 ths
        switch (sel) {
3356 9c2149c8 ths
        case 0:
3357 2423f660 ths
            gen_op_mfc0_framemask();
3358 2423f660 ths
            rn = "Framemask";
3359 2423f660 ths
            break;
3360 9c2149c8 ths
        default:
3361 9c2149c8 ths
            goto die;
3362 9c2149c8 ths
        }
3363 9c2149c8 ths
        break;
3364 9c2149c8 ths
    case 22:
3365 2423f660 ths
        /* ignored */
3366 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
3367 2423f660 ths
        break;
3368 9c2149c8 ths
    case 23:
3369 9c2149c8 ths
        switch (sel) {
3370 9c2149c8 ths
        case 0:
3371 2423f660 ths
            gen_op_mfc0_debug(); /* EJTAG support */
3372 2423f660 ths
            rn = "Debug";
3373 2423f660 ths
            break;
3374 9c2149c8 ths
        case 1:
3375 2423f660 ths
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3376 2423f660 ths
            rn = "TraceControl";
3377 2423f660 ths
//            break;
3378 9c2149c8 ths
        case 2:
3379 2423f660 ths
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3380 2423f660 ths
            rn = "TraceControl2";
3381 2423f660 ths
//            break;
3382 9c2149c8 ths
        case 3:
3383 2423f660 ths
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3384 2423f660 ths
            rn = "UserTraceData";
3385 2423f660 ths
//            break;
3386 9c2149c8 ths
        case 4:
3387 2423f660 ths
//            gen_op_dmfc0_debug(); /* PDtrace support */
3388 2423f660 ths
            rn = "TraceBPC";
3389 2423f660 ths
//            break;
3390 9c2149c8 ths
        default:
3391 9c2149c8 ths
            goto die;
3392 9c2149c8 ths
        }
3393 9c2149c8 ths
        break;
3394 9c2149c8 ths
    case 24:
3395 9c2149c8 ths
        switch (sel) {
3396 9c2149c8 ths
        case 0:
3397 2423f660 ths
            gen_op_dmfc0_depc(); /* EJTAG support */
3398 2423f660 ths
            rn = "DEPC";
3399 2423f660 ths
            break;
3400 9c2149c8 ths
        default:
3401 9c2149c8 ths
            goto die;
3402 9c2149c8 ths
        }
3403 9c2149c8 ths
        break;
3404 9c2149c8 ths
    case 25:
3405 9c2149c8 ths
        switch (sel) {
3406 9c2149c8 ths
        case 0:
3407 2423f660 ths
            gen_op_mfc0_performance0();
3408 2423f660 ths
            rn = "Performance0";
3409 9c2149c8 ths
            break;
3410 9c2149c8 ths
        case 1:
3411 2423f660 ths
//            gen_op_dmfc0_performance1();
3412 2423f660 ths
            rn = "Performance1";
3413 2423f660 ths
//            break;
3414 9c2149c8 ths
        case 2:
3415 2423f660 ths
//            gen_op_dmfc0_performance2();
3416 2423f660 ths
            rn = "Performance2";
3417 2423f660 ths
//            break;
3418 9c2149c8 ths
        case 3:
3419 2423f660 ths
//            gen_op_dmfc0_performance3();
3420 2423f660 ths
            rn = "Performance3";
3421 2423f660 ths
//            break;
3422 9c2149c8 ths
        case 4:
3423 2423f660 ths
//            gen_op_dmfc0_performance4();
3424 2423f660 ths
            rn = "Performance4";
3425 2423f660 ths
//            break;
3426 9c2149c8 ths
        case 5:
3427 2423f660 ths
//            gen_op_dmfc0_performance5();
3428 2423f660 ths
            rn = "Performance5";
3429 2423f660 ths
//            break;
3430 9c2149c8 ths
        case 6:
3431 2423f660 ths
//            gen_op_dmfc0_performance6();
3432 2423f660 ths
            rn = "Performance6";
3433 2423f660 ths
//            break;
3434 9c2149c8 ths
        case 7:
3435 2423f660 ths
//            gen_op_dmfc0_performance7();
3436 2423f660 ths
            rn = "Performance7";
3437 2423f660 ths
//            break;
3438 9c2149c8 ths
        default:
3439 9c2149c8 ths
            goto die;
3440 9c2149c8 ths
        }
3441 9c2149c8 ths
        break;
3442 9c2149c8 ths
    case 26:
3443 9c2149c8 ths
       rn = "ECC";
3444 9c2149c8 ths
       break;
3445 9c2149c8 ths
    case 27:
3446 9c2149c8 ths
        switch (sel) {
3447 9c2149c8 ths
        /* ignored */
3448 9c2149c8 ths
        case 0 ... 3:
3449 2423f660 ths
            rn = "CacheErr";
3450 2423f660 ths
            break;
3451 9c2149c8 ths
        default:
3452 9c2149c8 ths
            goto die;
3453 9c2149c8 ths
        }
3454 9c2149c8 ths
        break;
3455 9c2149c8 ths
    case 28:
3456 9c2149c8 ths
        switch (sel) {
3457 9c2149c8 ths
        case 0:
3458 9c2149c8 ths
        case 2:
3459 9c2149c8 ths
        case 4:
3460 9c2149c8 ths
        case 6:
3461 9c2149c8 ths
            gen_op_mfc0_taglo();
3462 9c2149c8 ths
            rn = "TagLo";
3463 9c2149c8 ths
            break;
3464 9c2149c8 ths
        case 1:
3465 9c2149c8 ths
        case 3:
3466 9c2149c8 ths
        case 5:
3467 9c2149c8 ths
        case 7:
3468 9c2149c8 ths
            gen_op_mfc0_datalo();
3469 9c2149c8 ths
            rn = "DataLo";
3470 9c2149c8 ths
            break;
3471 9c2149c8 ths
        default:
3472 9c2149c8 ths
            goto die;
3473 9c2149c8 ths
        }
3474 9c2149c8 ths
        break;
3475 9c2149c8 ths
    case 29:
3476 9c2149c8 ths
        switch (sel) {
3477 9c2149c8 ths
        case 0:
3478 9c2149c8 ths
        case 2:
3479 9c2149c8 ths
        case 4:
3480 9c2149c8 ths
        case 6:
3481 9c2149c8 ths
            gen_op_mfc0_taghi();
3482 9c2149c8 ths
            rn = "TagHi";
3483 9c2149c8 ths
            break;
3484 9c2149c8 ths
        case 1:
3485 9c2149c8 ths
        case 3:
3486 9c2149c8 ths
        case 5:
3487 9c2149c8 ths
        case 7:
3488 9c2149c8 ths
            gen_op_mfc0_datahi();
3489 9c2149c8 ths
            rn = "DataHi";
3490 9c2149c8 ths
            break;
3491 9c2149c8 ths
        default:
3492 9c2149c8 ths
            goto die;
3493 9c2149c8 ths
        }
3494 9c2149c8 ths
        break;
3495 9c2149c8 ths
    case 30:
3496 9c2149c8 ths
        switch (sel) {
3497 9c2149c8 ths
        case 0:
3498 2423f660 ths
            gen_op_dmfc0_errorepc();
3499 2423f660 ths
            rn = "ErrorEPC";
3500 2423f660 ths
            break;
3501 9c2149c8 ths
        default:
3502 9c2149c8 ths
            goto die;
3503 9c2149c8 ths
        }
3504 9c2149c8 ths
        break;
3505 9c2149c8 ths
    case 31:
3506 9c2149c8 ths
        switch (sel) {
3507 9c2149c8 ths
        case 0:
3508 2423f660 ths
            gen_op_mfc0_desave(); /* EJTAG support */
3509 2423f660 ths
            rn = "DESAVE";
3510 2423f660 ths
            break;
3511 9c2149c8 ths
        default:
3512 9c2149c8 ths
            goto die;
3513 9c2149c8 ths
        }
3514 9c2149c8 ths
        break;
3515 9c2149c8 ths
    default:
3516 876d4b07 ths
        goto die;
3517 9c2149c8 ths
    }
3518 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
3519 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3520 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3521 9c2149c8 ths
                rn, reg, sel);
3522 9c2149c8 ths
    }
3523 9c2149c8 ths
#endif
3524 9c2149c8 ths
    return;
3525 9c2149c8 ths
3526 9c2149c8 ths
die:
3527 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
3528 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3529 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3530 9c2149c8 ths
                rn, reg, sel);
3531 9c2149c8 ths
    }
3532 9c2149c8 ths
#endif
3533 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
3534 9c2149c8 ths
}
3535 9c2149c8 ths
3536 9c2149c8 ths
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3537 9c2149c8 ths
{
3538 9c2149c8 ths
    const char *rn = "invalid";
3539 9c2149c8 ths
3540 9c2149c8 ths
    switch (reg) {
3541 9c2149c8 ths
    case 0:
3542 9c2149c8 ths
        switch (sel) {
3543 9c2149c8 ths
        case 0:
3544 9c2149c8 ths
            gen_op_mtc0_index();
3545 9c2149c8 ths
            rn = "Index";
3546 9c2149c8 ths
            break;
3547 9c2149c8 ths
        case 1:
3548 2423f660 ths
//            gen_op_dmtc0_mvpcontrol(); /* MT ASE */
3549 9c2149c8 ths
            rn = "MVPControl";
3550 2423f660 ths
//            break;
3551 9c2149c8 ths
        case 2:
3552 2423f660 ths
//            gen_op_dmtc0_mvpconf0(); /* MT ASE */
3553 9c2149c8 ths
            rn = "MVPConf0";
3554 2423f660 ths
//            break;
3555 9c2149c8 ths
        case 3:
3556 2423f660 ths
//            gen_op_dmtc0_mvpconf1(); /* MT ASE */
3557 9c2149c8 ths
            rn = "MVPConf1";
3558 2423f660 ths
//            break;
3559 9c2149c8 ths
        default:
3560 9c2149c8 ths
            goto die;
3561 9c2149c8 ths
        }
3562 9c2149c8 ths
        break;
3563 9c2149c8 ths
    case 1:
3564 9c2149c8 ths
        switch (sel) {
3565 9c2149c8 ths
        case 0:
3566 2423f660 ths
            /* ignored */
3567 9c2149c8 ths
            rn = "Random";
3568 2423f660 ths
            break;
3569 9c2149c8 ths
        case 1:
3570 2423f660 ths
//            gen_op_dmtc0_vpecontrol(); /* MT ASE */
3571 9c2149c8 ths
            rn = "VPEControl";
3572 2423f660 ths
//            break;
3573 9c2149c8 ths
        case 2:
3574 2423f660 ths
//            gen_op_dmtc0_vpeconf0(); /* MT ASE */
3575 9c2149c8 ths
            rn = "VPEConf0";
3576 2423f660 ths
//            break;
3577 9c2149c8 ths
        case 3:
3578 2423f660 ths
//            gen_op_dmtc0_vpeconf1(); /* MT ASE */
3579 9c2149c8 ths
            rn = "VPEConf1";
3580 2423f660 ths
//            break;
3581 9c2149c8 ths
        case 4:
3582 2423f660 ths
//            gen_op_dmtc0_YQMask(); /* MT ASE */
3583 9c2149c8 ths
            rn = "YQMask";
3584 2423f660 ths
//            break;
3585 9c2149c8 ths
        case 5:
3586 2423f660 ths
//            gen_op_dmtc0_vpeschedule(); /* MT ASE */
3587 9c2149c8 ths
            rn = "VPESchedule";
3588 2423f660 ths
//            break;
3589 9c2149c8 ths
        case 6:
3590 2423f660 ths
//            gen_op_dmtc0_vpeschefback(); /* MT ASE */
3591 9c2149c8 ths
            rn = "VPEScheFBack";
3592 2423f660 ths
//            break;
3593 9c2149c8 ths
        case 7:
3594 2423f660 ths
//            gen_op_dmtc0_vpeopt(); /* MT ASE */
3595 9c2149c8 ths
            rn = "VPEOpt";
3596 2423f660 ths
//            break;
3597 9c2149c8 ths
        default:
3598 9c2149c8 ths
            goto die;
3599 9c2149c8 ths
        }
3600 9c2149c8 ths
        break;
3601 9c2149c8 ths
    case 2:
3602 9c2149c8 ths
        switch (sel) {
3603 9c2149c8 ths
        case 0:
3604 2423f660 ths
            gen_op_dmtc0_entrylo0();
3605 2423f660 ths
            rn = "EntryLo0";
3606 2423f660 ths
            break;
3607 9c2149c8 ths
        case 1:
3608 2423f660 ths
//            gen_op_dmtc0_tcstatus(); /* MT ASE */
3609 2423f660 ths
            rn = "TCStatus";
3610 2423f660 ths
//            break;
3611 9c2149c8 ths
        case 2:
3612 2423f660 ths
//            gen_op_dmtc0_tcbind(); /* MT ASE */
3613 2423f660 ths
            rn = "TCBind";
3614 2423f660 ths
//            break;
3615 9c2149c8 ths
        case 3:
3616 2423f660 ths
//            gen_op_dmtc0_tcrestart(); /* MT ASE */
3617 2423f660 ths
            rn = "TCRestart";
3618 2423f660 ths
//            break;
3619 9c2149c8 ths
        case 4:
3620 2423f660 ths
//            gen_op_dmtc0_tchalt(); /* MT ASE */
3621 2423f660 ths
            rn = "TCHalt";
3622 2423f660 ths
//            break;
3623 9c2149c8 ths
        case 5:
3624 2423f660 ths
//            gen_op_dmtc0_tccontext(); /* MT ASE */
3625 2423f660 ths
            rn = "TCContext";
3626 2423f660 ths
//            break;
3627 9c2149c8 ths
        case 6:
3628 2423f660 ths
//            gen_op_dmtc0_tcschedule(); /* MT ASE */
3629 2423f660 ths
            rn = "TCSchedule";
3630 2423f660 ths
//            break;
3631 9c2149c8 ths
        case 7:
3632 2423f660 ths
//            gen_op_dmtc0_tcschefback(); /* MT ASE */
3633 2423f660 ths
            rn = "TCScheFBack";
3634 2423f660 ths
//            break;
3635 9c2149c8 ths
        default:
3636 9c2149c8 ths
            goto die;
3637 9c2149c8 ths
        }
3638 9c2149c8 ths
        break;
3639 9c2149c8 ths
    case 3:
3640 9c2149c8 ths
        switch (sel) {
3641 9c2149c8 ths
        case 0:
3642 2423f660 ths
            gen_op_dmtc0_entrylo1();
3643 2423f660 ths
            rn = "EntryLo1";
3644 2423f660 ths
            break;
3645 9c2149c8 ths
        default:
3646 9c2149c8 ths
            goto die;
3647 876d4b07 ths
        }
3648 9c2149c8 ths
        break;
3649 9c2149c8 ths
    case 4:
3650 9c2149c8 ths
        switch (sel) {
3651 9c2149c8 ths
        case 0:
3652 2423f660 ths
            gen_op_dmtc0_context();
3653 2423f660 ths
            rn = "Context";
3654 2423f660 ths
            break;
3655 9c2149c8 ths
        case 1:
3656 2423f660 ths
//           gen_op_dmtc0_contextconfig(); /* SmartMIPS ASE */
3657 2423f660 ths
            rn = "ContextConfig";
3658 2423f660 ths
//           break;
3659 9c2149c8 ths
        default:
3660 9c2149c8 ths
            goto die;
3661 876d4b07 ths
        }
3662 9c2149c8 ths
        break;
3663 9c2149c8 ths
    case 5:
3664 9c2149c8 ths
        switch (sel) {
3665 9c2149c8 ths
        case 0:
3666 2423f660 ths
            gen_op_mtc0_pagemask();
3667 2423f660 ths
            rn = "PageMask";
3668 2423f660 ths
            break;
3669 9c2149c8 ths
        case 1:
3670 2423f660 ths
            gen_op_mtc0_pagegrain();
3671 2423f660 ths
            rn = "PageGrain";
3672 2423f660 ths
            break;
3673 9c2149c8 ths
        default:
3674 9c2149c8 ths
            goto die;
3675 876d4b07 ths
        }
3676 9c2149c8 ths
        break;
3677 9c2149c8 ths
    case 6:
3678 9c2149c8 ths
        switch (sel) {
3679 9c2149c8 ths
        case 0:
3680 2423f660 ths
            gen_op_mtc0_wired();
3681 2423f660 ths
            rn = "Wired";
3682 2423f660 ths
            break;
3683 9c2149c8 ths
        case 1:
3684 2423f660 ths
//            gen_op_dmtc0_srsconf0(); /* shadow registers */
3685 2423f660 ths
            rn = "SRSConf0";
3686 2423f660 ths
//            break;
3687 9c2149c8 ths
        case 2:
3688 2423f660 ths
//            gen_op_dmtc0_srsconf1(); /* shadow registers */
3689 2423f660 ths
            rn = "SRSConf1";
3690 2423f660 ths
//            break;
3691 9c2149c8 ths
        case 3:
3692 2423f660 ths
//            gen_op_dmtc0_srsconf2(); /* shadow registers */
3693 2423f660 ths
            rn = "SRSConf2";
3694 2423f660 ths
//            break;
3695 9c2149c8 ths
        case 4:
3696 2423f660 ths
//            gen_op_dmtc0_srsconf3(); /* shadow registers */
3697 2423f660 ths
            rn = "SRSConf3";
3698 2423f660 ths
//            break;
3699 9c2149c8 ths
        case 5:
3700 2423f660 ths
//            gen_op_dmtc0_srsconf4(); /* shadow registers */
3701 2423f660 ths
            rn = "SRSConf4";
3702 2423f660 ths
//            break;
3703 9c2149c8 ths
        default:
3704 9c2149c8 ths
            goto die;
3705 876d4b07 ths
        }
3706 9c2149c8 ths
        break;
3707 9c2149c8 ths
    case 7:
3708 9c2149c8 ths
        switch (sel) {
3709 9c2149c8 ths
        case 0:
3710 2423f660 ths
            gen_op_mtc0_hwrena();
3711 2423f660 ths
            rn = "HWREna";
3712 2423f660 ths
            break;
3713 9c2149c8 ths
        default:
3714 9c2149c8 ths
            goto die;
3715 876d4b07 ths
        }
3716 9c2149c8 ths
        break;
3717 9c2149c8 ths
    case 8:
3718 9c2149c8 ths
        /* ignored */
3719 9c2149c8 ths
        rn = "BadVaddr";
3720 9c2149c8 ths
        break;
3721 9c2149c8 ths
    case 9:
3722 9c2149c8 ths
        switch (sel) {
3723 9c2149c8 ths
        case 0:
3724 2423f660 ths
            gen_op_mtc0_count();
3725 2423f660 ths
            rn = "Count";
3726 2423f660 ths
            break;
3727 876d4b07 ths
        /* 6,7 are implementation dependent */
3728 9c2149c8 ths
        default:
3729 9c2149c8 ths
            goto die;
3730 876d4b07 ths
        }
3731 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3732 876d4b07 ths
        ctx->bstate = BS_STOP;
3733 9c2149c8 ths
        break;
3734 9c2149c8 ths
    case 10:
3735 9c2149c8 ths
        switch (sel) {
3736 9c2149c8 ths
        case 0:
3737 2423f660 ths
            gen_op_mtc0_entryhi();
3738 2423f660 ths
            rn = "EntryHi";
3739 2423f660 ths
            break;
3740 9c2149c8 ths
        default:
3741 9c2149c8 ths
            goto die;
3742 876d4b07 ths
        }
3743 9c2149c8 ths
        break;
3744 9c2149c8 ths
    case 11:
3745 9c2149c8 ths
        switch (sel) {
3746 9c2149c8 ths
        case 0:
3747 2423f660 ths
            gen_op_mtc0_compare();
3748 2423f660 ths
            rn = "Compare";
3749 2423f660 ths
            break;
3750 876d4b07 ths
        /* 6,7 are implementation dependent */
3751 9c2149c8 ths
        default:
3752 9c2149c8 ths
            goto die;
3753 876d4b07 ths
        }
3754 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3755 876d4b07 ths
        ctx->bstate = BS_STOP;
3756 9c2149c8 ths
        break;
3757 9c2149c8 ths
    case 12:
3758 9c2149c8 ths
        switch (sel) {
3759 9c2149c8 ths
        case 0:
3760 2423f660 ths
            gen_op_mtc0_status();
3761 2423f660 ths
            rn = "Status";
3762 2423f660 ths
            break;
3763 9c2149c8 ths
        case 1:
3764 2423f660 ths
            gen_op_mtc0_intctl();
3765 2423f660 ths
            rn = "IntCtl";
3766 2423f660 ths
            break;
3767 9c2149c8 ths
        case 2:
3768 2423f660 ths
            gen_op_mtc0_srsctl();
3769 2423f660 ths
            rn = "SRSCtl";
3770 2423f660 ths
            break;
3771 9c2149c8 ths
        case 3:
3772 2423f660 ths
            gen_op_mtc0_srsmap(); /* shadow registers */
3773 2423f660 ths
            rn = "SRSMap";
3774 2423f660 ths
            break;
3775 2423f660 ths
        default:
3776 9c2149c8 ths
            goto die;
3777 876d4b07 ths
        }
3778 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3779 876d4b07 ths
        ctx->bstate = BS_STOP;
3780 9c2149c8 ths
        break;
3781 9c2149c8 ths
    case 13:
3782 9c2149c8 ths
        switch (sel) {
3783 9c2149c8 ths
        case 0:
3784 2423f660 ths
            gen_op_mtc0_cause();
3785 2423f660 ths
            rn = "Cause";
3786 2423f660 ths
            break;
3787 9c2149c8 ths
        default:
3788 9c2149c8 ths
            goto die;
3789 876d4b07 ths
        }
3790 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3791 876d4b07 ths
        ctx->bstate = BS_STOP;
3792 9c2149c8 ths
        break;
3793 9c2149c8 ths
    case 14:
3794 9c2149c8 ths
        switch (sel) {
3795 9c2149c8 ths
        case 0:
3796 2423f660 ths
            gen_op_dmtc0_epc();
3797 2423f660 ths
            rn = "EPC";
3798 2423f660 ths
            break;
3799 9c2149c8 ths
        default:
3800 9c2149c8 ths
            goto die;
3801 876d4b07 ths
        }
3802 9c2149c8 ths
        break;
3803 9c2149c8 ths
    case 15:
3804 9c2149c8 ths
        switch (sel) {
3805 9c2149c8 ths
        case 0:
3806 2423f660 ths
            /* ignored */
3807 2423f660 ths
            rn = "PRid";
3808 2423f660 ths
            break;
3809 9c2149c8 ths
        case 1:
3810 2423f660 ths
            gen_op_mtc0_ebase();
3811 2423f660 ths
            rn = "EBase";
3812 2423f660 ths
            break;
3813 9c2149c8 ths
        default:
3814 9c2149c8 ths
            goto die;
3815 876d4b07 ths
        }
3816 9c2149c8 ths
        break;
3817 9c2149c8 ths
    case 16:
3818 9c2149c8 ths
        switch (sel) {
3819 9c2149c8 ths
        case 0:
3820 9c2149c8 ths
            gen_op_mtc0_config0();
3821 9c2149c8 ths
            rn = "Config";
3822 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3823 2423f660 ths
            ctx->bstate = BS_STOP;
3824 9c2149c8 ths
            break;
3825 9c2149c8 ths
        case 1:
3826 2423f660 ths
            /* ignored */
3827 9c2149c8 ths
            rn = "Config1";
3828 9c2149c8 ths
            break;
3829 9c2149c8 ths
        case 2:
3830 9c2149c8 ths
            gen_op_mtc0_config2();
3831 9c2149c8 ths
            rn = "Config2";
3832 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3833 2423f660 ths
            ctx->bstate = BS_STOP;
3834 9c2149c8 ths
            break;
3835 9c2149c8 ths
        case 3:
3836 2423f660 ths
            /* ignored */
3837 9c2149c8 ths
            rn = "Config3";
3838 9c2149c8 ths
            break;
3839 9c2149c8 ths
        /* 6,7 are implementation dependent */
3840 9c2149c8 ths
        default:
3841 9c2149c8 ths
            rn = "Invalid config selector";
3842 9c2149c8 ths
            goto die;
3843 9c2149c8 ths
        }
3844 9c2149c8 ths
        break;
3845 9c2149c8 ths
    case 17:
3846 9c2149c8 ths
        switch (sel) {
3847 9c2149c8 ths
        case 0:
3848 2423f660 ths
            /* ignored */
3849 2423f660 ths
            rn = "LLAddr";
3850 2423f660 ths
            break;
3851 9c2149c8 ths
        default:
3852 9c2149c8 ths
            goto die;
3853 9c2149c8 ths
        }
3854 9c2149c8 ths
        break;
3855 9c2149c8 ths
    case 18:
3856 9c2149c8 ths
        switch (sel) {
3857 9c2149c8 ths
        case 0:
3858 2423f660 ths
            gen_op_dmtc0_watchlo0();
3859 2423f660 ths
            rn = "WatchLo";
3860 2423f660 ths
            break;
3861 9c2149c8 ths
        case 1:
3862 2423f660 ths
//            gen_op_dmtc0_watchlo1();
3863 2423f660 ths
            rn = "WatchLo1";
3864 2423f660 ths
//            break;
3865 9c2149c8 ths
        case 2:
3866 2423f660 ths
//            gen_op_dmtc0_watchlo2();
3867 2423f660 ths
            rn = "WatchLo2";
3868 2423f660 ths
//            break;
3869 9c2149c8 ths
        case 3:
3870 2423f660 ths
//            gen_op_dmtc0_watchlo3();
3871 2423f660 ths
            rn = "WatchLo3";
3872 2423f660 ths
//            break;
3873 9c2149c8 ths
        case 4:
3874 2423f660 ths
//            gen_op_dmtc0_watchlo4();
3875 2423f660 ths
            rn = "WatchLo4";
3876 2423f660 ths
//            break;
3877 9c2149c8 ths
        case 5:
3878 2423f660 ths
//            gen_op_dmtc0_watchlo5();
3879 2423f660 ths
            rn = "WatchLo5";
3880 2423f660 ths
//            break;
3881 9c2149c8 ths
        case 6:
3882 2423f660 ths
//            gen_op_dmtc0_watchlo6();
3883 2423f660 ths
            rn = "WatchLo6";
3884 2423f660 ths
//            break;
3885 9c2149c8 ths
        case 7:
3886 2423f660 ths
//            gen_op_dmtc0_watchlo7();
3887 2423f660 ths
            rn = "WatchLo7";
3888 2423f660 ths
//            break;
3889 9c2149c8 ths
        default:
3890 9c2149c8 ths
            goto die;
3891 9c2149c8 ths
        }
3892 9c2149c8 ths
        break;
3893 9c2149c8 ths
    case 19:
3894 9c2149c8 ths
        switch (sel) {
3895 9c2149c8 ths
        case 0:
3896 2423f660 ths
            gen_op_mtc0_watchhi0();
3897 2423f660 ths
            rn = "WatchHi";
3898 2423f660 ths
            break;
3899 9c2149c8 ths
        case 1:
3900 2423f660 ths
//            gen_op_dmtc0_watchhi1();
3901 2423f660 ths
            rn = "WatchHi1";
3902 2423f660 ths
//            break;
3903 9c2149c8 ths
        case 2:
3904 2423f660 ths
//            gen_op_dmtc0_watchhi2();
3905 2423f660 ths
            rn = "WatchHi2";
3906 2423f660 ths
//            break;
3907 9c2149c8 ths
        case 3:
3908 2423f660 ths
//            gen_op_dmtc0_watchhi3();
3909 2423f660 ths
            rn = "WatchHi3";
3910 2423f660 ths
//            break;
3911 9c2149c8 ths
        case 4:
3912 2423f660 ths
//            gen_op_dmtc0_watchhi4();
3913 2423f660 ths
            rn = "WatchHi4";
3914 2423f660 ths
//            break;
3915 9c2149c8 ths
        case 5:
3916 2423f660 ths
//            gen_op_dmtc0_watchhi5();
3917 2423f660 ths
            rn = "WatchHi5";
3918 2423f660 ths
//            break;
3919 9c2149c8 ths
        case 6:
3920 2423f660 ths
//            gen_op_dmtc0_watchhi6();
3921 2423f660 ths
            rn = "WatchHi6";
3922 2423f660 ths
//            break;
3923 9c2149c8 ths
        case 7:
3924 2423f660 ths
//            gen_op_dmtc0_watchhi7();
3925 2423f660 ths
            rn = "WatchHi7";
3926 2423f660 ths
//            break;
3927 9c2149c8 ths
        default:
3928 9c2149c8 ths
            goto die;
3929 9c2149c8 ths
        }
3930 9c2149c8 ths
        break;
3931 9c2149c8 ths
    case 20:
3932 9c2149c8 ths
        switch (sel) {
3933 9c2149c8 ths
        case 0:
3934 2423f660 ths
            /* 64 bit MMU only */
3935 2423f660 ths
            gen_op_dmtc0_xcontext();
3936 2423f660 ths
            rn = "XContext";
3937 2423f660 ths
            break;
3938 9c2149c8 ths
        default:
3939 9c2149c8 ths
            goto die;
3940 9c2149c8 ths
        }
3941 9c2149c8 ths
        break;
3942 9c2149c8 ths
    case 21:
3943 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3944 9c2149c8 ths
        switch (sel) {
3945 9c2149c8 ths
        case 0:
3946 2423f660 ths
            gen_op_mtc0_framemask();
3947 2423f660 ths
            rn = "Framemask";
3948 2423f660 ths
            break;
3949 9c2149c8 ths
        default:
3950 9c2149c8 ths
            goto die;
3951 9c2149c8 ths
        }
3952 9c2149c8 ths
        break;
3953 9c2149c8 ths
    case 22:
3954 9c2149c8 ths
        /* ignored */
3955 9c2149c8 ths
        rn = "Diagnostic"; /* implementation dependent */
3956 876d4b07 ths
        break;
3957 9c2149c8 ths
    case 23:
3958 9c2149c8 ths
        switch (sel) {
3959 9c2149c8 ths
        case 0:
3960 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
3961 2423f660 ths
            rn = "Debug";
3962 2423f660 ths
            break;
3963 9c2149c8 ths
        case 1:
3964 2423f660 ths
//            gen_op_dmtc0_tracecontrol(); /* PDtrace support */
3965 2423f660 ths
            rn = "TraceControl";
3966 2423f660 ths
//            break;
3967 9c2149c8 ths
        case 2:
3968 2423f660 ths
//            gen_op_dmtc0_tracecontrol2(); /* PDtrace support */
3969 2423f660 ths
            rn = "TraceControl2";
3970 2423f660 ths
//            break;
3971 9c2149c8 ths
        case 3:
3972 2423f660 ths
//            gen_op_dmtc0_usertracedata(); /* PDtrace support */
3973 2423f660 ths
            rn = "UserTraceData";
3974 2423f660 ths
//            break;
3975 9c2149c8 ths
        case 4:
3976 2423f660 ths
//            gen_op_dmtc0_debug(); /* PDtrace support */
3977 2423f660 ths
            rn = "TraceBPC";
3978 2423f660 ths
//            break;
3979 9c2149c8 ths
        default:
3980 9c2149c8 ths
            goto die;
3981 9c2149c8 ths
        }
3982 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
3983 2423f660 ths
        ctx->bstate = BS_STOP;
3984 9c2149c8 ths
        break;
3985 9c2149c8 ths
    case 24:
3986 9c2149c8 ths
        switch (sel) {
3987 9c2149c8 ths
        case 0:
3988 2423f660 ths
            gen_op_dmtc0_depc(); /* EJTAG support */
3989 2423f660 ths
            rn = "DEPC";
3990 2423f660 ths
            break;
3991 9c2149c8 ths
        default:
3992 9c2149c8 ths
            goto die;
3993 9c2149c8 ths
        }
3994 9c2149c8 ths
        break;
3995 9c2149c8 ths
    case 25:
3996 9c2149c8 ths
        switch (sel) {
3997 9c2149c8 ths
        case 0:
3998 2423f660 ths
            gen_op_mtc0_performance0();
3999 2423f660 ths
            rn = "Performance0";
4000 2423f660 ths
            break;
4001 9c2149c8 ths
        case 1:
4002 2423f660 ths
//            gen_op_dmtc0_performance1();
4003 2423f660 ths
            rn = "Performance1";
4004 2423f660 ths
//            break;
4005 9c2149c8 ths
        case 2:
4006 2423f660 ths
//            gen_op_dmtc0_performance2();
4007 2423f660 ths
            rn = "Performance2";
4008 2423f660 ths
//            break;
4009 9c2149c8 ths
        case 3:
4010 2423f660 ths
//            gen_op_dmtc0_performance3();
4011 2423f660 ths
            rn = "Performance3";
4012 2423f660 ths
//            break;
4013 9c2149c8 ths
        case 4:
4014 2423f660 ths
//            gen_op_dmtc0_performance4();
4015 2423f660 ths
            rn = "Performance4";
4016 2423f660 ths
//            break;
4017 9c2149c8 ths
        case 5:
4018 2423f660 ths
//            gen_op_dmtc0_performance5();
4019 2423f660 ths
            rn = "Performance5";
4020 2423f660 ths
//            break;
4021 9c2149c8 ths
        case 6:
4022 2423f660 ths
//            gen_op_dmtc0_performance6();
4023 2423f660 ths
            rn = "Performance6";
4024 2423f660 ths
//            break;
4025 9c2149c8 ths
        case 7:
4026 2423f660 ths
//            gen_op_dmtc0_performance7();
4027 2423f660 ths
            rn = "Performance7";
4028 2423f660 ths
//            break;
4029 9c2149c8 ths
        default:
4030 9c2149c8 ths
            goto die;
4031 9c2149c8 ths
        }
4032 876d4b07 ths
        break;
4033 9c2149c8 ths
    case 26:
4034 876d4b07 ths
        /* ignored */
4035 9c2149c8 ths
        rn = "ECC";
4036 876d4b07 ths
        break;
4037 9c2149c8 ths
    case 27:
4038 9c2149c8 ths
        switch (sel) {
4039 9c2149c8 ths
        case 0 ... 3:
4040 2423f660 ths
            /* ignored */
4041 2423f660 ths
            rn = "CacheErr";
4042 2423f660 ths
            break;
4043 9c2149c8 ths
        default:
4044 9c2149c8 ths
            goto die;
4045 9c2149c8 ths
        }
4046 876d4b07 ths
        break;
4047 9c2149c8 ths
    case 28:
4048 9c2149c8 ths
        switch (sel) {
4049 9c2149c8 ths
        case 0:
4050 9c2149c8 ths
        case 2:
4051 9c2149c8 ths
        case 4:
4052 9c2149c8 ths
        case 6:
4053 9c2149c8 ths
            gen_op_mtc0_taglo();
4054 9c2149c8 ths
            rn = "TagLo";
4055 9c2149c8 ths
            break;
4056 9c2149c8 ths
        case 1:
4057 9c2149c8 ths
        case 3:
4058 9c2149c8 ths
        case 5:
4059 9c2149c8 ths
        case 7:
4060 2423f660 ths
            gen_op_mtc0_datalo();
4061 9c2149c8 ths
            rn = "DataLo";
4062 9c2149c8 ths
            break;
4063 9c2149c8 ths
        default:
4064 9c2149c8 ths
            goto die;
4065 9c2149c8 ths
        }
4066 9c2149c8 ths
        break;
4067 9c2149c8 ths
    case 29:
4068 9c2149c8 ths
        switch (sel) {
4069 9c2149c8 ths
        case 0:
4070 9c2149c8 ths
        case 2:
4071 9c2149c8 ths
        case 4:
4072 9c2149c8 ths
        case 6:
4073 9c2149c8 ths
            gen_op_mtc0_taghi();
4074 9c2149c8 ths
            rn = "TagHi";
4075 9c2149c8 ths
            break;
4076 9c2149c8 ths
        case 1:
4077 9c2149c8 ths
        case 3:
4078 9c2149c8 ths
        case 5:
4079 9c2149c8 ths
        case 7:
4080 2423f660 ths
            gen_op_mtc0_datahi();
4081 9c2149c8 ths
            rn = "DataHi";
4082 9c2149c8 ths
            break;
4083 9c2149c8 ths
        default:
4084 9c2149c8 ths
            rn = "invalid sel";
4085 9c2149c8 ths
            goto die;
4086 9c2149c8 ths
        }
4087 876d4b07 ths
        break;
4088 9c2149c8 ths
    case 30:
4089 9c2149c8 ths
        switch (sel) {
4090 9c2149c8 ths
        case 0:
4091 2423f660 ths
            gen_op_dmtc0_errorepc();
4092 2423f660 ths
            rn = "ErrorEPC";
4093 2423f660 ths
            break;
4094 9c2149c8 ths
        default:
4095 9c2149c8 ths
            goto die;
4096 9c2149c8 ths
        }
4097 9c2149c8 ths
        break;
4098 9c2149c8 ths
    case 31:
4099 9c2149c8 ths
        switch (sel) {
4100 9c2149c8 ths
        case 0:
4101 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
4102 2423f660 ths
            rn = "DESAVE";
4103 2423f660 ths
            break;
4104 9c2149c8 ths
        default:
4105 9c2149c8 ths
            goto die;
4106 9c2149c8 ths
        }
4107 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
4108 876d4b07 ths
        ctx->bstate = BS_STOP;
4109 9c2149c8 ths
        break;
4110 9c2149c8 ths
    default:
4111 876d4b07 ths
        goto die;
4112 9c2149c8 ths
    }
4113 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4114 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4115 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4116 9c2149c8 ths
                rn, reg, sel);
4117 9c2149c8 ths
    }
4118 9c2149c8 ths
#endif
4119 9c2149c8 ths
    return;
4120 9c2149c8 ths
4121 9c2149c8 ths
die:
4122 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4123 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4124 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4125 9c2149c8 ths
                rn, reg, sel);
4126 9c2149c8 ths
    }
4127 9c2149c8 ths
#endif
4128 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
4129 9c2149c8 ths
}
4130 534ce69f ths
#endif /* TARGET_MIPS64 */
4131 9c2149c8 ths
4132 7a387fff ths
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4133 6af0bf9c bellard
{
4134 7a387fff ths
    const char *opn = "unk";
4135 6af0bf9c bellard
4136 6af0bf9c bellard
    switch (opc) {
4137 6af0bf9c bellard
    case OPC_MFC0:
4138 6af0bf9c bellard
        if (rt == 0) {
4139 6af0bf9c bellard
            /* Treat as NOP */
4140 6af0bf9c bellard
            return;
4141 6af0bf9c bellard
        }
4142 873eb012 ths
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4143 6af0bf9c bellard
        gen_op_store_T0_gpr(rt);
4144 6af0bf9c bellard
        opn = "mfc0";
4145 6af0bf9c bellard
        break;
4146 6af0bf9c bellard
    case OPC_MTC0:
4147 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, rt);
4148 8c0fdd85 ths
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4149 6af0bf9c bellard
        opn = "mtc0";
4150 6af0bf9c bellard
        break;
4151 534ce69f ths
#ifdef TARGET_MIPS64
4152 9c2149c8 ths
    case OPC_DMFC0:
4153 9c2149c8 ths
        if (rt == 0) {
4154 9c2149c8 ths
            /* Treat as NOP */
4155 9c2149c8 ths
            return;
4156 9c2149c8 ths
        }
4157 9c2149c8 ths
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4158 9c2149c8 ths
        gen_op_store_T0_gpr(rt);
4159 9c2149c8 ths
        opn = "dmfc0";
4160 9c2149c8 ths
        break;
4161 9c2149c8 ths
    case OPC_DMTC0:
4162 9c2149c8 ths
        GEN_LOAD_REG_TN(T0, rt);
4163 9c2149c8 ths
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4164 9c2149c8 ths
        opn = "dmtc0";
4165 9c2149c8 ths
        break;
4166 534ce69f ths
#endif
4167 6af0bf9c bellard
#if defined(MIPS_USES_R4K_TLB)
4168 6af0bf9c bellard
    case OPC_TLBWI:
4169 6af0bf9c bellard
        gen_op_tlbwi();
4170 6af0bf9c bellard
        opn = "tlbwi";
4171 6af0bf9c bellard
        break;
4172 6af0bf9c bellard
    case OPC_TLBWR:
4173 6af0bf9c bellard
        gen_op_tlbwr();
4174 6af0bf9c bellard
        opn = "tlbwr";
4175 6af0bf9c bellard
        break;
4176 6af0bf9c bellard
    case OPC_TLBP:
4177 6af0bf9c bellard
        gen_op_tlbp();
4178 6af0bf9c bellard
        opn = "tlbp";
4179 6af0bf9c bellard
        break;
4180 6af0bf9c bellard
    case OPC_TLBR:
4181 6af0bf9c bellard
        gen_op_tlbr();
4182 6af0bf9c bellard
        opn = "tlbr";
4183 6af0bf9c bellard
        break;
4184 6af0bf9c bellard
#endif
4185 6af0bf9c bellard
    case OPC_ERET:
4186 6af0bf9c bellard
        opn = "eret";
4187 6af0bf9c bellard
        save_cpu_state(ctx, 0);
4188 6af0bf9c bellard
        gen_op_eret();
4189 6af0bf9c bellard
        ctx->bstate = BS_EXCP;
4190 6af0bf9c bellard
        break;
4191 6af0bf9c bellard
    case OPC_DERET:
4192 6af0bf9c bellard
        opn = "deret";
4193 6af0bf9c bellard
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4194 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
4195 6af0bf9c bellard
        } else {
4196 6af0bf9c bellard
            save_cpu_state(ctx, 0);
4197 6af0bf9c bellard
            gen_op_deret();
4198 6af0bf9c bellard
            ctx->bstate = BS_EXCP;
4199 6af0bf9c bellard
        }
4200 6af0bf9c bellard
        break;
4201 4ad40f36 bellard
    case OPC_WAIT:
4202 4ad40f36 bellard
        opn = "wait";
4203 4ad40f36 bellard
        /* If we get an exception, we want to restart at next instruction */
4204 4ad40f36 bellard
        ctx->pc += 4;
4205 4ad40f36 bellard
        save_cpu_state(ctx, 1);
4206 4ad40f36 bellard
        ctx->pc -= 4;
4207 4ad40f36 bellard
        gen_op_wait();
4208 4ad40f36 bellard
        ctx->bstate = BS_EXCP;
4209 4ad40f36 bellard
        break;
4210 6af0bf9c bellard
    default:
4211 6af0bf9c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4212 6af0bf9c bellard
            fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
4213 6af0bf9c bellard
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4214 6af0bf9c bellard
                    ((ctx->opcode >> 16) & 0x1F));
4215 6af0bf9c bellard
        }
4216 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
4217 6af0bf9c bellard
        return;
4218 6af0bf9c bellard
    }
4219 6af0bf9c bellard
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4220 6af0bf9c bellard
}
4221 6af0bf9c bellard
4222 6ea83fed bellard
/* CP1 Branches (before delay slot) */
4223 7a387fff ths
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4224 6ea83fed bellard
                                 int32_t offset)
4225 6ea83fed bellard
{
4226 6ea83fed bellard
    target_ulong btarget;
4227 6ea83fed bellard
4228 6ea83fed bellard
    btarget = ctx->pc + 4 + offset;
4229 6ea83fed bellard
4230 7a387fff ths
    switch (op) {
4231 7a387fff ths
    case OPC_BC1F:
4232 6ea83fed bellard
        gen_op_bc1f();
4233 3594c774 ths
        MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
4234 6ea83fed bellard
        goto not_likely;
4235 7a387fff ths
    case OPC_BC1FL:
4236 6ea83fed bellard
        gen_op_bc1f();
4237 3594c774 ths
        MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
4238 6ea83fed bellard
        goto likely;
4239 7a387fff ths
    case OPC_BC1T:
4240 6ea83fed bellard
        gen_op_bc1t();
4241 3594c774 ths
        MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
4242 6ea83fed bellard
    not_likely:
4243 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BC;
4244 6ea83fed bellard
        break;
4245 7a387fff ths
    case OPC_BC1TL:
4246 6ea83fed bellard
        gen_op_bc1t();
4247 3594c774 ths
        MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
4248 6ea83fed bellard
    likely:
4249 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BL;
4250 6ea83fed bellard
        break;
4251 6ea83fed bellard
    default:    
4252 6ea83fed bellard
        MIPS_INVAL("cp1 branch/jump");
4253 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
4254 6ea83fed bellard
        return;
4255 6ea83fed bellard
    }
4256 6ea83fed bellard
    gen_op_set_bcond();
4257 6ea83fed bellard
4258 3594c774 ths
    MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
4259 6ea83fed bellard
               ctx->hflags, btarget);
4260 6ea83fed bellard
    ctx->btarget = btarget;
4261 6ea83fed bellard
4262 6ea83fed bellard
    return;
4263 6ea83fed bellard
}
4264 6ea83fed bellard
4265 6af0bf9c bellard
/* Coprocessor 1 (FPU) */
4266 7a387fff ths
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4267 6ea83fed bellard
{
4268 7a387fff ths
    const char *opn = "unk";
4269 6ea83fed bellard
4270 6ea83fed bellard
    switch (opc) {
4271 6ea83fed bellard
    case OPC_MFC1:
4272 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4273 6ea83fed bellard
        gen_op_mfc1();
4274 6ea83fed bellard
        GEN_STORE_TN_REG(rt, T0);
4275 6ea83fed bellard
        opn = "mfc1";
4276 6ea83fed bellard
        break;
4277 6ea83fed bellard
    case OPC_MTC1:
4278 6ea83fed bellard
        GEN_LOAD_REG_TN(T0, rt);
4279 6ea83fed bellard
        gen_op_mtc1();
4280 6ea83fed bellard
        GEN_STORE_FTN_FREG(fs, WT0);
4281 6ea83fed bellard
        opn = "mtc1";
4282 6ea83fed bellard
        break;
4283 6ea83fed bellard
    case OPC_CFC1:
4284 6ea83fed bellard
        if (fs != 0 && fs != 31) {
4285 6ea83fed bellard
            MIPS_INVAL("cfc1 freg");
4286 e397ee33 ths
            generate_exception (ctx, EXCP_RI);
4287 6ea83fed bellard
            return;
4288 6ea83fed bellard
        }
4289 6ea83fed bellard
        GEN_LOAD_IMM_TN(T1, fs);
4290 6ea83fed bellard
        gen_op_cfc1();
4291 6ea83fed bellard
        GEN_STORE_TN_REG(rt, T0);
4292 6ea83fed bellard
        opn = "cfc1";
4293 6ea83fed bellard
        break;
4294 6ea83fed bellard
    case OPC_CTC1:
4295 7a387fff ths
         if (fs != 0 && fs != 31) {
4296 6ea83fed bellard
            MIPS_INVAL("ctc1 freg");
4297 e397ee33 ths
            generate_exception (ctx, EXCP_RI);
4298 6ea83fed bellard
            return;
4299 6ea83fed bellard
        }
4300 6ea83fed bellard
        GEN_LOAD_IMM_TN(T1, fs);
4301 6ea83fed bellard
        GEN_LOAD_REG_TN(T0, rt);
4302 6ea83fed bellard
        gen_op_ctc1();
4303 6ea83fed bellard
        opn = "ctc1";
4304 6ea83fed bellard
        break;
4305 9c2149c8 ths
    case OPC_DMFC1:
4306 9c2149c8 ths
    case OPC_DMTC1:
4307 9c2149c8 ths
        /* Not implemented, fallthrough. */
4308 6ea83fed bellard
    default:
4309 6ea83fed bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4310 6ea83fed bellard
            fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
4311 6ea83fed bellard
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4312 6ea83fed bellard
                    ((ctx->opcode >> 16) & 0x1F));
4313 6ea83fed bellard
        }
4314 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
4315 6ea83fed bellard
        return;
4316 6ea83fed bellard
    }
4317 6ea83fed bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4318 6ea83fed bellard
}
4319 6ea83fed bellard
4320 6ea83fed bellard
/* verify if floating point register is valid; an operation is not defined
4321 6ea83fed bellard
 * if bit 0 of any register specification is set and the FR bit in the
4322 6ea83fed bellard
 * Status register equals zero, since the register numbers specify an
4323 6ea83fed bellard
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
4324 6ea83fed bellard
 * in the Status register equals one, both even and odd register numbers
4325 00a709c7 ths
 * are valid. This limitation exists only for 64 bit wide (d,l) registers.
4326 6ea83fed bellard
 * 
4327 00a709c7 ths
 * Multiple 64 bit wide registers can be checked by calling
4328 6ea83fed bellard
 * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
4329 6ea83fed bellard
 */
4330 6ea83fed bellard
#define CHECK_FR(ctx, freg) do { \
4331 6ea83fed bellard
        if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
4332 e397ee33 ths
            generate_exception (ctx, EXCP_RI); \
4333 6ea83fed bellard
            return; \
4334 6ea83fed bellard
        } \
4335 6ea83fed bellard
    } while(0)
4336 6ea83fed bellard
4337 6ea83fed bellard
#define FOP(func, fmt) (((fmt) << 21) | (func))
4338 6ea83fed bellard
4339 7a387fff ths
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
4340 6ea83fed bellard
{
4341 7a387fff ths
    const char *opn = "unk";
4342 6ea83fed bellard
    const char *condnames[] = {
4343 6ea83fed bellard
            "c.f",
4344 6ea83fed bellard
            "c.un",
4345 6ea83fed bellard
            "c.eq",
4346 6ea83fed bellard
            "c.ueq",
4347 6ea83fed bellard
            "c.olt",
4348 6ea83fed bellard
            "c.ult",
4349 6ea83fed bellard
            "c.ole",
4350 6ea83fed bellard
            "c.ule",
4351 6ea83fed bellard
            "c.sf",
4352 6ea83fed bellard
            "c.ngle",
4353 6ea83fed bellard
            "c.seq",
4354 6ea83fed bellard
            "c.ngl",
4355 6ea83fed bellard
            "c.lt",
4356 6ea83fed bellard
            "c.nge",
4357 6ea83fed bellard
            "c.le",
4358 6ea83fed bellard
            "c.ngt",
4359 6ea83fed bellard
    };
4360 6ea83fed bellard
    int binary = 0;
4361 7a387fff ths
    uint32_t func = ctx->opcode & 0x3f;
4362 7a387fff ths
4363 6ea83fed bellard
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4364 6ea83fed bellard
    case FOP(0, 17):
4365 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
4366 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4367 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4368 6ea83fed bellard
        gen_op_float_add_d();
4369 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4370 6ea83fed bellard
        opn = "add.d";
4371 6ea83fed bellard
        binary = 1;
4372 6ea83fed bellard
        break;
4373 6ea83fed bellard
    case FOP(1, 17):
4374 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
4375 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4376 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4377 6ea83fed bellard
        gen_op_float_sub_d();
4378 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4379 6ea83fed bellard
        opn = "sub.d";
4380 6ea83fed bellard
        binary = 1;
4381 6ea83fed bellard
        break;
4382 6ea83fed bellard
    case FOP(2, 17):
4383 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
4384 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4385 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4386 6ea83fed bellard
        gen_op_float_mul_d();
4387 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4388 6ea83fed bellard
        opn = "mul.d";
4389 6ea83fed bellard
        binary = 1;
4390 6ea83fed bellard
        break;
4391 6ea83fed bellard
    case FOP(3, 17):
4392 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
4393 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4394 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4395 6ea83fed bellard
        gen_op_float_div_d();
4396 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4397 6ea83fed bellard
        opn = "div.d";
4398 6ea83fed bellard
        binary = 1;
4399 6ea83fed bellard
        break;
4400 6ea83fed bellard
    case FOP(4, 17):
4401 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
4402 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4403 6ea83fed bellard
        gen_op_float_sqrt_d();
4404 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4405 6ea83fed bellard
        opn = "sqrt.d";
4406 6ea83fed bellard
        break;
4407 6ea83fed bellard
    case FOP(5, 17):
4408 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
4409 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4410 6ea83fed bellard
        gen_op_float_abs_d();
4411 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4412 6ea83fed bellard
        opn = "abs.d";
4413 6ea83fed bellard
        break;
4414 6ea83fed bellard
    case FOP(6, 17):
4415 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
4416 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4417 6ea83fed bellard
        gen_op_float_mov_d();
4418 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4419 6ea83fed bellard
        opn = "mov.d";
4420 6ea83fed bellard
        break;
4421 6ea83fed bellard
    case FOP(7, 17):
4422 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
4423 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4424 6ea83fed bellard
        gen_op_float_chs_d();
4425 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4426 6ea83fed bellard
        opn = "neg.d";
4427 6ea83fed bellard
        break;
4428 6ea83fed bellard
    /*  8 - round.l */
4429 6ea83fed bellard
    /*  9 - trunc.l */
4430 6ea83fed bellard
    /* 10 - ceil.l  */
4431 6ea83fed bellard
    /* 11 - floor.l */
4432 6ea83fed bellard
    case FOP(12, 17):
4433 00a709c7 ths
        CHECK_FR(ctx, fs);
4434 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4435 6ea83fed bellard
        gen_op_float_roundw_d();
4436 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4437 6ea83fed bellard
        opn = "round.w.d";
4438 6ea83fed bellard
        break;
4439 6ea83fed bellard
    case FOP(13, 17):
4440 00a709c7 ths
        CHECK_FR(ctx, fs);
4441 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4442 6ea83fed bellard
        gen_op_float_truncw_d();
4443 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4444 6ea83fed bellard
        opn = "trunc.w.d";
4445 6ea83fed bellard
        break;
4446 6ea83fed bellard
    case FOP(14, 17):
4447 00a709c7 ths
        CHECK_FR(ctx, fs);
4448 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4449 6ea83fed bellard
        gen_op_float_ceilw_d();
4450 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4451 6ea83fed bellard
        opn = "ceil.w.d";
4452 6ea83fed bellard
        break;
4453 6ea83fed bellard
    case FOP(15, 17):
4454 00a709c7 ths
        CHECK_FR(ctx, fs);
4455 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4456 6ea83fed bellard
        gen_op_float_floorw_d();
4457 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4458 7a387fff ths
        opn = "floor.w.d";
4459 6ea83fed bellard
        break;
4460 00a709c7 ths
    case FOP(33, 16):
4461 00a709c7 ths
        CHECK_FR(ctx, fd);
4462 dd016883 bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4463 dd016883 bellard
        gen_op_float_cvtd_s();
4464 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4465 dd016883 bellard
        opn = "cvt.d.s";
4466 dd016883 bellard
        break;
4467 00a709c7 ths
    case FOP(33, 20):
4468 00a709c7 ths
        CHECK_FR(ctx, fd);
4469 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4470 6ea83fed bellard
        gen_op_float_cvtd_w();
4471 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4472 6ea83fed bellard
        opn = "cvt.d.w";
4473 6ea83fed bellard
        break;
4474 6ea83fed bellard
    case FOP(48, 17):
4475 6ea83fed bellard
    case FOP(49, 17):
4476 6ea83fed bellard
    case FOP(50, 17):
4477 6ea83fed bellard
    case FOP(51, 17):
4478 6ea83fed bellard
    case FOP(52, 17):
4479 6ea83fed bellard
    case FOP(53, 17):
4480 6ea83fed bellard
    case FOP(54, 17):
4481 6ea83fed bellard
    case FOP(55, 17):
4482 6ea83fed bellard
    case FOP(56, 17):
4483 6ea83fed bellard
    case FOP(57, 17):
4484 6ea83fed bellard
    case FOP(58, 17):
4485 6ea83fed bellard
    case FOP(59, 17):
4486 6ea83fed bellard
    case FOP(60, 17):
4487 6ea83fed bellard
    case FOP(61, 17):
4488 6ea83fed bellard
    case FOP(62, 17):
4489 6ea83fed bellard
    case FOP(63, 17):
4490 6ea83fed bellard
        CHECK_FR(ctx, fs | ft);
4491 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4492 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4493 6ea83fed bellard
        gen_cmp_d(func-48);
4494 6ea83fed bellard
        opn = condnames[func-48];
4495 6ea83fed bellard
        break;
4496 6ea83fed bellard
    case FOP(0, 16):
4497 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4498 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4499 6ea83fed bellard
        gen_op_float_add_s();
4500 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4501 6ea83fed bellard
        opn = "add.s";
4502 6ea83fed bellard
        binary = 1;
4503 6ea83fed bellard
        break;
4504 6ea83fed bellard
    case FOP(1, 16):
4505 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4506 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4507 6ea83fed bellard
        gen_op_float_sub_s();
4508 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4509 6ea83fed bellard
        opn = "sub.s";
4510 6ea83fed bellard
        binary = 1;
4511 6ea83fed bellard
        break;
4512 6ea83fed bellard
    case FOP(2, 16):
4513 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4514 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4515 6ea83fed bellard
        gen_op_float_mul_s();
4516 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4517 6ea83fed bellard
        opn = "mul.s";
4518 6ea83fed bellard
        binary = 1;
4519 6ea83fed bellard
        break;
4520 6ea83fed bellard
    case FOP(3, 16):
4521 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4522 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4523 6ea83fed bellard
        gen_op_float_div_s();
4524 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4525 6ea83fed bellard
        opn = "div.s";
4526 6ea83fed bellard
        binary = 1;
4527 6ea83fed bellard
        break;
4528 6ea83fed bellard
    case FOP(4, 16):
4529 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4530 6ea83fed bellard
        gen_op_float_sqrt_s();
4531 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4532 6ea83fed bellard
        opn = "sqrt.s";
4533 6ea83fed bellard
        break;
4534 6ea83fed bellard
    case FOP(5, 16):
4535 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4536 6ea83fed bellard
        gen_op_float_abs_s();
4537 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4538 6ea83fed bellard
        opn = "abs.s";
4539 6ea83fed bellard
        break;
4540 6ea83fed bellard
    case FOP(6, 16):
4541 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4542 6ea83fed bellard
        gen_op_float_mov_s();
4543 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4544 6ea83fed bellard
        opn = "mov.s";
4545 6ea83fed bellard
        break;
4546 6ea83fed bellard
    case FOP(7, 16):
4547 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4548 6ea83fed bellard
        gen_op_float_chs_s();
4549 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4550 6ea83fed bellard
        opn = "neg.s";
4551 6ea83fed bellard
        break;
4552 6ea83fed bellard
    case FOP(12, 16):
4553 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4554 6ea83fed bellard
        gen_op_float_roundw_s();
4555 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4556 6ea83fed bellard
        opn = "round.w.s";
4557 6ea83fed bellard
        break;
4558 6ea83fed bellard
    case FOP(13, 16):
4559 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4560 6ea83fed bellard
        gen_op_float_truncw_s();
4561 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4562 6ea83fed bellard
        opn = "trunc.w.s";
4563 6ea83fed bellard
        break;
4564 00a709c7 ths
    case FOP(32, 17):
4565 00a709c7 ths
        CHECK_FR(ctx, fs);
4566 417f38f0 pbrook
        GEN_LOAD_FREG_FTN(DT0, fs);
4567 dd016883 bellard
        gen_op_float_cvts_d();
4568 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4569 dd016883 bellard
        opn = "cvt.s.d";
4570 dd016883 bellard
        break;
4571 00a709c7 ths
    case FOP(32, 20):
4572 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4573 6ea83fed bellard
        gen_op_float_cvts_w();
4574 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4575 6ea83fed bellard
        opn = "cvt.s.w";
4576 6ea83fed bellard
        break;
4577 00a709c7 ths
    case FOP(36, 16):
4578 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4579 6ea83fed bellard
        gen_op_float_cvtw_s();
4580 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4581 6ea83fed bellard
        opn = "cvt.w.s";
4582 6ea83fed bellard
        break;
4583 00a709c7 ths
    case FOP(36, 17):
4584 00a709c7 ths
        CHECK_FR(ctx, fs);
4585 417f38f0 pbrook
        GEN_LOAD_FREG_FTN(DT0, fs);
4586 6ea83fed bellard
        gen_op_float_cvtw_d();
4587 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4588 6ea83fed bellard
        opn = "cvt.w.d";
4589 6ea83fed bellard
        break;
4590 6ea83fed bellard
    case FOP(48, 16):
4591 6ea83fed bellard
    case FOP(49, 16):
4592 6ea83fed bellard
    case FOP(50, 16):
4593 6ea83fed bellard
    case FOP(51, 16):
4594 6ea83fed bellard
    case FOP(52, 16):
4595 6ea83fed bellard
    case FOP(53, 16):
4596 6ea83fed bellard
    case FOP(54, 16):
4597 6ea83fed bellard
    case FOP(55, 16):
4598 6ea83fed bellard
    case FOP(56, 16):
4599 6ea83fed bellard
    case FOP(57, 16):
4600 6ea83fed bellard
    case FOP(58, 16):
4601 6ea83fed bellard
    case FOP(59, 16):
4602 6ea83fed bellard
    case FOP(60, 16):
4603 6ea83fed bellard
    case FOP(61, 16):
4604 6ea83fed bellard
    case FOP(62, 16):
4605 6ea83fed bellard
    case FOP(63, 16):
4606 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4607 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4608 6ea83fed bellard
        gen_cmp_s(func-48);
4609 6ea83fed bellard
        opn = condnames[func-48];
4610 6ea83fed bellard
        break;
4611 6ea83fed bellard
    default:    
4612 6ea83fed bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4613 7a387fff ths
            fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
4614 6ea83fed bellard
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4615 6ea83fed bellard
                    ((ctx->opcode >> 16) & 0x1F));
4616 6ea83fed bellard
        }
4617 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
4618 6ea83fed bellard
        return;
4619 6ea83fed bellard
    }
4620 6ea83fed bellard
    if (binary)
4621 6ea83fed bellard
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
4622 6ea83fed bellard
    else
4623 6ea83fed bellard
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
4624 6ea83fed bellard
}
4625 6af0bf9c bellard
4626 7a387fff ths
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4627 7a387fff ths
{
4628 7a387fff ths
    uint32_t ccbit;
4629 7a387fff ths
4630 7a387fff ths
    if (cc)
4631 7a387fff ths
        ccbit = 1 << (24 + cc);
4632 7a387fff ths
    else
4633 7a387fff ths
        ccbit = 1 << 23;
4634 7a387fff ths
    if (!tf)
4635 7a387fff ths
        gen_op_movf(ccbit, rd, rs);
4636 7a387fff ths
    else
4637 7a387fff ths
       gen_op_movt(ccbit, rd, rs);
4638 7a387fff ths
}
4639 7a387fff ths
4640 7a387fff ths
/* ISA extensions (ASEs) */
4641 6af0bf9c bellard
/* MIPS16 extension to MIPS32 */
4642 6af0bf9c bellard
/* SmartMIPS extension to MIPS32 */
4643 6af0bf9c bellard
4644 60aa19ab ths
#ifdef TARGET_MIPS64
4645 6af0bf9c bellard
/* Coprocessor 3 (FPU) */
4646 6af0bf9c bellard
4647 6af0bf9c bellard
/* MDMX extension to MIPS64 */
4648 6af0bf9c bellard
/* MIPS-3D extension to MIPS64 */
4649 6af0bf9c bellard
4650 6af0bf9c bellard
#endif
4651 6af0bf9c bellard
4652 c53be334 bellard
static void gen_blikely(DisasContext *ctx)
4653 c53be334 bellard
{
4654 eeef26cd bellard
    int l1;
4655 eeef26cd bellard
    l1 = gen_new_label();
4656 eeef26cd bellard
    gen_op_jnz_T2(l1);
4657 4ad40f36 bellard
    gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
4658 eeef26cd bellard
    gen_goto_tb(ctx, 1, ctx->pc + 4);
4659 eeef26cd bellard
    gen_set_label(l1);
4660 c53be334 bellard
}
4661 c53be334 bellard
4662 36d23958 ths
static void decode_opc (CPUState *env, DisasContext *ctx)
4663 6af0bf9c bellard
{
4664 6af0bf9c bellard
    int32_t offset;
4665 6af0bf9c bellard
    int rs, rt, rd, sa;
4666 7a387fff ths
    uint32_t op, op1, op2;
4667 6af0bf9c bellard
    int16_t imm;
4668 6af0bf9c bellard
4669 d796321b bellard
    /* make sure instructions are on a word boundary */
4670 d796321b bellard
    if (ctx->pc & 0x3) {
4671 cbeb0857 ths
        env->CP0_BadVAddr = ctx->pc;
4672 d796321b bellard
        generate_exception(ctx, EXCP_AdEL);
4673 d796321b bellard
        return;
4674 d796321b bellard
    }
4675 d796321b bellard
4676 4ad40f36 bellard
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
4677 6af0bf9c bellard
        /* Handle blikely not taken case */
4678 3594c774 ths
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
4679 c53be334 bellard
        gen_blikely(ctx);
4680 6af0bf9c bellard
    }
4681 7a387fff ths
    op = MASK_OP_MAJOR(ctx->opcode);
4682 7a387fff ths
    rs = (ctx->opcode >> 21) & 0x1f;
4683 7a387fff ths
    rt = (ctx->opcode >> 16) & 0x1f;
4684 7a387fff ths
    rd = (ctx->opcode >> 11) & 0x1f;
4685 7a387fff ths
    sa = (ctx->opcode >> 6) & 0x1f;
4686 6af0bf9c bellard
    imm = (int16_t)ctx->opcode;
4687 6af0bf9c bellard
    switch (op) {
4688 7a387fff ths
    case OPC_SPECIAL:
4689 7a387fff ths
        op1 = MASK_SPECIAL(ctx->opcode);
4690 6af0bf9c bellard
        switch (op1) {
4691 7a387fff ths
        case OPC_SLL:          /* Arithmetic with immediate */
4692 7a387fff ths
        case OPC_SRL ... OPC_SRA:
4693 7a387fff ths
            gen_arith_imm(ctx, op1, rd, rt, sa);
4694 7a387fff ths
            break;
4695 7a387fff ths
        case OPC_SLLV:         /* Arithmetic */
4696 7a387fff ths
        case OPC_SRLV ... OPC_SRAV:
4697 7a387fff ths
        case OPC_MOVZ ... OPC_MOVN:
4698 7a387fff ths
        case OPC_ADD ... OPC_NOR:
4699 7a387fff ths
        case OPC_SLT ... OPC_SLTU:
4700 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
4701 7a387fff ths
            break;
4702 7a387fff ths
        case OPC_MULT ... OPC_DIVU:
4703 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
4704 7a387fff ths
            break;
4705 7a387fff ths
        case OPC_JR ... OPC_JALR:
4706 7a387fff ths
            gen_compute_branch(ctx, op1, rs, rd, sa);
4707 6af0bf9c bellard
            return;
4708 7a387fff ths
        case OPC_TGE ... OPC_TEQ: /* Traps */
4709 7a387fff ths
        case OPC_TNE:
4710 7a387fff ths
            gen_trap(ctx, op1, rs, rt, -1);
4711 6af0bf9c bellard
            break;
4712 7a387fff ths
        case OPC_MFHI:          /* Move from HI/LO */
4713 7a387fff ths
        case OPC_MFLO:
4714 7a387fff ths
            gen_HILO(ctx, op1, rd);
4715 6af0bf9c bellard
            break;
4716 7a387fff ths
        case OPC_MTHI:
4717 7a387fff ths
        case OPC_MTLO:          /* Move to HI/LO */
4718 7a387fff ths
            gen_HILO(ctx, op1, rs);
4719 6af0bf9c bellard
            break;
4720 b48cfdff ths
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
4721 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
4722 b48cfdff ths
            MIPS_INVAL("PMON / selsl");
4723 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
4724 b48cfdff ths
#else
4725 7a387fff ths
            gen_op_pmon(sa);
4726 b48cfdff ths
#endif
4727 7a387fff ths
            break;
4728 7a387fff ths
        case OPC_SYSCALL:
4729 6af0bf9c bellard
            generate_exception(ctx, EXCP_SYSCALL);
4730 6af0bf9c bellard
            break;
4731 7a387fff ths
        case OPC_BREAK:
4732 6af0bf9c bellard
            generate_exception(ctx, EXCP_BREAK);
4733 6af0bf9c bellard
            break;
4734 b48cfdff ths
        case OPC_SPIM:
4735 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
4736 b48cfdff ths
            MIPS_INVAL("SPIM");
4737 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
4738 b48cfdff ths
#else
4739 7a387fff ths
           /* Implemented as RI exception for now. */
4740 7a387fff ths
            MIPS_INVAL("spim (unofficial)");
4741 7a387fff ths
            generate_exception(ctx, EXCP_RI);
4742 b48cfdff ths
#endif
4743 6af0bf9c bellard
            break;
4744 7a387fff ths
        case OPC_SYNC:
4745 7a387fff ths
            /* Treat as a noop. */
4746 6af0bf9c bellard
            break;
4747 4ad40f36 bellard
4748 7a387fff ths
        case OPC_MOVCI:
4749 36d23958 ths
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4750 e397ee33 ths
                save_cpu_state(ctx, 1);
4751 36d23958 ths
                gen_op_cp1_enabled();
4752 36d23958 ths
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
4753 36d23958 ths
                          (ctx->opcode >> 16) & 1);
4754 36d23958 ths
            } else {
4755 e397ee33 ths
                generate_exception_err(ctx, EXCP_CpU, 1);
4756 36d23958 ths
            }
4757 4ad40f36 bellard
            break;
4758 4ad40f36 bellard
4759 60aa19ab ths
#ifdef TARGET_MIPS64
4760 7a387fff ths
       /* MIPS64 specific opcodes */
4761 7a387fff ths
        case OPC_DSLL:
4762 7a387fff ths
        case OPC_DSRL ... OPC_DSRA:
4763 7a387fff ths
        case OPC_DSLL32:
4764 7a387fff ths
        case OPC_DSRL32 ... OPC_DSRA32:
4765 7a387fff ths
            gen_arith_imm(ctx, op1, rd, rt, sa);
4766 7a387fff ths
            break;
4767 7a387fff ths
        case OPC_DSLLV:
4768 7a387fff ths
        case OPC_DSRLV ... OPC_DSRAV:
4769 7a387fff ths
        case OPC_DADD ... OPC_DSUBU:
4770 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
4771 7a387fff ths
            break;
4772 7a387fff ths
        case OPC_DMULT ... OPC_DDIVU:
4773 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
4774 7a387fff ths
            break;
4775 6af0bf9c bellard
#endif
4776 6af0bf9c bellard
        default:            /* Invalid */
4777 6af0bf9c bellard
            MIPS_INVAL("special");
4778 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
4779 6af0bf9c bellard
            break;
4780 6af0bf9c bellard
        }
4781 6af0bf9c bellard
        break;
4782 7a387fff ths
    case OPC_SPECIAL2:
4783 7a387fff ths
        op1 = MASK_SPECIAL2(ctx->opcode);
4784 6af0bf9c bellard
        switch (op1) {
4785 7a387fff ths
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
4786 7a387fff ths
        case OPC_MSUB ... OPC_MSUBU:
4787 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
4788 6af0bf9c bellard
            break;
4789 7a387fff ths
        case OPC_MUL:
4790 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
4791 6af0bf9c bellard
            break;
4792 7a387fff ths
        case OPC_CLZ ... OPC_CLO:
4793 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
4794 6af0bf9c bellard
            break;
4795 7a387fff ths
        case OPC_SDBBP:
4796 6af0bf9c bellard
            /* XXX: not clear which exception should be raised
4797 6af0bf9c bellard
             *      when in debug mode...
4798 6af0bf9c bellard
             */
4799 6af0bf9c bellard
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4800 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
4801 6af0bf9c bellard
            } else {
4802 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
4803 6af0bf9c bellard
            }
4804 6af0bf9c bellard
            /* Treat as a noop */
4805 6af0bf9c bellard
            break;
4806 60aa19ab ths
#ifdef TARGET_MIPS64
4807 7a387fff ths
        case OPC_DCLZ ... OPC_DCLO:
4808 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
4809 7a387fff ths
            break;
4810 7a387fff ths
#endif
4811 6af0bf9c bellard
        default:            /* Invalid */
4812 6af0bf9c bellard
            MIPS_INVAL("special2");
4813 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
4814 6af0bf9c bellard
            break;
4815 6af0bf9c bellard
        }
4816 6af0bf9c bellard
        break;
4817 7a387fff ths
    case OPC_SPECIAL3:
4818 1579a72e ths
         op1 = MASK_SPECIAL3(ctx->opcode);
4819 1579a72e ths
         switch (op1) {
4820 1579a72e ths
         case OPC_EXT:
4821 1579a72e ths
         case OPC_INS:
4822 1579a72e ths
             gen_bitops(ctx, op1, rt, rs, sa, rd);
4823 1579a72e ths
             break;
4824 1579a72e ths
         case OPC_BSHFL:
4825 1579a72e ths
             op2 = MASK_BSHFL(ctx->opcode);
4826 1579a72e ths
             switch (op2) {
4827 1579a72e ths
             case OPC_WSBH:
4828 1579a72e ths
                 GEN_LOAD_REG_TN(T1, rt);
4829 1579a72e ths
                 gen_op_wsbh();
4830 1579a72e ths
                 break;
4831 1579a72e ths
             case OPC_SEB:
4832 1579a72e ths
                 GEN_LOAD_REG_TN(T1, rt);
4833 1579a72e ths
                 gen_op_seb();
4834 1579a72e ths
                 break;
4835 1579a72e ths
             case OPC_SEH:
4836 1579a72e ths
                 GEN_LOAD_REG_TN(T1, rt);
4837 1579a72e ths
                 gen_op_seh();
4838 1579a72e ths
                 break;
4839 1579a72e ths
             default:            /* Invalid */
4840 1579a72e ths
                 MIPS_INVAL("bshfl");
4841 1579a72e ths
                 generate_exception(ctx, EXCP_RI);
4842 1579a72e ths
                 break;
4843 1579a72e ths
            }
4844 1579a72e ths
            GEN_STORE_TN_REG(rd, T0);
4845 7a387fff ths
            break;
4846 1579a72e ths
        case OPC_RDHWR:
4847 1579a72e ths
            switch (rd) {
4848 1579a72e ths
            case 0:
4849 97428a4d ths
                save_cpu_state(ctx, 1);
4850 1579a72e ths
                gen_op_rdhwr_cpunum();
4851 7a387fff ths
                break;
4852 1579a72e ths
            case 1:
4853 97428a4d ths
                save_cpu_state(ctx, 1);
4854 1579a72e ths
                gen_op_rdhwr_synci_step();
4855 7a387fff ths
                break;
4856 1579a72e ths
            case 2:
4857 97428a4d ths
                save_cpu_state(ctx, 1);
4858 1579a72e ths
                gen_op_rdhwr_cc();
4859 7a387fff ths
                break;
4860 1579a72e ths
            case 3:
4861 97428a4d ths
                save_cpu_state(ctx, 1);
4862 1579a72e ths
                gen_op_rdhwr_ccres();
4863 7a387fff ths
                break;
4864 1579a72e ths
            case 29:
4865 6f5b89a0 ths
#if defined (CONFIG_USER_ONLY)
4866 1579a72e ths
                gen_op_tls_value ();
4867 1579a72e ths
                break;
4868 97428a4d ths
#endif
4869 1579a72e ths
            default:            /* Invalid */
4870 1579a72e ths
                MIPS_INVAL("rdhwr");
4871 1579a72e ths
                generate_exception(ctx, EXCP_RI);
4872 1579a72e ths
                break;
4873 1579a72e ths
            }
4874 1579a72e ths
            GEN_STORE_TN_REG(rt, T0);
4875 1579a72e ths
            break;
4876 60aa19ab ths
#ifdef TARGET_MIPS64
4877 1579a72e ths
        case OPC_DEXTM ... OPC_DEXT:
4878 1579a72e ths
        case OPC_DINSM ... OPC_DINS:
4879 1579a72e ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
4880 7a387fff ths
            break;
4881 1579a72e ths
        case OPC_DBSHFL:
4882 1579a72e ths
            op2 = MASK_DBSHFL(ctx->opcode);
4883 1579a72e ths
            switch (op2) {
4884 1579a72e ths
            case OPC_DSBH:
4885 1579a72e ths
                GEN_LOAD_REG_TN(T1, rt);
4886 1579a72e ths
                gen_op_dsbh();
4887 1579a72e ths
                break;
4888 1579a72e ths
            case OPC_DSHD:
4889 1579a72e ths
                GEN_LOAD_REG_TN(T1, rt);
4890 1579a72e ths
                gen_op_dshd();
4891 1579a72e ths
                break;
4892 7a387fff ths
            default:            /* Invalid */
4893 7a387fff ths
                MIPS_INVAL("dbshfl");
4894 7a387fff ths
                generate_exception(ctx, EXCP_RI);
4895 7a387fff ths
                break;
4896 1579a72e ths
            }
4897 1579a72e ths
            GEN_STORE_TN_REG(rd, T0);
4898 7a387fff ths
#endif
4899 7a387fff ths
        default:            /* Invalid */
4900 7a387fff ths
            MIPS_INVAL("special3");
4901 7a387fff ths
            generate_exception(ctx, EXCP_RI);
4902 7a387fff ths
            break;
4903 7a387fff ths
        }
4904 7a387fff ths
        break;
4905 7a387fff ths
    case OPC_REGIMM:
4906 7a387fff ths
        op1 = MASK_REGIMM(ctx->opcode);
4907 7a387fff ths
        switch (op1) {
4908 7a387fff ths
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
4909 7a387fff ths
        case OPC_BLTZAL ... OPC_BGEZALL:
4910 7a387fff ths
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
4911 6af0bf9c bellard
            return;
4912 7a387fff ths
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
4913 7a387fff ths
        case OPC_TNEI:
4914 7a387fff ths
            gen_trap(ctx, op1, rs, -1, imm);
4915 7a387fff ths
            break;
4916 7a387fff ths
        case OPC_SYNCI:
4917 24c7b0e3 ths
            /* treat as noop */
4918 6af0bf9c bellard
            break;
4919 6af0bf9c bellard
        default:            /* Invalid */
4920 6af0bf9c bellard
            MIPS_INVAL("REGIMM");
4921 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
4922 6af0bf9c bellard
            break;
4923 6af0bf9c bellard
        }
4924 6af0bf9c bellard
        break;
4925 7a387fff ths
    case OPC_CP0:
4926 f41c52f1 ths
        save_cpu_state(ctx, 1);
4927 24c7b0e3 ths
        gen_op_cp0_enabled();
4928 7a387fff ths
        op1 = MASK_CP0(ctx->opcode);
4929 6af0bf9c bellard
        switch (op1) {
4930 7a387fff ths
        case OPC_MFC0:
4931 7a387fff ths
        case OPC_MTC0:
4932 60aa19ab ths
#ifdef TARGET_MIPS64
4933 7a387fff ths
        case OPC_DMFC0:
4934 7a387fff ths
        case OPC_DMTC0:
4935 7a387fff ths
#endif
4936 7a387fff ths
            gen_cp0(ctx, op1, rt, rd);
4937 7a387fff ths
            break;
4938 7a387fff ths
        case OPC_C0_FIRST ... OPC_C0_LAST:
4939 7a387fff ths
            gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
4940 7a387fff ths
            break;
4941 7a387fff ths
        case OPC_MFMC0:
4942 7a387fff ths
            op2 = MASK_MFMC0(ctx->opcode);
4943 7a387fff ths
            switch (op2) {
4944 7a387fff ths
            case OPC_DI:
4945 7a387fff ths
                gen_op_di();
4946 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
4947 7a387fff ths
                ctx->bstate = BS_STOP;
4948 7a387fff ths
                break;
4949 7a387fff ths
            case OPC_EI:
4950 7a387fff ths
                gen_op_ei();
4951 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
4952 7a387fff ths
                ctx->bstate = BS_STOP;
4953 7a387fff ths
                break;
4954 7a387fff ths
            default:            /* Invalid */
4955 7a387fff ths
                MIPS_INVAL("MFMC0");
4956 7a387fff ths
                generate_exception(ctx, EXCP_RI);
4957 7a387fff ths
                break;
4958 7a387fff ths
            }
4959 7a387fff ths
            GEN_STORE_TN_REG(rt, T0);
4960 6af0bf9c bellard
            break;
4961 7a387fff ths
        case OPC_RDPGPR:
4962 7a387fff ths
        case OPC_WRPGPR:
4963 38121543 ths
            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
4964 38121543 ths
                /* Shadow registers not implemented. */
4965 38121543 ths
                GEN_LOAD_REG_TN(T0, rt);
4966 38121543 ths
                GEN_STORE_TN_REG(rd, T0);
4967 38121543 ths
            } else
4968 38121543 ths
                generate_exception(ctx, EXCP_RI);
4969 38121543 ths
            break;
4970 6af0bf9c bellard
        default:
4971 7a387fff ths
            generate_exception(ctx, EXCP_RI);
4972 6af0bf9c bellard
            break;
4973 6af0bf9c bellard
        }
4974 6af0bf9c bellard
        break;
4975 7a387fff ths
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
4976 7a387fff ths
         gen_arith_imm(ctx, op, rt, rs, imm);
4977 7a387fff ths
         break;
4978 7a387fff ths
    case OPC_J ... OPC_JAL: /* Jump */
4979 7a387fff ths
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
4980 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, offset);
4981 7a387fff ths
         return;
4982 7a387fff ths
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
4983 7a387fff ths
    case OPC_BEQL ... OPC_BGTZL:
4984 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
4985 7a387fff ths
         return;
4986 7a387fff ths
    case OPC_LB ... OPC_LWR: /* Load and stores */
4987 7a387fff ths
    case OPC_SB ... OPC_SW:
4988 7a387fff ths
    case OPC_SWR:
4989 7a387fff ths
    case OPC_LL:
4990 7a387fff ths
    case OPC_SC:
4991 7a387fff ths
         gen_ldst(ctx, op, rt, rs, imm);
4992 7a387fff ths
         break;
4993 7a387fff ths
    case OPC_CACHE:
4994 7a387fff ths
         /* Treat as a noop */
4995 7a387fff ths
         break;
4996 7a387fff ths
    case OPC_PREF:
4997 6af0bf9c bellard
        /* Treat as a noop */
4998 6af0bf9c bellard
        break;
4999 4ad40f36 bellard
5000 4ad40f36 bellard
    /* Floating point.  */
5001 7a387fff ths
    case OPC_LWC1:
5002 7a387fff ths
    case OPC_LDC1:
5003 7a387fff ths
    case OPC_SWC1:
5004 7a387fff ths
    case OPC_SDC1:
5005 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5006 36d23958 ths
            save_cpu_state(ctx, 1);
5007 36d23958 ths
            gen_op_cp1_enabled();
5008 36d23958 ths
            gen_flt_ldst(ctx, op, rt, rs, imm);
5009 36d23958 ths
        } else {
5010 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
5011 36d23958 ths
        }
5012 6ea83fed bellard
        break;
5013 6ea83fed bellard
5014 7a387fff ths
    case OPC_CP1:
5015 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5016 36d23958 ths
            save_cpu_state(ctx, 1);
5017 36d23958 ths
            gen_op_cp1_enabled();
5018 36d23958 ths
            op1 = MASK_CP1(ctx->opcode);
5019 36d23958 ths
            switch (op1) {
5020 36d23958 ths
            case OPC_MFC1:
5021 36d23958 ths
            case OPC_CFC1:
5022 36d23958 ths
            case OPC_MTC1:
5023 36d23958 ths
            case OPC_CTC1:
5024 60aa19ab ths
#ifdef TARGET_MIPS64
5025 36d23958 ths
            case OPC_DMFC1:
5026 36d23958 ths
            case OPC_DMTC1:
5027 9c2149c8 ths
#endif
5028 36d23958 ths
                gen_cp1(ctx, op1, rt, rd);
5029 36d23958 ths
                break;
5030 36d23958 ths
            case OPC_BC1:
5031 36d23958 ths
                gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
5032 36d23958 ths
                return;
5033 36d23958 ths
            case OPC_S_FMT:
5034 36d23958 ths
            case OPC_D_FMT:
5035 36d23958 ths
            case OPC_W_FMT:
5036 36d23958 ths
            case OPC_L_FMT:
5037 36d23958 ths
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
5038 36d23958 ths
                break;
5039 36d23958 ths
            default:
5040 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
5041 36d23958 ths
                break;
5042 36d23958 ths
            }
5043 36d23958 ths
        } else {
5044 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
5045 6ea83fed bellard
        }
5046 4ad40f36 bellard
        break;
5047 4ad40f36 bellard
5048 4ad40f36 bellard
    /* COP2.  */
5049 7a387fff ths
    case OPC_LWC2:
5050 7a387fff ths
    case OPC_LDC2:
5051 7a387fff ths
    case OPC_SWC2:
5052 7a387fff ths
    case OPC_SDC2:
5053 7a387fff ths
    case OPC_CP2:
5054 7a387fff ths
        /* COP2: Not implemented. */
5055 4ad40f36 bellard
        generate_exception_err(ctx, EXCP_CpU, 2);
5056 4ad40f36 bellard
        break;
5057 4ad40f36 bellard
5058 7a387fff ths
    case OPC_CP3:
5059 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5060 e397ee33 ths
            save_cpu_state(ctx, 1);
5061 36d23958 ths
            gen_op_cp1_enabled();
5062 36d23958 ths
            op1 = MASK_CP3(ctx->opcode);
5063 36d23958 ths
            switch (op1) {
5064 e0c84da7 ths
            case OPC_PREFX:
5065 e0c84da7 ths
                /* treat as noop */
5066 e0c84da7 ths
                break;
5067 36d23958 ths
            /* Not implemented */
5068 36d23958 ths
            default:
5069 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
5070 36d23958 ths
                break;
5071 36d23958 ths
            }
5072 36d23958 ths
        } else {
5073 e397ee33 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
5074 7a387fff ths
        }
5075 4ad40f36 bellard
        break;
5076 4ad40f36 bellard
5077 60aa19ab ths
#ifdef TARGET_MIPS64
5078 7a387fff ths
    /* MIPS64 opcodes */
5079 7a387fff ths
    case OPC_LWU:
5080 7a387fff ths
    case OPC_LDL ... OPC_LDR:
5081 7a387fff ths
    case OPC_SDL ... OPC_SDR:
5082 7a387fff ths
    case OPC_LLD:
5083 7a387fff ths
    case OPC_LD:
5084 7a387fff ths
    case OPC_SCD:
5085 7a387fff ths
    case OPC_SD:
5086 7a387fff ths
        gen_ldst(ctx, op, rt, rs, imm);
5087 7a387fff ths
        break;
5088 7a387fff ths
    case OPC_DADDI ... OPC_DADDIU:
5089 7a387fff ths
        gen_arith_imm(ctx, op, rt, rs, imm);
5090 7a387fff ths
        break;
5091 6af0bf9c bellard
#endif
5092 7a387fff ths
#ifdef MIPS_HAS_MIPS16
5093 7a387fff ths
    case OPC_JALX:
5094 7a387fff ths
        /* MIPS16: Not implemented. */
5095 7a387fff ths
#endif
5096 7a387fff ths
#ifdef MIPS_HAS_MDMX
5097 7a387fff ths
    case OPC_MDMX:
5098 7a387fff ths
        /* MDMX: Not implemented. */
5099 6af0bf9c bellard
#endif
5100 6af0bf9c bellard
    default:            /* Invalid */
5101 6af0bf9c bellard
        MIPS_INVAL("");
5102 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
5103 6af0bf9c bellard
        break;
5104 6af0bf9c bellard
    }
5105 4ad40f36 bellard
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5106 c53f4a62 ths
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5107 6af0bf9c bellard
        /* Branches completion */
5108 4ad40f36 bellard
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5109 6af0bf9c bellard
        ctx->bstate = BS_BRANCH;
5110 6af0bf9c bellard
        save_cpu_state(ctx, 0);
5111 6af0bf9c bellard
        switch (hflags & MIPS_HFLAG_BMASK) {
5112 6af0bf9c bellard
        case MIPS_HFLAG_B:
5113 6af0bf9c bellard
            /* unconditional branch */
5114 6af0bf9c bellard
            MIPS_DEBUG("unconditional branch");
5115 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
5116 6af0bf9c bellard
            break;
5117 6af0bf9c bellard
        case MIPS_HFLAG_BL:
5118 6af0bf9c bellard
            /* blikely taken case */
5119 6af0bf9c bellard
            MIPS_DEBUG("blikely branch taken");
5120 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
5121 6af0bf9c bellard
            break;
5122 6af0bf9c bellard
        case MIPS_HFLAG_BC:
5123 6af0bf9c bellard
            /* Conditional branch */
5124 6af0bf9c bellard
            MIPS_DEBUG("conditional branch");
5125 c53be334 bellard
            {
5126 c53be334 bellard
              int l1;
5127 c53be334 bellard
              l1 = gen_new_label();
5128 c53be334 bellard
              gen_op_jnz_T2(l1);
5129 6e256c93 bellard
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5130 eeef26cd bellard
              gen_set_label(l1);
5131 eeef26cd bellard
              gen_goto_tb(ctx, 0, ctx->btarget);
5132 c53be334 bellard
            }
5133 6af0bf9c bellard
            break;
5134 6af0bf9c bellard
        case MIPS_HFLAG_BR:
5135 6af0bf9c bellard
            /* unconditional branch to register */
5136 6af0bf9c bellard
            MIPS_DEBUG("branch to register");
5137 6af0bf9c bellard
            gen_op_breg();
5138 6af0bf9c bellard
            break;
5139 6af0bf9c bellard
        default:
5140 6af0bf9c bellard
            MIPS_DEBUG("unknown branch");
5141 6af0bf9c bellard
            break;
5142 6af0bf9c bellard
        }
5143 6af0bf9c bellard
    }
5144 6af0bf9c bellard
}
5145 6af0bf9c bellard
5146 820e00f2 ths
static inline int
5147 820e00f2 ths
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5148 820e00f2 ths
                                int search_pc)
5149 6af0bf9c bellard
{
5150 6af0bf9c bellard
    DisasContext ctx, *ctxp = &ctx;
5151 6af0bf9c bellard
    target_ulong pc_start;
5152 6af0bf9c bellard
    uint16_t *gen_opc_end;
5153 6af0bf9c bellard
    int j, lj = -1;
5154 6af0bf9c bellard
5155 4ad40f36 bellard
    if (search_pc && loglevel)
5156 6ea83fed bellard
        fprintf (logfile, "search pc %d\n", search_pc);
5157 4ad40f36 bellard
5158 6af0bf9c bellard
    pc_start = tb->pc;
5159 6af0bf9c bellard
    gen_opc_ptr = gen_opc_buf;
5160 6af0bf9c bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5161 6af0bf9c bellard
    gen_opparam_ptr = gen_opparam_buf;
5162 c53be334 bellard
    nb_gen_labels = 0;
5163 6af0bf9c bellard
    ctx.pc = pc_start;
5164 4ad40f36 bellard
    ctx.saved_pc = -1;
5165 6af0bf9c bellard
    ctx.tb = tb;
5166 6af0bf9c bellard
    ctx.bstate = BS_NONE;
5167 4ad40f36 bellard
    /* Restore delay slot state from the tb context.  */
5168 4ad40f36 bellard
    ctx.hflags = tb->flags;
5169 6af0bf9c bellard
    ctx.saved_hflags = ctx.hflags;
5170 6af0bf9c bellard
    if (ctx.hflags & MIPS_HFLAG_BR) {
5171 6af0bf9c bellard
        gen_op_restore_breg_target();
5172 6af0bf9c bellard
    } else if (ctx.hflags & MIPS_HFLAG_B) {
5173 6af0bf9c bellard
        ctx.btarget = env->btarget;
5174 6af0bf9c bellard
    } else if (ctx.hflags & MIPS_HFLAG_BMASK) {
5175 6af0bf9c bellard
        /* If we are in the delay slot of a conditional branch,
5176 6af0bf9c bellard
         * restore the branch condition from env->bcond to T2
5177 6af0bf9c bellard
         */
5178 6af0bf9c bellard
        ctx.btarget = env->btarget;
5179 6af0bf9c bellard
        gen_op_restore_bcond();
5180 6af0bf9c bellard
    }
5181 6af0bf9c bellard
#if defined(CONFIG_USER_ONLY)
5182 6af0bf9c bellard
    ctx.mem_idx = 0;
5183 6af0bf9c bellard
#else
5184 3d9fb9fe bellard
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5185 6af0bf9c bellard
#endif
5186 6af0bf9c bellard
    ctx.CP0_Status = env->CP0_Status;
5187 6af0bf9c bellard
#ifdef DEBUG_DISAS
5188 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
5189 6af0bf9c bellard
        fprintf(logfile, "------------------------------------------------\n");
5190 4ad40f36 bellard
        /* FIXME: This may print out stale hflags from env... */
5191 6af0bf9c bellard
        cpu_dump_state(env, logfile, fprintf, 0);
5192 6af0bf9c bellard
    }
5193 6af0bf9c bellard
#endif
5194 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
5195 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
5196 4ad40f36 bellard
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5197 4ad40f36 bellard
                tb, ctx.mem_idx, ctx.hflags);
5198 6af0bf9c bellard
#endif
5199 6af0bf9c bellard
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5200 4ad40f36 bellard
        if (env->nb_breakpoints > 0) {
5201 4ad40f36 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
5202 4ad40f36 bellard
                if (env->breakpoints[j] == ctx.pc) {
5203 4ad40f36 bellard
                    save_cpu_state(ctxp, 1);
5204 4ad40f36 bellard
                    ctx.bstate = BS_BRANCH;
5205 4ad40f36 bellard
                    gen_op_debug();
5206 4ad40f36 bellard
                    goto done_generating;
5207 4ad40f36 bellard
                }
5208 4ad40f36 bellard
            }
5209 4ad40f36 bellard
        }
5210 4ad40f36 bellard
5211 6af0bf9c bellard
        if (search_pc) {
5212 6af0bf9c bellard
            j = gen_opc_ptr - gen_opc_buf;
5213 6af0bf9c bellard
            if (lj < j) {
5214 6af0bf9c bellard
                lj++;
5215 6af0bf9c bellard
                while (lj < j)
5216 6af0bf9c bellard
                    gen_opc_instr_start[lj++] = 0;
5217 6af0bf9c bellard
            }
5218 4ad40f36 bellard
            gen_opc_pc[lj] = ctx.pc;
5219 4ad40f36 bellard
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5220 4ad40f36 bellard
            gen_opc_instr_start[lj] = 1;
5221 6af0bf9c bellard
        }
5222 6af0bf9c bellard
        ctx.opcode = ldl_code(ctx.pc);
5223 36d23958 ths
        decode_opc(env, &ctx);
5224 6af0bf9c bellard
        ctx.pc += 4;
5225 4ad40f36 bellard
5226 4ad40f36 bellard
        if (env->singlestep_enabled)
5227 4ad40f36 bellard
            break;
5228 4ad40f36 bellard
5229 6af0bf9c bellard
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5230 6af0bf9c bellard
            break;
5231 4ad40f36 bellard
5232 6af0bf9c bellard
#if defined (MIPS_SINGLE_STEP)
5233 6af0bf9c bellard
        break;
5234 6af0bf9c bellard
#endif
5235 6af0bf9c bellard
    }
5236 4ad40f36 bellard
    if (env->singlestep_enabled) {
5237 4ad40f36 bellard
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5238 4ad40f36 bellard
        gen_op_debug();
5239 16c00cb2 ths
    } else {
5240 16c00cb2 ths
        switch (ctx.bstate) {
5241 16c00cb2 ths
        case BS_EXCP:
5242 16c00cb2 ths
            gen_op_interrupt_restart();
5243 a85427b1 ths
            gen_op_reset_T0();
5244 a85427b1 ths
            /* Generate the return instruction. */
5245 a85427b1 ths
            gen_op_exit_tb();
5246 16c00cb2 ths
            break;
5247 16c00cb2 ths
        case BS_STOP:
5248 16c00cb2 ths
            gen_op_interrupt_restart();
5249 16c00cb2 ths
            /* Fall through. */
5250 16c00cb2 ths
        case BS_NONE:
5251 16c00cb2 ths
            save_cpu_state(ctxp, 0);
5252 16c00cb2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
5253 16c00cb2 ths
            break;
5254 16c00cb2 ths
        case BS_BRANCH:
5255 16c00cb2 ths
        default:
5256 a85427b1 ths
            gen_op_reset_T0();
5257 a85427b1 ths
            /* Generate the return instruction. */
5258 a85427b1 ths
            gen_op_exit_tb();
5259 16c00cb2 ths
            break;
5260 16c00cb2 ths
        }
5261 6af0bf9c bellard
    }
5262 4ad40f36 bellard
done_generating:
5263 6af0bf9c bellard
    *gen_opc_ptr = INDEX_op_end;
5264 6af0bf9c bellard
    if (search_pc) {
5265 6af0bf9c bellard
        j = gen_opc_ptr - gen_opc_buf;
5266 6af0bf9c bellard
        lj++;
5267 6af0bf9c bellard
        while (lj <= j)
5268 6af0bf9c bellard
            gen_opc_instr_start[lj++] = 0;
5269 6af0bf9c bellard
        tb->size = 0;
5270 6af0bf9c bellard
    } else {
5271 6af0bf9c bellard
        tb->size = ctx.pc - pc_start;
5272 6af0bf9c bellard
    }
5273 6af0bf9c bellard
#ifdef DEBUG_DISAS
5274 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
5275 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
5276 6af0bf9c bellard
        fprintf(logfile, "\n");
5277 6af0bf9c bellard
#endif
5278 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5279 6af0bf9c bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5280 9898128f ths
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5281 6af0bf9c bellard
        fprintf(logfile, "\n");
5282 6af0bf9c bellard
    }
5283 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_OP) {
5284 6af0bf9c bellard
        fprintf(logfile, "OP:\n");
5285 6af0bf9c bellard
        dump_ops(gen_opc_buf, gen_opparam_buf);
5286 6af0bf9c bellard
        fprintf(logfile, "\n");
5287 6af0bf9c bellard
    }
5288 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
5289 6af0bf9c bellard
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5290 6af0bf9c bellard
    }
5291 6af0bf9c bellard
#endif
5292 6af0bf9c bellard
    
5293 6af0bf9c bellard
    return 0;
5294 6af0bf9c bellard
}
5295 6af0bf9c bellard
5296 6af0bf9c bellard
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5297 6af0bf9c bellard
{
5298 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 0);
5299 6af0bf9c bellard
}
5300 6af0bf9c bellard
5301 6af0bf9c bellard
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5302 6af0bf9c bellard
{
5303 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 1);
5304 6af0bf9c bellard
}
5305 6af0bf9c bellard
5306 6ea83fed bellard
void fpu_dump_state(CPUState *env, FILE *f, 
5307 6ea83fed bellard
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5308 6ea83fed bellard
                    int flags)
5309 6ea83fed bellard
{
5310 6ea83fed bellard
    int i;
5311 6ea83fed bellard
5312 6ea83fed bellard
#   define printfpr(fp) do { \
5313 6ea83fed bellard
        fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
5314 6ea83fed bellard
                (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
5315 6ea83fed bellard
    } while(0)
5316 6ea83fed bellard
5317 6ea83fed bellard
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d\n",
5318 6ea83fed bellard
                env->fcr0, env->fcr31,
5319 7a387fff ths
                (env->CP0_Status & (1 << CP0St_FR)) != 0);
5320 6ea83fed bellard
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5321 6ea83fed bellard
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5322 6ea83fed bellard
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5323 7a387fff ths
    for(i = 0; i < 32; i += 2) {
5324 7a387fff ths
        fpu_fprintf(f, "%s: ", fregnames[i]);
5325 6ea83fed bellard
        printfpr(FPR(env, i));
5326 6ea83fed bellard
    }
5327 6ea83fed bellard
5328 6ea83fed bellard
#undef printfpr
5329 6ea83fed bellard
}
5330 6ea83fed bellard
5331 7a387fff ths
void dump_fpu (CPUState *env)
5332 6ea83fed bellard
{
5333 6ea83fed bellard
    if (loglevel) { 
5334 3594c774 ths
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5335 6ea83fed bellard
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5336 6ea83fed bellard
       fpu_dump_state(env, logfile, fprintf, 0);
5337 6ea83fed bellard
    }
5338 6ea83fed bellard
}
5339 6ea83fed bellard
5340 60aa19ab ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5341 c570fd16 ths
/* Debug help: The architecture requires 32bit code to maintain proper
5342 c570fd16 ths
   sign-extened values on 64bit machines.  */
5343 c570fd16 ths
5344 c570fd16 ths
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5345 c570fd16 ths
5346 c570fd16 ths
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5347 c570fd16 ths
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5348 c570fd16 ths
                     int flags)
5349 c570fd16 ths
{
5350 c570fd16 ths
    int i;
5351 c570fd16 ths
5352 c570fd16 ths
    if (!SIGN_EXT_P(env->PC))
5353 3594c774 ths
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5354 c570fd16 ths
    if (!SIGN_EXT_P(env->HI))
5355 3594c774 ths
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5356 c570fd16 ths
    if (!SIGN_EXT_P(env->LO))
5357 3594c774 ths
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5358 c570fd16 ths
    if (!SIGN_EXT_P(env->btarget))
5359 3594c774 ths
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5360 c570fd16 ths
5361 c570fd16 ths
    for (i = 0; i < 32; i++) {
5362 c570fd16 ths
        if (!SIGN_EXT_P(env->gpr[i]))
5363 3594c774 ths
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5364 c570fd16 ths
    }
5365 c570fd16 ths
5366 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_EPC))
5367 3594c774 ths
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5368 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5369 3594c774 ths
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5370 c570fd16 ths
}
5371 c570fd16 ths
#endif
5372 c570fd16 ths
5373 6af0bf9c bellard
void cpu_dump_state (CPUState *env, FILE *f, 
5374 6af0bf9c bellard
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5375 6af0bf9c bellard
                     int flags)
5376 6af0bf9c bellard
{
5377 568b600d bellard
    uint32_t c0_status;
5378 6af0bf9c bellard
    int i;
5379 6af0bf9c bellard
    
5380 3594c774 ths
    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",
5381 6af0bf9c bellard
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5382 6af0bf9c bellard
    for (i = 0; i < 32; i++) {
5383 6af0bf9c bellard
        if ((i & 3) == 0)
5384 6af0bf9c bellard
            cpu_fprintf(f, "GPR%02d:", i);
5385 3594c774 ths
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
5386 6af0bf9c bellard
        if ((i & 3) == 3)
5387 6af0bf9c bellard
            cpu_fprintf(f, "\n");
5388 6af0bf9c bellard
    }
5389 568b600d bellard
5390 568b600d bellard
    c0_status = env->CP0_Status;
5391 568b600d bellard
5392 3594c774 ths
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
5393 568b600d bellard
                c0_status, env->CP0_Cause, env->CP0_EPC);
5394 3594c774 ths
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5395 6af0bf9c bellard
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
5396 7a387fff ths
    if (c0_status & (1 << CP0St_CU1))
5397 7a387fff ths
        fpu_dump_state(env, f, cpu_fprintf, flags);
5398 60aa19ab ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5399 c570fd16 ths
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5400 c570fd16 ths
#endif
5401 6af0bf9c bellard
}
5402 6af0bf9c bellard
5403 6af0bf9c bellard
CPUMIPSState *cpu_mips_init (void)
5404 6af0bf9c bellard
{
5405 6af0bf9c bellard
    CPUMIPSState *env;
5406 6af0bf9c bellard
5407 6af0bf9c bellard
    env = qemu_mallocz(sizeof(CPUMIPSState));
5408 6af0bf9c bellard
    if (!env)
5409 6af0bf9c bellard
        return NULL;
5410 173d6cfe bellard
    cpu_exec_init(env);
5411 6ae81775 ths
    cpu_reset(env);
5412 6ae81775 ths
    return env;
5413 6ae81775 ths
}
5414 6ae81775 ths
5415 6ae81775 ths
void cpu_reset (CPUMIPSState *env)
5416 6ae81775 ths
{
5417 6ae81775 ths
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5418 6ae81775 ths
5419 6af0bf9c bellard
    tlb_flush(env, 1);
5420 6ae81775 ths
5421 6af0bf9c bellard
    /* Minimal init */
5422 ca7c2b1b ths
#if !defined(CONFIG_USER_ONLY)
5423 aa328add ths
    if (env->hflags & MIPS_HFLAG_BMASK) {
5424 aa328add ths
        /* If the exception was raised from a delay slot,
5425 aa328add ths
         * come back to the jump.  */
5426 aa328add ths
        env->CP0_ErrorEPC = env->PC - 4;
5427 aa328add ths
        env->hflags &= ~MIPS_HFLAG_BMASK;
5428 aa328add ths
    } else {
5429 aa328add ths
        env->CP0_ErrorEPC = env->PC;
5430 aa328add ths
    }
5431 24c7b0e3 ths
    env->hflags = 0;
5432 5dc4b744 ths
    env->PC = (int32_t)0xBFC00000;
5433 6af0bf9c bellard
    env->CP0_Wired = 0;
5434 7a387fff ths
    /* SMP not implemented */
5435 b29a0341 ths
    env->CP0_EBase = 0x80000000;
5436 aa328add ths
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
5437 c090a8f4 ths
    /* vectored interrupts not implemented, timer on int 7,
5438 c090a8f4 ths
       no performance counters. */
5439 c090a8f4 ths
    env->CP0_IntCtl = 0xe0000000;
5440 6af0bf9c bellard
    env->CP0_WatchLo = 0;
5441 4e7a4a4e ths
    env->CP0_WatchHi = 0;
5442 6af0bf9c bellard
    /* Count register increments in debug mode, EJTAG version 1 */
5443 6af0bf9c bellard
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
5444 ca7c2b1b ths
#endif
5445 6af0bf9c bellard
    env->exception_index = EXCP_NONE;
5446 eeef26cd bellard
#if defined(CONFIG_USER_ONLY)
5447 eeef26cd bellard
    env->hflags |= MIPS_HFLAG_UM;
5448 ca7c2b1b ths
    env->user_mode_only = 1;
5449 eeef26cd bellard
#endif
5450 6af0bf9c bellard
}
5451 33d68b5f ths
5452 33d68b5f ths
#include "translate_init.c"