Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 16c00cb2

History | View | Annotate | Download (144.3 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
        gen_op_exit_tb();
1459 6e256c93 bellard
    } else {
1460 6e256c93 bellard
        gen_op_save_pc(dest);
1461 6e256c93 bellard
        gen_op_set_T0(0);
1462 6e256c93 bellard
        gen_op_exit_tb();
1463 6e256c93 bellard
    }
1464 c53be334 bellard
}
1465 c53be334 bellard
1466 6af0bf9c bellard
/* Branches (before delay slot) */
1467 7a387fff ths
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1468 6af0bf9c bellard
                                int rs, int rt, int32_t offset)
1469 6af0bf9c bellard
{
1470 3ad4bb2d ths
    target_ulong btarget = -1;
1471 3ad4bb2d ths
    int blink = 0;
1472 3ad4bb2d ths
    int bcond = 0;
1473 3ad4bb2d ths
1474 3ad4bb2d ths
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1475 3ad4bb2d ths
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1476 3ad4bb2d ths
            fprintf(logfile,
1477 38121543 ths
                    "undefined branch in delay slot at PC " TARGET_FMT_lx "\n",
1478 38121543 ths
                    ctx->pc);
1479 3ad4bb2d ths
        }
1480 3ad4bb2d ths
        MIPS_INVAL("branch/jump in bdelay slot");
1481 3ad4bb2d ths
        generate_exception(ctx, EXCP_RI);
1482 3ad4bb2d ths
        return;
1483 3ad4bb2d ths
    }
1484 6af0bf9c bellard
1485 6af0bf9c bellard
    /* Load needed operands */
1486 6af0bf9c bellard
    switch (opc) {
1487 6af0bf9c bellard
    case OPC_BEQ:
1488 6af0bf9c bellard
    case OPC_BEQL:
1489 6af0bf9c bellard
    case OPC_BNE:
1490 6af0bf9c bellard
    case OPC_BNEL:
1491 6af0bf9c bellard
        /* Compare two registers */
1492 6af0bf9c bellard
        if (rs != rt) {
1493 6af0bf9c bellard
            GEN_LOAD_REG_TN(T0, rs);
1494 6af0bf9c bellard
            GEN_LOAD_REG_TN(T1, rt);
1495 6af0bf9c bellard
            bcond = 1;
1496 6af0bf9c bellard
        }
1497 6af0bf9c bellard
        btarget = ctx->pc + 4 + offset;
1498 6af0bf9c bellard
        break;
1499 6af0bf9c bellard
    case OPC_BGEZ:
1500 6af0bf9c bellard
    case OPC_BGEZAL:
1501 6af0bf9c bellard
    case OPC_BGEZALL:
1502 6af0bf9c bellard
    case OPC_BGEZL:
1503 6af0bf9c bellard
    case OPC_BGTZ:
1504 6af0bf9c bellard
    case OPC_BGTZL:
1505 6af0bf9c bellard
    case OPC_BLEZ:
1506 6af0bf9c bellard
    case OPC_BLEZL:
1507 6af0bf9c bellard
    case OPC_BLTZ:
1508 6af0bf9c bellard
    case OPC_BLTZAL:
1509 6af0bf9c bellard
    case OPC_BLTZALL:
1510 6af0bf9c bellard
    case OPC_BLTZL:
1511 6af0bf9c bellard
        /* Compare to zero */
1512 6af0bf9c bellard
        if (rs != 0) {
1513 6af0bf9c bellard
            gen_op_load_gpr_T0(rs);
1514 6af0bf9c bellard
            bcond = 1;
1515 6af0bf9c bellard
        }
1516 6af0bf9c bellard
        btarget = ctx->pc + 4 + offset;
1517 6af0bf9c bellard
        break;
1518 6af0bf9c bellard
    case OPC_J:
1519 6af0bf9c bellard
    case OPC_JAL:
1520 6af0bf9c bellard
        /* Jump to immediate */
1521 5dc4b744 ths
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset;
1522 6af0bf9c bellard
        break;
1523 6af0bf9c bellard
    case OPC_JR:
1524 6af0bf9c bellard
    case OPC_JALR:
1525 6af0bf9c bellard
        /* Jump to register */
1526 7a387fff ths
        if (offset != 0 && offset != 16) {
1527 7a387fff ths
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1528 cbeb0857 ths
               others are reserved. */
1529 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1530 6af0bf9c bellard
            return;
1531 6af0bf9c bellard
        }
1532 6af0bf9c bellard
        GEN_LOAD_REG_TN(T2, rs);
1533 6af0bf9c bellard
        break;
1534 6af0bf9c bellard
    default:
1535 6af0bf9c bellard
        MIPS_INVAL("branch/jump");
1536 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1537 6af0bf9c bellard
        return;
1538 6af0bf9c bellard
    }
1539 6af0bf9c bellard
    if (bcond == 0) {
1540 6af0bf9c bellard
        /* No condition to be computed */
1541 6af0bf9c bellard
        switch (opc) {
1542 6af0bf9c bellard
        case OPC_BEQ:     /* rx == rx        */
1543 6af0bf9c bellard
        case OPC_BEQL:    /* rx == rx likely */
1544 6af0bf9c bellard
        case OPC_BGEZ:    /* 0 >= 0          */
1545 6af0bf9c bellard
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1546 6af0bf9c bellard
        case OPC_BLEZ:    /* 0 <= 0          */
1547 6af0bf9c bellard
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1548 6af0bf9c bellard
            /* Always take */
1549 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1550 6af0bf9c bellard
            MIPS_DEBUG("balways");
1551 6af0bf9c bellard
            break;
1552 6af0bf9c bellard
        case OPC_BGEZAL:  /* 0 >= 0          */
1553 6af0bf9c bellard
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1554 6af0bf9c bellard
            /* Always take and link */
1555 6af0bf9c bellard
            blink = 31;
1556 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1557 6af0bf9c bellard
            MIPS_DEBUG("balways and link");
1558 6af0bf9c bellard
            break;
1559 6af0bf9c bellard
        case OPC_BNE:     /* rx != rx        */
1560 6af0bf9c bellard
        case OPC_BGTZ:    /* 0 > 0           */
1561 6af0bf9c bellard
        case OPC_BLTZ:    /* 0 < 0           */
1562 6af0bf9c bellard
            /* Treated as NOP */
1563 6af0bf9c bellard
            MIPS_DEBUG("bnever (NOP)");
1564 6af0bf9c bellard
            return;
1565 eeef26cd bellard
        case OPC_BLTZAL:  /* 0 < 0           */
1566 eeef26cd bellard
            gen_op_set_T0(ctx->pc + 8);
1567 eeef26cd bellard
            gen_op_store_T0_gpr(31);
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 e04bcc69 ths
            gen_goto_tb(ctx, 0, ctx->pc + 8);
1573 eeef26cd bellard
            return;
1574 6af0bf9c bellard
        case OPC_BNEL:    /* rx != rx likely */
1575 6af0bf9c bellard
        case OPC_BGTZL:   /* 0 > 0 likely */
1576 6af0bf9c bellard
        case OPC_BLTZL:   /* 0 < 0 likely */
1577 6af0bf9c bellard
            /* Skip the instruction in the delay slot */
1578 6af0bf9c bellard
            MIPS_DEBUG("bnever and skip");
1579 e04bcc69 ths
            gen_goto_tb(ctx, 0, ctx->pc + 8);
1580 6af0bf9c bellard
            return;
1581 6af0bf9c bellard
        case OPC_J:
1582 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1583 6af0bf9c bellard
            MIPS_DEBUG("j %08x", btarget);
1584 6af0bf9c bellard
            break;
1585 6af0bf9c bellard
        case OPC_JAL:
1586 6af0bf9c bellard
            blink = 31;
1587 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1588 6af0bf9c bellard
            MIPS_DEBUG("jal %08x", btarget);
1589 6af0bf9c bellard
            break;
1590 6af0bf9c bellard
        case OPC_JR:
1591 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
1592 6af0bf9c bellard
            MIPS_DEBUG("jr %s", regnames[rs]);
1593 6af0bf9c bellard
            break;
1594 6af0bf9c bellard
        case OPC_JALR:
1595 6af0bf9c bellard
            blink = rt;
1596 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
1597 6af0bf9c bellard
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1598 6af0bf9c bellard
            break;
1599 6af0bf9c bellard
        default:
1600 6af0bf9c bellard
            MIPS_INVAL("branch/jump");
1601 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1602 6af0bf9c bellard
            return;
1603 6af0bf9c bellard
        }
1604 6af0bf9c bellard
    } else {
1605 6af0bf9c bellard
        switch (opc) {
1606 6af0bf9c bellard
        case OPC_BEQ:
1607 6af0bf9c bellard
            gen_op_eq();
1608 6af0bf9c bellard
            MIPS_DEBUG("beq %s, %s, %08x",
1609 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1610 6af0bf9c bellard
            goto not_likely;
1611 6af0bf9c bellard
        case OPC_BEQL:
1612 6af0bf9c bellard
            gen_op_eq();
1613 6af0bf9c bellard
            MIPS_DEBUG("beql %s, %s, %08x",
1614 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1615 6af0bf9c bellard
            goto likely;
1616 6af0bf9c bellard
        case OPC_BNE:
1617 6af0bf9c bellard
            gen_op_ne();
1618 6af0bf9c bellard
            MIPS_DEBUG("bne %s, %s, %08x",
1619 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1620 6af0bf9c bellard
            goto not_likely;
1621 6af0bf9c bellard
        case OPC_BNEL:
1622 6af0bf9c bellard
            gen_op_ne();
1623 6af0bf9c bellard
            MIPS_DEBUG("bnel %s, %s, %08x",
1624 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1625 6af0bf9c bellard
            goto likely;
1626 6af0bf9c bellard
        case OPC_BGEZ:
1627 6af0bf9c bellard
            gen_op_gez();
1628 6af0bf9c bellard
            MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget);
1629 6af0bf9c bellard
            goto not_likely;
1630 6af0bf9c bellard
        case OPC_BGEZL:
1631 6af0bf9c bellard
            gen_op_gez();
1632 6af0bf9c bellard
            MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget);
1633 6af0bf9c bellard
            goto likely;
1634 6af0bf9c bellard
        case OPC_BGEZAL:
1635 6af0bf9c bellard
            gen_op_gez();
1636 6af0bf9c bellard
            MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget);
1637 6af0bf9c bellard
            blink = 31;
1638 6af0bf9c bellard
            goto not_likely;
1639 6af0bf9c bellard
        case OPC_BGEZALL:
1640 6af0bf9c bellard
            gen_op_gez();
1641 6af0bf9c bellard
            blink = 31;
1642 6af0bf9c bellard
            MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget);
1643 6af0bf9c bellard
            goto likely;
1644 6af0bf9c bellard
        case OPC_BGTZ:
1645 6af0bf9c bellard
            gen_op_gtz();
1646 6af0bf9c bellard
            MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget);
1647 6af0bf9c bellard
            goto not_likely;
1648 6af0bf9c bellard
        case OPC_BGTZL:
1649 6af0bf9c bellard
            gen_op_gtz();
1650 6af0bf9c bellard
            MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget);
1651 6af0bf9c bellard
            goto likely;
1652 6af0bf9c bellard
        case OPC_BLEZ:
1653 6af0bf9c bellard
            gen_op_lez();
1654 6af0bf9c bellard
            MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget);
1655 6af0bf9c bellard
            goto not_likely;
1656 6af0bf9c bellard
        case OPC_BLEZL:
1657 6af0bf9c bellard
            gen_op_lez();
1658 6af0bf9c bellard
            MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget);
1659 6af0bf9c bellard
            goto likely;
1660 6af0bf9c bellard
        case OPC_BLTZ:
1661 6af0bf9c bellard
            gen_op_ltz();
1662 6af0bf9c bellard
            MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget);
1663 6af0bf9c bellard
            goto not_likely;
1664 6af0bf9c bellard
        case OPC_BLTZL:
1665 6af0bf9c bellard
            gen_op_ltz();
1666 6af0bf9c bellard
            MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget);
1667 6af0bf9c bellard
            goto likely;
1668 6af0bf9c bellard
        case OPC_BLTZAL:
1669 6af0bf9c bellard
            gen_op_ltz();
1670 6af0bf9c bellard
            blink = 31;
1671 6af0bf9c bellard
            MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
1672 6af0bf9c bellard
        not_likely:
1673 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BC;
1674 6af0bf9c bellard
            break;
1675 6af0bf9c bellard
        case OPC_BLTZALL:
1676 6af0bf9c bellard
            gen_op_ltz();
1677 6af0bf9c bellard
            blink = 31;
1678 6af0bf9c bellard
            MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
1679 6af0bf9c bellard
        likely:
1680 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BL;
1681 6af0bf9c bellard
            break;
1682 c53f4a62 ths
        default:
1683 c53f4a62 ths
            MIPS_INVAL("conditional branch/jump");
1684 c53f4a62 ths
            generate_exception(ctx, EXCP_RI);
1685 c53f4a62 ths
            return;
1686 6af0bf9c bellard
        }
1687 6af0bf9c bellard
        gen_op_set_bcond();
1688 6af0bf9c bellard
    }
1689 6af0bf9c bellard
    MIPS_DEBUG("enter ds: link %d cond %02x target %08x",
1690 6af0bf9c bellard
               blink, ctx->hflags, btarget);
1691 6af0bf9c bellard
    ctx->btarget = btarget;
1692 6af0bf9c bellard
    if (blink > 0) {
1693 6af0bf9c bellard
        gen_op_set_T0(ctx->pc + 8);
1694 6af0bf9c bellard
        gen_op_store_T0_gpr(blink);
1695 6af0bf9c bellard
    }
1696 6af0bf9c bellard
}
1697 6af0bf9c bellard
1698 7a387fff ths
/* special3 bitfield operations */
1699 7a387fff ths
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1700 7a387fff ths
                       int rs, int lsb, int msb)
1701 7a387fff ths
{
1702 7a387fff ths
    GEN_LOAD_REG_TN(T1, rs);
1703 7a387fff ths
    switch (opc) {
1704 7a387fff ths
    case OPC_EXT:
1705 7a387fff ths
        if (lsb + msb > 31)
1706 7a387fff ths
            goto fail;
1707 7a387fff ths
        gen_op_ext(lsb, msb + 1);
1708 7a387fff ths
        break;
1709 7a387fff ths
    case OPC_DEXTM:
1710 7a387fff ths
        if (lsb + msb > 63)
1711 7a387fff ths
            goto fail;
1712 7a387fff ths
        gen_op_ext(lsb, msb + 1 + 32);
1713 7a387fff ths
        break;
1714 7a387fff ths
    case OPC_DEXTU:
1715 7a387fff ths
        if (lsb + msb > 63)
1716 7a387fff ths
            goto fail;
1717 7a387fff ths
        gen_op_ext(lsb + 32, msb + 1);
1718 7a387fff ths
        break;
1719 7a387fff ths
    case OPC_DEXT:
1720 7a387fff ths
        gen_op_ext(lsb, msb + 1);
1721 7a387fff ths
        break;
1722 7a387fff ths
    case OPC_INS:
1723 7a387fff ths
        if (lsb > msb)
1724 7a387fff ths
            goto fail;
1725 7a387fff ths
        GEN_LOAD_REG_TN(T2, rt);
1726 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1);
1727 7a387fff ths
        break;
1728 7a387fff ths
    case OPC_DINSM:
1729 7a387fff ths
        if (lsb > msb)
1730 7a387fff ths
            goto fail;
1731 7a387fff ths
        GEN_LOAD_REG_TN(T2, rt);
1732 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1733 7a387fff ths
        break;
1734 7a387fff ths
    case OPC_DINSU:
1735 7a387fff ths
        if (lsb > msb)
1736 7a387fff ths
            goto fail;
1737 7a387fff ths
        GEN_LOAD_REG_TN(T2, rt);
1738 7a387fff ths
        gen_op_ins(lsb + 32, msb - lsb + 1);
1739 7a387fff ths
        break;
1740 7a387fff ths
    case OPC_DINS:
1741 7a387fff ths
        if (lsb > msb)
1742 7a387fff ths
            goto fail;
1743 7a387fff ths
        GEN_LOAD_REG_TN(T2, rt);
1744 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1);
1745 7a387fff ths
        break;
1746 7a387fff ths
    default:
1747 7a387fff ths
fail:
1748 7a387fff ths
        MIPS_INVAL("bitops");
1749 7a387fff ths
        generate_exception(ctx, EXCP_RI);
1750 7a387fff ths
        return;
1751 7a387fff ths
    }
1752 7a387fff ths
    GEN_STORE_TN_REG(rt, T0);
