Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a4bc3afc

History | View | Annotate | Download (139 kB)

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