Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 97428a4d

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