1753 7a387fff ths
}
1754 7a387fff ths
1755 6af0bf9c bellard
/* CP0 (MMU and control) */
1756 873eb012 ths
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1757 873eb012 ths
{
1758 7a387fff ths
    const char *rn = "invalid";
1759 873eb012 ths
1760 873eb012 ths
    switch (reg) {
1761 873eb012 ths
    case 0:
1762 7a387fff ths
        switch (sel) {
1763 7a387fff ths
        case 0:
1764 2423f660 ths
            gen_op_mfc0_index();
1765 7a387fff ths
            rn = "Index";
1766 7a387fff ths
            break;
1767 7a387fff ths
        case 1:
1768 2423f660 ths
//            gen_op_mfc0_mvpcontrol(); /* MT ASE */
1769 7a387fff ths
            rn = "MVPControl";
1770 2423f660 ths
//            break;
1771 7a387fff ths
        case 2:
1772 2423f660 ths
//            gen_op_mfc0_mvpconf0(); /* MT ASE */
1773 7a387fff ths
            rn = "MVPConf0";
1774 2423f660 ths
//            break;
1775 7a387fff ths
        case 3:
1776 2423f660 ths
//            gen_op_mfc0_mvpconf1(); /* MT ASE */
1777 7a387fff ths
            rn = "MVPConf1";
1778 2423f660 ths
//            break;
1779 7a387fff ths
        default:
1780 7a387fff ths
            goto die;
1781 7a387fff ths
        }
1782 873eb012 ths
        break;
1783 873eb012 ths
    case 1:
1784 7a387fff ths
        switch (sel) {
1785 7a387fff ths
        case 0:
1786 7a387fff ths
            gen_op_mfc0_random();
1787 7a387fff ths
            rn = "Random";
1788 2423f660 ths
            break;
1789 7a387fff ths
        case 1:
1790 2423f660 ths
//            gen_op_mfc0_vpecontrol(); /* MT ASE */
1791 7a387fff ths
            rn = "VPEControl";
1792 2423f660 ths
//            break;
1793 7a387fff ths
        case 2:
1794 2423f660 ths
//            gen_op_mfc0_vpeconf0(); /* MT ASE */
1795 7a387fff ths
            rn = "VPEConf0";
1796 2423f660 ths
//            break;
1797 7a387fff ths
        case 3:
1798 2423f660 ths
//            gen_op_mfc0_vpeconf1(); /* MT ASE */
1799 7a387fff ths
            rn = "VPEConf1";
1800 2423f660 ths
//            break;
1801 7a387fff ths
        case 4:
1802 2423f660 ths
//            gen_op_mfc0_YQMask(); /* MT ASE */
1803 7a387fff ths
            rn = "YQMask";
1804 2423f660 ths
//            break;
1805 7a387fff ths
        case 5:
1806 2423f660 ths
//            gen_op_mfc0_vpeschedule(); /* MT ASE */
1807 7a387fff ths
            rn = "VPESchedule";
1808 2423f660 ths
//            break;
1809 7a387fff ths
        case 6:
1810 2423f660 ths
//            gen_op_mfc0_vpeschefback(); /* MT ASE */
1811 7a387fff ths
            rn = "VPEScheFBack";
1812 2423f660 ths
//            break;
1813 7a387fff ths
        case 7:
1814 2423f660 ths
//            gen_op_mfc0_vpeopt(); /* MT ASE */
1815 7a387fff ths
            rn = "VPEOpt";
1816 2423f660 ths
//            break;
1817 7a387fff ths
        default:
1818 7a387fff ths
            goto die;
1819 7a387fff ths
        }
1820 873eb012 ths
        break;
1821 873eb012 ths
    case 2:
1822 7a387fff ths
        switch (sel) {
1823 7a387fff ths
        case 0:
1824 2423f660 ths
            gen_op_mfc0_entrylo0();
1825 2423f660 ths
            rn = "EntryLo0";
1826 2423f660 ths
            break;
1827 7a387fff ths
        case 1:
1828 2423f660 ths
//            gen_op_mfc0_tcstatus(); /* MT ASE */
1829 2423f660 ths
            rn = "TCStatus";
1830 2423f660 ths
//            break;
1831 7a387fff ths
        case 2:
1832 2423f660 ths
//            gen_op_mfc0_tcbind(); /* MT ASE */
1833 2423f660 ths
            rn = "TCBind";
1834 2423f660 ths
//            break;
1835 7a387fff ths
        case 3:
1836 2423f660 ths
//            gen_op_mfc0_tcrestart(); /* MT ASE */
1837 2423f660 ths
            rn = "TCRestart";
1838 2423f660 ths
//            break;
1839 7a387fff ths
        case 4:
1840 2423f660 ths
//            gen_op_mfc0_tchalt(); /* MT ASE */
1841 2423f660 ths
            rn = "TCHalt";
1842 2423f660 ths
//            break;
1843 7a387fff ths
        case 5:
1844 2423f660 ths
//            gen_op_mfc0_tccontext(); /* MT ASE */
1845 2423f660 ths
            rn = "TCContext";
1846 2423f660 ths
//            break;
1847 7a387fff ths
        case 6:
1848 2423f660 ths
//            gen_op_mfc0_tcschedule(); /* MT ASE */
1849 2423f660 ths
            rn = "TCSchedule";
1850 2423f660 ths
//            break;
1851 7a387fff ths
        case 7:
1852 2423f660 ths
//            gen_op_mfc0_tcschefback(); /* MT ASE */
1853 2423f660 ths
            rn = "TCScheFBack";
1854 2423f660 ths
//            break;
1855 7a387fff ths
        default:
1856 7a387fff ths
            goto die;
1857 7a387fff ths
        }
1858 873eb012 ths
        break;
1859 873eb012 ths
    case 3:
1860 7a387fff ths
        switch (sel) {
1861 7a387fff ths
        case 0:
1862 2423f660 ths
            gen_op_mfc0_entrylo1();
1863 2423f660 ths
            rn = "EntryLo1";
1864 2423f660 ths
            break;
1865 7a387fff ths
        default:
1866 7a387fff ths
            goto die;
1867 1579a72e ths
        }
1868 873eb012 ths
        break;
1869 873eb012 ths
    case 4:
1870 7a387fff ths
        switch (sel) {
1871 7a387fff ths
        case 0:
1872 2423f660 ths
            gen_op_mfc0_context();
1873 2423f660 ths
            rn = "Context";
1874 2423f660 ths
            break;
1875 7a387fff ths
        case 1:
1876 2423f660 ths
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
1877 2423f660 ths
            rn = "ContextConfig";
1878 2423f660 ths
//            break;
1879 7a387fff ths
        default:
1880 7a387fff ths
            goto die;
1881 1579a72e ths
        }
1882 873eb012 ths
        break;
1883 873eb012 ths
    case 5:
1884 7a387fff ths
        switch (sel) {
1885 7a387fff ths
        case 0:
1886 2423f660 ths
            gen_op_mfc0_pagemask();
1887 2423f660 ths
            rn = "PageMask";
1888 2423f660 ths
            break;
1889 7a387fff ths
        case 1:
1890 2423f660 ths
            gen_op_mfc0_pagegrain();
1891 2423f660 ths
            rn = "PageGrain";
1892 2423f660 ths
            break;
1893 7a387fff ths
        default:
1894 7a387fff ths
            goto die;
1895 1579a72e ths
        }
1896 873eb012 ths
        break;
1897 873eb012 ths
    case 6:
1898 7a387fff ths
        switch (sel) {
1899 7a387fff ths
        case 0:
1900 2423f660 ths
            gen_op_mfc0_wired();
1901 2423f660 ths
            rn = "Wired";
1902 2423f660 ths
            break;
1903 7a387fff ths
        case 1:
1904 2423f660 ths
//            gen_op_mfc0_srsconf0(); /* shadow registers */
1905 2423f660 ths
            rn = "SRSConf0";
1906 2423f660 ths
//            break;
1907 7a387fff ths
        case 2:
1908 2423f660 ths
//            gen_op_mfc0_srsconf1(); /* shadow registers */
1909 2423f660 ths
            rn = "SRSConf1";
1910 2423f660 ths
//            break;
1911 7a387fff ths
        case 3:
1912 2423f660 ths
//            gen_op_mfc0_srsconf2(); /* shadow registers */
1913 2423f660 ths
            rn = "SRSConf2";
1914 2423f660 ths
//            break;
1915 7a387fff ths
        case 4:
1916 2423f660 ths
//            gen_op_mfc0_srsconf3(); /* shadow registers */
1917 2423f660 ths
            rn = "SRSConf3";
1918 2423f660 ths
//            break;
1919 7a387fff ths
        case 5:
1920 2423f660 ths
//            gen_op_mfc0_srsconf4(); /* shadow registers */
1921 2423f660 ths
            rn = "SRSConf4";
1922 2423f660 ths
//            break;
1923 7a387fff ths
        default:
1924 7a387fff ths
            goto die;
1925 1579a72e ths
        }
1926 873eb012 ths
        break;
1927 8c0fdd85 ths
    case 7:
1928 7a387fff ths
        switch (sel) {
1929 7a387fff ths
        case 0:
1930 2423f660 ths
            gen_op_mfc0_hwrena();
1931 2423f660 ths
            rn = "HWREna";
1932 2423f660 ths
            break;
1933 7a387fff ths
        default:
1934 7a387fff ths
            goto die;
1935 1579a72e ths
        }
1936 8c0fdd85 ths
        break;
1937 873eb012 ths
    case 8:
1938 7a387fff ths
        switch (sel) {
1939 7a387fff ths
        case 0:
1940 2423f660 ths
            gen_op_mfc0_badvaddr();
1941 2423f660 ths
            rn = "BadVaddr";
1942 2423f660 ths
            break;
1943 7a387fff ths
        default:
1944 7a387fff ths
            goto die;
1945 7a387fff ths
       }
1946 873eb012 ths
        break;
1947 873eb012 ths
    case 9:
1948 7a387fff ths
        switch (sel) {
1949 7a387fff ths
        case 0:
1950 2423f660 ths
            gen_op_mfc0_count();
1951 2423f660 ths
            rn = "Count";
1952 2423f660 ths
            break;
1953 2423f660 ths
        /* 6,7 are implementation dependent */
1954 7a387fff ths
        default:
1955 7a387fff ths
            goto die;
1956 2423f660 ths
        }
1957 873eb012 ths
        break;
1958 873eb012 ths
    case 10:
1959 7a387fff ths
        switch (sel) {
1960 7a387fff ths
        case 0:
1961 2423f660 ths
            gen_op_mfc0_entryhi();
1962 2423f660 ths
            rn = "EntryHi";
1963 2423f660 ths
            break;
1964 7a387fff ths
        default:
1965 7a387fff ths
            goto die;
1966 1579a72e ths
        }
1967 873eb012 ths
        break;
1968 873eb012 ths
    case 11:
1969 7a387fff ths
        switch (sel) {
1970 7a387fff ths
        case 0:
1971 2423f660 ths
            gen_op_mfc0_compare();
1972 2423f660 ths
            rn = "Compare";
1973 2423f660 ths
            break;
1974 2423f660 ths
        /* 6,7 are implementation dependent */
1975 7a387fff ths
        default:
1976 7a387fff ths
            goto die;
1977 2423f660 ths
        }
1978 873eb012 ths
        break;
1979 873eb012 ths
    case 12:
1980 7a387fff ths
        switch (sel) {
1981 7a387fff ths
        case 0:
1982 2423f660 ths
            gen_op_mfc0_status();
1983 2423f660 ths
            rn = "Status";
1984 2423f660 ths
            break;
1985 7a387fff ths
        case 1:
1986 2423f660 ths
            gen_op_mfc0_intctl();
1987 2423f660 ths
            rn = "IntCtl";
1988 2423f660 ths
            break;
1989 7a387fff ths
        case 2:
1990 2423f660 ths
            gen_op_mfc0_srsctl();
1991 2423f660 ths
            rn = "SRSCtl";
1992 2423f660 ths
            break;
1993 7a387fff ths
        case 3:
1994 2423f660 ths
//            gen_op_mfc0_srsmap(); /* shadow registers */
1995 2423f660 ths
            rn = "SRSMap";
1996 2423f660 ths
//            break;
1997 7a387fff ths
        default:
1998 7a387fff ths
            goto die;
1999 7a387fff ths
       }
2000 873eb012 ths
        break;
2001 873eb012 ths
    case 13:
2002 7a387fff ths
        switch (sel) {
2003 7a387fff ths
        case 0:
2004 2423f660 ths
            gen_op_mfc0_cause();
2005 2423f660 ths
            rn = "Cause";
2006 2423f660 ths
            break;
2007 7a387fff ths
        default:
2008 7a387fff ths
            goto die;
2009 7a387fff ths
       }
2010 873eb012 ths
        break;
2011 873eb012 ths
    case 14:
2012 7a387fff ths
        switch (sel) {
2013 7a387fff ths
        case 0:
2014 2423f660 ths
            gen_op_mfc0_epc();
2015 2423f660 ths
            rn = "EPC";
2016 2423f660 ths
            break;
2017 7a387fff ths
        default:
2018 7a387fff ths
            goto die;
2019 1579a72e ths
        }
2020 873eb012 ths
        break;
2021 873eb012 ths
    case 15:
2022 7a387fff ths
        switch (sel) {
2023 7a387fff ths
        case 0:
2024 2423f660 ths
            gen_op_mfc0_prid();
2025 2423f660 ths
            rn = "PRid";
2026 2423f660 ths
            break;
2027 7a387fff ths
        case 1:
2028 2423f660 ths
            gen_op_mfc0_ebase();
2029 2423f660 ths
            rn = "EBase";
2030 2423f660 ths
            break;
2031 7a387fff ths
        default:
2032 7a387fff ths
            goto die;
2033 7a387fff ths
       }
2034 873eb012 ths
        break;
2035 873eb012 ths
    case 16:
2036 873eb012 ths
        switch (sel) {
2037 873eb012 ths
        case 0:
2038 e397ee33 ths
            gen_op_mfc0_config0();
2039 873eb012 ths
            rn = "Config";
2040 873eb012 ths
            break;
2041 873eb012 ths
        case 1:
2042 e397ee33 ths
            gen_op_mfc0_config1();
2043 873eb012 ths
            rn = "Config1";
2044 873eb012 ths
            break;
2045 7a387fff ths
        case 2:
2046 e397ee33 ths
            gen_op_mfc0_config2();
2047 7a387fff ths
            rn = "Config2";
2048 7a387fff ths
            break;
2049 7a387fff ths
        case 3:
2050 e397ee33 ths
            gen_op_mfc0_config3();
2051 7a387fff ths
            rn = "Config3";
2052 7a387fff ths
            break;
2053 e397ee33 ths
        /* 4,5 are reserved */
2054 e397ee33 ths
        /* 6,7 are implementation dependent */
2055 e397ee33 ths
        case 6:
2056 e397ee33 ths
            gen_op_mfc0_config6();
2057 e397ee33 ths
            rn = "Config6";
2058 e397ee33 ths
            break;
2059 e397ee33 ths
        case 7:
2060 e397ee33 ths
            gen_op_mfc0_config7();
2061 e397ee33 ths
            rn = "Config7";
2062 e397ee33 ths
            break;
2063 873eb012 ths
        default:
2064 873eb012 ths
            goto die;
2065 873eb012 ths
        }
2066 873eb012 ths
        break;
2067 873eb012 ths
    case 17:
2068 7a387fff ths
        switch (sel) {
2069 7a387fff ths
        case 0:
2070 2423f660 ths
            gen_op_mfc0_lladdr();
2071 2423f660 ths
            rn = "LLAddr";
2072 2423f660 ths
            break;
2073 7a387fff ths
        default:
2074 7a387fff ths
            goto die;
2075 7a387fff ths
        }
2076 873eb012 ths
        break;
2077 873eb012 ths
    case 18:
2078 7a387fff ths
        switch (sel) {
2079 7a387fff ths
        case 0:
2080 2423f660 ths
            gen_op_mfc0_watchlo0();
2081 2423f660 ths
            rn = "WatchLo";
2082 2423f660 ths
            break;
2083 7a387fff ths
        case 1:
2084 2423f660 ths
//            gen_op_mfc0_watchlo1();
2085 2423f660 ths
            rn = "WatchLo1";
2086 2423f660 ths
//            break;
2087 7a387fff ths
        case 2:
2088 2423f660 ths
//            gen_op_mfc0_watchlo2();
2089 2423f660 ths
            rn = "WatchLo2";
2090 2423f660 ths
//            break;
2091 7a387fff ths
        case 3:
2092 2423f660 ths
//            gen_op_mfc0_watchlo3();
2093 2423f660 ths
            rn = "WatchLo3";
2094 2423f660 ths
//            break;
2095 7a387fff ths
        case 4:
2096 2423f660 ths
//            gen_op_mfc0_watchlo4();
2097 2423f660 ths
            rn = "WatchLo4";
2098 2423f660 ths
//            break;
2099 7a387fff ths
        case 5:
2100 2423f660 ths
//            gen_op_mfc0_watchlo5();
2101 2423f660 ths
            rn = "WatchLo5";
2102 2423f660 ths
//            break;
2103 7a387fff ths
        case 6:
2104 2423f660 ths
//            gen_op_mfc0_watchlo6();
2105 2423f660 ths
            rn = "WatchLo6";
2106 2423f660 ths
//            break;
2107 7a387fff ths
        case 7:
2108 2423f660 ths
//            gen_op_mfc0_watchlo7();
2109 2423f660 ths
            rn = "WatchLo7";
2110 2423f660 ths
//            break;
2111 7a387fff ths
        default:
2112 7a387fff ths
            goto die;
2113 7a387fff ths
        }
2114 873eb012 ths
        break;
2115 873eb012 ths
    case 19:
2116 7a387fff ths
        switch (sel) {
2117 7a387fff ths
        case 0:
2118 2423f660 ths
            gen_op_mfc0_watchhi0();
2119 2423f660 ths
            rn = "WatchHi";
2120 2423f660 ths
            break;
2121 7a387fff ths
        case 1:
2122 2423f660 ths
//            gen_op_mfc0_watchhi1();
2123 2423f660 ths
            rn = "WatchHi1";
2124 2423f660 ths
//            break;
2125 7a387fff ths
        case 2:
2126 2423f660 ths
//            gen_op_mfc0_watchhi2();
2127 2423f660 ths
            rn = "WatchHi2";
2128 2423f660 ths
//            break;
2129 7a387fff ths
        case 3:
2130 2423f660 ths
//            gen_op_mfc0_watchhi3();
2131 2423f660 ths
            rn = "WatchHi3";
2132 2423f660 ths
//            break;
2133 7a387fff ths
        case 4:
2134 2423f660 ths
//            gen_op_mfc0_watchhi4();
2135 2423f660 ths
            rn = "WatchHi4";
2136 2423f660 ths
//            break;
2137 7a387fff ths
        case 5:
2138 2423f660 ths
//            gen_op_mfc0_watchhi5();
2139 2423f660 ths
            rn = "WatchHi5";
2140 2423f660 ths
//            break;
2141 7a387fff ths
        case 6:
2142 2423f660 ths
//            gen_op_mfc0_watchhi6();
2143 2423f660 ths
            rn = "WatchHi6";
2144 2423f660 ths
//            break;
2145 7a387fff ths
        case 7:
2146 2423f660 ths
//            gen_op_mfc0_watchhi7();
2147 2423f660 ths
            rn = "WatchHi7";
2148 2423f660 ths
//            break;
2149 7a387fff ths
        default:
2150 7a387fff ths
            goto die;
2151 7a387fff ths
        }
2152 873eb012 ths
        break;
2153 8c0fdd85 ths
    case 20:
2154 7a387fff ths
        switch (sel) {
2155 7a387fff ths
        case 0:
2156 2423f660 ths
            /* 64 bit MMU only */
2157 2423f660 ths
            gen_op_mfc0_xcontext();
2158 2423f660 ths
            rn = "XContext";
2159 2423f660 ths
            break;
2160 7a387fff ths
        default:
2161 7a387fff ths
            goto die;
2162 7a387fff ths
        }
2163 8c0fdd85 ths
        break;
2164 8c0fdd85 ths
    case 21:
2165 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2166 7a387fff ths
        switch (sel) {
2167 7a387fff ths
        case 0:
2168 2423f660 ths
            gen_op_mfc0_framemask();
2169 2423f660 ths
            rn = "Framemask";
2170 2423f660 ths
            break;
2171 7a387fff ths
        default:
2172 7a387fff ths
            goto die;
2173 7a387fff ths
        }
2174 8c0fdd85 ths
        break;
2175 8c0fdd85 ths
    case 22:
2176 2423f660 ths
        /* ignored */
2177 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
2178 2423f660 ths
        break;
2179 873eb012 ths
    case 23:
2180 7a387fff ths
        switch (sel) {
2181 7a387fff ths
        case 0:
2182 2423f660 ths
            gen_op_mfc0_debug(); /* EJTAG support */
2183 2423f660 ths
            rn = "Debug";
2184 2423f660 ths
            break;
2185 7a387fff ths
        case 1:
2186 2423f660 ths
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2187 2423f660 ths
            rn = "TraceControl";
2188 2423f660 ths
//            break;
2189 7a387fff ths
        case 2:
2190 2423f660 ths
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2191 2423f660 ths
            rn = "TraceControl2";
2192 2423f660 ths
//            break;
2193 7a387fff ths
        case 3:
2194 2423f660 ths
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2195 2423f660 ths
            rn = "UserTraceData";
2196 2423f660 ths
//            break;
2197 7a387fff ths
        case 4:
2198 2423f660 ths
//            gen_op_mfc0_debug(); /* PDtrace support */
2199 2423f660 ths
            rn = "TraceBPC";
2200 2423f660 ths
//            break;
2201 7a387fff ths
        default:
2202 7a387fff ths
            goto die;
2203 7a387fff ths
        }
2204 873eb012 ths
        break;
2205 873eb012 ths
    case 24:
2206 7a387fff ths
        switch (sel) {
2207 7a387fff ths
        case 0:
2208 2423f660 ths
            gen_op_mfc0_depc(); /* EJTAG support */
2209 2423f660 ths
            rn = "DEPC";
2210 2423f660 ths
            break;
2211 7a387fff ths
        default:
2212 7a387fff ths
            goto die;
2213 7a387fff ths
        }
2214 873eb012 ths
        break;
2215 8c0fdd85 ths
    case 25:
2216 7a387fff ths
        switch (sel) {
2217 7a387fff ths
        case 0:
2218 2423f660 ths
            gen_op_mfc0_performance0();
2219 2423f660 ths
            rn = "Performance0";
2220 7a387fff ths
            break;
2221 7a387fff ths
        case 1:
2222 2423f660 ths
//            gen_op_mfc0_performance1();
2223 2423f660 ths
            rn = "Performance1";
2224 2423f660 ths
//            break;
2225 7a387fff ths
        case 2:
2226 2423f660 ths
//            gen_op_mfc0_performance2();
2227 2423f660 ths
            rn = "Performance2";
2228 2423f660 ths
//            break;
2229 7a387fff ths
        case 3:
2230 2423f660 ths
//            gen_op_mfc0_performance3();
2231 2423f660 ths
            rn = "Performance3";
2232 2423f660 ths
//            break;
2233 7a387fff ths
        case 4:
2234 2423f660 ths
//            gen_op_mfc0_performance4();
2235 2423f660 ths
            rn = "Performance4";
2236 2423f660 ths
//            break;
2237 7a387fff ths
        case 5:
2238 2423f660 ths
//            gen_op_mfc0_performance5();
2239 2423f660 ths
            rn = "Performance5";
2240 2423f660 ths
//            break;
2241 7a387fff ths
        case 6:
2242 2423f660 ths
//            gen_op_mfc0_performance6();
2243 2423f660 ths
            rn = "Performance6";
2244 2423f660 ths
//            break;
2245 7a387fff ths
        case 7:
2246 2423f660 ths
//            gen_op_mfc0_performance7();
2247 2423f660 ths
            rn = "Performance7";
2248 2423f660 ths
//            break;
2249 7a387fff ths
        default:
2250 7a387fff ths
            goto die;
2251 7a387fff ths
        }
2252 8c0fdd85 ths
        break;
2253 8c0fdd85 ths
    case 26:
2254 7a387fff ths
       rn = "ECC";
2255 7a387fff ths
       break;
2256 8c0fdd85 ths
    case 27:
2257 7a387fff ths
        switch (sel) {
2258 7a387fff ths
        /* ignored */
2259 7a387fff ths
        case 0 ... 3:
2260 2423f660 ths
            rn = "CacheErr";
2261 2423f660 ths
            break;
2262 7a387fff ths
        default:
2263 7a387fff ths
            goto die;
2264 7a387fff ths
        }
2265 8c0fdd85 ths
        break;
2266 873eb012 ths
    case 28:
2267 873eb012 ths
        switch (sel) {
2268 873eb012 ths
        case 0:
2269 7a387fff ths
        case 2:
2270 7a387fff ths
        case 4:
2271 7a387fff ths
        case 6:
2272 873eb012 ths
            gen_op_mfc0_taglo();
2273 873eb012 ths
            rn = "TagLo";
2274 873eb012 ths
            break;
2275 873eb012 ths
        case 1:
2276 7a387fff ths
        case 3:
2277 7a387fff ths
        case 5:
2278 7a387fff ths
        case 7:
2279 873eb012 ths
            gen_op_mfc0_datalo();
2280 873eb012 ths
            rn = "DataLo";
2281 873eb012 ths
            break;
2282 873eb012 ths
        default:
2283 873eb012 ths
            goto die;
2284 873eb012 ths
        }
2285 873eb012 ths
        break;
2286 8c0fdd85 ths
    case 29:
2287 7a387fff ths
        switch (sel) {
2288 7a387fff ths
        case 0:
2289 7a387fff ths
        case 2:
2290 7a387fff ths
        case 4:
2291 7a387fff ths
        case 6:
2292 7a387fff ths
            gen_op_mfc0_taghi();
2293 7a387fff ths
            rn = "TagHi";
2294 7a387fff ths
            break;
2295 7a387fff ths
        case 1:
2296 7a387fff ths
        case 3:
2297 7a387fff ths
        case 5:
2298 7a387fff ths
        case 7:
2299 7a387fff ths
            gen_op_mfc0_datahi();
2300 7a387fff ths
            rn = "DataHi";
2301 7a387fff ths
            break;
2302 7a387fff ths
        default:
2303 7a387fff ths
            goto die;
2304 7a387fff ths
        }
2305 8c0fdd85 ths
        break;
2306 873eb012 ths
    case 30:
2307 7a387fff ths
        switch (sel) {
2308 7a387fff ths
        case 0:
2309 2423f660 ths
            gen_op_mfc0_errorepc();
2310 2423f660 ths
            rn = "ErrorEPC";
2311 2423f660 ths
            break;
2312 7a387fff ths
        default:
2313 7a387fff ths
            goto die;
2314 7a387fff ths
        }
2315 873eb012 ths
        break;
2316 873eb012 ths
    case 31:
2317 7a387fff ths
        switch (sel) {
2318 7a387fff ths
        case 0:
2319 2423f660 ths
            gen_op_mfc0_desave(); /* EJTAG support */
2320 2423f660 ths
            rn = "DESAVE";
2321 2423f660 ths
            break;
2322 7a387fff ths
        default:
2323 7a387fff ths
            goto die;
2324 7a387fff ths
        }
2325 873eb012 ths
        break;
2326 873eb012 ths
    default:
2327 873eb012 ths
       goto die;
2328 873eb012 ths
    }
2329 873eb012 ths
#if defined MIPS_DEBUG_DISAS
2330 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2331 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2332 7a387fff ths
                rn, reg, sel);
2333 873eb012 ths
    }
2334 873eb012 ths
#endif
2335 873eb012 ths
    return;
2336 873eb012 ths
2337 873eb012 ths
die:
2338 873eb012 ths
#if defined MIPS_DEBUG_DISAS
2339 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2340 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2341 7a387fff ths
                rn, reg, sel);
2342 873eb012 ths
    }
2343 873eb012 ths
#endif
2344 873eb012 ths
    generate_exception(ctx, EXCP_RI);
