Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 1579a72e

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