Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (165 kB)

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