2345 873eb012 ths
}
2346 873eb012 ths
2347 8c0fdd85 ths
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2348 8c0fdd85 ths
{
2349 7a387fff ths
    const char *rn = "invalid";
2350 7a387fff ths
2351 8c0fdd85 ths
    switch (reg) {
2352 8c0fdd85 ths
    case 0:
2353 7a387fff ths
        switch (sel) {
2354 7a387fff ths
        case 0:
2355 7a387fff ths
           gen_op_mtc0_index();
2356 7a387fff ths
            rn = "Index";
2357 7a387fff ths
            break;
2358 7a387fff ths
        case 1:
2359 2423f660 ths
//            gen_op_mtc0_mvpcontrol(); /* MT ASE */
2360 7a387fff ths
            rn = "MVPControl";
2361 2423f660 ths
//            break;
2362 7a387fff ths
        case 2:
2363 2423f660 ths
//            gen_op_mtc0_mvpconf0(); /* MT ASE */
2364 7a387fff ths
            rn = "MVPConf0";
2365 2423f660 ths
//            break;
2366 7a387fff ths
        case 3:
2367 2423f660 ths
//            gen_op_mtc0_mvpconf1(); /* MT ASE */
2368 7a387fff ths
            rn = "MVPConf1";
2369 2423f660 ths
//            break;
2370 7a387fff ths
        default:
2371 7a387fff ths
            goto die;
2372 7a387fff ths
        }
2373 8c0fdd85 ths
        break;
2374 8c0fdd85 ths
    case 1:
2375 7a387fff ths
        switch (sel) {
2376 7a387fff ths
        case 0:
2377 2423f660 ths
            /* ignored */
2378 7a387fff ths
            rn = "Random";
2379 2423f660 ths
            break;
2380 7a387fff ths
        case 1:
2381 2423f660 ths
//            gen_op_mtc0_vpecontrol(); /* MT ASE */
2382 7a387fff ths
            rn = "VPEControl";
2383 2423f660 ths
//            break;
2384 7a387fff ths
        case 2:
2385 2423f660 ths
//            gen_op_mtc0_vpeconf0(); /* MT ASE */
2386 7a387fff ths
            rn = "VPEConf0";
2387 2423f660 ths
//            break;
2388 7a387fff ths
        case 3:
2389 2423f660 ths
//            gen_op_mtc0_vpeconf1(); /* MT ASE */
2390 7a387fff ths
            rn = "VPEConf1";
2391 2423f660 ths
//            break;
2392 7a387fff ths
        case 4:
2393 2423f660 ths
//            gen_op_mtc0_YQMask(); /* MT ASE */
2394 7a387fff ths
            rn = "YQMask";
2395 2423f660 ths
//            break;
2396 7a387fff ths
        case 5:
2397 2423f660 ths
//            gen_op_mtc0_vpeschedule(); /* MT ASE */
2398 7a387fff ths
            rn = "VPESchedule";
2399 2423f660 ths
//            break;
2400 7a387fff ths
        case 6:
2401 2423f660 ths
//            gen_op_mtc0_vpeschefback(); /* MT ASE */
2402 7a387fff ths
            rn = "VPEScheFBack";
2403 2423f660 ths
//            break;
2404 7a387fff ths
        case 7:
2405 2423f660 ths
//            gen_op_mtc0_vpeopt(); /* MT ASE */
2406 7a387fff ths
            rn = "VPEOpt";
2407 2423f660 ths
//            break;
2408 7a387fff ths
        default:
2409 7a387fff ths
            goto die;
2410 7a387fff ths
        }
2411 8c0fdd85 ths
        break;
2412 8c0fdd85 ths
    case 2:
2413 7a387fff ths
        switch (sel) {
2414 7a387fff ths
        case 0:
2415 2423f660 ths
            gen_op_mtc0_entrylo0();
2416 2423f660 ths
            rn = "EntryLo0";
2417 2423f660 ths
            break;
2418 7a387fff ths
        case 1:
2419 2423f660 ths
//            gen_op_mtc0_tcstatus(); /* MT ASE */
2420 2423f660 ths
            rn = "TCStatus";
2421 2423f660 ths
//            break;
2422 7a387fff ths
        case 2:
2423 2423f660 ths
//            gen_op_mtc0_tcbind(); /* MT ASE */
2424 2423f660 ths
            rn = "TCBind";
2425 2423f660 ths
//            break;
2426 7a387fff ths
        case 3:
2427 2423f660 ths
//            gen_op_mtc0_tcrestart(); /* MT ASE */
2428 2423f660 ths
            rn = "TCRestart";
2429 2423f660 ths
//            break;
2430 7a387fff ths
        case 4:
2431 2423f660 ths
//            gen_op_mtc0_tchalt(); /* MT ASE */
2432 2423f660 ths
            rn = "TCHalt";
2433 2423f660 ths
//            break;
2434 7a387fff ths
        case 5:
2435 2423f660 ths
//            gen_op_mtc0_tccontext(); /* MT ASE */
2436 2423f660 ths
            rn = "TCContext";
2437 2423f660 ths
//            break;
2438 7a387fff ths
        case 6:
2439 2423f660 ths
//            gen_op_mtc0_tcschedule(); /* MT ASE */
2440 2423f660 ths
            rn = "TCSchedule";
2441 2423f660 ths
//            break;
2442 7a387fff ths
        case 7:
2443 2423f660 ths
//            gen_op_mtc0_tcschefback(); /* MT ASE */
2444 2423f660 ths
            rn = "TCScheFBack";
2445 2423f660 ths
//            break;
2446 7a387fff ths
        default:
2447 7a387fff ths
            goto die;
2448 7a387fff ths
        }
2449 8c0fdd85 ths
        break;
2450 8c0fdd85 ths
    case 3:
2451 7a387fff ths
        switch (sel) {
2452 7a387fff ths
        case 0:
2453 2423f660 ths
            gen_op_mtc0_entrylo1();
2454 2423f660 ths
            rn = "EntryLo1";
2455 2423f660 ths
            break;
2456 7a387fff ths
        default:
2457 7a387fff ths
            goto die;
2458 876d4b07 ths
        }
2459 8c0fdd85 ths
        break;
2460 8c0fdd85 ths
    case 4:
2461 7a387fff ths
        switch (sel) {
2462 7a387fff ths
        case 0:
2463 2423f660 ths
            gen_op_mtc0_context();
2464 2423f660 ths
            rn = "Context";
2465 2423f660 ths
            break;
2466 7a387fff ths
        case 1:
2467 2423f660 ths
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2468 2423f660 ths
            rn = "ContextConfig";
2469 2423f660 ths
//            break;
2470 7a387fff ths
        default:
2471 7a387fff ths
            goto die;
2472 876d4b07 ths
        }
2473 8c0fdd85 ths
        break;
2474 8c0fdd85 ths
    case 5:
2475 7a387fff ths
        switch (sel) {
2476 7a387fff ths
        case 0:
2477 2423f660 ths
            gen_op_mtc0_pagemask();
2478 2423f660 ths
            rn = "PageMask";
2479 2423f660 ths
            break;
2480 7a387fff ths
        case 1:
2481 2423f660 ths
            gen_op_mtc0_pagegrain();
2482 2423f660 ths
            rn = "PageGrain";
2483 2423f660 ths
            break;
2484 7a387fff ths
        default:
2485 7a387fff ths
            goto die;
2486 876d4b07 ths
        }
2487 8c0fdd85 ths
        break;
2488 8c0fdd85 ths
    case 6:
2489 7a387fff ths
        switch (sel) {
2490 7a387fff ths
        case 0:
2491 2423f660 ths
            gen_op_mtc0_wired();
2492 2423f660 ths
            rn = "Wired";
2493 2423f660 ths
            break;
2494 7a387fff ths
        case 1:
2495 2423f660 ths
//            gen_op_mtc0_srsconf0(); /* shadow registers */
2496 2423f660 ths
            rn = "SRSConf0";
2497 2423f660 ths
//            break;
2498 7a387fff ths
        case 2:
2499 2423f660 ths
//            gen_op_mtc0_srsconf1(); /* shadow registers */
2500 2423f660 ths
            rn = "SRSConf1";
2501 2423f660 ths
//            break;
2502 7a387fff ths
        case 3:
2503 2423f660 ths
//            gen_op_mtc0_srsconf2(); /* shadow registers */
2504 2423f660 ths
            rn = "SRSConf2";
2505 2423f660 ths
//            break;
2506 7a387fff ths
        case 4:
2507 2423f660 ths
//            gen_op_mtc0_srsconf3(); /* shadow registers */
2508 2423f660 ths
            rn = "SRSConf3";
2509 2423f660 ths
//            break;
2510 7a387fff ths
        case 5:
2511 2423f660 ths
//            gen_op_mtc0_srsconf4(); /* shadow registers */
2512 2423f660 ths
            rn = "SRSConf4";
2513 2423f660 ths
//            break;
2514 7a387fff ths
        default:
2515 7a387fff ths
            goto die;
2516 876d4b07 ths
        }
2517 8c0fdd85 ths
        break;
2518 8c0fdd85 ths
    case 7:
2519 7a387fff ths
        switch (sel) {
2520 7a387fff ths
        case 0:
2521 2423f660 ths
            gen_op_mtc0_hwrena();
2522 2423f660 ths
            rn = "HWREna";
2523 2423f660 ths
            break;
2524 7a387fff ths
        default:
2525 7a387fff ths
            goto die;
2526 876d4b07 ths
        }
2527 8c0fdd85 ths
        break;
2528 8c0fdd85 ths
    case 8:
2529 7a387fff ths
        /* ignored */
2530 8c0fdd85 ths
        rn = "BadVaddr";
2531 8c0fdd85 ths
        break;
2532 8c0fdd85 ths
    case 9:
2533 7a387fff ths
        switch (sel) {
2534 7a387fff ths
        case 0:
2535 2423f660 ths
            gen_op_mtc0_count();
2536 2423f660 ths
            rn = "Count";
2537 2423f660 ths
            break;
2538 876d4b07 ths
        /* 6,7 are implementation dependent */
2539 7a387fff ths
        default:
2540 7a387fff ths
            goto die;
2541 876d4b07 ths
        }
2542 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
2543 876d4b07 ths
        ctx->bstate = BS_STOP;
2544 8c0fdd85 ths
        break;
2545 8c0fdd85 ths
    case 10:
2546 7a387fff ths
        switch (sel) {
2547 7a387fff ths
        case 0:
2548 2423f660 ths
            gen_op_mtc0_entryhi();
2549 2423f660 ths
            rn = "EntryHi";
2550 2423f660 ths
            break;
2551 7a387fff ths
        default:
2552 7a387fff ths
            goto die;
2553 876d4b07 ths
        }
2554 8c0fdd85 ths
        break;
2555 8c0fdd85 ths
    case 11:
2556 7a387fff ths
        switch (sel) {
2557 7a387fff ths
        case 0:
2558 2423f660 ths
            gen_op_mtc0_compare();
2559 2423f660 ths
            rn = "Compare";
2560 2423f660 ths
            break;
2561 2423f660 ths
        /* 6,7 are implementation dependent */
2562 7a387fff ths
        default:
2563 7a387fff ths
            goto die;
2564 876d4b07 ths
        }
2565 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
2566 876d4b07 ths
        ctx->bstate = BS_STOP;
2567 8c0fdd85 ths
        break;
2568 8c0fdd85 ths
    case 12:
2569 7a387fff ths
        switch (sel) {
2570 7a387fff ths
        case 0:
2571 2423f660 ths
            gen_op_mtc0_status();
2572 2423f660 ths
            rn = "Status";
2573 2423f660 ths
            break;
2574 7a387fff ths
        case 1:
2575 2423f660 ths
            gen_op_mtc0_intctl();
2576 2423f660 ths
            rn = "IntCtl";
2577 2423f660 ths
            break;
2578 7a387fff ths
        case 2:
2579 2423f660 ths
            gen_op_mtc0_srsctl();
2580 2423f660 ths
            rn = "SRSCtl";
2581 2423f660 ths
            break;
2582 7a387fff ths
        case 3:
2583 2423f660 ths
//            gen_op_mtc0_srsmap(); /* shadow registers */
2584 2423f660 ths
            rn = "SRSMap";
2585 2423f660 ths
//            break;
2586 7a387fff ths
        default:
2587 7a387fff ths
            goto die;
2588 876d4b07 ths
        }
2589 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
2590 876d4b07 ths
        ctx->bstate = BS_STOP;
2591 8c0fdd85 ths
        break;
2592 8c0fdd85 ths
    case 13:
2593 7a387fff ths
        switch (sel) {
2594 7a387fff ths
        case 0:
2595 2423f660 ths
            gen_op_mtc0_cause();
2596 2423f660 ths
            rn = "Cause";
2597 2423f660 ths
            break;
2598 7a387fff ths
        default:
2599 7a387fff ths
            goto die;
2600 876d4b07 ths
        }
2601 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
2602 876d4b07 ths
        ctx->bstate = BS_STOP;
2603 8c0fdd85 ths
        break;
2604 8c0fdd85 ths
    case 14:
2605 7a387fff ths
        switch (sel) {
2606 7a387fff ths
        case 0:
2607 2423f660 ths
            gen_op_mtc0_epc();
2608 2423f660 ths
            rn = "EPC";
2609 2423f660 ths
            break;
2610 7a387fff ths
        default:
2611 7a387fff ths
            goto die;
2612 876d4b07 ths
        }
2613 8c0fdd85 ths
        break;
2614 8c0fdd85 ths
    case 15:
2615 7a387fff ths
        switch (sel) {
2616 7a387fff ths
        case 0:
2617 2423f660 ths
            /* ignored */
2618 2423f660 ths
            rn = "PRid";
2619 2423f660 ths
            break;
2620 7a387fff ths
        case 1:
2621 2423f660 ths
            gen_op_mtc0_ebase();
2622 2423f660 ths
            rn = "EBase";
2623 2423f660 ths
            break;
2624 7a387fff ths
        default:
2625 7a387fff ths
            goto die;
2626 1579a72e ths
        }
2627 8c0fdd85 ths
        break;
2628 8c0fdd85 ths
    case 16:
2629 8c0fdd85 ths
        switch (sel) {
2630 8c0fdd85 ths
        case 0:
2631 e397ee33 ths
            gen_op_mtc0_config0();
2632 7a387fff ths
            rn = "Config";
2633 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
2634 2423f660 ths
            ctx->bstate = BS_STOP;
2635 7a387fff ths
            break;
2636 7a387fff ths
        case 1:
2637 e397ee33 ths
            /* ignored, read only */
2638 7a387fff ths
            rn = "Config1";
2639 7a387fff ths
            break;
2640 7a387fff ths
        case 2:
2641 e397ee33 ths
            gen_op_mtc0_config2();
2642 7a387fff ths
            rn = "Config2";
2643 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
2644 2423f660 ths
            ctx->bstate = BS_STOP;
2645 8c0fdd85 ths
            break;
2646 7a387fff ths
        case 3:
2647 e397ee33 ths
            /* ignored, read only */
2648 7a387fff ths
            rn = "Config3";
2649 7a387fff ths
            break;
2650 e397ee33 ths
        /* 4,5 are reserved */
2651 e397ee33 ths
        /* 6,7 are implementation dependent */
2652 e397ee33 ths
        case 6:
2653 e397ee33 ths
            /* ignored */
2654 e397ee33 ths
            rn = "Config6";
2655 e397ee33 ths
            break;
2656 e397ee33 ths
        case 7:
2657 e397ee33 ths
            /* ignored */
2658 e397ee33 ths
            rn = "Config7";
2659 e397ee33 ths
            break;
2660 8c0fdd85 ths
        default:
2661 8c0fdd85 ths
            rn = "Invalid config selector";
2662 8c0fdd85 ths
            goto die;
2663 8c0fdd85 ths
        }
2664 8c0fdd85 ths
        break;
2665 8c0fdd85 ths
    case 17:
2666 7a387fff ths
        switch (sel) {
2667 7a387fff ths
        case 0:
2668 2423f660 ths
            /* ignored */
2669 2423f660 ths
            rn = "LLAddr";
2670 2423f660 ths
            break;
2671 7a387fff ths
        default:
2672 7a387fff ths
            goto die;
2673 7a387fff ths
        }
2674 8c0fdd85 ths
        break;
2675 8c0fdd85 ths
    case 18:
2676 7a387fff ths
        switch (sel) {
2677 7a387fff ths
        case 0:
2678 2423f660 ths
            gen_op_mtc0_watchlo0();
2679 2423f660 ths
            rn = "WatchLo";
2680 2423f660 ths
            break;
2681 7a387fff ths
        case 1:
2682 2423f660 ths
//            gen_op_mtc0_watchlo1();
2683 2423f660 ths
            rn = "WatchLo1";
2684 2423f660 ths
//            break;
2685 7a387fff ths
        case 2:
2686 2423f660 ths
//            gen_op_mtc0_watchlo2();
2687 2423f660 ths
            rn = "WatchLo2";
2688 2423f660 ths
//            break;
2689 7a387fff ths
        case 3:
2690 2423f660 ths
//            gen_op_mtc0_watchlo3();
2691 2423f660 ths
            rn = "WatchLo3";
2692 2423f660 ths
//            break;
2693 7a387fff ths
        case 4:
2694 2423f660 ths
//            gen_op_mtc0_watchlo4();
2695 2423f660 ths
            rn = "WatchLo4";
2696 2423f660 ths
//            break;
2697 7a387fff ths
        case 5:
2698 2423f660 ths
//            gen_op_mtc0_watchlo5();
2699 2423f660 ths
            rn = "WatchLo5";
2700 2423f660 ths
//            break;
2701 7a387fff ths
        case 6:
2702 2423f660 ths
//            gen_op_mtc0_watchlo6();
2703 2423f660 ths
            rn = "WatchLo6";
2704 2423f660 ths
//            break;
2705 7a387fff ths
        case 7:
2706 2423f660 ths
//            gen_op_mtc0_watchlo7();
2707 2423f660 ths
            rn = "WatchLo7";
2708 2423f660 ths
//            break;
2709 7a387fff ths
        default:
2710 7a387fff ths
            goto die;
2711 7a387fff ths
        }
2712 8c0fdd85 ths
        break;
2713 8c0fdd85 ths
    case 19:
2714 7a387fff ths
        switch (sel) {
2715 7a387fff ths
        case 0:
2716 2423f660 ths
            gen_op_mtc0_watchhi0();
2717 2423f660 ths
            rn = "WatchHi";
2718 2423f660 ths
            break;
2719 7a387fff ths
        case 1:
2720 2423f660 ths
//            gen_op_mtc0_watchhi1();
2721 2423f660 ths
            rn = "WatchHi1";
2722 2423f660 ths
//            break;
2723 7a387fff ths
        case 2:
2724 2423f660 ths
//            gen_op_mtc0_watchhi2();
2725 2423f660 ths
            rn = "WatchHi2";
2726 2423f660 ths
//            break;
2727 7a387fff ths
        case 3:
2728 2423f660 ths
//            gen_op_mtc0_watchhi3();
2729 2423f660 ths
            rn = "WatchHi3";
2730 2423f660 ths
//            break;
2731 7a387fff ths
        case 4:
2732 2423f660 ths
//            gen_op_mtc0_watchhi4();
2733 2423f660 ths
            rn = "WatchHi4";
2734 2423f660 ths
//            break;
2735 7a387fff ths
        case 5:
2736 2423f660 ths
//            gen_op_mtc0_watchhi5();
2737 2423f660 ths
            rn = "WatchHi5";
2738 2423f660 ths
//            break;
2739 7a387fff ths
        case 6:
2740 2423f660 ths
//            gen_op_mtc0_watchhi6();
2741 2423f660 ths
            rn = "WatchHi6";
2742 2423f660 ths
//            break;
2743 7a387fff ths
        case 7:
2744 2423f660 ths
//            gen_op_mtc0_watchhi7();
2745 2423f660 ths
            rn = "WatchHi7";
2746 2423f660 ths
//            break;
2747 7a387fff ths
        default:
2748 7a387fff ths
            goto die;
2749 7a387fff ths
        }
2750 8c0fdd85 ths
        break;
2751 8c0fdd85 ths
    case 20:
2752 7a387fff ths
        switch (sel) {
2753 7a387fff ths
        case 0:
2754 2423f660 ths
            /* 64 bit MMU only */
2755 2423f660 ths
            /* Nothing writable in lower 32 bits */
2756 2423f660 ths
            rn = "XContext";
2757 2423f660 ths
            break;
2758 7a387fff ths
        default:
2759 7a387fff ths
            goto die;
2760 7a387fff ths
        }
2761 8c0fdd85 ths
        break;
2762 8c0fdd85 ths
    case 21:
2763 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2764 7a387fff ths
        switch (sel) {
2765 7a387fff ths
        case 0:
2766 2423f660 ths
            gen_op_mtc0_framemask();
2767 2423f660 ths
            rn = "Framemask";
2768 2423f660 ths
            break;
2769 7a387fff ths
        default:
2770 7a387fff ths
            goto die;
2771 7a387fff ths
        }
2772 7a387fff ths
        break;
2773 8c0fdd85 ths
    case 22:
2774 7a387fff ths
        /* ignored */
2775 7a387fff ths
        rn = "Diagnostic"; /* implementation dependent */
2776 2423f660 ths
        break;
2777 8c0fdd85 ths
    case 23:
2778 7a387fff ths
        switch (sel) {
2779 7a387fff ths
        case 0:
2780 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
2781 2423f660 ths
            rn = "Debug";
2782 2423f660 ths
            break;
2783 7a387fff ths
        case 1:
2784 2423f660 ths
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
2785 2423f660 ths
            rn = "TraceControl";
2786 2423f660 ths
//            break;
2787 7a387fff ths
        case 2:
2788 2423f660 ths
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2789 2423f660 ths
            rn = "TraceControl2";
2790 2423f660 ths
//            break;
2791 7a387fff ths
        case 3:
2792 2423f660 ths
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
2793 2423f660 ths
            rn = "UserTraceData";
2794 2423f660 ths
//            break;
2795 7a387fff ths
        case 4:
2796 2423f660 ths
//            gen_op_mtc0_debug(); /* PDtrace support */
2797 2423f660 ths
            rn = "TraceBPC";
2798 2423f660 ths
//            break;
2799 7a387fff ths
        default:
2800 7a387fff ths
            goto die;
2801 7a387fff ths
        }
2802 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
2803 2423f660 ths
        ctx->bstate = BS_STOP;
2804 8c0fdd85 ths
        break;
2805 8c0fdd85 ths
    case 24:
2806 7a387fff ths
        switch (sel) {
2807 7a387fff ths
        case 0:
2808 2423f660 ths
            gen_op_mtc0_depc(); /* EJTAG support */
2809 2423f660 ths
            rn = "DEPC";
2810 2423f660 ths
            break;
2811 7a387fff ths
        default:
2812 7a387fff ths
            goto die;
2813 7a387fff ths
        }
2814 8c0fdd85 ths
        break;
2815 8c0fdd85 ths
    case 25:
2816 7a387fff ths
        switch (sel) {
2817 7a387fff ths
        case 0:
2818 2423f660 ths
            gen_op_mtc0_performance0();
2819 2423f660 ths
            rn = "Performance0";
2820 2423f660 ths
            break;
2821 7a387fff ths
        case 1:
2822 2423f660 ths
//            gen_op_mtc0_performance1();
2823 2423f660 ths
            rn = "Performance1";
2824 2423f660 ths
//            break;
2825 7a387fff ths
        case 2:
2826 2423f660 ths
//            gen_op_mtc0_performance2();
2827 2423f660 ths
            rn = "Performance2";
2828 2423f660 ths
//            break;
2829 7a387fff ths
        case 3:
2830 2423f660 ths
//            gen_op_mtc0_performance3();
2831 2423f660 ths
            rn = "Performance3";
2832 2423f660 ths
//            break;
2833 7a387fff ths
        case 4:
2834 2423f660 ths
//            gen_op_mtc0_performance4();
2835 2423f660 ths
            rn = "Performance4";
2836 2423f660 ths
//            break;
2837 7a387fff ths
        case 5:
2838 2423f660 ths
//            gen_op_mtc0_performance5();
2839 2423f660 ths
            rn = "Performance5";
2840 2423f660 ths
//            break;
2841 7a387fff ths
        case 6:
2842 2423f660 ths
//            gen_op_mtc0_performance6();
2843 2423f660 ths
            rn = "Performance6";
2844 2423f660 ths
//            break;
2845 7a387fff ths
        case 7:
2846 2423f660 ths
//            gen_op_mtc0_performance7();
2847 2423f660 ths
            rn = "Performance7";
2848 2423f660 ths
//            break;
2849 7a387fff ths
        default:
2850 7a387fff ths
            goto die;
2851 7a387fff ths
        }
2852 8c0fdd85 ths
       break;
2853 8c0fdd85 ths
    case 26:
2854 2423f660 ths
        /* ignored */
2855 8c0fdd85 ths
        rn = "ECC";
2856 2423f660 ths
        break;
2857 8c0fdd85 ths
    case 27:
2858 7a387fff ths
        switch (sel) {
2859 7a387fff ths
        case 0 ... 3:
2860 2423f660 ths
            /* ignored */
2861 2423f660 ths
            rn = "CacheErr";
2862 2423f660 ths
            break;
2863 7a387fff ths
        default:
2864 7a387fff ths
            goto die;
2865 7a387fff ths
        }
2866 8c0fdd85 ths
       break;
2867 8c0fdd85 ths
    case 28:
2868 8c0fdd85 ths
        switch (sel) {
2869 8c0fdd85 ths
        case 0:
2870 7a387fff ths
        case 2:
2871 7a387fff ths
        case 4:
2872 7a387fff ths
        case 6:
2873 8c0fdd85 ths
            gen_op_mtc0_taglo();
2874 8c0fdd85 ths
            rn = "TagLo";
2875 8c0fdd85 ths
            break;
2876 7a387fff ths
        case 1:
2877 7a387fff ths
        case 3:
2878 7a387fff ths
        case 5:
2879 7a387fff ths
        case 7:
2880 2423f660 ths
            gen_op_mtc0_datalo();
2881 7a387fff ths
            rn = "DataLo";
2882 7a387fff ths
            break;
2883 8c0fdd85 ths
        default:
2884 8c0fdd85 ths
            goto die;
2885 8c0fdd85 ths
        }
2886 8c0fdd85 ths
        break;
2887 8c0fdd85 ths
    case 29:
2888 7a387fff ths
        switch (sel) {
2889 7a387fff ths
        case 0:
2890 7a387fff ths
        case 2:
2891 7a387fff ths
        case 4:
2892 7a387fff ths
        case 6:
2893 7a387fff ths
            gen_op_mtc0_taghi();
2894 7a387fff ths
            rn = "TagHi";
2895 7a387fff ths
            break;
2896 7a387fff ths
        case 1:
2897 7a387fff ths
        case 3:
2898 7a387fff ths
        case 5:
2899 7a387fff ths
        case 7:
2900 2423f660 ths
            gen_op_mtc0_datahi();
2901 7a387fff ths
            rn = "DataHi";
2902 7a387fff ths
            break;
2903 7a387fff ths
        default:
2904 7a387fff ths
            rn = "invalid sel";
2905 7a387fff ths
            goto die;
2906 7a387fff ths
        }
2907 8c0fdd85 ths
       break;
2908 8c0fdd85 ths
    case 30:
2909 7a387fff ths
        switch (sel) {
2910 7a387fff ths
        case 0:
2911 2423f660 ths
            gen_op_mtc0_errorepc();
2912 2423f660 ths
            rn = "ErrorEPC";
2913 2423f660 ths
            break;
2914 7a387fff ths
        default:
2915 7a387fff ths
            goto die;
2916 7a387fff ths
        }
2917 8c0fdd85 ths
        break;
2918 8c0fdd85 ths
    case 31:
2919 7a387fff ths
        switch (sel) {
2920 7a387fff ths
        case 0:
2921 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
2922 2423f660 ths
            rn = "DESAVE";
2923 2423f660 ths
            break;
2924 7a387fff ths
        default:
2925 7a387fff ths
            goto die;
2926 7a387fff ths
        }
2927 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
2928 2423f660 ths
        ctx->bstate = BS_STOP;
2929 8c0fdd85 ths
        break;
2930 8c0fdd85 ths
    default:
2931 8c0fdd85 ths
       goto die;
2932 8c0fdd85 ths
    }
2933 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
2934 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2935 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2936 7a387fff ths
                rn, reg, sel);
2937 8c0fdd85 ths
    }
2938 8c0fdd85 ths
#endif
2939 8c0fdd85 ths
    return;
2940 8c0fdd85 ths
2941 8c0fdd85 ths
die:
2942 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
2943 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2944 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2945 7a387fff ths
                rn, reg, sel);
2946 8c0fdd85 ths
    }
2947 8c0fdd85 ths
#endif
2948 8c0fdd85 ths
    generate_exception(ctx, EXCP_RI);
