Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 5a1e8ffb

History | View | Annotate | Download (163.7 kB)

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