Statistics
| Branch: | Revision:

root / target-mips / translate.c @ c090a8f4

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