2949 8c0fdd85 ths
}
2950 8c0fdd85 ths
2951 534ce69f ths
#ifdef TARGET_MIPS64
2952 9c2149c8 ths
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2953 9c2149c8 ths
{
2954 9c2149c8 ths
    const char *rn = "invalid";
2955 9c2149c8 ths
2956 9c2149c8 ths
    switch (reg) {
2957 9c2149c8 ths
    case 0:
2958 9c2149c8 ths
        switch (sel) {
2959 9c2149c8 ths
        case 0:
2960 2423f660 ths
            gen_op_mfc0_index();
2961 9c2149c8 ths
            rn = "Index";
2962 9c2149c8 ths
            break;
2963 9c2149c8 ths
        case 1:
2964 2423f660 ths
//            gen_op_dmfc0_mvpcontrol(); /* MT ASE */
2965 9c2149c8 ths
            rn = "MVPControl";
2966 2423f660 ths
//            break;
2967 9c2149c8 ths
        case 2:
2968 2423f660 ths
//            gen_op_dmfc0_mvpconf0(); /* MT ASE */
2969 9c2149c8 ths
            rn = "MVPConf0";
2970 2423f660 ths
//            break;
2971 9c2149c8 ths
        case 3:
2972 2423f660 ths
//            gen_op_dmfc0_mvpconf1(); /* MT ASE */
2973 9c2149c8 ths
            rn = "MVPConf1";
2974 2423f660 ths
//            break;
2975 9c2149c8 ths
        default:
2976 9c2149c8 ths
            goto die;
2977 9c2149c8 ths
        }
2978 9c2149c8 ths
        break;
2979 9c2149c8 ths
    case 1:
2980 9c2149c8 ths
        switch (sel) {
2981 9c2149c8 ths
        case 0:
2982 9c2149c8 ths
            gen_op_mfc0_random();
2983 9c2149c8 ths
            rn = "Random";
2984 2423f660 ths
            break;
2985 9c2149c8 ths
        case 1:
2986 2423f660 ths
//            gen_op_dmfc0_vpecontrol(); /* MT ASE */
2987 9c2149c8 ths
            rn = "VPEControl";
2988 2423f660 ths
//            break;
2989 9c2149c8 ths
        case 2:
2990 2423f660 ths
//            gen_op_dmfc0_vpeconf0(); /* MT ASE */
2991 9c2149c8 ths
            rn = "VPEConf0";
2992 2423f660 ths
//            break;
2993 9c2149c8 ths
        case 3:
2994 2423f660 ths
//            gen_op_dmfc0_vpeconf1(); /* MT ASE */
2995 9c2149c8 ths
            rn = "VPEConf1";
2996 2423f660 ths
//            break;
2997 9c2149c8 ths
        case 4:
2998 2423f660 ths
//            gen_op_dmfc0_YQMask(); /* MT ASE */
2999 9c2149c8 ths
            rn = "YQMask";
3000 2423f660 ths
//            break;
3001 9c2149c8 ths
        case 5:
3002 2423f660 ths
//            gen_op_dmfc0_vpeschedule(); /* MT ASE */
3003 9c2149c8 ths
            rn = "VPESchedule";
3004 2423f660 ths
//            break;
3005 9c2149c8 ths
        case 6:
3006 2423f660 ths
//            gen_op_dmfc0_vpeschefback(); /* MT ASE */
3007 9c2149c8 ths
            rn = "VPEScheFBack";
3008 2423f660 ths
//            break;
3009 9c2149c8 ths
        case 7:
3010 2423f660 ths
//            gen_op_dmfc0_vpeopt(); /* MT ASE */
3011 9c2149c8 ths
            rn = "VPEOpt";
3012 2423f660 ths
//            break;
3013 9c2149c8 ths
        default:
3014 9c2149c8 ths
            goto die;
3015 9c2149c8 ths
        }
3016 9c2149c8 ths
        break;
3017 9c2149c8 ths
    case 2:
3018 9c2149c8 ths
        switch (sel) {
3019 9c2149c8 ths
        case 0:
3020 2423f660 ths
            gen_op_dmfc0_entrylo0();
3021 2423f660 ths
            rn = "EntryLo0";
3022 2423f660 ths
            break;
3023 9c2149c8 ths
        case 1:
3024 2423f660 ths
//            gen_op_dmfc0_tcstatus(); /* MT ASE */
3025 2423f660 ths
            rn = "TCStatus";
3026 2423f660 ths
//            break;
3027 9c2149c8 ths
        case 2:
3028 2423f660 ths
//            gen_op_dmfc0_tcbind(); /* MT ASE */
3029 2423f660 ths
            rn = "TCBind";
3030 2423f660 ths
//            break;
3031 9c2149c8 ths
        case 3:
3032 2423f660 ths
//            gen_op_dmfc0_tcrestart(); /* MT ASE */
3033 2423f660 ths
            rn = "TCRestart";
3034 2423f660 ths
//            break;
3035 9c2149c8 ths
        case 4:
3036 2423f660 ths
//            gen_op_dmfc0_tchalt(); /* MT ASE */
3037 2423f660 ths
            rn = "TCHalt";
3038 2423f660 ths
//            break;
3039 9c2149c8 ths
        case 5:
3040 2423f660 ths
//            gen_op_dmfc0_tccontext(); /* MT ASE */
3041 2423f660 ths
            rn = "TCContext";
3042 2423f660 ths
//            break;
3043 9c2149c8 ths
        case 6:
3044 2423f660 ths
//            gen_op_dmfc0_tcschedule(); /* MT ASE */
3045 2423f660 ths
            rn = "TCSchedule";
3046 2423f660 ths
//            break;
3047 9c2149c8 ths
        case 7:
3048 2423f660 ths
//            gen_op_dmfc0_tcschefback(); /* MT ASE */
3049 2423f660 ths
            rn = "TCScheFBack";
3050 2423f660 ths
//            break;
3051 9c2149c8 ths
        default:
3052 9c2149c8 ths
            goto die;
3053 9c2149c8 ths
        }
3054 9c2149c8 ths
        break;
3055 9c2149c8 ths
    case 3:
3056 9c2149c8 ths
        switch (sel) {
3057 9c2149c8 ths
        case 0:
3058 2423f660 ths
            gen_op_dmfc0_entrylo1();
3059 2423f660 ths
            rn = "EntryLo1";
3060 2423f660 ths
            break;
3061 9c2149c8 ths
        default:
3062 9c2149c8 ths
            goto die;
3063 1579a72e ths
        }
3064 9c2149c8 ths
        break;
3065 9c2149c8 ths
    case 4:
3066 9c2149c8 ths
        switch (sel) {
3067 9c2149c8 ths
        case 0:
3068 2423f660 ths
            gen_op_dmfc0_context();
3069 2423f660 ths
            rn = "Context";
3070 2423f660 ths
            break;
3071 9c2149c8 ths
        case 1:
3072 2423f660 ths
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3073 2423f660 ths
            rn = "ContextConfig";
3074 2423f660 ths
//            break;
3075 9c2149c8 ths
        default:
3076 9c2149c8 ths
            goto die;
3077 876d4b07 ths
        }
3078 9c2149c8 ths
        break;
3079 9c2149c8 ths
    case 5:
3080 9c2149c8 ths
        switch (sel) {
3081 9c2149c8 ths
        case 0:
3082 2423f660 ths
            gen_op_mfc0_pagemask();
3083 2423f660 ths
            rn = "PageMask";
3084 2423f660 ths
            break;
3085 9c2149c8 ths
        case 1:
3086 2423f660 ths
            gen_op_mfc0_pagegrain();
3087 2423f660 ths
            rn = "PageGrain";
3088 2423f660 ths
            break;
3089 9c2149c8 ths
        default:
3090 9c2149c8 ths
            goto die;
3091 876d4b07 ths
        }
3092 9c2149c8 ths
        break;
3093 9c2149c8 ths
    case 6:
3094 9c2149c8 ths
        switch (sel) {
3095 9c2149c8 ths
        case 0:
3096 2423f660 ths
            gen_op_mfc0_wired();
3097 2423f660 ths
            rn = "Wired";
3098 2423f660 ths
            break;
3099 9c2149c8 ths
        case 1:
3100 2423f660 ths
//            gen_op_dmfc0_srsconf0(); /* shadow registers */
3101 2423f660 ths
            rn = "SRSConf0";
3102 2423f660 ths
//            break;
3103 9c2149c8 ths
        case 2:
3104 2423f660 ths
//            gen_op_dmfc0_srsconf1(); /* shadow registers */
3105 2423f660 ths
            rn = "SRSConf1";
3106 2423f660 ths
//            break;
3107 9c2149c8 ths
        case 3:
3108 2423f660 ths
//            gen_op_dmfc0_srsconf2(); /* shadow registers */
3109 2423f660 ths
            rn = "SRSConf2";
3110 2423f660 ths
//            break;
3111 9c2149c8 ths
        case 4:
3112 2423f660 ths
//            gen_op_dmfc0_srsconf3(); /* shadow registers */
3113 2423f660 ths
            rn = "SRSConf3";
3114 2423f660 ths
//            break;
3115 9c2149c8 ths
        case 5:
3116 2423f660 ths
//            gen_op_dmfc0_srsconf4(); /* shadow registers */
3117 2423f660 ths
            rn = "SRSConf4";
3118 2423f660 ths
//            break;
3119 9c2149c8 ths
        default:
3120 9c2149c8 ths
            goto die;
3121 876d4b07 ths
        }
3122 9c2149c8 ths
        break;
3123 9c2149c8 ths
    case 7:
3124 9c2149c8 ths
        switch (sel) {
3125 9c2149c8 ths
        case 0:
3126 2423f660 ths
            gen_op_mfc0_hwrena();
3127 2423f660 ths
            rn = "HWREna";
3128 2423f660 ths
            break;
3129 9c2149c8 ths
        default:
3130 9c2149c8 ths
            goto die;
3131 876d4b07 ths
        }
3132 9c2149c8 ths
        break;
3133 9c2149c8 ths
    case 8:
3134 9c2149c8 ths
        switch (sel) {
3135 9c2149c8 ths
        case 0:
3136 2423f660 ths
            gen_op_dmfc0_badvaddr();
3137 2423f660 ths
            rn = "BadVaddr";
3138 2423f660 ths
            break;
3139 9c2149c8 ths
        default:
3140 9c2149c8 ths
            goto die;
3141 876d4b07 ths
        }
3142 9c2149c8 ths
        break;
3143 9c2149c8 ths
    case 9:
3144 9c2149c8 ths
        switch (sel) {
3145 9c2149c8 ths
        case 0:
3146 2423f660 ths
            gen_op_mfc0_count();
3147 2423f660 ths
            rn = "Count";
3148 2423f660 ths
            break;
3149 2423f660 ths
        /* 6,7 are implementation dependent */
3150 9c2149c8 ths
        default:
3151 9c2149c8 ths
            goto die;
3152 876d4b07 ths
        }
3153 9c2149c8 ths
        break;
3154 9c2149c8 ths
    case 10:
3155 9c2149c8 ths
        switch (sel) {
3156 9c2149c8 ths
        case 0:
3157 2423f660 ths
            gen_op_dmfc0_entryhi();
3158 2423f660 ths
            rn = "EntryHi";
3159 2423f660 ths
            break;
3160 9c2149c8 ths
        default:
3161 9c2149c8 ths
            goto die;
3162 876d4b07 ths
        }
3163 9c2149c8 ths
        break;
3164 9c2149c8 ths
    case 11:
3165 9c2149c8 ths
        switch (sel) {
3166 9c2149c8 ths
        case 0:
3167 2423f660 ths
            gen_op_mfc0_compare();
3168 2423f660 ths
            rn = "Compare";
3169 2423f660 ths
            break;
3170 876d4b07 ths
        /* 6,7 are implementation dependent */
3171 9c2149c8 ths
        default:
3172 9c2149c8 ths
            goto die;
3173 876d4b07 ths
        }
3174 9c2149c8 ths
        break;
3175 9c2149c8 ths
    case 12:
3176 9c2149c8 ths
        switch (sel) {
3177 9c2149c8 ths
        case 0:
3178 2423f660 ths
            gen_op_mfc0_status();
3179 2423f660 ths
            rn = "Status";
3180 2423f660 ths
            break;
3181 9c2149c8 ths
        case 1:
3182 2423f660 ths
            gen_op_mfc0_intctl();
3183 2423f660 ths
            rn = "IntCtl";
3184 2423f660 ths
            break;
3185 9c2149c8 ths
        case 2:
3186 2423f660 ths
            gen_op_mfc0_srsctl();
3187 2423f660 ths
            rn = "SRSCtl";
3188 2423f660 ths
            break;
3189 9c2149c8 ths
        case 3:
3190 2423f660 ths
            gen_op_mfc0_srsmap(); /* shadow registers */
3191 2423f660 ths
            rn = "SRSMap";
3192 2423f660 ths
            break;
3193 9c2149c8 ths
        default:
3194 9c2149c8 ths
            goto die;
3195 876d4b07 ths
        }
3196 9c2149c8 ths
        break;
3197 9c2149c8 ths
    case 13:
3198 9c2149c8 ths
        switch (sel) {
3199 9c2149c8 ths
        case 0:
3200 2423f660 ths
            gen_op_mfc0_cause();
3201 2423f660 ths
            rn = "Cause";
3202 2423f660 ths
            break;
3203 9c2149c8 ths
        default:
3204 9c2149c8 ths
            goto die;
3205 876d4b07 ths
        }
3206 9c2149c8 ths
        break;
3207 9c2149c8 ths
    case 14:
3208 9c2149c8 ths
        switch (sel) {
3209 9c2149c8 ths
        case 0:
3210 2423f660 ths
            gen_op_dmfc0_epc();
3211 2423f660 ths
            rn = "EPC";
3212 2423f660 ths
            break;
3213 9c2149c8 ths
        default:
3214 9c2149c8 ths
            goto die;
3215 876d4b07 ths
        }
3216 9c2149c8 ths
        break;
3217 9c2149c8 ths
    case 15:
3218 9c2149c8 ths
        switch (sel) {
3219 9c2149c8 ths
        case 0:
3220 2423f660 ths
            gen_op_mfc0_prid();
3221 2423f660 ths
            rn = "PRid";
3222 2423f660 ths
            break;
3223 9c2149c8 ths
        case 1:
3224 2423f660 ths
            gen_op_mfc0_ebase();
3225 2423f660 ths
            rn = "EBase";
3226 2423f660 ths
            break;
3227 9c2149c8 ths
        default:
3228 9c2149c8 ths
            goto die;
3229 876d4b07 ths
        }
3230 9c2149c8 ths
        break;
3231 9c2149c8 ths
    case 16:
3232 9c2149c8 ths
        switch (sel) {
3233 9c2149c8 ths
        case 0:
3234 2423f660 ths
            gen_op_mfc0_config0();
3235 9c2149c8 ths
            rn = "Config";
3236 9c2149c8 ths
            break;
3237 9c2149c8 ths
        case 1:
3238 2423f660 ths
            gen_op_mfc0_config1();
3239 9c2149c8 ths
            rn = "Config1";
3240 9c2149c8 ths
            break;
3241 9c2149c8 ths
        case 2:
3242 2423f660 ths
            gen_op_mfc0_config2();
3243 9c2149c8 ths
            rn = "Config2";
3244 9c2149c8 ths
            break;
3245 9c2149c8 ths
        case 3:
3246 2423f660 ths
            gen_op_mfc0_config3();
3247 9c2149c8 ths
            rn = "Config3";
3248 9c2149c8 ths
            break;
3249 9c2149c8 ths
       /* 6,7 are implementation dependent */
3250 9c2149c8 ths
        default:
3251 9c2149c8 ths
            goto die;
3252 9c2149c8 ths
        }
3253 9c2149c8 ths
        break;
3254 9c2149c8 ths
    case 17:
3255 9c2149c8 ths
        switch (sel) {
3256 9c2149c8 ths
        case 0:
3257 2423f660 ths
            gen_op_dmfc0_lladdr();
3258 2423f660 ths
            rn = "LLAddr";
3259 2423f660 ths
            break;
3260 9c2149c8 ths
        default:
3261 9c2149c8 ths
            goto die;
3262 9c2149c8 ths
        }
3263 9c2149c8 ths
        break;
3264 9c2149c8 ths
    case 18:
3265 9c2149c8 ths
        switch (sel) {
3266 9c2149c8 ths
        case 0:
3267 2423f660 ths
            gen_op_dmfc0_watchlo0();
3268 2423f660 ths
            rn = "WatchLo";
3269 2423f660 ths
            break;
3270 9c2149c8 ths
        case 1:
3271 2423f660 ths
//            gen_op_dmfc0_watchlo1();
3272 2423f660 ths
            rn = "WatchLo1";
3273 2423f660 ths
//            break;
3274 9c2149c8 ths
        case 2:
3275 2423f660 ths
//            gen_op_dmfc0_watchlo2();
3276 2423f660 ths
            rn = "WatchLo2";
3277 2423f660 ths
//            break;
3278 9c2149c8 ths
        case 3:
3279 2423f660 ths
//            gen_op_dmfc0_watchlo3();
3280 2423f660 ths
            rn = "WatchLo3";
3281 2423f660 ths
//            break;
3282 9c2149c8 ths
        case 4:
3283 2423f660 ths
//            gen_op_dmfc0_watchlo4();
3284 2423f660 ths
            rn = "WatchLo4";
3285 2423f660 ths
//            break;
3286 9c2149c8 ths
        case 5:
3287 2423f660 ths
//            gen_op_dmfc0_watchlo5();
3288 2423f660 ths
            rn = "WatchLo5";
3289 2423f660 ths
//            break;
3290 9c2149c8 ths
        case 6:
3291 2423f660 ths
//            gen_op_dmfc0_watchlo6();
3292 2423f660 ths
            rn = "WatchLo6";
3293 2423f660 ths
//            break;
3294 9c2149c8 ths
        case 7:
3295 2423f660 ths
//            gen_op_dmfc0_watchlo7();
3296 2423f660 ths
            rn = "WatchLo7";
3297 2423f660 ths
//            break;
3298 9c2149c8 ths
        default:
3299 9c2149c8 ths
            goto die;
3300 9c2149c8 ths
        }
3301 9c2149c8 ths
        break;
3302 9c2149c8 ths
    case 19:
3303 9c2149c8 ths
        switch (sel) {
3304 9c2149c8 ths
        case 0:
3305 2423f660 ths
            gen_op_mfc0_watchhi0();
3306 2423f660 ths
            rn = "WatchHi";
3307 2423f660 ths
            break;
3308 9c2149c8 ths
        case 1:
3309 2423f660 ths
//            gen_op_mfc0_watchhi1();
3310 2423f660 ths
            rn = "WatchHi1";
3311 2423f660 ths
//            break;
3312 9c2149c8 ths
        case 2:
3313 2423f660 ths
//            gen_op_mfc0_watchhi2();
3314 2423f660 ths
            rn = "WatchHi2";
3315 2423f660 ths
//            break;
3316 9c2149c8 ths
        case 3:
3317 2423f660 ths
//            gen_op_mfc0_watchhi3();
3318 2423f660 ths
            rn = "WatchHi3";
3319 2423f660 ths
//            break;
3320 9c2149c8 ths
        case 4:
3321 2423f660 ths
//            gen_op_mfc0_watchhi4();
3322 2423f660 ths
            rn = "WatchHi4";
3323 2423f660 ths
//            break;
3324 9c2149c8 ths
        case 5:
3325 2423f660 ths
//            gen_op_mfc0_watchhi5();
3326 2423f660 ths
            rn = "WatchHi5";
3327 2423f660 ths
//            break;
3328 9c2149c8 ths
        case 6:
3329 2423f660 ths
//            gen_op_mfc0_watchhi6();
3330 2423f660 ths
            rn = "WatchHi6";
3331 2423f660 ths
//            break;
3332 9c2149c8 ths
        case 7:
3333 2423f660 ths
//            gen_op_mfc0_watchhi7();
3334 2423f660 ths
            rn = "WatchHi7";
3335 2423f660 ths
//            break;
3336 9c2149c8 ths
        default:
3337 9c2149c8 ths
            goto die;
3338 9c2149c8 ths
        }
3339 9c2149c8 ths
        break;
3340 9c2149c8 ths
    case 20:
3341 9c2149c8 ths
        switch (sel) {
3342 9c2149c8 ths
        case 0:
3343 2423f660 ths
            /* 64 bit MMU only */
3344 2423f660 ths
            gen_op_dmfc0_xcontext();
3345 2423f660 ths
            rn = "XContext";
3346 2423f660 ths
            break;
3347 9c2149c8 ths
        default:
3348 9c2149c8 ths
            goto die;
3349 9c2149c8 ths
        }
3350 9c2149c8 ths
        break;
3351 9c2149c8 ths
    case 21:
3352 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3353 9c2149c8 ths
        switch (sel) {
3354 9c2149c8 ths
        case 0:
3355 2423f660 ths
            gen_op_mfc0_framemask();
3356 2423f660 ths
            rn = "Framemask";
3357 2423f660 ths
            break;
3358 9c2149c8 ths
        default:
3359 9c2149c8 ths
            goto die;
3360 9c2149c8 ths
        }
3361 9c2149c8 ths
        break;
3362 9c2149c8 ths
    case 22:
3363 2423f660 ths
        /* ignored */
3364 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
3365 2423f660 ths
        break;
3366 9c2149c8 ths
    case 23:
3367 9c2149c8 ths
        switch (sel) {
3368 9c2149c8 ths
        case 0:
3369 2423f660 ths
            gen_op_mfc0_debug(); /* EJTAG support */
3370 2423f660 ths
            rn = "Debug";
3371 2423f660 ths
            break;
3372 9c2149c8 ths
        case 1:
3373 2423f660 ths
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3374 2423f660 ths
            rn = "TraceControl";
3375 2423f660 ths
//            break;
3376 9c2149c8 ths
        case 2:
3377 2423f660 ths
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3378 2423f660 ths
            rn = "TraceControl2";
3379 2423f660 ths
//            break;
3380 9c2149c8 ths
        case 3:
3381 2423f660 ths
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3382 2423f660 ths
            rn = "UserTraceData";
3383 2423f660 ths
//            break;
3384 9c2149c8 ths
        case 4:
3385 2423f660 ths
//            gen_op_dmfc0_debug(); /* PDtrace support */
3386 2423f660 ths
            rn = "TraceBPC";
3387 2423f660 ths
//            break;
3388 9c2149c8 ths
        default:
3389 9c2149c8 ths
            goto die;
3390 9c2149c8 ths
        }
3391 9c2149c8 ths
        break;
3392 9c2149c8 ths
    case 24:
3393 9c2149c8 ths
        switch (sel) {
3394 9c2149c8 ths
        case 0:
3395 2423f660 ths
            gen_op_dmfc0_depc(); /* EJTAG support */
3396 2423f660 ths
            rn = "DEPC";
3397 2423f660 ths
            break;
3398 9c2149c8 ths
        default:
3399 9c2149c8 ths
            goto die;
3400 9c2149c8 ths
        }
3401 9c2149c8 ths
        break;
3402 9c2149c8 ths
    case 25:
3403 9c2149c8 ths
        switch (sel) {
3404 9c2149c8 ths
        case 0:
3405 2423f660 ths
            gen_op_mfc0_performance0();
3406 2423f660 ths
            rn = "Performance0";
3407 9c2149c8 ths
            break;
3408 9c2149c8 ths
        case 1:
3409 2423f660 ths
//            gen_op_dmfc0_performance1();
3410 2423f660 ths
            rn = "Performance1";
3411 2423f660 ths
//            break;
3412 9c2149c8 ths
        case 2:
3413 2423f660 ths
//            gen_op_dmfc0_performance2();
3414 2423f660 ths
            rn = "Performance2";
3415 2423f660 ths
//            break;
3416 9c2149c8 ths
        case 3:
3417 2423f660 ths
//            gen_op_dmfc0_performance3();
3418 2423f660 ths
            rn = "Performance3";
3419 2423f660 ths
//            break;
3420 9c2149c8 ths
        case 4:
3421 2423f660 ths
//            gen_op_dmfc0_performance4();
3422 2423f660 ths
            rn = "Performance4";
3423 2423f660 ths
//            break;
3424 9c2149c8 ths
        case 5:
3425 2423f660 ths
//            gen_op_dmfc0_performance5();
3426 2423f660 ths
            rn = "Performance5";
3427 2423f660 ths
//            break;
3428 9c2149c8 ths
        case 6:
3429 2423f660 ths
//            gen_op_dmfc0_performance6();
3430 2423f660 ths
            rn = "Performance6";
3431 2423f660 ths
//            break;
3432 9c2149c8 ths
        case 7:
3433 2423f660 ths
//            gen_op_dmfc0_performance7();
3434 2423f660 ths
            rn = "Performance7";
3435 2423f660 ths
//            break;
3436 9c2149c8 ths
        default:
3437 9c2149c8 ths
            goto die;
3438 9c2149c8 ths
        }
3439 9c2149c8 ths
        break;
3440 9c2149c8 ths
    case 26:
3441 9c2149c8 ths
       rn = "ECC";
3442 9c2149c8 ths
       break;
3443 9c2149c8 ths
    case 27:
3444 9c2149c8 ths
        switch (sel) {
3445 9c2149c8 ths
        /* ignored */
3446 9c2149c8 ths
        case 0 ... 3:
3447 2423f660 ths
            rn = "CacheErr";
3448 2423f660 ths
            break;
3449 9c2149c8 ths
        default:
3450 9c2149c8 ths
            goto die;
3451 9c2149c8 ths
        }
3452 9c2149c8 ths
        break;
3453 9c2149c8 ths
    case 28:
3454 9c2149c8 ths
        switch (sel) {
3455 9c2149c8 ths
        case 0:
3456 9c2149c8 ths
        case 2:
3457 9c2149c8 ths
        case 4:
3458 9c2149c8 ths
        case 6:
3459 9c2149c8 ths
            gen_op_mfc0_taglo();
3460 9c2149c8 ths
            rn = "TagLo";
3461 9c2149c8 ths
            break;
3462 9c2149c8 ths
        case 1:
3463 9c2149c8 ths
        case 3:
3464 9c2149c8 ths
        case 5:
3465 9c2149c8 ths
        case 7:
3466 9c2149c8 ths
            gen_op_mfc0_datalo();
3467 9c2149c8 ths
            rn = "DataLo";
3468 9c2149c8 ths
            break;
3469 9c2149c8 ths
        default:
3470 9c2149c8 ths
            goto die;
3471 9c2149c8 ths
        }
3472 9c2149c8 ths
        break;
3473 9c2149c8 ths
    case 29:
3474 9c2149c8 ths
        switch (sel) {
3475 9c2149c8 ths
        case 0:
3476 9c2149c8 ths
        case 2:
3477 9c2149c8 ths
        case 4:
3478 9c2149c8 ths
        case 6:
3479 9c2149c8 ths
            gen_op_mfc0_taghi();
3480 9c2149c8 ths
            rn = "TagHi";
3481 9c2149c8 ths
            break;
3482 9c2149c8 ths
        case 1:
3483 9c2149c8 ths
        case 3:
3484 9c2149c8 ths
        case 5:
3485 9c2149c8 ths
        case 7:
3486 9c2149c8 ths
            gen_op_mfc0_datahi();
3487 9c2149c8 ths
            rn = "DataHi";
3488 9c2149c8 ths
            break;
3489 9c2149c8 ths
        default:
3490 9c2149c8 ths
            goto die;
3491 9c2149c8 ths
        }
3492 9c2149c8 ths
        break;
3493 9c2149c8 ths
    case 30:
3494 9c2149c8 ths
        switch (sel) {
3495 9c2149c8 ths
        case 0:
3496 2423f660 ths
            gen_op_dmfc0_errorepc();
3497 2423f660 ths
            rn = "ErrorEPC";
3498 2423f660 ths
            break;
3499 9c2149c8 ths
        default:
3500 9c2149c8 ths
            goto die;
3501 9c2149c8 ths
        }
3502 9c2149c8 ths
        break;
3503 9c2149c8 ths
    case 31:
3504 9c2149c8 ths
        switch (sel) {
3505 9c2149c8 ths
        case 0:
3506 2423f660 ths
            gen_op_mfc0_desave(); /* EJTAG support */
3507 2423f660 ths
            rn = "DESAVE";
3508 2423f660 ths
            break;
3509 9c2149c8 ths
        default:
3510 9c2149c8 ths
            goto die;
3511 9c2149c8 ths
        }
3512 9c2149c8 ths
        break;
3513 9c2149c8 ths
    default:
3514 876d4b07 ths
        goto die;
3515 9c2149c8 ths
    }
3516 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
3517 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3518 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3519 9c2149c8 ths
                rn, reg, sel);
