Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 00a709c7

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