3520 9c2149c8 ths
    }
3521 9c2149c8 ths
#endif
3522 9c2149c8 ths
    return;
3523 9c2149c8 ths
3524 9c2149c8 ths
die:
3525 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
3526 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3527 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3528 9c2149c8 ths
                rn, reg, sel);
3529 9c2149c8 ths
    }
3530 9c2149c8 ths
#endif
3531 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
3532 9c2149c8 ths
}
3533 9c2149c8 ths
3534 9c2149c8 ths
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3535 9c2149c8 ths
{
3536 9c2149c8 ths
    const char *rn = "invalid";
3537 9c2149c8 ths
3538 9c2149c8 ths
    switch (reg) {
3539 9c2149c8 ths
    case 0:
3540 9c2149c8 ths
        switch (sel) {
3541 9c2149c8 ths
        case 0:
3542 9c2149c8 ths
            gen_op_mtc0_index();
3543 9c2149c8 ths
            rn = "Index";
3544 9c2149c8 ths
            break;
3545 9c2149c8 ths
        case 1:
3546 2423f660 ths
//            gen_op_dmtc0_mvpcontrol(); /* MT ASE */
3547 9c2149c8 ths
            rn = "MVPControl";
3548 2423f660 ths
//            break;
3549 9c2149c8 ths
        case 2:
3550 2423f660 ths
//            gen_op_dmtc0_mvpconf0(); /* MT ASE */
3551 9c2149c8 ths
            rn = "MVPConf0";
3552 2423f660 ths
//            break;
3553 9c2149c8 ths
        case 3:
3554 2423f660 ths
//            gen_op_dmtc0_mvpconf1(); /* MT ASE */
3555 9c2149c8 ths
            rn = "MVPConf1";
3556 2423f660 ths
//            break;
3557 9c2149c8 ths
        default:
3558 9c2149c8 ths
            goto die;
3559 9c2149c8 ths
        }
3560 9c2149c8 ths
        break;
3561 9c2149c8 ths
    case 1:
3562 9c2149c8 ths
        switch (sel) {
3563 9c2149c8 ths
        case 0:
3564 2423f660 ths
            /* ignored */
3565 9c2149c8 ths
            rn = "Random";
3566 2423f660 ths
            break;
3567 9c2149c8 ths
        case 1:
3568 2423f660 ths
//            gen_op_dmtc0_vpecontrol(); /* MT ASE */
3569 9c2149c8 ths
            rn = "VPEControl";
3570 2423f660 ths
//            break;
3571 9c2149c8 ths
        case 2:
3572 2423f660 ths
//            gen_op_dmtc0_vpeconf0(); /* MT ASE */
3573 9c2149c8 ths
            rn = "VPEConf0";
3574 2423f660 ths
//            break;
3575 9c2149c8 ths
        case 3:
3576 2423f660 ths
//            gen_op_dmtc0_vpeconf1(); /* MT ASE */
3577 9c2149c8 ths
            rn = "VPEConf1";
3578 2423f660 ths
//            break;
3579 9c2149c8 ths
        case 4:
3580 2423f660 ths
//            gen_op_dmtc0_YQMask(); /* MT ASE */
3581 9c2149c8 ths
            rn = "YQMask";
3582 2423f660 ths
//            break;
3583 9c2149c8 ths
        case 5:
3584 2423f660 ths
//            gen_op_dmtc0_vpeschedule(); /* MT ASE */
3585 9c2149c8 ths
            rn = "VPESchedule";
3586 2423f660 ths
//            break;
3587 9c2149c8 ths
        case 6:
3588 2423f660 ths
//            gen_op_dmtc0_vpeschefback(); /* MT ASE */
3589 9c2149c8 ths
            rn = "VPEScheFBack";
3590 2423f660 ths
//            break;
3591 9c2149c8 ths
        case 7:
3592 2423f660 ths
//            gen_op_dmtc0_vpeopt(); /* MT ASE */
3593 9c2149c8 ths
            rn = "VPEOpt";
3594 2423f660 ths
//            break;
3595 9c2149c8 ths
        default:
3596 9c2149c8 ths
            goto die;
3597 9c2149c8 ths
        }
3598 9c2149c8 ths
        break;
3599 9c2149c8 ths
    case 2:
3600 9c2149c8 ths
        switch (sel) {
3601 9c2149c8 ths
        case 0:
3602 2423f660 ths
            gen_op_dmtc0_entrylo0();
3603 2423f660 ths
            rn = "EntryLo0";
3604 2423f660 ths
            break;
3605 9c2149c8 ths
        case 1:
3606 2423f660 ths
//            gen_op_dmtc0_tcstatus(); /* MT ASE */
3607 2423f660 ths
            rn = "TCStatus";
3608 2423f660 ths
//            break;
3609 9c2149c8 ths
        case 2:
3610 2423f660 ths
//            gen_op_dmtc0_tcbind(); /* MT ASE */
3611 2423f660 ths
            rn = "TCBind";
3612 2423f660 ths
//            break;
3613 9c2149c8 ths
        case 3:
3614 2423f660 ths
//            gen_op_dmtc0_tcrestart(); /* MT ASE */
3615 2423f660 ths
            rn = "TCRestart";
3616 2423f660 ths
//            break;
3617 9c2149c8 ths
        case 4:
3618 2423f660 ths
//            gen_op_dmtc0_tchalt(); /* MT ASE */
3619 2423f660 ths
            rn = "TCHalt";
3620 2423f660 ths
//            break;
3621 9c2149c8 ths
        case 5:
3622 2423f660 ths
//            gen_op_dmtc0_tccontext(); /* MT ASE */
3623 2423f660 ths
            rn = "TCContext";
3624 2423f660 ths
//            break;
3625 9c2149c8 ths
        case 6:
3626 2423f660 ths
//            gen_op_dmtc0_tcschedule(); /* MT ASE */
3627 2423f660 ths
            rn = "TCSchedule";
3628 2423f660 ths
//            break;
3629 9c2149c8 ths
        case 7:
3630 2423f660 ths
//            gen_op_dmtc0_tcschefback(); /* MT ASE */
3631 2423f660 ths
            rn = "TCScheFBack";
3632 2423f660 ths
//            break;
3633 9c2149c8 ths
        default:
3634 9c2149c8 ths
            goto die;
3635 9c2149c8 ths
        }
3636 9c2149c8 ths
        break;
3637 9c2149c8 ths
    case 3:
3638 9c2149c8 ths
        switch (sel) {
3639 9c2149c8 ths
        case 0:
3640 2423f660 ths
            gen_op_dmtc0_entrylo1();
3641 2423f660 ths
            rn = "EntryLo1";
3642 2423f660 ths
            break;
3643 9c2149c8 ths
        default:
3644 9c2149c8 ths
            goto die;
3645 876d4b07 ths
        }
3646 9c2149c8 ths
        break;
3647 9c2149c8 ths
    case 4:
3648 9c2149c8 ths
        switch (sel) {
3649 9c2149c8 ths
        case 0:
3650 2423f660 ths
            gen_op_dmtc0_context();
3651 2423f660 ths
            rn = "Context";
3652 2423f660 ths
            break;
3653 9c2149c8 ths
        case 1:
3654 2423f660 ths
//           gen_op_dmtc0_contextconfig(); /* SmartMIPS ASE */
3655 2423f660 ths
            rn = "ContextConfig";
3656 2423f660 ths
//           break;
3657 9c2149c8 ths
        default:
3658 9c2149c8 ths
            goto die;
3659 876d4b07 ths
        }
3660 9c2149c8 ths
        break;
3661 9c2149c8 ths
    case 5:
3662 9c2149c8 ths
        switch (sel) {
3663 9c2149c8 ths
        case 0:
3664 2423f660 ths
            gen_op_mtc0_pagemask();
3665 2423f660 ths
            rn = "PageMask";
3666 2423f660 ths
            break;
3667 9c2149c8 ths
        case 1:
3668 2423f660 ths
            gen_op_mtc0_pagegrain();
3669 2423f660 ths
            rn = "PageGrain";
3670 2423f660 ths
            break;
3671 9c2149c8 ths
        default:
3672 9c2149c8 ths
            goto die;
3673 876d4b07 ths
        }
3674 9c2149c8 ths
        break;
3675 9c2149c8 ths
    case 6:
3676 9c2149c8 ths
        switch (sel) {
3677 9c2149c8 ths
        case 0:
3678 2423f660 ths
            gen_op_mtc0_wired();
3679 2423f660 ths
            rn = "Wired";
3680 2423f660 ths
            break;
3681 9c2149c8 ths
        case 1:
3682 2423f660 ths
//            gen_op_dmtc0_srsconf0(); /* shadow registers */
3683 2423f660 ths
            rn = "SRSConf0";
3684 2423f660 ths
//            break;
3685 9c2149c8 ths
        case 2:
3686 2423f660 ths
//            gen_op_dmtc0_srsconf1(); /* shadow registers */
3687 2423f660 ths
            rn = "SRSConf1";
3688 2423f660 ths
//            break;
3689 9c2149c8 ths
        case 3:
3690 2423f660 ths
//            gen_op_dmtc0_srsconf2(); /* shadow registers */
3691 2423f660 ths
            rn = "SRSConf2";
3692 2423f660 ths
//            break;
3693 9c2149c8 ths
        case 4:
3694 2423f660 ths
//            gen_op_dmtc0_srsconf3(); /* shadow registers */
3695 2423f660 ths
            rn = "SRSConf3";
3696 2423f660 ths
//            break;
3697 9c2149c8 ths
        case 5:
3698 2423f660 ths
//            gen_op_dmtc0_srsconf4(); /* shadow registers */
3699 2423f660 ths
            rn = "SRSConf4";
3700 2423f660 ths
//            break;
3701 9c2149c8 ths
        default:
3702 9c2149c8 ths
            goto die;
3703 876d4b07 ths
        }
3704 9c2149c8 ths
        break;
3705 9c2149c8 ths
    case 7:
3706 9c2149c8 ths
        switch (sel) {
3707 9c2149c8 ths
        case 0:
3708 2423f660 ths
            gen_op_mtc0_hwrena();
3709 2423f660 ths
            rn = "HWREna";
3710 2423f660 ths
            break;
3711 9c2149c8 ths
        default:
3712 9c2149c8 ths
            goto die;
3713 876d4b07 ths
        }
3714 9c2149c8 ths
        break;
3715 9c2149c8 ths
    case 8:
3716 9c2149c8 ths
        /* ignored */
3717 9c2149c8 ths
        rn = "BadVaddr";
3718 9c2149c8 ths
        break;
3719 9c2149c8 ths
    case 9:
3720 9c2149c8 ths
        switch (sel) {
3721 9c2149c8 ths
        case 0:
3722 2423f660 ths
            gen_op_mtc0_count();
3723 2423f660 ths
            rn = "Count";
3724 2423f660 ths
            break;
3725 876d4b07 ths
        /* 6,7 are implementation dependent */
3726 9c2149c8 ths
        default:
3727 9c2149c8 ths
            goto die;
3728 876d4b07 ths
        }
3729 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3730 876d4b07 ths
        ctx->bstate = BS_STOP;
3731 9c2149c8 ths
        break;
3732 9c2149c8 ths
    case 10:
3733 9c2149c8 ths
        switch (sel) {
3734 9c2149c8 ths
        case 0:
3735 2423f660 ths
            gen_op_mtc0_entryhi();
3736 2423f660 ths
            rn = "EntryHi";
3737 2423f660 ths
            break;
3738 9c2149c8 ths
        default:
3739 9c2149c8 ths
            goto die;
3740 876d4b07 ths
        }
3741 9c2149c8 ths
        break;
3742 9c2149c8 ths
    case 11:
3743 9c2149c8 ths
        switch (sel) {
3744 9c2149c8 ths
        case 0:
3745 2423f660 ths
            gen_op_mtc0_compare();
3746 2423f660 ths
            rn = "Compare";
3747 2423f660 ths
            break;
3748 876d4b07 ths
        /* 6,7 are implementation dependent */
3749 9c2149c8 ths
        default:
3750 9c2149c8 ths
            goto die;
3751 876d4b07 ths
        }
3752 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3753 876d4b07 ths
        ctx->bstate = BS_STOP;
3754 9c2149c8 ths
        break;
3755 9c2149c8 ths
    case 12:
3756 9c2149c8 ths
        switch (sel) {
3757 9c2149c8 ths
        case 0:
3758 2423f660 ths
            gen_op_mtc0_status();
3759 2423f660 ths
            rn = "Status";
3760 2423f660 ths
            break;
3761 9c2149c8 ths
        case 1:
3762 2423f660 ths
            gen_op_mtc0_intctl();
3763 2423f660 ths
            rn = "IntCtl";
3764 2423f660 ths
            break;
3765 9c2149c8 ths
        case 2:
3766 2423f660 ths
            gen_op_mtc0_srsctl();
3767 2423f660 ths
            rn = "SRSCtl";
3768 2423f660 ths
            break;
3769 9c2149c8 ths
        case 3:
3770 2423f660 ths
            gen_op_mtc0_srsmap(); /* shadow registers */
3771 2423f660 ths
            rn = "SRSMap";
3772 2423f660 ths
            break;
3773 2423f660 ths
        default:
3774 9c2149c8 ths
            goto die;
3775 876d4b07 ths
        }
3776 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3777 876d4b07 ths
        ctx->bstate = BS_STOP;
3778 9c2149c8 ths
        break;
3779 9c2149c8 ths
    case 13:
3780 9c2149c8 ths
        switch (sel) {
3781 9c2149c8 ths
        case 0:
3782 2423f660 ths
            gen_op_mtc0_cause();
3783 2423f660 ths
            rn = "Cause";
3784 2423f660 ths
            break;
3785 9c2149c8 ths
        default:
3786 9c2149c8 ths
            goto die;
3787 876d4b07 ths
        }
3788 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3789 876d4b07 ths
        ctx->bstate = BS_STOP;
3790 9c2149c8 ths
        break;
3791 9c2149c8 ths
    case 14:
3792 9c2149c8 ths
        switch (sel) {
3793 9c2149c8 ths
        case 0:
3794 2423f660 ths
            gen_op_dmtc0_epc();
3795 2423f660 ths
            rn = "EPC";
3796 2423f660 ths
            break;
3797 9c2149c8 ths
        default:
3798 9c2149c8 ths
            goto die;
3799 876d4b07 ths
        }
3800 9c2149c8 ths
        break;
3801 9c2149c8 ths
    case 15:
3802 9c2149c8 ths
        switch (sel) {
3803 9c2149c8 ths
        case 0:
3804 2423f660 ths
            /* ignored */
3805 2423f660 ths
            rn = "PRid";
3806 2423f660 ths
            break;
3807 9c2149c8 ths
        case 1:
3808 2423f660 ths
            gen_op_mtc0_ebase();
3809 2423f660 ths
            rn = "EBase";
3810 2423f660 ths
            break;
3811 9c2149c8 ths
        default:
3812 9c2149c8 ths
            goto die;
3813 876d4b07 ths
        }
3814 9c2149c8 ths
        break;
3815 9c2149c8 ths
    case 16:
3816 9c2149c8 ths
        switch (sel) {
3817 9c2149c8 ths
        case 0:
3818 9c2149c8 ths
            gen_op_mtc0_config0();
3819 9c2149c8 ths
            rn = "Config";
3820 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3821 2423f660 ths
            ctx->bstate = BS_STOP;
3822 9c2149c8 ths
            break;
3823 9c2149c8 ths
        case 1:
3824 2423f660 ths
            /* ignored */
3825 9c2149c8 ths
            rn = "Config1";
3826 9c2149c8 ths
            break;
3827 9c2149c8 ths
        case 2:
3828 9c2149c8 ths
            gen_op_mtc0_config2();
3829 9c2149c8 ths
            rn = "Config2";
3830 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3831 2423f660 ths
            ctx->bstate = BS_STOP;
3832 9c2149c8 ths
            break;
3833 9c2149c8 ths
        case 3:
3834 2423f660 ths
            /* ignored */
3835 9c2149c8 ths
            rn = "Config3";
3836 9c2149c8 ths
            break;
3837 9c2149c8 ths
        /* 6,7 are implementation dependent */
3838 9c2149c8 ths
        default:
3839 9c2149c8 ths
            rn = "Invalid config selector";
3840 9c2149c8 ths
            goto die;
3841 9c2149c8 ths
        }
3842 9c2149c8 ths
        break;
3843 9c2149c8 ths
    case 17:
3844 9c2149c8 ths
        switch (sel) {
3845 9c2149c8 ths
        case 0:
3846 2423f660 ths
            /* ignored */
3847 2423f660 ths
            rn = "LLAddr";
3848 2423f660 ths
            break;
3849 9c2149c8 ths
        default:
3850 9c2149c8 ths
            goto die;
3851 9c2149c8 ths
        }
3852 9c2149c8 ths
        break;
3853 9c2149c8 ths
    case 18:
3854 9c2149c8 ths
        switch (sel) {
3855 9c2149c8 ths
        case 0:
3856 2423f660 ths
            gen_op_dmtc0_watchlo0();
3857 2423f660 ths
            rn = "WatchLo";
3858 2423f660 ths
            break;
3859 9c2149c8 ths
        case 1:
3860 2423f660 ths
//            gen_op_dmtc0_watchlo1();
3861 2423f660 ths
            rn = "WatchLo1";
3862 2423f660 ths
//            break;
3863 9c2149c8 ths
        case 2:
3864 2423f660 ths
//            gen_op_dmtc0_watchlo2();
3865 2423f660 ths
            rn = "WatchLo2";
3866 2423f660 ths
//            break;
3867 9c2149c8 ths
        case 3:
3868 2423f660 ths
//            gen_op_dmtc0_watchlo3();
3869 2423f660 ths
            rn = "WatchLo3";
3870 2423f660 ths
//            break;
3871 9c2149c8 ths
        case 4:
3872 2423f660 ths
//            gen_op_dmtc0_watchlo4();
3873 2423f660 ths
            rn = "WatchLo4";
3874 2423f660 ths
//            break;
3875 9c2149c8 ths
        case 5:
3876 2423f660 ths
//            gen_op_dmtc0_watchlo5();
3877 2423f660 ths
            rn = "WatchLo5";
3878 2423f660 ths
//            break;
3879 9c2149c8 ths
        case 6:
3880 2423f660 ths
//            gen_op_dmtc0_watchlo6();
3881 2423f660 ths
            rn = "WatchLo6";
3882 2423f660 ths
//            break;
3883 9c2149c8 ths
        case 7:
3884 2423f660 ths
//            gen_op_dmtc0_watchlo7();
3885 2423f660 ths
            rn = "WatchLo7";
3886 2423f660 ths
//            break;
3887 9c2149c8 ths
        default:
3888 9c2149c8 ths
            goto die;
3889 9c2149c8 ths
        }
3890 9c2149c8 ths
        break;
3891 9c2149c8 ths
    case 19:
3892 9c2149c8 ths
        switch (sel) {
3893 9c2149c8 ths
        case 0:
3894 2423f660 ths
            gen_op_mtc0_watchhi0();
3895 2423f660 ths
            rn = "WatchHi";
3896 2423f660 ths
            break;
3897 9c2149c8 ths
        case 1:
3898 2423f660 ths
//            gen_op_dmtc0_watchhi1();
3899 2423f660 ths
            rn = "WatchHi1";
3900 2423f660 ths
//            break;
3901 9c2149c8 ths
        case 2:
3902 2423f660 ths
//            gen_op_dmtc0_watchhi2();
3903 2423f660 ths
            rn = "WatchHi2";
3904 2423f660 ths
//            break;
3905 9c2149c8 ths
        case 3:
3906 2423f660 ths
//            gen_op_dmtc0_watchhi3();
3907 2423f660 ths
            rn = "WatchHi3";
3908 2423f660 ths
//            break;
3909 9c2149c8 ths
        case 4:
3910 2423f660 ths
//            gen_op_dmtc0_watchhi4();
3911 2423f660 ths
            rn = "WatchHi4";
3912 2423f660 ths
//            break;
3913 9c2149c8 ths
        case 5:
3914 2423f660 ths
//            gen_op_dmtc0_watchhi5();
3915 2423f660 ths
            rn = "WatchHi5";
3916 2423f660 ths
//            break;
3917 9c2149c8 ths
        case 6:
3918 2423f660 ths
//            gen_op_dmtc0_watchhi6();
3919 2423f660 ths
            rn = "WatchHi6";
3920 2423f660 ths
//            break;
3921 9c2149c8 ths
        case 7:
3922 2423f660 ths
//            gen_op_dmtc0_watchhi7();
3923 2423f660 ths
            rn = "WatchHi7";
3924 2423f660 ths
//            break;
3925 9c2149c8 ths
        default:
3926 9c2149c8 ths
            goto die;
3927 9c2149c8 ths
        }
3928 9c2149c8 ths
        break;
3929 9c2149c8 ths
    case 20:
3930 9c2149c8 ths
        switch (sel) {
3931 9c2149c8 ths
        case 0:
3932 2423f660 ths
            /* 64 bit MMU only */
3933 2423f660 ths
            gen_op_dmtc0_xcontext();
3934 2423f660 ths
            rn = "XContext";
3935 2423f660 ths
            break;
3936 9c2149c8 ths
        default:
3937 9c2149c8 ths
            goto die;
3938 9c2149c8 ths
        }
3939 9c2149c8 ths
        break;
3940 9c2149c8 ths
    case 21:
3941 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3942 9c2149c8 ths
        switch (sel) {
3943 9c2149c8 ths
        case 0:
3944 2423f660 ths
            gen_op_mtc0_framemask();
3945 2423f660 ths
            rn = "Framemask";
3946 2423f660 ths
            break;
3947 9c2149c8 ths
        default:
3948 9c2149c8 ths
            goto die;
3949 9c2149c8 ths
        }
3950 9c2149c8 ths
        break;
3951 9c2149c8 ths
    case 22:
3952 9c2149c8 ths
        /* ignored */
3953 9c2149c8 ths
        rn = "Diagnostic"; /* implementation dependent */
3954 876d4b07 ths
        break;
3955 9c2149c8 ths
    case 23:
3956 9c2149c8 ths
        switch (sel) {
3957 9c2149c8 ths
        case 0:
3958 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
3959 2423f660 ths
            rn = "Debug";
3960 2423f660 ths
            break;
3961 9c2149c8 ths
        case 1:
3962 2423f660 ths
//            gen_op_dmtc0_tracecontrol(); /* PDtrace support */
3963 2423f660 ths
            rn = "TraceControl";
3964 2423f660 ths
//            break;
3965 9c2149c8 ths
        case 2:
3966 2423f660 ths
//            gen_op_dmtc0_tracecontrol2(); /* PDtrace support */
3967 2423f660 ths
            rn = "TraceControl2";
3968 2423f660 ths
//            break;
3969 9c2149c8 ths
        case 3:
3970 2423f660 ths
//            gen_op_dmtc0_usertracedata(); /* PDtrace support */
3971 2423f660 ths
            rn = "UserTraceData";
3972 2423f660 ths
//            break;
3973 9c2149c8 ths
        case 4:
3974 2423f660 ths
//            gen_op_dmtc0_debug(); /* PDtrace support */
3975 2423f660 ths
            rn = "TraceBPC";
3976 2423f660 ths
//            break;
3977 9c2149c8 ths
        default:
3978 9c2149c8 ths
            goto die;
3979 9c2149c8 ths
        }
3980 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
3981 2423f660 ths
        ctx->bstate = BS_STOP;
3982 9c2149c8 ths
        break;
3983 9c2149c8 ths
    case 24:
3984 9c2149c8 ths
        switch (sel) {
3985 9c2149c8 ths
        case 0:
3986 2423f660 ths
            gen_op_dmtc0_depc(); /* EJTAG support */
3987 2423f660 ths
            rn = "DEPC";
3988 2423f660 ths
            break;
3989 9c2149c8 ths
        default:
3990 9c2149c8 ths
            goto die;
3991 9c2149c8 ths
        }
3992 9c2149c8 ths
        break;
3993 9c2149c8 ths
    case 25:
3994 9c2149c8 ths
        switch (sel) {
3995 9c2149c8 ths
        case 0:
3996 2423f660 ths
            gen_op_mtc0_performance0();
3997 2423f660 ths
            rn = "Performance0";
3998 2423f660 ths
            break;
3999 9c2149c8 ths
        case 1:
4000 2423f660 ths
//            gen_op_dmtc0_performance1();
4001 2423f660 ths
            rn = "Performance1";
4002 2423f660 ths
//            break;
4003 9c2149c8 ths
        case 2:
4004 2423f660 ths
//            gen_op_dmtc0_performance2();
4005 2423f660 ths
            rn = "Performance2";
4006 2423f660 ths
//            break;
4007 9c2149c8 ths
        case 3:
4008 2423f660 ths
//            gen_op_dmtc0_performance3();
4009 2423f660 ths
            rn = "Performance3";
4010 2423f660 ths
//            break;
4011 9c2149c8 ths
        case 4:
4012 2423f660 ths
//            gen_op_dmtc0_performance4();
4013 2423f660 ths
            rn = "Performance4";
4014 2423f660 ths
//            break;
4015 9c2149c8 ths
        case 5:
4016 2423f660 ths
//            gen_op_dmtc0_performance5();
4017 2423f660 ths
            rn = "Performance5";
4018 2423f660 ths
//            break;
4019 9c2149c8 ths
        case 6:
4020 2423f660 ths
//            gen_op_dmtc0_performance6();
4021 2423f660 ths
            rn = "Performance6";
4022 2423f660 ths
//            break;
4023 9c2149c8 ths
        case 7:
4024 2423f660 ths
//            gen_op_dmtc0_performance7();
4025 2423f660 ths
            rn = "Performance7";
4026 2423f660 ths
//            break;
4027 9c2149c8 ths
        default:
4028 9c2149c8 ths
            goto die;
4029 9c2149c8 ths
        }
4030 876d4b07 ths
        break;
4031 9c2149c8 ths
    case 26:
4032 876d4b07 ths
        /* ignored */
4033 9c2149c8 ths
        rn = "ECC";
4034 876d4b07 ths
        break;
4035 9c2149c8 ths
    case 27:
4036 9c2149c8 ths
        switch (sel) {
4037 9c2149c8 ths
        case 0 ... 3:
4038 2423f660 ths
            /* ignored */
4039 2423f660 ths
            rn = "CacheErr";
4040 2423f660 ths
            break;
4041 9c2149c8 ths
        default:
4042 9c2149c8 ths
            goto die;
4043 9c2149c8 ths
        }
4044 876d4b07 ths
        break;
4045 9c2149c8 ths
    case 28:
4046 9c2149c8 ths
        switch (sel) {
4047 9c2149c8 ths
        case 0:
4048 9c2149c8 ths
        case 2:
4049 9c2149c8 ths
        case 4:
4050 9c2149c8 ths
        case 6:
4051 9c2149c8 ths
            gen_op_mtc0_taglo();
4052 9c2149c8 ths
            rn = "TagLo";
4053 9c2149c8 ths
            break;
4054 9c2149c8 ths
        case 1:
4055 9c2149c8 ths
        case 3:
4056 9c2149c8 ths
        case 5:
4057 9c2149c8 ths
        case 7:
4058 2423f660 ths
            gen_op_mtc0_datalo();
4059 9c2149c8 ths
            rn = "DataLo";
4060 9c2149c8 ths
            break;
4061 9c2149c8 ths
        default:
4062 9c2149c8 ths
            goto die;
4063 9c2149c8 ths
        }
4064 9c2149c8 ths
        break;
4065 9c2149c8 ths
    case 29:
4066 9c2149c8 ths
        switch (sel) {
4067 9c2149c8 ths
        case 0:
4068 9c2149c8 ths
        case 2:
4069 9c2149c8 ths
        case 4:
4070 9c2149c8 ths
        case 6:
4071 9c2149c8 ths
            gen_op_mtc0_taghi();
4072 9c2149c8 ths
            rn = "TagHi";
4073 9c2149c8 ths
            break;
4074 9c2149c8 ths
        case 1:
4075 9c2149c8 ths
        case 3:
4076 9c2149c8 ths
        case 5:
4077 9c2149c8 ths
        case 7:
4078 2423f660 ths
            gen_op_mtc0_datahi();
4079 9c2149c8 ths
            rn = "DataHi";
4080 9c2149c8 ths
            break;
4081 9c2149c8 ths
        default:
4082 9c2149c8 ths
            rn = "invalid sel";
4083 9c2149c8 ths
            goto die;
4084 9c2149c8 ths
        }
4085 876d4b07 ths
        break;
4086 9c2149c8 ths
    case 30:
4087 9c2149c8 ths
        switch (sel) {
4088 9c2149c8 ths
        case 0:
4089 2423f660 ths
            gen_op_dmtc0_errorepc();
4090 2423f660 ths
            rn = "ErrorEPC";
4091 2423f660 ths
            break;
4092 9c2149c8 ths
        default:
4093 9c2149c8 ths
            goto die;
4094 9c2149c8 ths
        }
4095 9c2149c8 ths
        break;
4096 9c2149c8 ths
    case 31:
4097 9c2149c8 ths
        switch (sel) {
4098 9c2149c8 ths
        case 0:
4099 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
4100 2423f660 ths
            rn = "DESAVE";
4101 2423f660 ths
            break;
4102 9c2149c8 ths
        default:
4103 9c2149c8 ths
            goto die;
4104 9c2149c8 ths
        }
4105 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
4106 876d4b07 ths
        ctx->bstate = BS_STOP;
4107 9c2149c8 ths
        break;
4108 9c2149c8 ths
    default:
4109 876d4b07 ths
        goto die;
4110 9c2149c8 ths
    }
4111 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4112 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4113 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4114 9c2149c8 ths
                rn, reg, sel);
4115 9c2149c8 ths
    }
4116 9c2149c8 ths
#endif
4117 9c2149c8 ths
    return;
4118 9c2149c8 ths
4119 9c2149c8 ths
die:
4120 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4121 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4122 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4123 9c2149c8 ths
                rn, reg, sel);
4124 9c2149c8 ths
    }
4125 9c2149c8 ths
#endif
4126 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
4127 9c2149c8 ths
}
4128 534ce69f ths
#endif /* TARGET_MIPS64 */
4129 9c2149c8 ths
4130 7a387fff ths
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4131 6af0bf9c bellard
{
4132 7a387fff ths
    const char *opn = "unk";
4133 6af0bf9c bellard
4134 6af0bf9c bellard
    switch (opc) {
4135 6af0bf9c bellard
    case OPC_MFC0:
4136 6af0bf9c bellard
        if (rt == 0) {
4137 6af0bf9c bellard
            /* Treat as NOP */
4138 6af0bf9c bellard
            return;
4139 6af0bf9c bellard
        }
4140 873eb012 ths
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4141 6af0bf9c bellard
        gen_op_store_T0_gpr(rt);
4142 6af0bf9c bellard
        opn = "mfc0";
4143 6af0bf9c bellard
        break;
4144 6af0bf9c bellard
    case OPC_MTC0:
4145 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, rt);
4146 8c0fdd85 ths
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4147 6af0bf9c bellard
        opn = "mtc0";
4148 6af0bf9c bellard
        break;
4149 534ce69f ths
#ifdef TARGET_MIPS64
4150 9c2149c8 ths
    case OPC_DMFC0:
4151 9c2149c8 ths
        if (rt == 0) {
4152 9c2149c8 ths
            /* Treat as NOP */
4153 9c2149c8 ths
            return;
4154 9c2149c8 ths
        }
4155 9c2149c8 ths
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4156 9c2149c8 ths
        gen_op_store_T0_gpr(rt);
4157 9c2149c8 ths
        opn = "dmfc0";
4158 9c2149c8 ths
        break;
4159 9c2149c8 ths
    case OPC_DMTC0:
4160 9c2149c8 ths
        GEN_LOAD_REG_TN(T0, rt);
4161 9c2149c8 ths
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4162 9c2149c8 ths
        opn = "dmtc0";
4163 9c2149c8 ths
        break;
4164 534ce69f ths
#endif
4165 6af0bf9c bellard
#if defined(MIPS_USES_R4K_TLB)
4166 6af0bf9c bellard
    case OPC_TLBWI:
4167 6af0bf9c bellard
        gen_op_tlbwi();
4168 6af0bf9c bellard
        opn = "tlbwi";
4169 6af0bf9c bellard
        break;
4170 6af0bf9c bellard
    case OPC_TLBWR:
4171 6af0bf9c bellard
        gen_op_tlbwr();
4172 6af0bf9c bellard
        opn = "tlbwr";
4173 6af0bf9c bellard
        break;
4174 6af0bf9c bellard
    case OPC_TLBP:
4175 6af0bf9c bellard
        gen_op_tlbp();
4176 6af0bf9c bellard
        opn = "tlbp";
4177 6af0bf9c bellard
        break;
4178 6af0bf9c bellard
    case OPC_TLBR:
4179 6af0bf9c bellard
        gen_op_tlbr();
4180 6af0bf9c bellard
        opn = "tlbr";
4181 6af0bf9c bellard
        break;
4182 6af0bf9c bellard
#endif
4183 6af0bf9c bellard
    case OPC_ERET:
4184 6af0bf9c bellard
        opn = "eret";
4185 6af0bf9c bellard
        save_cpu_state(ctx, 0);
4186 6af0bf9c bellard
        gen_op_eret();
4187 6af0bf9c bellard
        ctx->bstate = BS_EXCP;
4188 6af0bf9c bellard
        break;
4189 6af0bf9c bellard
    case OPC_DERET:
4190 6af0bf9c bellard
        opn = "deret";
4191 6af0bf9c bellard
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4192 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
4193 6af0bf9c bellard
        } else {
4194 6af0bf9c bellard
            save_cpu_state(ctx, 0);
4195 6af0bf9c bellard
            gen_op_deret();
4196 6af0bf9c bellard
            ctx->bstate = BS_EXCP;
4197 6af0bf9c bellard
        }
4198 6af0bf9c bellard
        break;
4199 4ad40f36 bellard
    case OPC_WAIT:
4200 4ad40f36 bellard
        opn = "wait";
4201 4ad40f36 bellard
        /* If we get an exception, we want to restart at next instruction */
4202 4ad40f36 bellard
        ctx->pc += 4;
4203 4ad40f36 bellard
        save_cpu_state(ctx, 1);
4204 4ad40f36 bellard
        ctx->pc -= 4;
4205 4ad40f36 bellard
        gen_op_wait();
4206 4ad40f36 bellard
        ctx->bstate = BS_EXCP;
4207 4ad40f36 bellard
        break;
4208 6af0bf9c bellard
    default:
4209 6af0bf9c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4210 6af0bf9c bellard
            fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
4211 6af0bf9c bellard
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4212 6af0bf9c bellard
                    ((ctx->opcode >> 16) & 0x1F));
4213 6af0bf9c bellard
        }
4214 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
4215 6af0bf9c bellard
        return;
4216 6af0bf9c bellard
    }
4217 6af0bf9c bellard
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4218 6af0bf9c bellard
}
4219 6af0bf9c bellard
4220 6ea83fed bellard
/* CP1 Branches (before delay slot) */
4221 7a387fff ths
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4222 6ea83fed bellard
                                 int32_t offset)
4223 6ea83fed bellard
{
4224 6ea83fed bellard
    target_ulong btarget;
4225 6ea83fed bellard
4226 6ea83fed bellard
    btarget = ctx->pc + 4 + offset;
4227 6ea83fed bellard
4228 7a387fff ths
    switch (op) {
4229 7a387fff ths
    case OPC_BC1F:
4230 6ea83fed bellard
        gen_op_bc1f();
4231 3594c774 ths
        MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
4232 6ea83fed bellard
        goto not_likely;
4233 7a387fff ths
    case OPC_BC1FL:
4234 6ea83fed bellard
        gen_op_bc1f();
4235 3594c774 ths
        MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
4236 6ea83fed bellard
        goto likely;
4237 7a387fff ths
    case OPC_BC1T:
4238 6ea83fed bellard
        gen_op_bc1t();
4239 3594c774 ths
        MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
4240 6ea83fed bellard
    not_likely:
4241 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BC;
4242 6ea83fed bellard
        break;
4243 7a387fff ths
    case OPC_BC1TL:
4244 6ea83fed bellard
        gen_op_bc1t();
4245 3594c774 ths
        MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
4246 6ea83fed bellard
    likely:
4247 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BL;
4248 6ea83fed bellard
        break;
4249 6ea83fed bellard
    default:    
4250 6ea83fed bellard
        MIPS_INVAL("cp1 branch/jump");
4251 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
4252 6ea83fed bellard
        return;
4253 6ea83fed bellard
    }
4254 6ea83fed bellard
    gen_op_set_bcond();
4255 6ea83fed bellard
4256 3594c774 ths
    MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
4257 6ea83fed bellard
               ctx->hflags, btarget);
4258 6ea83fed bellard
    ctx->btarget = btarget;
4259 6ea83fed bellard
4260 6ea83fed bellard
    return;
4261 6ea83fed bellard
}
4262 6ea83fed bellard
4263 6af0bf9c bellard
/* Coprocessor 1 (FPU) */
4264 7a387fff ths
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4265 6ea83fed bellard
{
4266 7a387fff ths
    const char *opn = "unk";
4267 6ea83fed bellard
4268 6ea83fed bellard
    switch (opc) {
4269 6ea83fed bellard
    case OPC_MFC1:
4270 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4271 6ea83fed bellard
        gen_op_mfc1();
4272 6ea83fed bellard
        GEN_STORE_TN_REG(rt, T0);
4273 6ea83fed bellard
        opn = "mfc1";
4274 6ea83fed bellard
        break;
4275 6ea83fed bellard
    case OPC_MTC1:
4276 6ea83fed bellard
        GEN_LOAD_REG_TN(T0, rt);
4277 6ea83fed bellard
        gen_op_mtc1();
4278 6ea83fed bellard
        GEN_STORE_FTN_FREG(fs, WT0);
4279 6ea83fed bellard
        opn = "mtc1";
4280 6ea83fed bellard
        break;
4281 6ea83fed bellard
    case OPC_CFC1:
4282 6ea83fed bellard
        if (fs != 0 && fs != 31) {
4283 6ea83fed bellard
            MIPS_INVAL("cfc1 freg");
4284 e397ee33 ths
            generate_exception (ctx, EXCP_RI);
4285 6ea83fed bellard
            return;
4286 6ea83fed bellard
        }
4287 6ea83fed bellard
        GEN_LOAD_IMM_TN(T1, fs);
4288 6ea83fed bellard
        gen_op_cfc1();
4289 6ea83fed bellard
        GEN_STORE_TN_REG(rt, T0);
4290 6ea83fed bellard
        opn = "cfc1";
4291 6ea83fed bellard
        break;
4292 6ea83fed bellard
    case OPC_CTC1:
4293 7a387fff ths
         if (fs != 0 && fs != 31) {
4294 6ea83fed bellard
            MIPS_INVAL("ctc1 freg");
4295 e397ee33 ths
            generate_exception (ctx, EXCP_RI);
4296 6ea83fed bellard
            return;
4297 6ea83fed bellard
        }
4298 6ea83fed bellard
        GEN_LOAD_IMM_TN(T1, fs);
4299 6ea83fed bellard
        GEN_LOAD_REG_TN(T0, rt);
4300 6ea83fed bellard
        gen_op_ctc1();
4301 6ea83fed bellard
        opn = "ctc1";
4302 6ea83fed bellard
        break;
4303 9c2149c8 ths
    case OPC_DMFC1:
4304 9c2149c8 ths
    case OPC_DMTC1:
4305 9c2149c8 ths
        /* Not implemented, fallthrough. */
4306 6ea83fed bellard
    default:
4307 6ea83fed bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4308 6ea83fed bellard
            fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
4309 6ea83fed bellard
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4310 6ea83fed bellard
                    ((ctx->opcode >> 16) & 0x1F));
4311 6ea83fed bellard
        }
4312 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
4313 6ea83fed bellard
        return;
4314 6ea83fed bellard
    }
4315 6ea83fed bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4316 6ea83fed bellard
}
4317 6ea83fed bellard
4318 6ea83fed bellard
/* verify if floating point register is valid; an operation is not defined
4319 6ea83fed bellard
 * if bit 0 of any register specification is set and the FR bit in the
4320 6ea83fed bellard
 * Status register equals zero, since the register numbers specify an
4321 6ea83fed bellard
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
4322 6ea83fed bellard
 * in the Status register equals one, both even and odd register numbers
4323 00a709c7 ths
 * are valid. This limitation exists only for 64 bit wide (d,l) registers.
4324 6ea83fed bellard
 * 
4325 00a709c7 ths
 * Multiple 64 bit wide registers can be checked by calling
4326 6ea83fed bellard
 * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
4327 6ea83fed bellard
 */
4328 6ea83fed bellard
#define CHECK_FR(ctx, freg) do { \
4329 6ea83fed bellard
        if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
4330 e397ee33 ths
            generate_exception (ctx, EXCP_RI); \
4331 6ea83fed bellard
            return; \
4332 6ea83fed bellard
        } \
4333 6ea83fed bellard
    } while(0)
4334 6ea83fed bellard
4335 6ea83fed bellard
#define FOP(func, fmt) (((fmt) << 21) | (func))
4336 6ea83fed bellard
4337 7a387fff ths
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
4338 6ea83fed bellard
{
4339 7a387fff ths
    const char *opn = "unk";
4340 6ea83fed bellard
    const char *condnames[] = {
4341 6ea83fed bellard
            "c.f",
4342 6ea83fed bellard
            "c.un",
4343 6ea83fed bellard
            "c.eq",
4344 6ea83fed bellard
            "c.ueq",
4345 6ea83fed bellard
            "c.olt",
4346 6ea83fed bellard
            "c.ult",
4347 6ea83fed bellard
            "c.ole",
4348 6ea83fed bellard
            "c.ule",
4349 6ea83fed bellard
            "c.sf",
4350 6ea83fed bellard
            "c.ngle",
4351 6ea83fed bellard
            "c.seq",
4352 6ea83fed bellard
            "c.ngl",
4353 6ea83fed bellard
            "c.lt",
4354 6ea83fed bellard
            "c.nge",
4355 6ea83fed bellard
            "c.le",
4356 6ea83fed bellard
            "c.ngt",
4357 6ea83fed bellard
    };
4358 6ea83fed bellard
    int binary = 0;
4359 7a387fff ths
    uint32_t func = ctx->opcode & 0x3f;
4360 7a387fff ths
4361 6ea83fed bellard
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4362 6ea83fed bellard
    case FOP(0, 17):
4363 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
4364 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4365 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4366 6ea83fed bellard
        gen_op_float_add_d();
4367 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4368 6ea83fed bellard
        opn = "add.d";
4369 6ea83fed bellard
        binary = 1;
4370 6ea83fed bellard
        break;
4371 6ea83fed bellard
    case FOP(1, 17):
4372 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
4373 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4374 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4375 6ea83fed bellard
        gen_op_float_sub_d();
4376 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4377 6ea83fed bellard
        opn = "sub.d";
4378 6ea83fed bellard
        binary = 1;
4379 6ea83fed bellard
        break;
4380 6ea83fed bellard
    case FOP(2, 17):
4381 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
4382 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4383 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4384 6ea83fed bellard
        gen_op_float_mul_d();
4385 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4386 6ea83fed bellard
        opn = "mul.d";
4387 6ea83fed bellard
        binary = 1;
4388 6ea83fed bellard
        break;
4389 6ea83fed bellard
    case FOP(3, 17):
4390 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
4391 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4392 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4393 6ea83fed bellard
        gen_op_float_div_d();
4394 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4395 6ea83fed bellard
        opn = "div.d";
4396 6ea83fed bellard
        binary = 1;
4397 6ea83fed bellard
        break;
4398 6ea83fed bellard
    case FOP(4, 17):
4399 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
4400 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4401 6ea83fed bellard
        gen_op_float_sqrt_d();
4402 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4403 6ea83fed bellard
        opn = "sqrt.d";
4404 6ea83fed bellard
        break;
4405 6ea83fed bellard
    case FOP(5, 17):
4406 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
4407 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4408 6ea83fed bellard
        gen_op_float_abs_d();
4409 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4410 6ea83fed bellard
        opn = "abs.d";
4411 6ea83fed bellard
        break;
4412 6ea83fed bellard
    case FOP(6, 17):
4413 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
4414 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4415 6ea83fed bellard
        gen_op_float_mov_d();
4416 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4417 6ea83fed bellard
        opn = "mov.d";
4418 6ea83fed bellard
        break;
4419 6ea83fed bellard
    case FOP(7, 17):
4420 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
4421 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4422 6ea83fed bellard
        gen_op_float_chs_d();
4423 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4424 6ea83fed bellard
        opn = "neg.d";
4425 6ea83fed bellard
        break;
4426 6ea83fed bellard
    /*  8 - round.l */
4427 6ea83fed bellard
    /*  9 - trunc.l */
4428 6ea83fed bellard
    /* 10 - ceil.l  */
4429 6ea83fed bellard
    /* 11 - floor.l */
4430 6ea83fed bellard
    case FOP(12, 17):
4431 00a709c7 ths
        CHECK_FR(ctx, fs);
4432 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4433 6ea83fed bellard
        gen_op_float_roundw_d();
4434 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4435 6ea83fed bellard
        opn = "round.w.d";
4436 6ea83fed bellard
        break;
4437 6ea83fed bellard
    case FOP(13, 17):
4438 00a709c7 ths
        CHECK_FR(ctx, fs);
4439 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4440 6ea83fed bellard
        gen_op_float_truncw_d();
4441 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4442 6ea83fed bellard
        opn = "trunc.w.d";
4443 6ea83fed bellard
        break;
4444 6ea83fed bellard
    case FOP(14, 17):
4445 00a709c7 ths
        CHECK_FR(ctx, fs);
4446 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4447 6ea83fed bellard
        gen_op_float_ceilw_d();
4448 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4449 6ea83fed bellard
        opn = "ceil.w.d";
4450 6ea83fed bellard
        break;
4451 6ea83fed bellard
    case FOP(15, 17):
4452 00a709c7 ths
        CHECK_FR(ctx, fs);
4453 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4454 6ea83fed bellard
        gen_op_float_floorw_d();
4455 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4456 7a387fff ths
        opn = "floor.w.d";
4457 6ea83fed bellard
        break;
4458 00a709c7 ths
    case FOP(33, 16):
4459 00a709c7 ths
        CHECK_FR(ctx, fd);
4460 dd016883 bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4461 dd016883 bellard
        gen_op_float_cvtd_s();
4462 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4463 dd016883 bellard
        opn = "cvt.d.s";
4464 dd016883 bellard
        break;
4465 00a709c7 ths
    case FOP(33, 20):
4466 00a709c7 ths
        CHECK_FR(ctx, fd);
4467 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4468 6ea83fed bellard
        gen_op_float_cvtd_w();
4469 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4470 6ea83fed bellard
        opn = "cvt.d.w";
4471 6ea83fed bellard
        break;
4472 6ea83fed bellard
    case FOP(48, 17):
4473 6ea83fed bellard
    case FOP(49, 17):
4474 6ea83fed bellard
    case FOP(50, 17):
4475 6ea83fed bellard
    case FOP(51, 17):
4476 6ea83fed bellard
    case FOP(52, 17):
4477 6ea83fed bellard
    case FOP(53, 17):
4478 6ea83fed bellard
    case FOP(54, 17):
4479 6ea83fed bellard
    case FOP(55, 17):
4480 6ea83fed bellard
    case FOP(56, 17):
4481 6ea83fed bellard
    case FOP(57, 17):
4482 6ea83fed bellard
    case FOP(58, 17):
4483 6ea83fed bellard
    case FOP(59, 17):
4484 6ea83fed bellard
    case FOP(60, 17):
4485 6ea83fed bellard
    case FOP(61, 17):
4486 6ea83fed bellard
    case FOP(62, 17):
4487 6ea83fed bellard
    case FOP(63, 17):
4488 6ea83fed bellard
        CHECK_FR(ctx, fs | ft);
4489 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4490 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4491 6ea83fed bellard
        gen_cmp_d(func-48);
4492 6ea83fed bellard
        opn = condnames[func-48];
4493 6ea83fed bellard
        break;
4494 6ea83fed bellard
    case FOP(0, 16):
4495 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4496 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4497 6ea83fed bellard
        gen_op_float_add_s();
4498 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4499 6ea83fed bellard
        opn = "add.s";
4500 6ea83fed bellard
        binary = 1;
4501 6ea83fed bellard
        break;
4502 6ea83fed bellard
    case FOP(1, 16):
4503 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4504 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4505 6ea83fed bellard
        gen_op_float_sub_s();
4506 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4507 6ea83fed bellard
        opn = "sub.s";
4508 6ea83fed bellard
        binary = 1;
4509 6ea83fed bellard
        break;
4510 6ea83fed bellard
    case FOP(2, 16):
4511 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4512 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4513 6ea83fed bellard
        gen_op_float_mul_s();
4514 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4515 6ea83fed bellard
        opn = "mul.s";
4516 6ea83fed bellard
        binary = 1;
4517 6ea83fed bellard
        break;
4518 6ea83fed bellard
    case FOP(3, 16):
4519 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4520 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4521 6ea83fed bellard
        gen_op_float_div_s();
4522 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4523 6ea83fed bellard
        opn = "div.s";
4524 6ea83fed bellard
        binary = 1;
4525 6ea83fed bellard
        break;
4526 6ea83fed bellard
    case FOP(4, 16):
4527 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4528 6ea83fed bellard
        gen_op_float_sqrt_s();
4529 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4530 6ea83fed bellard
        opn = "sqrt.s";
4531 6ea83fed bellard
        break;
4532 6ea83fed bellard
    case FOP(5, 16):
4533 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4534 6ea83fed bellard
        gen_op_float_abs_s();
4535 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4536 6ea83fed bellard
        opn = "abs.s";
4537 6ea83fed bellard
        break;
4538 6ea83fed bellard
    case FOP(6, 16):
4539 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4540 6ea83fed bellard
        gen_op_float_mov_s();
4541 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4542 6ea83fed bellard
        opn = "mov.s";
4543 6ea83fed bellard
        break;
4544 6ea83fed bellard
    case FOP(7, 16):
4545 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4546 6ea83fed bellard
        gen_op_float_chs_s();
4547 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4548 6ea83fed bellard
        opn = "neg.s";
4549 6ea83fed bellard
        break;
4550 6ea83fed bellard
    case FOP(12, 16):
4551 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4552 6ea83fed bellard
        gen_op_float_roundw_s();
4553 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4554 6ea83fed bellard
        opn = "round.w.s";
4555 6ea83fed bellard
        break;
4556 6ea83fed bellard
    case FOP(13, 16):
4557 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4558 6ea83fed bellard
        gen_op_float_truncw_s();
4559 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4560 6ea83fed bellard
        opn = "trunc.w.s";
4561 6ea83fed bellard
        break;
4562 00a709c7 ths
    case FOP(32, 17):
4563 00a709c7 ths
        CHECK_FR(ctx, fs);
4564 417f38f0 pbrook
        GEN_LOAD_FREG_FTN(DT0, fs);
4565 dd016883 bellard
        gen_op_float_cvts_d();
4566 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4567 dd016883 bellard
        opn = "cvt.s.d";
4568 dd016883 bellard
        break;
4569 00a709c7 ths
    case FOP(32, 20):
4570 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4571 6ea83fed bellard
        gen_op_float_cvts_w();
4572 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4573 6ea83fed bellard
        opn = "cvt.s.w";
4574 6ea83fed bellard
        break;
4575 00a709c7 ths
    case FOP(36, 16):
4576 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4577 6ea83fed bellard
        gen_op_float_cvtw_s();
4578 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4579 6ea83fed bellard
        opn = "cvt.w.s";
4580 6ea83fed bellard
        break;
4581 00a709c7 ths
    case FOP(36, 17):
4582 00a709c7 ths
        CHECK_FR(ctx, fs);
4583 417f38f0 pbrook
        GEN_LOAD_FREG_FTN(DT0, fs);
4584 6ea83fed bellard
        gen_op_float_cvtw_d();
4585 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4586 6ea83fed bellard
        opn = "cvt.w.d";
4587 6ea83fed bellard
        break;
4588 6ea83fed bellard
    case FOP(48, 16):
4589 6ea83fed bellard
    case FOP(49, 16):
4590 6ea83fed bellard
    case FOP(50, 16):
4591 6ea83fed bellard
    case FOP(51, 16):
4592 6ea83fed bellard
    case FOP(52, 16):
4593 6ea83fed bellard
    case FOP(53, 16):
4594 6ea83fed bellard
    case FOP(54, 16):
4595 6ea83fed bellard
    case FOP(55, 16):
4596 6ea83fed bellard
    case FOP(56, 16):
4597 6ea83fed bellard
    case FOP(57, 16):
4598 6ea83fed bellard
    case FOP(58, 16):
4599 6ea83fed bellard
    case FOP(59, 16):
4600 6ea83fed bellard
    case FOP(60, 16):
4601 6ea83fed bellard
    case FOP(61, 16):
4602 6ea83fed bellard
    case FOP(62, 16):
4603 6ea83fed bellard
    case FOP(63, 16):
4604 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4605 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4606 6ea83fed bellard
        gen_cmp_s(func-48);
4607 6ea83fed bellard
        opn = condnames[func-48];
4608 6ea83fed bellard
        break;
4609 6ea83fed bellard
    default:    
4610 6ea83fed bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
4611 7a387fff ths
            fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
4612 6ea83fed bellard
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4613 6ea83fed bellard
                    ((ctx->opcode >> 16) & 0x1F));
4614 6ea83fed bellard
        }
4615 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
4616 6ea83fed bellard
        return;
4617 6ea83fed bellard
    }
4618 6ea83fed bellard
    if (binary)
4619 6ea83fed bellard
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
4620 6ea83fed bellard
    else
4621 6ea83fed bellard
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
4622 6ea83fed bellard
}
4623 6af0bf9c bellard
4624 7a387fff ths
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4625 7a387fff ths
{
4626 7a387fff ths
    uint32_t ccbit;
4627 7a387fff ths
4628 7a387fff ths
    if (cc)
4629 7a387fff ths
        ccbit = 1 << (24 + cc);
4630 7a387fff ths
    else
4631 7a387fff ths
        ccbit = 1 << 23;
4632 7a387fff ths
    if (!tf)
4633 7a387fff ths
        gen_op_movf(ccbit, rd, rs);
4634 7a387fff ths
    else
4635 7a387fff ths
       gen_op_movt(ccbit, rd, rs);
4636 7a387fff ths
}
4637 7a387fff ths
4638 7a387fff ths
/* ISA extensions (ASEs) */
4639 6af0bf9c bellard
/* MIPS16 extension to MIPS32 */
4640 6af0bf9c bellard
/* SmartMIPS extension to MIPS32 */
4641 6af0bf9c bellard
4642 60aa19ab ths
#ifdef TARGET_MIPS64
4643 6af0bf9c bellard
/* Coprocessor 3 (FPU) */
4644 6af0bf9c bellard
4645 6af0bf9c bellard
/* MDMX extension to MIPS64 */
4646 6af0bf9c bellard
/* MIPS-3D extension to MIPS64 */
4647 6af0bf9c bellard
4648 6af0bf9c bellard
#endif
4649 6af0bf9c bellard
4650 c53be334 bellard
static void gen_blikely(DisasContext *ctx)
4651 c53be334 bellard
{
4652 eeef26cd bellard
    int l1;
4653 eeef26cd bellard
    l1 = gen_new_label();
4654 eeef26cd bellard
    gen_op_jnz_T2(l1);
4655 4ad40f36 bellard
    gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
4656 eeef26cd bellard
    gen_goto_tb(ctx, 1, ctx->pc + 4);
4657 eeef26cd bellard
    gen_set_label(l1);
4658 c53be334 bellard
}
4659 c53be334 bellard
4660 36d23958 ths
static void decode_opc (CPUState *env, DisasContext *ctx)
4661 6af0bf9c bellard
{
4662 6af0bf9c bellard
    int32_t offset;
4663 6af0bf9c bellard
    int rs, rt, rd, sa;
4664 7a387fff ths
    uint32_t op, op1, op2;
4665 6af0bf9c bellard
    int16_t imm;
4666 6af0bf9c bellard
4667 d796321b bellard
    /* make sure instructions are on a word boundary */
4668 d796321b bellard
    if (ctx->pc & 0x3) {
4669 cbeb0857 ths
        env->CP0_BadVAddr = ctx->pc;
4670 d796321b bellard
        generate_exception(ctx, EXCP_AdEL);
4671 d796321b bellard
        return;
4672 d796321b bellard
    }
4673 d796321b bellard
4674 4ad40f36 bellard
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
4675 6af0bf9c bellard
        /* Handle blikely not taken case */
4676 3594c774 ths
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
4677 c53be334 bellard
        gen_blikely(ctx);
4678 6af0bf9c bellard
    }
4679 7a387fff ths
    op = MASK_OP_MAJOR(ctx->opcode);
4680 7a387fff ths
    rs = (ctx->opcode >> 21) & 0x1f;
4681 7a387fff ths
    rt = (ctx->opcode >> 16) & 0x1f;
4682 7a387fff ths
    rd = (ctx->opcode >> 11) & 0x1f;
4683 7a387fff ths
    sa = (ctx->opcode >> 6) & 0x1f;
4684 6af0bf9c bellard
    imm = (int16_t)ctx->opcode;
4685 6af0bf9c bellard
    switch (op) {
4686 7a387fff ths
    case OPC_SPECIAL:
4687 7a387fff ths
        op1 = MASK_SPECIAL(ctx->opcode);
4688 6af0bf9c bellard
        switch (op1) {
4689 7a387fff ths
        case OPC_SLL:          /* Arithmetic with immediate */
4690 7a387fff ths
        case OPC_SRL ... OPC_SRA:
4691 7a387fff ths
            gen_arith_imm(ctx, op1, rd, rt, sa);
4692 7a387fff ths
            break;
4693 7a387fff ths
        case OPC_SLLV:         /* Arithmetic */
4694 7a387fff ths
        case OPC_SRLV ... OPC_SRAV:
4695 7a387fff ths
        case OPC_MOVZ ... OPC_MOVN:
4696 7a387fff ths
        case OPC_ADD ... OPC_NOR:
4697 7a387fff ths
        case OPC_SLT ... OPC_SLTU:
4698 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
4699 7a387fff ths
            break;
4700 7a387fff ths
        case OPC_MULT ... OPC_DIVU:
4701 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
4702 7a387fff ths
            break;
4703 7a387fff ths
        case OPC_JR ... OPC_JALR:
4704 7a387fff ths
            gen_compute_branch(ctx, op1, rs, rd, sa);
4705 6af0bf9c bellard
            return;
4706 7a387fff ths
        case OPC_TGE ... OPC_TEQ: /* Traps */
4707 7a387fff ths
        case OPC_TNE:
4708 7a387fff ths
            gen_trap(ctx, op1, rs, rt, -1);
4709 6af0bf9c bellard
            break;
4710 7a387fff ths
        case OPC_MFHI:          /* Move from HI/LO */
4711 7a387fff ths
        case OPC_MFLO:
4712 7a387fff ths
            gen_HILO(ctx, op1, rd);
4713 6af0bf9c bellard
            break;
4714 7a387fff ths
        case OPC_MTHI:
4715 7a387fff ths
        case OPC_MTLO:          /* Move to HI/LO */
4716 7a387fff ths
            gen_HILO(ctx, op1, rs);
4717 6af0bf9c bellard
            break;
4718 b48cfdff ths
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
4719 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
4720 b48cfdff ths
            MIPS_INVAL("PMON / selsl");
4721 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
4722 b48cfdff ths
#else
4723 7a387fff ths
            gen_op_pmon(sa);
4724 b48cfdff ths
#endif
4725 7a387fff ths
            break;
4726 7a387fff ths
        case OPC_SYSCALL:
4727 6af0bf9c bellard
            generate_exception(ctx, EXCP_SYSCALL);
4728 6af0bf9c bellard
            break;
4729 7a387fff ths
        case OPC_BREAK:
4730 6af0bf9c bellard
            generate_exception(ctx, EXCP_BREAK);
4731 6af0bf9c bellard
            break;
4732 b48cfdff ths
        case OPC_SPIM:
4733 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
4734 b48cfdff ths
            MIPS_INVAL("SPIM");
4735 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
4736 b48cfdff ths
#else
4737 7a387fff ths
           /* Implemented as RI exception for now. */
4738 7a387fff ths
            MIPS_INVAL("spim (unofficial)");
4739 7a387fff ths
            generate_exception(ctx, EXCP_RI);
4740 b48cfdff ths
#endif
4741 6af0bf9c bellard
            break;
4742 7a387fff ths
        case OPC_SYNC:
4743 7a387fff ths
            /* Treat as a noop. */
4744 6af0bf9c bellard
            break;
4745 4ad40f36 bellard
4746 7a387fff ths
        case OPC_MOVCI:
4747 36d23958 ths
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4748 e397ee33 ths
                save_cpu_state(ctx, 1);
4749 36d23958 ths
                gen_op_cp1_enabled();
4750 36d23958 ths
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
4751 36d23958 ths
                          (ctx->opcode >> 16) & 1);
4752 36d23958 ths
            } else {
4753 e397ee33 ths
                generate_exception_err(ctx, EXCP_CpU, 1);
4754 36d23958 ths
            }
4755 4ad40f36 bellard
            break;
4756 4ad40f36 bellard
4757 60aa19ab ths
#ifdef TARGET_MIPS64
4758 7a387fff ths
       /* MIPS64 specific opcodes */
4759 7a387fff ths
        case OPC_DSLL:
4760 7a387fff ths
        case OPC_DSRL ... OPC_DSRA:
4761 7a387fff ths
        case OPC_DSLL32:
4762 7a387fff ths
        case OPC_DSRL32 ... OPC_DSRA32:
4763 7a387fff ths
            gen_arith_imm(ctx, op1, rd, rt, sa);
4764 7a387fff ths
            break;
4765 7a387fff ths
        case OPC_DSLLV:
4766 7a387fff ths
        case OPC_DSRLV ... OPC_DSRAV:
4767 7a387fff ths
        case OPC_DADD ... OPC_DSUBU:
4768 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
4769 7a387fff ths
            break;
4770 7a387fff ths
        case OPC_DMULT ... OPC_DDIVU:
4771 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
4772 7a387fff ths
            break;
4773 6af0bf9c bellard
#endif
4774 6af0bf9c bellard
        default:            /* Invalid */
4775 6af0bf9c bellard
            MIPS_INVAL("special");
4776 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
4777 6af0bf9c bellard
            break;
4778 6af0bf9c bellard
        }
4779 6af0bf9c bellard
        break;
4780 7a387fff ths
    case OPC_SPECIAL2:
4781 7a387fff ths
        op1 = MASK_SPECIAL2(ctx->opcode);
4782 6af0bf9c bellard
        switch (op1) {
4783 7a387fff ths
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
4784 7a387fff ths
        case OPC_MSUB ... OPC_MSUBU:
4785 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
4786 6af0bf9c bellard
            break;
4787 7a387fff ths
        case OPC_MUL:
4788 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
4789 6af0bf9c bellard
            break;
4790 7a387fff ths
        case OPC_CLZ ... OPC_CLO:
4791 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
4792 6af0bf9c bellard
            break;
4793 7a387fff ths
        case OPC_SDBBP:
4794 6af0bf9c bellard
            /* XXX: not clear which exception should be raised
4795 6af0bf9c bellard
             *      when in debug mode...
4796 6af0bf9c bellard
             */
4797 6af0bf9c bellard
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4798 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
4799 6af0bf9c bellard
            } else {
4800 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
4801 6af0bf9c bellard
            }
4802 6af0bf9c bellard
            /* Treat as a noop */
4803 6af0bf9c bellard
            break;
4804 60aa19ab ths
#ifdef TARGET_MIPS64
4805 7a387fff ths
        case OPC_DCLZ ... OPC_DCLO:
4806 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
4807 7a387fff ths
            break;
4808 7a387fff ths
#endif
4809 6af0bf9c bellard
        default:            /* Invalid */
4810 6af0bf9c bellard
            MIPS_INVAL("special2");
4811 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
4812 6af0bf9c bellard
            break;
4813 6af0bf9c bellard
        }
4814 6af0bf9c bellard
        break;
4815 7a387fff ths
    case OPC_SPECIAL3:
4816 1579a72e ths
         op1 = MASK_SPECIAL3(ctx->opcode);
4817 1579a72e ths
         switch (op1) {
4818 1579a72e ths
         case OPC_EXT:
4819 1579a72e ths
         case OPC_INS:
4820 1579a72e ths
             gen_bitops(ctx, op1, rt, rs, sa, rd);
4821 1579a72e ths
             break;
4822 1579a72e ths
         case OPC_BSHFL:
4823 1579a72e ths
             op2 = MASK_BSHFL(ctx->opcode);
4824 1579a72e ths
             switch (op2) {
4825 1579a72e ths
             case OPC_WSBH:
4826 1579a72e ths
                 GEN_LOAD_REG_TN(T1, rt);
4827 1579a72e ths
                 gen_op_wsbh();
4828 1579a72e ths
                 break;
4829 1579a72e ths
             case OPC_SEB:
4830 1579a72e ths
                 GEN_LOAD_REG_TN(T1, rt);
4831 1579a72e ths
                 gen_op_seb();
4832 1579a72e ths
                 break;
4833 1579a72e ths
             case OPC_SEH:
4834 1579a72e ths
                 GEN_LOAD_REG_TN(T1, rt);
4835 1579a72e ths
                 gen_op_seh();
4836 1579a72e ths
                 break;
4837 1579a72e ths
             default:            /* Invalid */
4838 1579a72e ths
                 MIPS_INVAL("bshfl");
4839 1579a72e ths
                 generate_exception(ctx, EXCP_RI);
4840 1579a72e ths
                 break;
4841 1579a72e ths
            }
4842 1579a72e ths
            GEN_STORE_TN_REG(rd, T0);
4843 7a387fff ths
            break;
4844 1579a72e ths
        case OPC_RDHWR:
4845 1579a72e ths
            switch (rd) {
4846 1579a72e ths
            case 0:
4847 97428a4d ths
                save_cpu_state(ctx, 1);
4848 1579a72e ths
                gen_op_rdhwr_cpunum();
4849 7a387fff ths
                break;
4850 1579a72e ths
            case 1:
4851 97428a4d ths
                save_cpu_state(ctx, 1);
4852 1579a72e ths
                gen_op_rdhwr_synci_step();
4853 7a387fff ths
                break;
4854 1579a72e ths
            case 2:
4855 97428a4d ths
                save_cpu_state(ctx, 1);
4856 1579a72e ths
                gen_op_rdhwr_cc();
4857 7a387fff ths
                break;
4858 1579a72e ths
            case 3:
4859 97428a4d ths
                save_cpu_state(ctx, 1);
4860 1579a72e ths
                gen_op_rdhwr_ccres();
4861 7a387fff ths
                break;
4862 1579a72e ths
            case 29:
4863 6f5b89a0 ths
#if defined (CONFIG_USER_ONLY)
4864 1579a72e ths
                gen_op_tls_value ();
4865 1579a72e ths
                break;
4866 97428a4d ths
#endif
4867 1579a72e ths
            default:            /* Invalid */
4868 1579a72e ths
                MIPS_INVAL("rdhwr");
4869 1579a72e ths
                generate_exception(ctx, EXCP_RI);
4870 1579a72e ths
                break;
4871 1579a72e ths
            }
4872 1579a72e ths
            GEN_STORE_TN_REG(rt, T0);
4873 1579a72e ths
            break;
4874 60aa19ab ths
#ifdef TARGET_MIPS64
4875 1579a72e ths
        case OPC_DEXTM ... OPC_DEXT:
4876 1579a72e ths
        case OPC_DINSM ... OPC_DINS:
4877 1579a72e ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
4878 7a387fff ths
            break;
4879 1579a72e ths
        case OPC_DBSHFL:
4880 1579a72e ths
            op2 = MASK_DBSHFL(ctx->opcode);
4881 1579a72e ths
            switch (op2) {
4882 1579a72e ths
            case OPC_DSBH:
4883 1579a72e ths
                GEN_LOAD_REG_TN(T1, rt);
4884 1579a72e ths
                gen_op_dsbh();
4885 1579a72e ths
                break;
4886 1579a72e ths
            case OPC_DSHD:
4887 1579a72e ths
                GEN_LOAD_REG_TN(T1, rt);
4888 1579a72e ths
                gen_op_dshd();
4889 1579a72e ths
                break;
4890 7a387fff ths
            default:            /* Invalid */
4891 7a387fff ths
                MIPS_INVAL("dbshfl");
4892 7a387fff ths
                generate_exception(ctx, EXCP_RI);
4893 7a387fff ths
                break;
4894 1579a72e ths
            }
4895 1579a72e ths
            GEN_STORE_TN_REG(rd, T0);
4896 7a387fff ths
#endif
4897 7a387fff ths
        default:            /* Invalid */
4898 7a387fff ths
            MIPS_INVAL("special3");
4899 7a387fff ths
            generate_exception(ctx, EXCP_RI);
4900 7a387fff ths
            break;
4901 7a387fff ths
        }
4902 7a387fff ths
        break;
4903 7a387fff ths
    case OPC_REGIMM:
4904 7a387fff ths
        op1 = MASK_REGIMM(ctx->opcode);
4905 7a387fff ths
        switch (op1) {
4906 7a387fff ths
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
4907 7a387fff ths
        case OPC_BLTZAL ... OPC_BGEZALL:
4908 7a387fff ths
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
4909 6af0bf9c bellard
            return;
4910 7a387fff ths
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
4911 7a387fff ths
        case OPC_TNEI:
4912 7a387fff ths
            gen_trap(ctx, op1, rs, -1, imm);
4913 7a387fff ths
            break;
4914 7a387fff ths
        case OPC_SYNCI:
4915 24c7b0e3 ths
            /* treat as noop */
4916 6af0bf9c bellard
            break;
4917 6af0bf9c bellard
        default:            /* Invalid */
4918 6af0bf9c bellard
            MIPS_INVAL("REGIMM");
4919 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
4920 6af0bf9c bellard
            break;
4921 6af0bf9c bellard
        }
4922 6af0bf9c bellard
        break;
4923 7a387fff ths
    case OPC_CP0:
4924 f41c52f1 ths
        save_cpu_state(ctx, 1);
4925 24c7b0e3 ths
        gen_op_cp0_enabled();
4926 7a387fff ths
        op1 = MASK_CP0(ctx->opcode);
4927 6af0bf9c bellard
        switch (op1) {
4928 7a387fff ths
        case OPC_MFC0:
4929 7a387fff ths
        case OPC_MTC0:
4930 60aa19ab ths
#ifdef TARGET_MIPS64
4931 7a387fff ths
        case OPC_DMFC0:
4932 7a387fff ths
        case OPC_DMTC0:
4933 7a387fff ths
#endif
4934 7a387fff ths
            gen_cp0(ctx, op1, rt, rd);
4935 7a387fff ths
            break;
4936 7a387fff ths
        case OPC_C0_FIRST ... OPC_C0_LAST:
4937 7a387fff ths
            gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
4938 7a387fff ths
            break;
4939 7a387fff ths
        case OPC_MFMC0:
4940 7a387fff ths
            op2 = MASK_MFMC0(ctx->opcode);
4941 7a387fff ths
            switch (op2) {
4942 7a387fff ths
            case OPC_DI:
4943 7a387fff ths
                gen_op_di();
4944 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
4945 7a387fff ths
                ctx->bstate = BS_STOP;
4946 7a387fff ths
                break;
4947 7a387fff ths
            case OPC_EI:
4948 7a387fff ths
                gen_op_ei();
4949 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
4950 7a387fff ths
                ctx->bstate = BS_STOP;
4951 7a387fff ths
                break;
4952 7a387fff ths
            default:            /* Invalid */
4953 7a387fff ths
                MIPS_INVAL("MFMC0");
4954 7a387fff ths
                generate_exception(ctx, EXCP_RI);
4955 7a387fff ths
                break;
4956 7a387fff ths
            }
4957 7a387fff ths
            GEN_STORE_TN_REG(rt, T0);
4958 6af0bf9c bellard
            break;
4959 7a387fff ths
        case OPC_RDPGPR:
4960 7a387fff ths
        case OPC_WRPGPR:
4961 38121543 ths
            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
4962 38121543 ths
                /* Shadow registers not implemented. */
4963 38121543 ths
                GEN_LOAD_REG_TN(T0, rt);
4964 38121543 ths
                GEN_STORE_TN_REG(rd, T0);
4965 38121543 ths
            } else
4966 38121543 ths
                generate_exception(ctx, EXCP_RI);
4967 38121543 ths
            break;
4968 6af0bf9c bellard
        default:
4969 7a387fff ths
            generate_exception(ctx, EXCP_RI);
4970 6af0bf9c bellard
            break;
4971 6af0bf9c bellard
        }
4972 6af0bf9c bellard
        break;
4973 7a387fff ths
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
4974 7a387fff ths
         gen_arith_imm(ctx, op, rt, rs, imm);
4975 7a387fff ths
         break;
4976 7a387fff ths
    case OPC_J ... OPC_JAL: /* Jump */
4977 7a387fff ths
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
4978 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, offset);
4979 7a387fff ths
         return;
4980 7a387fff ths
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
4981 7a387fff ths
    case OPC_BEQL ... OPC_BGTZL:
4982 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
4983 7a387fff ths
         return;
4984 7a387fff ths
    case OPC_LB ... OPC_LWR: /* Load and stores */
4985 7a387fff ths
    case OPC_SB ... OPC_SW:
4986 7a387fff ths
    case OPC_SWR:
4987 7a387fff ths
    case OPC_LL:
4988 7a387fff ths
    case OPC_SC:
4989 7a387fff ths
         gen_ldst(ctx, op, rt, rs, imm);
4990 7a387fff ths
         break;
4991 7a387fff ths
    case OPC_CACHE:
4992 7a387fff ths
         /* Treat as a noop */
4993 7a387fff ths
         break;
4994 7a387fff ths
    case OPC_PREF:
4995 6af0bf9c bellard
        /* Treat as a noop */
4996 6af0bf9c bellard
        break;
4997 4ad40f36 bellard
4998 4ad40f36 bellard
    /* Floating point.  */
4999 7a387fff ths
    case OPC_LWC1:
5000 7a387fff ths
    case OPC_LDC1:
5001 7a387fff ths
    case OPC_SWC1:
5002 7a387fff ths
    case OPC_SDC1:
5003 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5004 36d23958 ths
            save_cpu_state(ctx, 1);
5005 36d23958 ths
            gen_op_cp1_enabled();
5006 36d23958 ths
            gen_flt_ldst(ctx, op, rt, rs, imm);
5007 36d23958 ths
        } else {
5008 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
5009 36d23958 ths
        }
5010 6ea83fed bellard
        break;
5011 6ea83fed bellard
5012 7a387fff ths
    case OPC_CP1:
5013 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5014 36d23958 ths
            save_cpu_state(ctx, 1);
5015 36d23958 ths
            gen_op_cp1_enabled();
5016 36d23958 ths
            op1 = MASK_CP1(ctx->opcode);
5017 36d23958 ths
            switch (op1) {
5018 36d23958 ths
            case OPC_MFC1:
5019 36d23958 ths
            case OPC_CFC1:
5020 36d23958 ths
            case OPC_MTC1:
5021 36d23958 ths
            case OPC_CTC1:
5022 60aa19ab ths
#ifdef TARGET_MIPS64
5023 36d23958 ths
            case OPC_DMFC1:
5024 36d23958 ths
            case OPC_DMTC1:
5025 9c2149c8 ths
#endif
5026 36d23958 ths
                gen_cp1(ctx, op1, rt, rd);
5027 36d23958 ths
                break;
5028 36d23958 ths
            case OPC_BC1:
5029 36d23958 ths
                gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
5030 36d23958 ths
                return;
5031 36d23958 ths
            case OPC_S_FMT:
5032 36d23958 ths
            case OPC_D_FMT:
5033 36d23958 ths
            case OPC_W_FMT:
5034 36d23958 ths
            case OPC_L_FMT:
5035 36d23958 ths
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
5036 36d23958 ths
                break;
5037 36d23958 ths
            default:
5038 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
5039 36d23958 ths
                break;
5040 36d23958 ths
            }
5041 36d23958 ths
        } else {
5042 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
5043 6ea83fed bellard
        }
5044 4ad40f36 bellard
        break;
5045 4ad40f36 bellard
5046 4ad40f36 bellard
    /* COP2.  */
5047 7a387fff ths
    case OPC_LWC2:
5048 7a387fff ths
    case OPC_LDC2:
5049 7a387fff ths
    case OPC_SWC2:
5050 7a387fff ths
    case OPC_SDC2:
5051 7a387fff ths
    case OPC_CP2:
5052 7a387fff ths
        /* COP2: Not implemented. */
5053 4ad40f36 bellard
        generate_exception_err(ctx, EXCP_CpU, 2);
5054 4ad40f36 bellard
        break;
5055 4ad40f36 bellard
5056 7a387fff ths
    case OPC_CP3:
5057 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5058 e397ee33 ths
            save_cpu_state(ctx, 1);
5059 36d23958 ths
            gen_op_cp1_enabled();
5060 36d23958 ths
            op1 = MASK_CP3(ctx->opcode);
5061 36d23958 ths
            switch (op1) {
5062 e0c84da7 ths
            case OPC_PREFX:
5063 e0c84da7 ths
                /* treat as noop */
5064 e0c84da7 ths
                break;
5065 36d23958 ths
            /* Not implemented */
5066 36d23958 ths
            default:
5067 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
5068 36d23958 ths
                break;
5069 36d23958 ths
            }
5070 36d23958 ths
        } else {
5071 e397ee33 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
5072 7a387fff ths
        }
5073 4ad40f36 bellard
        break;
5074 4ad40f36 bellard
5075 60aa19ab ths
#ifdef TARGET_MIPS64
5076 7a387fff ths
    /* MIPS64 opcodes */
5077 7a387fff ths
    case OPC_LWU:
5078 7a387fff ths
    case OPC_LDL ... OPC_LDR:
5079 7a387fff ths
    case OPC_SDL ... OPC_SDR:
5080 7a387fff ths
    case OPC_LLD:
5081 7a387fff ths
    case OPC_LD:
5082 7a387fff ths
    case OPC_SCD:
5083 7a387fff ths
    case OPC_SD:
5084 7a387fff ths
        gen_ldst(ctx, op, rt, rs, imm);
5085 7a387fff ths
        break;
5086 7a387fff ths
    case OPC_DADDI ... OPC_DADDIU:
5087 7a387fff ths
        gen_arith_imm(ctx, op, rt, rs, imm);
5088 7a387fff ths
        break;
5089 6af0bf9c bellard
#endif
5090 7a387fff ths
#ifdef MIPS_HAS_MIPS16
5091 7a387fff ths
    case OPC_JALX:
5092 7a387fff ths
        /* MIPS16: Not implemented. */
5093 7a387fff ths
#endif
5094 7a387fff ths
#ifdef MIPS_HAS_MDMX
5095 7a387fff ths
    case OPC_MDMX:
5096 7a387fff ths
        /* MDMX: Not implemented. */
5097 6af0bf9c bellard
#endif
5098 6af0bf9c bellard
    default:            /* Invalid */
5099 6af0bf9c bellard
        MIPS_INVAL("");
5100 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
5101 6af0bf9c bellard
        break;
5102 6af0bf9c bellard
    }
5103 4ad40f36 bellard
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5104 c53f4a62 ths
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5105 6af0bf9c bellard
        /* Branches completion */
5106 4ad40f36 bellard
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5107 6af0bf9c bellard
        ctx->bstate = BS_BRANCH;
5108 6af0bf9c bellard
        save_cpu_state(ctx, 0);
5109 6af0bf9c bellard
        switch (hflags & MIPS_HFLAG_BMASK) {
5110 6af0bf9c bellard
        case MIPS_HFLAG_B:
5111 6af0bf9c bellard
            /* unconditional branch */
5112 6af0bf9c bellard
            MIPS_DEBUG("unconditional branch");
5113 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
5114 6af0bf9c bellard
            break;
5115 6af0bf9c bellard
        case MIPS_HFLAG_BL:
5116 6af0bf9c bellard
            /* blikely taken case */
5117 6af0bf9c bellard
            MIPS_DEBUG("blikely branch taken");
5118 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
5119 6af0bf9c bellard
            break;
5120 6af0bf9c bellard
        case MIPS_HFLAG_BC:
5121 6af0bf9c bellard
            /* Conditional branch */
5122 6af0bf9c bellard
            MIPS_DEBUG("conditional branch");
5123 c53be334 bellard
            {
5124 c53be334 bellard
              int l1;
5125 c53be334 bellard
              l1 = gen_new_label();
5126 c53be334 bellard
              gen_op_jnz_T2(l1);
5127 6e256c93 bellard
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5128 eeef26cd bellard
              gen_set_label(l1);
5129 eeef26cd bellard
              gen_goto_tb(ctx, 0, ctx->btarget);
5130 c53be334 bellard
            }
5131 6af0bf9c bellard
            break;
5132 6af0bf9c bellard
        case MIPS_HFLAG_BR:
5133 6af0bf9c bellard
            /* unconditional branch to register */
5134 6af0bf9c bellard
            MIPS_DEBUG("branch to register");
5135 6af0bf9c bellard
            gen_op_breg();
5136 6af0bf9c bellard
            break;
5137 6af0bf9c bellard
        default:
5138 6af0bf9c bellard
            MIPS_DEBUG("unknown branch");
5139 6af0bf9c bellard
            break;
5140 6af0bf9c bellard
        }
5141 6af0bf9c bellard
    }
5142 6af0bf9c bellard
}
5143 6af0bf9c bellard
5144 820e00f2 ths
static inline int
5145 820e00f2 ths
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5146 820e00f2 ths
                                int search_pc)
5147 6af0bf9c bellard
{
5148 6af0bf9c bellard
    DisasContext ctx, *ctxp = &ctx;
5149 6af0bf9c bellard
    target_ulong pc_start;
5150 6af0bf9c bellard
    uint16_t *gen_opc_end;
5151 6af0bf9c bellard
    int j, lj = -1;
5152 6af0bf9c bellard
5153 4ad40f36 bellard
    if (search_pc && loglevel)
5154 6ea83fed bellard
        fprintf (logfile, "search pc %d\n", search_pc);
5155 4ad40f36 bellard
5156 6af0bf9c bellard
    pc_start = tb->pc;
5157 6af0bf9c bellard
    gen_opc_ptr = gen_opc_buf;
5158 6af0bf9c bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5159 6af0bf9c bellard
    gen_opparam_ptr = gen_opparam_buf;
5160 c53be334 bellard
    nb_gen_labels = 0;
5161 6af0bf9c bellard
    ctx.pc = pc_start;
5162 4ad40f36 bellard
    ctx.saved_pc = -1;
5163 6af0bf9c bellard
    ctx.tb = tb;
5164 6af0bf9c bellard
    ctx.bstate = BS_NONE;
5165 4ad40f36 bellard
    /* Restore delay slot state from the tb context.  */
5166 4ad40f36 bellard
    ctx.hflags = tb->flags;
5167 6af0bf9c bellard
    ctx.saved_hflags = ctx.hflags;
5168 6af0bf9c bellard
    if (ctx.hflags & MIPS_HFLAG_BR) {
5169 6af0bf9c bellard
        gen_op_restore_breg_target();
5170 6af0bf9c bellard
    } else if (ctx.hflags & MIPS_HFLAG_B) {
5171 6af0bf9c bellard
        ctx.btarget = env->btarget;
5172 6af0bf9c bellard
    } else if (ctx.hflags & MIPS_HFLAG_BMASK) {
5173 6af0bf9c bellard
        /* If we are in the delay slot of a conditional branch,
5174 6af0bf9c bellard
         * restore the branch condition from env->bcond to T2
5175 6af0bf9c bellard
         */
5176 6af0bf9c bellard
        ctx.btarget = env->btarget;
5177 6af0bf9c bellard
        gen_op_restore_bcond();
5178 6af0bf9c bellard
    }
5179 6af0bf9c bellard
#if defined(CONFIG_USER_ONLY)
5180 6af0bf9c bellard
    ctx.mem_idx = 0;
5181 6af0bf9c bellard
#else
5182 3d9fb9fe bellard
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5183 6af0bf9c bellard
#endif
5184 6af0bf9c bellard
    ctx.CP0_Status = env->CP0_Status;
5185 6af0bf9c bellard
#ifdef DEBUG_DISAS
5186 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
5187 6af0bf9c bellard
        fprintf(logfile, "------------------------------------------------\n");
5188 4ad40f36 bellard
        /* FIXME: This may print out stale hflags from env... */
5189 6af0bf9c bellard
        cpu_dump_state(env, logfile, fprintf, 0);
5190 6af0bf9c bellard
    }
5191 6af0bf9c bellard
#endif
5192 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
5193 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
5194 4ad40f36 bellard
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5195 4ad40f36 bellard
                tb, ctx.mem_idx, ctx.hflags);
5196 6af0bf9c bellard
#endif
5197 6af0bf9c bellard
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5198 4ad40f36 bellard
        if (env->nb_breakpoints > 0) {
5199 4ad40f36 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
5200 4ad40f36 bellard
                if (env->breakpoints[j] == ctx.pc) {
5201 4ad40f36 bellard
                    save_cpu_state(ctxp, 1);
5202 4ad40f36 bellard
                    ctx.bstate = BS_BRANCH;
5203 4ad40f36 bellard
                    gen_op_debug();
5204 4ad40f36 bellard
                    goto done_generating;
5205 4ad40f36 bellard
                }
5206 4ad40f36 bellard
            }
5207 4ad40f36 bellard
        }
5208 4ad40f36 bellard
5209 6af0bf9c bellard
        if (search_pc) {
5210 6af0bf9c bellard
            j = gen_opc_ptr - gen_opc_buf;
5211 6af0bf9c bellard
            if (lj < j) {
5212 6af0bf9c bellard
                lj++;
5213 6af0bf9c bellard
                while (lj < j)
5214 6af0bf9c bellard
                    gen_opc_instr_start[lj++] = 0;
5215 6af0bf9c bellard
            }
5216 4ad40f36 bellard
            gen_opc_pc[lj] = ctx.pc;
5217 4ad40f36 bellard
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5218 4ad40f36 bellard
            gen_opc_instr_start[lj] = 1;
5219 6af0bf9c bellard
        }
5220 6af0bf9c bellard
        ctx.opcode = ldl_code(ctx.pc);
5221 36d23958 ths
        decode_opc(env, &ctx);
5222 6af0bf9c bellard
        ctx.pc += 4;
5223 4ad40f36 bellard
5224 4ad40f36 bellard
        if (env->singlestep_enabled)
5225 4ad40f36 bellard
            break;
5226 4ad40f36 bellard
5227 6af0bf9c bellard
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5228 6af0bf9c bellard
            break;
5229 4ad40f36 bellard
5230 6af0bf9c bellard
#if defined (MIPS_SINGLE_STEP)
5231 6af0bf9c bellard
        break;
5232 6af0bf9c bellard
#endif
5233 6af0bf9c bellard
    }
5234 4ad40f36 bellard
    if (env->singlestep_enabled) {
5235 4ad40f36 bellard
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5236 4ad40f36 bellard
        gen_op_debug();
5237 16c00cb2 ths
    } else {
5238 16c00cb2 ths
        switch (ctx.bstate) {
5239 16c00cb2 ths
        case BS_EXCP:
5240 16c00cb2 ths
            gen_op_interrupt_restart();
5241 16c00cb2 ths
            break;
5242 16c00cb2 ths
        case BS_STOP:
5243 16c00cb2 ths
            gen_op_interrupt_restart();
5244 16c00cb2 ths
            /* Fall through. */
5245 16c00cb2 ths
        case BS_NONE:
5246 16c00cb2 ths
            save_cpu_state(ctxp, 0);
5247 16c00cb2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
5248 16c00cb2 ths
            break;
5249 16c00cb2 ths
        case BS_BRANCH:
5250 16c00cb2 ths
        default:
5251 16c00cb2 ths
            break;
5252 16c00cb2 ths
        }
5253 16c00cb2 ths
        gen_op_reset_T0();
5254 16c00cb2 ths
        /* Generate the return instruction. */
5255 16c00cb2 ths
        gen_op_exit_tb();
5256 6af0bf9c bellard
    }
5257 4ad40f36 bellard
done_generating:
5258 6af0bf9c bellard
    *gen_opc_ptr = INDEX_op_end;
5259 6af0bf9c bellard
    if (search_pc) {
5260 6af0bf9c bellard
        j = gen_opc_ptr - gen_opc_buf;
5261 6af0bf9c bellard
        lj++;
5262 6af0bf9c bellard
        while (lj <= j)
5263 6af0bf9c bellard
            gen_opc_instr_start[lj++] = 0;
5264 6af0bf9c bellard
        tb->size = 0;
5265 6af0bf9c bellard
    } else {
5266 6af0bf9c bellard
        tb->size = ctx.pc - pc_start;
5267 6af0bf9c bellard
    }
5268 6af0bf9c bellard
#ifdef DEBUG_DISAS
5269 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
5270 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
5271 6af0bf9c bellard
        fprintf(logfile, "\n");
5272 6af0bf9c bellard
#endif
5273 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5274 6af0bf9c bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5275 6ea83fed bellard
    target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5276 6af0bf9c bellard
        fprintf(logfile, "\n");
5277 6af0bf9c bellard
    }
5278 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_OP) {
5279 6af0bf9c bellard
        fprintf(logfile, "OP:\n");
5280 6af0bf9c bellard
        dump_ops(gen_opc_buf, gen_opparam_buf);
5281 6af0bf9c bellard
        fprintf(logfile, "\n");
5282 6af0bf9c bellard
    }
5283 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
5284 6af0bf9c bellard
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5285 6af0bf9c bellard
    }
5286 6af0bf9c bellard
#endif
5287 6af0bf9c bellard
    
5288 6af0bf9c bellard
    return 0;
5289 6af0bf9c bellard
}
5290 6af0bf9c bellard
5291 6af0bf9c bellard
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5292 6af0bf9c bellard
{
5293 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 0);
5294 6af0bf9c bellard
}
5295 6af0bf9c bellard
5296 6af0bf9c bellard
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5297 6af0bf9c bellard
{
5298 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 1);
5299 6af0bf9c bellard
}
5300 6af0bf9c bellard
5301 6ea83fed bellard
void fpu_dump_state(CPUState *env, FILE *f, 
5302 6ea83fed bellard
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5303 6ea83fed bellard
                    int flags)
5304 6ea83fed bellard
{
5305 6ea83fed bellard
    int i;
5306 6ea83fed bellard
5307 6ea83fed bellard
#   define printfpr(fp) do { \
5308 6ea83fed bellard
        fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
5309 6ea83fed bellard
                (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
5310 6ea83fed bellard
    } while(0)
5311 6ea83fed bellard
5312 6ea83fed bellard
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d\n",
5313 6ea83fed bellard
                env->fcr0, env->fcr31,
5314 7a387fff ths
                (env->CP0_Status & (1 << CP0St_FR)) != 0);
5315 6ea83fed bellard
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5316 6ea83fed bellard
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5317 6ea83fed bellard
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5318 7a387fff ths
    for(i = 0; i < 32; i += 2) {
5319 7a387fff ths
        fpu_fprintf(f, "%s: ", fregnames[i]);
5320 6ea83fed bellard
        printfpr(FPR(env, i));
5321 6ea83fed bellard
    }
5322 6ea83fed bellard
5323 6ea83fed bellard
#undef printfpr
5324 6ea83fed bellard
}
5325 6ea83fed bellard
5326 7a387fff ths
void dump_fpu (CPUState *env)
5327 6ea83fed bellard
{
5328 6ea83fed bellard
    if (loglevel) { 
5329 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",
5330 6ea83fed bellard
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5331 6ea83fed bellard
       fpu_dump_state(env, logfile, fprintf, 0);
5332 6ea83fed bellard
    }
5333 6ea83fed bellard
}
5334 6ea83fed bellard
5335 60aa19ab ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5336 c570fd16 ths
/* Debug help: The architecture requires 32bit code to maintain proper
5337 c570fd16 ths
   sign-extened values on 64bit machines.  */
5338 c570fd16 ths
5339 c570fd16 ths
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5340 c570fd16 ths
5341 c570fd16 ths
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5342 c570fd16 ths
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5343 c570fd16 ths
                     int flags)
5344 c570fd16 ths
{
5345 c570fd16 ths
    int i;
5346 c570fd16 ths
5347 c570fd16 ths
    if (!SIGN_EXT_P(env->PC))
5348 3594c774 ths
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5349 c570fd16 ths
    if (!SIGN_EXT_P(env->HI))
5350 3594c774 ths
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5351 c570fd16 ths
    if (!SIGN_EXT_P(env->LO))
5352 3594c774 ths
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5353 c570fd16 ths
    if (!SIGN_EXT_P(env->btarget))
5354 3594c774 ths
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5355 c570fd16 ths
5356 c570fd16 ths
    for (i = 0; i < 32; i++) {
5357 c570fd16 ths
        if (!SIGN_EXT_P(env->gpr[i]))
5358 3594c774 ths
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5359 c570fd16 ths
    }
5360 c570fd16 ths
5361 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_EPC))
5362 3594c774 ths
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5363 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_LLAddr))
5364 3594c774 ths
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5365 c570fd16 ths
}
5366 c570fd16 ths
#endif
5367 c570fd16 ths
5368 6af0bf9c bellard
void cpu_dump_state (CPUState *env, FILE *f, 
5369 6af0bf9c bellard
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5370 6af0bf9c bellard
                     int flags)
5371 6af0bf9c bellard
{
5372 568b600d bellard
    uint32_t c0_status;
5373 6af0bf9c bellard
    int i;
5374 6af0bf9c bellard
    
5375 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",
5376 6af0bf9c bellard
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5377 6af0bf9c bellard
    for (i = 0; i < 32; i++) {
5378 6af0bf9c bellard
        if ((i & 3) == 0)
5379 6af0bf9c bellard
            cpu_fprintf(f, "GPR%02d:", i);
5380 3594c774 ths
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
5381 6af0bf9c bellard
        if ((i & 3) == 3)
5382 6af0bf9c bellard
            cpu_fprintf(f, "\n");
5383 6af0bf9c bellard
    }
5384 568b600d bellard
5385 568b600d bellard
    c0_status = env->CP0_Status;
5386 568b600d bellard
5387 3594c774 ths
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
5388 568b600d bellard
                c0_status, env->CP0_Cause, env->CP0_EPC);
5389 3594c774 ths
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5390 6af0bf9c bellard
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
5391 7a387fff ths
    if (c0_status & (1 << CP0St_CU1))
5392 7a387fff ths
        fpu_dump_state(env, f, cpu_fprintf, flags);
5393 60aa19ab ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5394 c570fd16 ths
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5395 c570fd16 ths
#endif
5396 6af0bf9c bellard
}
5397 6af0bf9c bellard
5398 6af0bf9c bellard
CPUMIPSState *cpu_mips_init (void)
5399 6af0bf9c bellard
{
5400 6af0bf9c bellard
    CPUMIPSState *env;
5401 6af0bf9c bellard
5402 6af0bf9c bellard
    env = qemu_mallocz(sizeof(CPUMIPSState));
5403 6af0bf9c bellard
    if (!env)
5404 6af0bf9c bellard
        return NULL;
5405 173d6cfe bellard
    cpu_exec_init(env);
5406 6ae81775 ths
    cpu_reset(env);
5407 6ae81775 ths
    return env;
5408 6ae81775 ths
}
5409 6ae81775 ths
5410 6ae81775 ths
void cpu_reset (CPUMIPSState *env)
5411 6ae81775 ths
{
5412 6ae81775 ths
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5413 6ae81775 ths
5414 6af0bf9c bellard
    tlb_flush(env, 1);
5415 6ae81775 ths
5416 6af0bf9c bellard
    /* Minimal init */
5417 ca7c2b1b ths
#if !defined(CONFIG_USER_ONLY)
5418 aa328add ths
    if (env->hflags & MIPS_HFLAG_BMASK) {
5419 aa328add ths
        /* If the exception was raised from a delay slot,
5420 aa328add ths
         * come back to the jump.  */
5421 aa328add ths
        env->CP0_ErrorEPC = env->PC - 4;
5422 aa328add ths
        env->hflags &= ~MIPS_HFLAG_BMASK;
5423 aa328add ths
    } else {
5424 aa328add ths
        env->CP0_ErrorEPC = env->PC;
5425 aa328add ths
    }
5426 24c7b0e3 ths
    env->hflags = 0;
5427 5dc4b744 ths
    env->PC = (int32_t)0xBFC00000;
5428 6af0bf9c bellard
#if defined (MIPS_USES_R4K_TLB)
5429 9c2149c8 ths
    env->CP0_Random = MIPS_TLB_NB - 1;
5430 814b9a47 ths
    env->tlb_in_use = MIPS_TLB_NB;
5431 6af0bf9c bellard
#endif
5432 6af0bf9c bellard
    env->CP0_Wired = 0;
5433 7a387fff ths
    /* SMP not implemented */
5434 b29a0341 ths
    env->CP0_EBase = 0x80000000;
5435 aa328add ths
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
5436 c090a8f4 ths
    /* vectored interrupts not implemented, timer on int 7,
5437 c090a8f4 ths
       no performance counters. */
5438 c090a8f4 ths
    env->CP0_IntCtl = 0xe0000000;
5439 6af0bf9c bellard
    env->CP0_WatchLo = 0;
5440 4e7a4a4e ths
    env->CP0_WatchHi = 0;
5441 6af0bf9c bellard
    /* Count register increments in debug mode, EJTAG version 1 */
5442 6af0bf9c bellard
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
5443 ca7c2b1b ths
#endif
5444 6af0bf9c bellard
    env->exception_index = EXCP_NONE;
5445 eeef26cd bellard
#if defined(CONFIG_USER_ONLY)
5446 eeef26cd bellard
    env->hflags |= MIPS_HFLAG_UM;
5447 ca7c2b1b ths
    env->user_mode_only = 1;
5448 eeef26cd bellard
#endif
5449 6af0bf9c bellard
}
5450 33d68b5f ths
5451 33d68b5f ths
#include "translate_init.c"