Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 8487327a

History | View | Annotate | Download (166.8 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 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
2631 8487327a ths
            gen_save_pc(ctx->pc + 4);
2632 8487327a ths
            ctx->bstate = BS_EXCP;
2633 2423f660 ths
            rn = "Status";
2634 2423f660 ths
            break;
2635 7a387fff ths
        case 1:
2636 2423f660 ths
            gen_op_mtc0_intctl();
2637 8487327a ths
            /* Stop translation as we may have switched the execution mode */
2638 8487327a ths
            ctx->bstate = BS_STOP;
2639 2423f660 ths
            rn = "IntCtl";
2640 2423f660 ths
            break;
2641 7a387fff ths
        case 2:
2642 2423f660 ths
            gen_op_mtc0_srsctl();
2643 8487327a ths
            /* Stop translation as we may have switched the execution mode */
2644 8487327a ths
            ctx->bstate = BS_STOP;
2645 2423f660 ths
            rn = "SRSCtl";
2646 2423f660 ths
            break;
2647 7a387fff ths
        case 3:
2648 fd88b6ab ths
            gen_op_mtc0_srsmap();
2649 8487327a ths
            /* Stop translation as we may have switched the execution mode */
2650 8487327a ths
            ctx->bstate = BS_STOP;
2651 2423f660 ths
            rn = "SRSMap";
2652 fd88b6ab ths
            break;
2653 7a387fff ths
        default:
2654 7a387fff ths
            goto die;
2655 876d4b07 ths
        }
2656 8c0fdd85 ths
        break;
2657 8c0fdd85 ths
    case 13:
2658 7a387fff ths
        switch (sel) {
2659 7a387fff ths
        case 0:
2660 2423f660 ths
            gen_op_mtc0_cause();
2661 2423f660 ths
            rn = "Cause";
2662 2423f660 ths
            break;
2663 7a387fff ths
        default:
2664 7a387fff ths
            goto die;
2665 876d4b07 ths
        }
2666 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
2667 876d4b07 ths
        ctx->bstate = BS_STOP;
2668 8c0fdd85 ths
        break;
2669 8c0fdd85 ths
    case 14:
2670 7a387fff ths
        switch (sel) {
2671 7a387fff ths
        case 0:
2672 2423f660 ths
            gen_op_mtc0_epc();
2673 2423f660 ths
            rn = "EPC";
2674 2423f660 ths
            break;
2675 7a387fff ths
        default:
2676 7a387fff ths
            goto die;
2677 876d4b07 ths
        }
2678 8c0fdd85 ths
        break;
2679 8c0fdd85 ths
    case 15:
2680 7a387fff ths
        switch (sel) {
2681 7a387fff ths
        case 0:
2682 2423f660 ths
            /* ignored */
2683 2423f660 ths
            rn = "PRid";
2684 2423f660 ths
            break;
2685 7a387fff ths
        case 1:
2686 2423f660 ths
            gen_op_mtc0_ebase();
2687 2423f660 ths
            rn = "EBase";
2688 2423f660 ths
            break;
2689 7a387fff ths
        default:
2690 7a387fff ths
            goto die;
2691 1579a72e ths
        }
2692 8c0fdd85 ths
        break;
2693 8c0fdd85 ths
    case 16:
2694 8c0fdd85 ths
        switch (sel) {
2695 8c0fdd85 ths
        case 0:
2696 e397ee33 ths
            gen_op_mtc0_config0();
2697 7a387fff ths
            rn = "Config";
2698 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
2699 2423f660 ths
            ctx->bstate = BS_STOP;
2700 7a387fff ths
            break;
2701 7a387fff ths
        case 1:
2702 e397ee33 ths
            /* ignored, read only */
2703 7a387fff ths
            rn = "Config1";
2704 7a387fff ths
            break;
2705 7a387fff ths
        case 2:
2706 e397ee33 ths
            gen_op_mtc0_config2();
2707 7a387fff ths
            rn = "Config2";
2708 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
2709 2423f660 ths
            ctx->bstate = BS_STOP;
2710 8c0fdd85 ths
            break;
2711 7a387fff ths
        case 3:
2712 e397ee33 ths
            /* ignored, read only */
2713 7a387fff ths
            rn = "Config3";
2714 7a387fff ths
            break;
2715 e397ee33 ths
        /* 4,5 are reserved */
2716 e397ee33 ths
        /* 6,7 are implementation dependent */
2717 e397ee33 ths
        case 6:
2718 e397ee33 ths
            /* ignored */
2719 e397ee33 ths
            rn = "Config6";
2720 e397ee33 ths
            break;
2721 e397ee33 ths
        case 7:
2722 e397ee33 ths
            /* ignored */
2723 e397ee33 ths
            rn = "Config7";
2724 e397ee33 ths
            break;
2725 8c0fdd85 ths
        default:
2726 8c0fdd85 ths
            rn = "Invalid config selector";
2727 8c0fdd85 ths
            goto die;
2728 8c0fdd85 ths
        }
2729 8c0fdd85 ths
        break;
2730 8c0fdd85 ths
    case 17:
2731 7a387fff ths
        switch (sel) {
2732 7a387fff ths
        case 0:
2733 2423f660 ths
            /* ignored */
2734 2423f660 ths
            rn = "LLAddr";
2735 2423f660 ths
            break;
2736 7a387fff ths
        default:
2737 7a387fff ths
            goto die;
2738 7a387fff ths
        }
2739 8c0fdd85 ths
        break;
2740 8c0fdd85 ths
    case 18:
2741 7a387fff ths
        switch (sel) {
2742 fd88b6ab ths
        case 0 ... 7:
2743 fd88b6ab ths
            gen_op_mtc0_watchlo(sel);
2744 2423f660 ths
            rn = "WatchLo";
2745 2423f660 ths
            break;
2746 7a387fff ths
        default:
2747 7a387fff ths
            goto die;
2748 7a387fff ths
        }
2749 8c0fdd85 ths
        break;
2750 8c0fdd85 ths
    case 19:
2751 7a387fff ths
        switch (sel) {
2752 fd88b6ab ths
        case 0 ... 7:
2753 fd88b6ab ths
            gen_op_mtc0_watchhi(sel);
2754 2423f660 ths
            rn = "WatchHi";
2755 2423f660 ths
            break;
2756 7a387fff ths
        default:
2757 7a387fff ths
            goto die;
2758 7a387fff ths
        }
2759 8c0fdd85 ths
        break;
2760 8c0fdd85 ths
    case 20:
2761 7a387fff ths
        switch (sel) {
2762 7a387fff ths
        case 0:
2763 703eaf37 ths
#ifdef TARGET_MIPS64
2764 f1b0aa5d ths
            gen_op_mtc0_xcontext();
2765 2423f660 ths
            rn = "XContext";
2766 2423f660 ths
            break;
2767 703eaf37 ths
#endif
2768 7a387fff ths
        default:
2769 7a387fff ths
            goto die;
2770 7a387fff ths
        }
2771 8c0fdd85 ths
        break;
2772 8c0fdd85 ths
    case 21:
2773 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2774 7a387fff ths
        switch (sel) {
2775 7a387fff ths
        case 0:
2776 2423f660 ths
            gen_op_mtc0_framemask();
2777 2423f660 ths
            rn = "Framemask";
2778 2423f660 ths
            break;
2779 7a387fff ths
        default:
2780 7a387fff ths
            goto die;
2781 7a387fff ths
        }
2782 7a387fff ths
        break;
2783 8c0fdd85 ths
    case 22:
2784 7a387fff ths
        /* ignored */
2785 7a387fff ths
        rn = "Diagnostic"; /* implementation dependent */
2786 2423f660 ths
        break;
2787 8c0fdd85 ths
    case 23:
2788 7a387fff ths
        switch (sel) {
2789 7a387fff ths
        case 0:
2790 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
2791 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
2792 8487327a ths
            gen_save_pc(ctx->pc + 4);
2793 8487327a ths
            ctx->bstate = BS_EXCP;
2794 2423f660 ths
            rn = "Debug";
2795 2423f660 ths
            break;
2796 7a387fff ths
        case 1:
2797 2423f660 ths
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
2798 2423f660 ths
            rn = "TraceControl";
2799 8487327a ths
            /* Stop translation as we may have switched the execution mode */
2800 8487327a ths
            ctx->bstate = BS_STOP;
2801 2423f660 ths
//            break;
2802 7a387fff ths
        case 2:
2803 2423f660 ths
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2804 2423f660 ths
            rn = "TraceControl2";
2805 8487327a ths
            /* Stop translation as we may have switched the execution mode */
2806 8487327a ths
            ctx->bstate = BS_STOP;
2807 2423f660 ths
//            break;
2808 7a387fff ths
        case 3:
2809 8487327a ths
            /* Stop translation as we may have switched the execution mode */
2810 8487327a ths
            ctx->bstate = BS_STOP;
2811 2423f660 ths
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
2812 2423f660 ths
            rn = "UserTraceData";
2813 8487327a ths
            /* Stop translation as we may have switched the execution mode */
2814 8487327a ths
            ctx->bstate = BS_STOP;
2815 2423f660 ths
//            break;
2816 7a387fff ths
        case 4:
2817 2423f660 ths
//            gen_op_mtc0_debug(); /* PDtrace support */
2818 8487327a ths
            /* Stop translation as we may have switched the execution mode */
2819 8487327a ths
            ctx->bstate = BS_STOP;
2820 2423f660 ths
            rn = "TraceBPC";
2821 2423f660 ths
//            break;
2822 7a387fff ths
        default:
2823 7a387fff ths
            goto die;
2824 7a387fff ths
        }
2825 8c0fdd85 ths
        break;
2826 8c0fdd85 ths
    case 24:
2827 7a387fff ths
        switch (sel) {
2828 7a387fff ths
        case 0:
2829 2423f660 ths
            gen_op_mtc0_depc(); /* EJTAG support */
2830 2423f660 ths
            rn = "DEPC";
2831 2423f660 ths
            break;
2832 7a387fff ths
        default:
2833 7a387fff ths
            goto die;
2834 7a387fff ths
        }
2835 8c0fdd85 ths
        break;
2836 8c0fdd85 ths
    case 25:
2837 7a387fff ths
        switch (sel) {
2838 7a387fff ths
        case 0:
2839 2423f660 ths
            gen_op_mtc0_performance0();
2840 2423f660 ths
            rn = "Performance0";
2841 2423f660 ths
            break;
2842 7a387fff ths
        case 1:
2843 2423f660 ths
//            gen_op_mtc0_performance1();
2844 2423f660 ths
            rn = "Performance1";
2845 2423f660 ths
//            break;
2846 7a387fff ths
        case 2:
2847 2423f660 ths
//            gen_op_mtc0_performance2();
2848 2423f660 ths
            rn = "Performance2";
2849 2423f660 ths
//            break;
2850 7a387fff ths
        case 3:
2851 2423f660 ths
//            gen_op_mtc0_performance3();
2852 2423f660 ths
            rn = "Performance3";
2853 2423f660 ths
//            break;
2854 7a387fff ths
        case 4:
2855 2423f660 ths
//            gen_op_mtc0_performance4();
2856 2423f660 ths
            rn = "Performance4";
2857 2423f660 ths
//            break;
2858 7a387fff ths
        case 5:
2859 2423f660 ths
//            gen_op_mtc0_performance5();
2860 2423f660 ths
            rn = "Performance5";
2861 2423f660 ths
//            break;
2862 7a387fff ths
        case 6:
2863 2423f660 ths
//            gen_op_mtc0_performance6();
2864 2423f660 ths
            rn = "Performance6";
2865 2423f660 ths
//            break;
2866 7a387fff ths
        case 7:
2867 2423f660 ths
//            gen_op_mtc0_performance7();
2868 2423f660 ths
            rn = "Performance7";
2869 2423f660 ths
//            break;
2870 7a387fff ths
        default:
2871 7a387fff ths
            goto die;
2872 7a387fff ths
        }
2873 8c0fdd85 ths
       break;
2874 8c0fdd85 ths
    case 26:
2875 2423f660 ths
        /* ignored */
2876 8c0fdd85 ths
        rn = "ECC";
2877 2423f660 ths
        break;
2878 8c0fdd85 ths
    case 27:
2879 7a387fff ths
        switch (sel) {
2880 7a387fff ths
        case 0 ... 3:
2881 2423f660 ths
            /* ignored */
2882 2423f660 ths
            rn = "CacheErr";
2883 2423f660 ths
            break;
2884 7a387fff ths
        default:
2885 7a387fff ths
            goto die;
2886 7a387fff ths
        }
2887 8c0fdd85 ths
       break;
2888 8c0fdd85 ths
    case 28:
2889 8c0fdd85 ths
        switch (sel) {
2890 8c0fdd85 ths
        case 0:
2891 7a387fff ths
        case 2:
2892 7a387fff ths
        case 4:
2893 7a387fff ths
        case 6:
2894 8c0fdd85 ths
            gen_op_mtc0_taglo();
2895 8c0fdd85 ths
            rn = "TagLo";
2896 8c0fdd85 ths
            break;
2897 7a387fff ths
        case 1:
2898 7a387fff ths
        case 3:
2899 7a387fff ths
        case 5:
2900 7a387fff ths
        case 7:
2901 2423f660 ths
            gen_op_mtc0_datalo();
2902 7a387fff ths
            rn = "DataLo";
2903 7a387fff ths
            break;
2904 8c0fdd85 ths
        default:
2905 8c0fdd85 ths
            goto die;
2906 8c0fdd85 ths
        }
2907 8c0fdd85 ths
        break;
2908 8c0fdd85 ths
    case 29:
2909 7a387fff ths
        switch (sel) {
2910 7a387fff ths
        case 0:
2911 7a387fff ths
        case 2:
2912 7a387fff ths
        case 4:
2913 7a387fff ths
        case 6:
2914 7a387fff ths
            gen_op_mtc0_taghi();
2915 7a387fff ths
            rn = "TagHi";
2916 7a387fff ths
            break;
2917 7a387fff ths
        case 1:
2918 7a387fff ths
        case 3:
2919 7a387fff ths
        case 5:
2920 7a387fff ths
        case 7:
2921 2423f660 ths
            gen_op_mtc0_datahi();
2922 7a387fff ths
            rn = "DataHi";
2923 7a387fff ths
            break;
2924 7a387fff ths
        default:
2925 7a387fff ths
            rn = "invalid sel";
2926 7a387fff ths
            goto die;
2927 7a387fff ths
        }
2928 8c0fdd85 ths
       break;
2929 8c0fdd85 ths
    case 30:
2930 7a387fff ths
        switch (sel) {
2931 7a387fff ths
        case 0:
2932 2423f660 ths
            gen_op_mtc0_errorepc();
2933 2423f660 ths
            rn = "ErrorEPC";
2934 2423f660 ths
            break;
2935 7a387fff ths
        default:
2936 7a387fff ths
            goto die;
2937 7a387fff ths
        }
2938 8c0fdd85 ths
        break;
2939 8c0fdd85 ths
    case 31:
2940 7a387fff ths
        switch (sel) {
2941 7a387fff ths
        case 0:
2942 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
2943 2423f660 ths
            rn = "DESAVE";
2944 2423f660 ths
            break;
2945 7a387fff ths
        default:
2946 7a387fff ths
            goto die;
2947 7a387fff ths
        }
2948 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
2949 2423f660 ths
        ctx->bstate = BS_STOP;
2950 8c0fdd85 ths
        break;
2951 8c0fdd85 ths
    default:
2952 8c0fdd85 ths
       goto die;
2953 8c0fdd85 ths
    }
2954 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
2955 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2956 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2957 7a387fff ths
                rn, reg, sel);
2958 8c0fdd85 ths
    }
2959 8c0fdd85 ths
#endif
2960 8c0fdd85 ths
    return;
2961 8c0fdd85 ths
2962 8c0fdd85 ths
die:
2963 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
2964 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2965 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2966 7a387fff ths
                rn, reg, sel);
2967 8c0fdd85 ths
    }
2968 8c0fdd85 ths
#endif
2969 8c0fdd85 ths
    generate_exception(ctx, EXCP_RI);
2970 8c0fdd85 ths
}
2971 8c0fdd85 ths
2972 534ce69f ths
#ifdef TARGET_MIPS64
2973 9c2149c8 ths
static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2974 9c2149c8 ths
{
2975 9c2149c8 ths
    const char *rn = "invalid";
2976 9c2149c8 ths
2977 9c2149c8 ths
    switch (reg) {
2978 9c2149c8 ths
    case 0:
2979 9c2149c8 ths
        switch (sel) {
2980 9c2149c8 ths
        case 0:
2981 2423f660 ths
            gen_op_mfc0_index();
2982 9c2149c8 ths
            rn = "Index";
2983 9c2149c8 ths
            break;
2984 9c2149c8 ths
        case 1:
2985 2423f660 ths
//            gen_op_dmfc0_mvpcontrol(); /* MT ASE */
2986 9c2149c8 ths
            rn = "MVPControl";
2987 2423f660 ths
//            break;
2988 9c2149c8 ths
        case 2:
2989 2423f660 ths
//            gen_op_dmfc0_mvpconf0(); /* MT ASE */
2990 9c2149c8 ths
            rn = "MVPConf0";
2991 2423f660 ths
//            break;
2992 9c2149c8 ths
        case 3:
2993 2423f660 ths
//            gen_op_dmfc0_mvpconf1(); /* MT ASE */
2994 9c2149c8 ths
            rn = "MVPConf1";
2995 2423f660 ths
//            break;
2996 9c2149c8 ths
        default:
2997 9c2149c8 ths
            goto die;
2998 9c2149c8 ths
        }
2999 9c2149c8 ths
        break;
3000 9c2149c8 ths
    case 1:
3001 9c2149c8 ths
        switch (sel) {
3002 9c2149c8 ths
        case 0:
3003 9c2149c8 ths
            gen_op_mfc0_random();
3004 9c2149c8 ths
            rn = "Random";
3005 2423f660 ths
            break;
3006 9c2149c8 ths
        case 1:
3007 2423f660 ths
//            gen_op_dmfc0_vpecontrol(); /* MT ASE */
3008 9c2149c8 ths
            rn = "VPEControl";
3009 2423f660 ths
//            break;
3010 9c2149c8 ths
        case 2:
3011 2423f660 ths
//            gen_op_dmfc0_vpeconf0(); /* MT ASE */
3012 9c2149c8 ths
            rn = "VPEConf0";
3013 2423f660 ths
//            break;
3014 9c2149c8 ths
        case 3:
3015 2423f660 ths
//            gen_op_dmfc0_vpeconf1(); /* MT ASE */
3016 9c2149c8 ths
            rn = "VPEConf1";
3017 2423f660 ths
//            break;
3018 9c2149c8 ths
        case 4:
3019 2423f660 ths
//            gen_op_dmfc0_YQMask(); /* MT ASE */
3020 9c2149c8 ths
            rn = "YQMask";
3021 2423f660 ths
//            break;
3022 9c2149c8 ths
        case 5:
3023 2423f660 ths
//            gen_op_dmfc0_vpeschedule(); /* MT ASE */
3024 9c2149c8 ths
            rn = "VPESchedule";
3025 2423f660 ths
//            break;
3026 9c2149c8 ths
        case 6:
3027 2423f660 ths
//            gen_op_dmfc0_vpeschefback(); /* MT ASE */
3028 9c2149c8 ths
            rn = "VPEScheFBack";
3029 2423f660 ths
//            break;
3030 9c2149c8 ths
        case 7:
3031 2423f660 ths
//            gen_op_dmfc0_vpeopt(); /* MT ASE */
3032 9c2149c8 ths
            rn = "VPEOpt";
3033 2423f660 ths
//            break;
3034 9c2149c8 ths
        default:
3035 9c2149c8 ths
            goto die;
3036 9c2149c8 ths
        }
3037 9c2149c8 ths
        break;
3038 9c2149c8 ths
    case 2:
3039 9c2149c8 ths
        switch (sel) {
3040 9c2149c8 ths
        case 0:
3041 2423f660 ths
            gen_op_dmfc0_entrylo0();
3042 2423f660 ths
            rn = "EntryLo0";
3043 2423f660 ths
            break;
3044 9c2149c8 ths
        case 1:
3045 2423f660 ths
//            gen_op_dmfc0_tcstatus(); /* MT ASE */
3046 2423f660 ths
            rn = "TCStatus";
3047 2423f660 ths
//            break;
3048 9c2149c8 ths
        case 2:
3049 2423f660 ths
//            gen_op_dmfc0_tcbind(); /* MT ASE */
3050 2423f660 ths
            rn = "TCBind";
3051 2423f660 ths
//            break;
3052 9c2149c8 ths
        case 3:
3053 2423f660 ths
//            gen_op_dmfc0_tcrestart(); /* MT ASE */
3054 2423f660 ths
            rn = "TCRestart";
3055 2423f660 ths
//            break;
3056 9c2149c8 ths
        case 4:
3057 2423f660 ths
//            gen_op_dmfc0_tchalt(); /* MT ASE */
3058 2423f660 ths
            rn = "TCHalt";
3059 2423f660 ths
//            break;
3060 9c2149c8 ths
        case 5:
3061 2423f660 ths
//            gen_op_dmfc0_tccontext(); /* MT ASE */
3062 2423f660 ths
            rn = "TCContext";
3063 2423f660 ths
//            break;
3064 9c2149c8 ths
        case 6:
3065 2423f660 ths
//            gen_op_dmfc0_tcschedule(); /* MT ASE */
3066 2423f660 ths
            rn = "TCSchedule";
3067 2423f660 ths
//            break;
3068 9c2149c8 ths
        case 7:
3069 2423f660 ths
//            gen_op_dmfc0_tcschefback(); /* MT ASE */
3070 2423f660 ths
            rn = "TCScheFBack";
3071 2423f660 ths
//            break;
3072 9c2149c8 ths
        default:
3073 9c2149c8 ths
            goto die;
3074 9c2149c8 ths
        }
3075 9c2149c8 ths
        break;
3076 9c2149c8 ths
    case 3:
3077 9c2149c8 ths
        switch (sel) {
3078 9c2149c8 ths
        case 0:
3079 2423f660 ths
            gen_op_dmfc0_entrylo1();
3080 2423f660 ths
            rn = "EntryLo1";
3081 2423f660 ths
            break;
3082 9c2149c8 ths
        default:
3083 9c2149c8 ths
            goto die;
3084 1579a72e ths
        }
3085 9c2149c8 ths
        break;
3086 9c2149c8 ths
    case 4:
3087 9c2149c8 ths
        switch (sel) {
3088 9c2149c8 ths
        case 0:
3089 2423f660 ths
            gen_op_dmfc0_context();
3090 2423f660 ths
            rn = "Context";
3091 2423f660 ths
            break;
3092 9c2149c8 ths
        case 1:
3093 2423f660 ths
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3094 2423f660 ths
            rn = "ContextConfig";
3095 2423f660 ths
//            break;
3096 9c2149c8 ths
        default:
3097 9c2149c8 ths
            goto die;
3098 876d4b07 ths
        }
3099 9c2149c8 ths
        break;
3100 9c2149c8 ths
    case 5:
3101 9c2149c8 ths
        switch (sel) {
3102 9c2149c8 ths
        case 0:
3103 2423f660 ths
            gen_op_mfc0_pagemask();
3104 2423f660 ths
            rn = "PageMask";
3105 2423f660 ths
            break;
3106 9c2149c8 ths
        case 1:
3107 2423f660 ths
            gen_op_mfc0_pagegrain();
3108 2423f660 ths
            rn = "PageGrain";
3109 2423f660 ths
            break;
3110 9c2149c8 ths
        default:
3111 9c2149c8 ths
            goto die;
3112 876d4b07 ths
        }
3113 9c2149c8 ths
        break;
3114 9c2149c8 ths
    case 6:
3115 9c2149c8 ths
        switch (sel) {
3116 9c2149c8 ths
        case 0:
3117 2423f660 ths
            gen_op_mfc0_wired();
3118 2423f660 ths
            rn = "Wired";
3119 2423f660 ths
            break;
3120 9c2149c8 ths
        case 1:
3121 2423f660 ths
//            gen_op_dmfc0_srsconf0(); /* shadow registers */
3122 2423f660 ths
            rn = "SRSConf0";
3123 2423f660 ths
//            break;
3124 9c2149c8 ths
        case 2:
3125 2423f660 ths
//            gen_op_dmfc0_srsconf1(); /* shadow registers */
3126 2423f660 ths
            rn = "SRSConf1";
3127 2423f660 ths
//            break;
3128 9c2149c8 ths
        case 3:
3129 2423f660 ths
//            gen_op_dmfc0_srsconf2(); /* shadow registers */
3130 2423f660 ths
            rn = "SRSConf2";
3131 2423f660 ths
//            break;
3132 9c2149c8 ths
        case 4:
3133 2423f660 ths
//            gen_op_dmfc0_srsconf3(); /* shadow registers */
3134 2423f660 ths
            rn = "SRSConf3";
3135 2423f660 ths
//            break;
3136 9c2149c8 ths
        case 5:
3137 2423f660 ths
//            gen_op_dmfc0_srsconf4(); /* shadow registers */
3138 2423f660 ths
            rn = "SRSConf4";
3139 2423f660 ths
//            break;
3140 9c2149c8 ths
        default:
3141 9c2149c8 ths
            goto die;
3142 876d4b07 ths
        }
3143 9c2149c8 ths
        break;
3144 9c2149c8 ths
    case 7:
3145 9c2149c8 ths
        switch (sel) {
3146 9c2149c8 ths
        case 0:
3147 2423f660 ths
            gen_op_mfc0_hwrena();
3148 2423f660 ths
            rn = "HWREna";
3149 2423f660 ths
            break;
3150 9c2149c8 ths
        default:
3151 9c2149c8 ths
            goto die;
3152 876d4b07 ths
        }
3153 9c2149c8 ths
        break;
3154 9c2149c8 ths
    case 8:
3155 9c2149c8 ths
        switch (sel) {
3156 9c2149c8 ths
        case 0:
3157 2423f660 ths
            gen_op_dmfc0_badvaddr();
3158 2423f660 ths
            rn = "BadVaddr";
3159 2423f660 ths
            break;
3160 9c2149c8 ths
        default:
3161 9c2149c8 ths
            goto die;
3162 876d4b07 ths
        }
3163 9c2149c8 ths
        break;
3164 9c2149c8 ths
    case 9:
3165 9c2149c8 ths
        switch (sel) {
3166 9c2149c8 ths
        case 0:
3167 2423f660 ths
            gen_op_mfc0_count();
3168 2423f660 ths
            rn = "Count";
3169 2423f660 ths
            break;
3170 2423f660 ths
        /* 6,7 are implementation dependent */
3171 9c2149c8 ths
        default:
3172 9c2149c8 ths
            goto die;
3173 876d4b07 ths
        }
3174 9c2149c8 ths
        break;
3175 9c2149c8 ths
    case 10:
3176 9c2149c8 ths
        switch (sel) {
3177 9c2149c8 ths
        case 0:
3178 2423f660 ths
            gen_op_dmfc0_entryhi();
3179 2423f660 ths
            rn = "EntryHi";
3180 2423f660 ths
            break;
3181 9c2149c8 ths
        default:
3182 9c2149c8 ths
            goto die;
3183 876d4b07 ths
        }
3184 9c2149c8 ths
        break;
3185 9c2149c8 ths
    case 11:
3186 9c2149c8 ths
        switch (sel) {
3187 9c2149c8 ths
        case 0:
3188 2423f660 ths
            gen_op_mfc0_compare();
3189 2423f660 ths
            rn = "Compare";
3190 2423f660 ths
            break;
3191 876d4b07 ths
        /* 6,7 are implementation dependent */
3192 9c2149c8 ths
        default:
3193 9c2149c8 ths
            goto die;
3194 876d4b07 ths
        }
3195 9c2149c8 ths
        break;
3196 9c2149c8 ths
    case 12:
3197 9c2149c8 ths
        switch (sel) {
3198 9c2149c8 ths
        case 0:
3199 2423f660 ths
            gen_op_mfc0_status();
3200 2423f660 ths
            rn = "Status";
3201 2423f660 ths
            break;
3202 9c2149c8 ths
        case 1:
3203 2423f660 ths
            gen_op_mfc0_intctl();
3204 2423f660 ths
            rn = "IntCtl";
3205 2423f660 ths
            break;
3206 9c2149c8 ths
        case 2:
3207 2423f660 ths
            gen_op_mfc0_srsctl();
3208 2423f660 ths
            rn = "SRSCtl";
3209 2423f660 ths
            break;
3210 9c2149c8 ths
        case 3:
3211 2423f660 ths
            gen_op_mfc0_srsmap(); /* shadow registers */
3212 2423f660 ths
            rn = "SRSMap";
3213 2423f660 ths
            break;
3214 9c2149c8 ths
        default:
3215 9c2149c8 ths
            goto die;
3216 876d4b07 ths
        }
3217 9c2149c8 ths
        break;
3218 9c2149c8 ths
    case 13:
3219 9c2149c8 ths
        switch (sel) {
3220 9c2149c8 ths
        case 0:
3221 2423f660 ths
            gen_op_mfc0_cause();
3222 2423f660 ths
            rn = "Cause";
3223 2423f660 ths
            break;
3224 9c2149c8 ths
        default:
3225 9c2149c8 ths
            goto die;
3226 876d4b07 ths
        }
3227 9c2149c8 ths
        break;
3228 9c2149c8 ths
    case 14:
3229 9c2149c8 ths
        switch (sel) {
3230 9c2149c8 ths
        case 0:
3231 2423f660 ths
            gen_op_dmfc0_epc();
3232 2423f660 ths
            rn = "EPC";
3233 2423f660 ths
            break;
3234 9c2149c8 ths
        default:
3235 9c2149c8 ths
            goto die;
3236 876d4b07 ths
        }
3237 9c2149c8 ths
        break;
3238 9c2149c8 ths
    case 15:
3239 9c2149c8 ths
        switch (sel) {
3240 9c2149c8 ths
        case 0:
3241 2423f660 ths
            gen_op_mfc0_prid();
3242 2423f660 ths
            rn = "PRid";
3243 2423f660 ths
            break;
3244 9c2149c8 ths
        case 1:
3245 2423f660 ths
            gen_op_mfc0_ebase();
3246 2423f660 ths
            rn = "EBase";
3247 2423f660 ths
            break;
3248 9c2149c8 ths
        default:
3249 9c2149c8 ths
            goto die;
3250 876d4b07 ths
        }
3251 9c2149c8 ths
        break;
3252 9c2149c8 ths
    case 16:
3253 9c2149c8 ths
        switch (sel) {
3254 9c2149c8 ths
        case 0:
3255 2423f660 ths
            gen_op_mfc0_config0();
3256 9c2149c8 ths
            rn = "Config";
3257 9c2149c8 ths
            break;
3258 9c2149c8 ths
        case 1:
3259 2423f660 ths
            gen_op_mfc0_config1();
3260 9c2149c8 ths
            rn = "Config1";
3261 9c2149c8 ths
            break;
3262 9c2149c8 ths
        case 2:
3263 2423f660 ths
            gen_op_mfc0_config2();
3264 9c2149c8 ths
            rn = "Config2";
3265 9c2149c8 ths
            break;
3266 9c2149c8 ths
        case 3:
3267 2423f660 ths
            gen_op_mfc0_config3();
3268 9c2149c8 ths
            rn = "Config3";
3269 9c2149c8 ths
            break;
3270 9c2149c8 ths
       /* 6,7 are implementation dependent */
3271 9c2149c8 ths
        default:
3272 9c2149c8 ths
            goto die;
3273 9c2149c8 ths
        }
3274 9c2149c8 ths
        break;
3275 9c2149c8 ths
    case 17:
3276 9c2149c8 ths
        switch (sel) {
3277 9c2149c8 ths
        case 0:
3278 2423f660 ths
            gen_op_dmfc0_lladdr();
3279 2423f660 ths
            rn = "LLAddr";
3280 2423f660 ths
            break;
3281 9c2149c8 ths
        default:
3282 9c2149c8 ths
            goto die;
3283 9c2149c8 ths
        }
3284 9c2149c8 ths
        break;
3285 9c2149c8 ths
    case 18:
3286 9c2149c8 ths
        switch (sel) {
3287 fd88b6ab ths
        case 0 ... 7:
3288 fd88b6ab ths
            gen_op_dmfc0_watchlo(sel);
3289 2423f660 ths
            rn = "WatchLo";
3290 2423f660 ths
            break;
3291 9c2149c8 ths
        default:
3292 9c2149c8 ths
            goto die;
3293 9c2149c8 ths
        }
3294 9c2149c8 ths
        break;
3295 9c2149c8 ths
    case 19:
3296 9c2149c8 ths
        switch (sel) {
3297 fd88b6ab ths
        case 0 ... 7:
3298 fd88b6ab ths
            gen_op_mfc0_watchhi(sel);
3299 2423f660 ths
            rn = "WatchHi";
3300 2423f660 ths
            break;
3301 9c2149c8 ths
        default:
3302 9c2149c8 ths
            goto die;
3303 9c2149c8 ths
        }
3304 9c2149c8 ths
        break;
3305 9c2149c8 ths
    case 20:
3306 9c2149c8 ths
        switch (sel) {
3307 9c2149c8 ths
        case 0:
3308 703eaf37 ths
#ifdef TARGET_MIPS64
3309 2423f660 ths
            gen_op_dmfc0_xcontext();
3310 2423f660 ths
            rn = "XContext";
3311 2423f660 ths
            break;
3312 703eaf37 ths
#endif
3313 9c2149c8 ths
        default:
3314 9c2149c8 ths
            goto die;
3315 9c2149c8 ths
        }
3316 9c2149c8 ths
        break;
3317 9c2149c8 ths
    case 21:
3318 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3319 9c2149c8 ths
        switch (sel) {
3320 9c2149c8 ths
        case 0:
3321 2423f660 ths
            gen_op_mfc0_framemask();
3322 2423f660 ths
            rn = "Framemask";
3323 2423f660 ths
            break;
3324 9c2149c8 ths
        default:
3325 9c2149c8 ths
            goto die;
3326 9c2149c8 ths
        }
3327 9c2149c8 ths
        break;
3328 9c2149c8 ths
    case 22:
3329 2423f660 ths
        /* ignored */
3330 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
3331 2423f660 ths
        break;
3332 9c2149c8 ths
    case 23:
3333 9c2149c8 ths
        switch (sel) {
3334 9c2149c8 ths
        case 0:
3335 2423f660 ths
            gen_op_mfc0_debug(); /* EJTAG support */
3336 2423f660 ths
            rn = "Debug";
3337 2423f660 ths
            break;
3338 9c2149c8 ths
        case 1:
3339 2423f660 ths
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3340 2423f660 ths
            rn = "TraceControl";
3341 2423f660 ths
//            break;
3342 9c2149c8 ths
        case 2:
3343 2423f660 ths
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3344 2423f660 ths
            rn = "TraceControl2";
3345 2423f660 ths
//            break;
3346 9c2149c8 ths
        case 3:
3347 2423f660 ths
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3348 2423f660 ths
            rn = "UserTraceData";
3349 2423f660 ths
//            break;
3350 9c2149c8 ths
        case 4:
3351 2423f660 ths
//            gen_op_dmfc0_debug(); /* PDtrace support */
3352 2423f660 ths
            rn = "TraceBPC";
3353 2423f660 ths
//            break;
3354 9c2149c8 ths
        default:
3355 9c2149c8 ths
            goto die;
3356 9c2149c8 ths
        }
3357 9c2149c8 ths
        break;
3358 9c2149c8 ths
    case 24:
3359 9c2149c8 ths
        switch (sel) {
3360 9c2149c8 ths
        case 0:
3361 2423f660 ths
            gen_op_dmfc0_depc(); /* EJTAG support */
3362 2423f660 ths
            rn = "DEPC";
3363 2423f660 ths
            break;
3364 9c2149c8 ths
        default:
3365 9c2149c8 ths
            goto die;
3366 9c2149c8 ths
        }
3367 9c2149c8 ths
        break;
3368 9c2149c8 ths
    case 25:
3369 9c2149c8 ths
        switch (sel) {
3370 9c2149c8 ths
        case 0:
3371 2423f660 ths
            gen_op_mfc0_performance0();
3372 2423f660 ths
            rn = "Performance0";
3373 9c2149c8 ths
            break;
3374 9c2149c8 ths
        case 1:
3375 2423f660 ths
//            gen_op_dmfc0_performance1();
3376 2423f660 ths
            rn = "Performance1";
3377 2423f660 ths
//            break;
3378 9c2149c8 ths
        case 2:
3379 2423f660 ths
//            gen_op_dmfc0_performance2();
3380 2423f660 ths
            rn = "Performance2";
3381 2423f660 ths
//            break;
3382 9c2149c8 ths
        case 3:
3383 2423f660 ths
//            gen_op_dmfc0_performance3();
3384 2423f660 ths
            rn = "Performance3";
3385 2423f660 ths
//            break;
3386 9c2149c8 ths
        case 4:
3387 2423f660 ths
//            gen_op_dmfc0_performance4();
3388 2423f660 ths
            rn = "Performance4";
3389 2423f660 ths
//            break;
3390 9c2149c8 ths
        case 5:
3391 2423f660 ths
//            gen_op_dmfc0_performance5();
3392 2423f660 ths
            rn = "Performance5";
3393 2423f660 ths
//            break;
3394 9c2149c8 ths
        case 6:
3395 2423f660 ths
//            gen_op_dmfc0_performance6();
3396 2423f660 ths
            rn = "Performance6";
3397 2423f660 ths
//            break;
3398 9c2149c8 ths
        case 7:
3399 2423f660 ths
//            gen_op_dmfc0_performance7();
3400 2423f660 ths
            rn = "Performance7";
3401 2423f660 ths
//            break;
3402 9c2149c8 ths
        default:
3403 9c2149c8 ths
            goto die;
3404 9c2149c8 ths
        }
3405 9c2149c8 ths
        break;
3406 9c2149c8 ths
    case 26:
3407 9c2149c8 ths
       rn = "ECC";
3408 9c2149c8 ths
       break;
3409 9c2149c8 ths
    case 27:
3410 9c2149c8 ths
        switch (sel) {
3411 9c2149c8 ths
        /* ignored */
3412 9c2149c8 ths
        case 0 ... 3:
3413 2423f660 ths
            rn = "CacheErr";
3414 2423f660 ths
            break;
3415 9c2149c8 ths
        default:
3416 9c2149c8 ths
            goto die;
3417 9c2149c8 ths
        }
3418 9c2149c8 ths
        break;
3419 9c2149c8 ths
    case 28:
3420 9c2149c8 ths
        switch (sel) {
3421 9c2149c8 ths
        case 0:
3422 9c2149c8 ths
        case 2:
3423 9c2149c8 ths
        case 4:
3424 9c2149c8 ths
        case 6:
3425 9c2149c8 ths
            gen_op_mfc0_taglo();
3426 9c2149c8 ths
            rn = "TagLo";
3427 9c2149c8 ths
            break;
3428 9c2149c8 ths
        case 1:
3429 9c2149c8 ths
        case 3:
3430 9c2149c8 ths
        case 5:
3431 9c2149c8 ths
        case 7:
3432 9c2149c8 ths
            gen_op_mfc0_datalo();
3433 9c2149c8 ths
            rn = "DataLo";
3434 9c2149c8 ths
            break;
3435 9c2149c8 ths
        default:
3436 9c2149c8 ths
            goto die;
3437 9c2149c8 ths
        }
3438 9c2149c8 ths
        break;
3439 9c2149c8 ths
    case 29:
3440 9c2149c8 ths
        switch (sel) {
3441 9c2149c8 ths
        case 0:
3442 9c2149c8 ths
        case 2:
3443 9c2149c8 ths
        case 4:
3444 9c2149c8 ths
        case 6:
3445 9c2149c8 ths
            gen_op_mfc0_taghi();
3446 9c2149c8 ths
            rn = "TagHi";
3447 9c2149c8 ths
            break;
3448 9c2149c8 ths
        case 1:
3449 9c2149c8 ths
        case 3:
3450 9c2149c8 ths
        case 5:
3451 9c2149c8 ths
        case 7:
3452 9c2149c8 ths
            gen_op_mfc0_datahi();
3453 9c2149c8 ths
            rn = "DataHi";
3454 9c2149c8 ths
            break;
3455 9c2149c8 ths
        default:
3456 9c2149c8 ths
            goto die;
3457 9c2149c8 ths
        }
3458 9c2149c8 ths
        break;
3459 9c2149c8 ths
    case 30:
3460 9c2149c8 ths
        switch (sel) {
3461 9c2149c8 ths
        case 0:
3462 2423f660 ths
            gen_op_dmfc0_errorepc();
3463 2423f660 ths
            rn = "ErrorEPC";
3464 2423f660 ths
            break;
3465 9c2149c8 ths
        default:
3466 9c2149c8 ths
            goto die;
3467 9c2149c8 ths
        }
3468 9c2149c8 ths
        break;
3469 9c2149c8 ths
    case 31:
3470 9c2149c8 ths
        switch (sel) {
3471 9c2149c8 ths
        case 0:
3472 2423f660 ths
            gen_op_mfc0_desave(); /* EJTAG support */
3473 2423f660 ths
            rn = "DESAVE";
3474 2423f660 ths
            break;
3475 9c2149c8 ths
        default:
3476 9c2149c8 ths
            goto die;
3477 9c2149c8 ths
        }
3478 9c2149c8 ths
        break;
3479 9c2149c8 ths
    default:
3480 876d4b07 ths
        goto die;
3481 9c2149c8 ths
    }
3482 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
3483 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3484 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3485 9c2149c8 ths
                rn, reg, sel);
3486 9c2149c8 ths
    }
3487 9c2149c8 ths
#endif
3488 9c2149c8 ths
    return;
3489 9c2149c8 ths
3490 9c2149c8 ths
die:
3491 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
3492 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3493 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3494 9c2149c8 ths
                rn, reg, sel);
3495 9c2149c8 ths
    }
3496 9c2149c8 ths
#endif
3497 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
3498 9c2149c8 ths
}
3499 9c2149c8 ths
3500 9c2149c8 ths
static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3501 9c2149c8 ths
{
3502 9c2149c8 ths
    const char *rn = "invalid";
3503 9c2149c8 ths
3504 9c2149c8 ths
    switch (reg) {
3505 9c2149c8 ths
    case 0:
3506 9c2149c8 ths
        switch (sel) {
3507 9c2149c8 ths
        case 0:
3508 9c2149c8 ths
            gen_op_mtc0_index();
3509 9c2149c8 ths
            rn = "Index";
3510 9c2149c8 ths
            break;
3511 9c2149c8 ths
        case 1:
3512 f1b0aa5d ths
//            gen_op_mtc0_mvpcontrol(); /* MT ASE */
3513 9c2149c8 ths
            rn = "MVPControl";
3514 2423f660 ths
//            break;
3515 9c2149c8 ths
        case 2:
3516 f1b0aa5d ths
//            gen_op_mtc0_mvpconf0(); /* MT ASE */
3517 9c2149c8 ths
            rn = "MVPConf0";
3518 2423f660 ths
//            break;
3519 9c2149c8 ths
        case 3:
3520 f1b0aa5d ths
//            gen_op_mtc0_mvpconf1(); /* MT ASE */
3521 9c2149c8 ths
            rn = "MVPConf1";
3522 2423f660 ths
//            break;
3523 9c2149c8 ths
        default:
3524 9c2149c8 ths
            goto die;
3525 9c2149c8 ths
        }
3526 9c2149c8 ths
        break;
3527 9c2149c8 ths
    case 1:
3528 9c2149c8 ths
        switch (sel) {
3529 9c2149c8 ths
        case 0:
3530 2423f660 ths
            /* ignored */
3531 9c2149c8 ths
            rn = "Random";
3532 2423f660 ths
            break;
3533 9c2149c8 ths
        case 1:
3534 f1b0aa5d ths
//            gen_op_mtc0_vpecontrol(); /* MT ASE */
3535 9c2149c8 ths
            rn = "VPEControl";
3536 2423f660 ths
//            break;
3537 9c2149c8 ths
        case 2:
3538 f1b0aa5d ths
//            gen_op_mtc0_vpeconf0(); /* MT ASE */
3539 9c2149c8 ths
            rn = "VPEConf0";
3540 2423f660 ths
//            break;
3541 9c2149c8 ths
        case 3:
3542 f1b0aa5d ths
//            gen_op_mtc0_vpeconf1(); /* MT ASE */
3543 9c2149c8 ths
            rn = "VPEConf1";
3544 2423f660 ths
//            break;
3545 9c2149c8 ths
        case 4:
3546 f1b0aa5d ths
//            gen_op_mtc0_YQMask(); /* MT ASE */
3547 9c2149c8 ths
            rn = "YQMask";
3548 2423f660 ths
//            break;
3549 9c2149c8 ths
        case 5:
3550 f1b0aa5d ths
//            gen_op_mtc0_vpeschedule(); /* MT ASE */
3551 9c2149c8 ths
            rn = "VPESchedule";
3552 2423f660 ths
//            break;
3553 9c2149c8 ths
        case 6:
3554 f1b0aa5d ths
//            gen_op_mtc0_vpeschefback(); /* MT ASE */
3555 9c2149c8 ths
            rn = "VPEScheFBack";
3556 2423f660 ths
//            break;
3557 9c2149c8 ths
        case 7:
3558 f1b0aa5d ths
//            gen_op_mtc0_vpeopt(); /* MT ASE */
3559 9c2149c8 ths
            rn = "VPEOpt";
3560 2423f660 ths
//            break;
3561 9c2149c8 ths
        default:
3562 9c2149c8 ths
            goto die;
3563 9c2149c8 ths
        }
3564 9c2149c8 ths
        break;
3565 9c2149c8 ths
    case 2:
3566 9c2149c8 ths
        switch (sel) {
3567 9c2149c8 ths
        case 0:
3568 f1b0aa5d ths
            gen_op_mtc0_entrylo0();
3569 2423f660 ths
            rn = "EntryLo0";
3570 2423f660 ths
            break;
3571 9c2149c8 ths
        case 1:
3572 f1b0aa5d ths
//            gen_op_mtc0_tcstatus(); /* MT ASE */
3573 2423f660 ths
            rn = "TCStatus";
3574 2423f660 ths
//            break;
3575 9c2149c8 ths
        case 2:
3576 f1b0aa5d ths
//            gen_op_mtc0_tcbind(); /* MT ASE */
3577 2423f660 ths
            rn = "TCBind";
3578 2423f660 ths
//            break;
3579 9c2149c8 ths
        case 3:
3580 f1b0aa5d ths
//            gen_op_mtc0_tcrestart(); /* MT ASE */
3581 2423f660 ths
            rn = "TCRestart";
3582 2423f660 ths
//            break;
3583 9c2149c8 ths
        case 4:
3584 f1b0aa5d ths
//            gen_op_mtc0_tchalt(); /* MT ASE */
3585 2423f660 ths
            rn = "TCHalt";
3586 2423f660 ths
//            break;
3587 9c2149c8 ths
        case 5:
3588 f1b0aa5d ths
//            gen_op_mtc0_tccontext(); /* MT ASE */
3589 2423f660 ths
            rn = "TCContext";
3590 2423f660 ths
//            break;
3591 9c2149c8 ths
        case 6:
3592 f1b0aa5d ths
//            gen_op_mtc0_tcschedule(); /* MT ASE */
3593 2423f660 ths
            rn = "TCSchedule";
3594 2423f660 ths
//            break;
3595 9c2149c8 ths
        case 7:
3596 f1b0aa5d ths
//            gen_op_mtc0_tcschefback(); /* MT ASE */
3597 2423f660 ths
            rn = "TCScheFBack";
3598 2423f660 ths
//            break;
3599 9c2149c8 ths
        default:
3600 9c2149c8 ths
            goto die;
3601 9c2149c8 ths
        }
3602 9c2149c8 ths
        break;
3603 9c2149c8 ths
    case 3:
3604 9c2149c8 ths
        switch (sel) {
3605 9c2149c8 ths
        case 0:
3606 f1b0aa5d ths
            gen_op_mtc0_entrylo1();
3607 2423f660 ths
            rn = "EntryLo1";
3608 2423f660 ths
            break;
3609 9c2149c8 ths
        default:
3610 9c2149c8 ths
            goto die;
3611 876d4b07 ths
        }
3612 9c2149c8 ths
        break;
3613 9c2149c8 ths
    case 4:
3614 9c2149c8 ths
        switch (sel) {
3615 9c2149c8 ths
        case 0:
3616 f1b0aa5d ths
            gen_op_mtc0_context();
3617 2423f660 ths
            rn = "Context";
3618 2423f660 ths
            break;
3619 9c2149c8 ths
        case 1:
3620 f1b0aa5d ths
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3621 2423f660 ths
            rn = "ContextConfig";
3622 2423f660 ths
//           break;
3623 9c2149c8 ths
        default:
3624 9c2149c8 ths
            goto die;
3625 876d4b07 ths
        }
3626 9c2149c8 ths
        break;
3627 9c2149c8 ths
    case 5:
3628 9c2149c8 ths
        switch (sel) {
3629 9c2149c8 ths
        case 0:
3630 2423f660 ths
            gen_op_mtc0_pagemask();
3631 2423f660 ths
            rn = "PageMask";
3632 2423f660 ths
            break;
3633 9c2149c8 ths
        case 1:
3634 2423f660 ths
            gen_op_mtc0_pagegrain();
3635 2423f660 ths
            rn = "PageGrain";
3636 2423f660 ths
            break;
3637 9c2149c8 ths
        default:
3638 9c2149c8 ths
            goto die;
3639 876d4b07 ths
        }
3640 9c2149c8 ths
        break;
3641 9c2149c8 ths
    case 6:
3642 9c2149c8 ths
        switch (sel) {
3643 9c2149c8 ths
        case 0:
3644 2423f660 ths
            gen_op_mtc0_wired();
3645 2423f660 ths
            rn = "Wired";
3646 2423f660 ths
            break;
3647 9c2149c8 ths
        case 1:
3648 f1b0aa5d ths
//            gen_op_mtc0_srsconf0(); /* shadow registers */
3649 2423f660 ths
            rn = "SRSConf0";
3650 2423f660 ths
//            break;
3651 9c2149c8 ths
        case 2:
3652 f1b0aa5d ths
//            gen_op_mtc0_srsconf1(); /* shadow registers */
3653 2423f660 ths
            rn = "SRSConf1";
3654 2423f660 ths
//            break;
3655 9c2149c8 ths
        case 3:
3656 f1b0aa5d ths
//            gen_op_mtc0_srsconf2(); /* shadow registers */
3657 2423f660 ths
            rn = "SRSConf2";
3658 2423f660 ths
//            break;
3659 9c2149c8 ths
        case 4:
3660 f1b0aa5d ths
//            gen_op_mtc0_srsconf3(); /* shadow registers */
3661 2423f660 ths
            rn = "SRSConf3";
3662 2423f660 ths
//            break;
3663 9c2149c8 ths
        case 5:
3664 f1b0aa5d ths
//            gen_op_mtc0_srsconf4(); /* shadow registers */
3665 2423f660 ths
            rn = "SRSConf4";
3666 2423f660 ths
//            break;
3667 9c2149c8 ths
        default:
3668 9c2149c8 ths
            goto die;
3669 876d4b07 ths
        }
3670 9c2149c8 ths
        break;
3671 9c2149c8 ths
    case 7:
3672 9c2149c8 ths
        switch (sel) {
3673 9c2149c8 ths
        case 0:
3674 2423f660 ths
            gen_op_mtc0_hwrena();
3675 2423f660 ths
            rn = "HWREna";
3676 2423f660 ths
            break;
3677 9c2149c8 ths
        default:
3678 9c2149c8 ths
            goto die;
3679 876d4b07 ths
        }
3680 9c2149c8 ths
        break;
3681 9c2149c8 ths
    case 8:
3682 9c2149c8 ths
        /* ignored */
3683 9c2149c8 ths
        rn = "BadVaddr";
3684 9c2149c8 ths
        break;
3685 9c2149c8 ths
    case 9:
3686 9c2149c8 ths
        switch (sel) {
3687 9c2149c8 ths
        case 0:
3688 2423f660 ths
            gen_op_mtc0_count();
3689 2423f660 ths
            rn = "Count";
3690 2423f660 ths
            break;
3691 876d4b07 ths
        /* 6,7 are implementation dependent */
3692 9c2149c8 ths
        default:
3693 9c2149c8 ths
            goto die;
3694 876d4b07 ths
        }
3695 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3696 876d4b07 ths
        ctx->bstate = BS_STOP;
3697 9c2149c8 ths
        break;
3698 9c2149c8 ths
    case 10:
3699 9c2149c8 ths
        switch (sel) {
3700 9c2149c8 ths
        case 0:
3701 2423f660 ths
            gen_op_mtc0_entryhi();
3702 2423f660 ths
            rn = "EntryHi";
3703 2423f660 ths
            break;
3704 9c2149c8 ths
        default:
3705 9c2149c8 ths
            goto die;
3706 876d4b07 ths
        }
3707 9c2149c8 ths
        break;
3708 9c2149c8 ths
    case 11:
3709 9c2149c8 ths
        switch (sel) {
3710 9c2149c8 ths
        case 0:
3711 2423f660 ths
            gen_op_mtc0_compare();
3712 2423f660 ths
            rn = "Compare";
3713 2423f660 ths
            break;
3714 876d4b07 ths
        /* 6,7 are implementation dependent */
3715 9c2149c8 ths
        default:
3716 9c2149c8 ths
            goto die;
3717 876d4b07 ths
        }
3718 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3719 876d4b07 ths
        ctx->bstate = BS_STOP;
3720 9c2149c8 ths
        break;
3721 9c2149c8 ths
    case 12:
3722 9c2149c8 ths
        switch (sel) {
3723 9c2149c8 ths
        case 0:
3724 2423f660 ths
            gen_op_mtc0_status();
3725 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
3726 8487327a ths
            gen_save_pc(ctx->pc + 4);
3727 8487327a ths
            ctx->bstate = BS_EXCP;
3728 2423f660 ths
            rn = "Status";
3729 2423f660 ths
            break;
3730 9c2149c8 ths
        case 1:
3731 2423f660 ths
            gen_op_mtc0_intctl();
3732 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3733 8487327a ths
            ctx->bstate = BS_STOP;
3734 2423f660 ths
            rn = "IntCtl";
3735 2423f660 ths
            break;
3736 9c2149c8 ths
        case 2:
3737 2423f660 ths
            gen_op_mtc0_srsctl();
3738 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3739 8487327a ths
            ctx->bstate = BS_STOP;
3740 2423f660 ths
            rn = "SRSCtl";
3741 2423f660 ths
            break;
3742 9c2149c8 ths
        case 3:
3743 fd88b6ab ths
            gen_op_mtc0_srsmap();
3744 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3745 8487327a ths
            ctx->bstate = BS_STOP;
3746 2423f660 ths
            rn = "SRSMap";
3747 2423f660 ths
            break;
3748 2423f660 ths
        default:
3749 9c2149c8 ths
            goto die;
3750 876d4b07 ths
        }
3751 9c2149c8 ths
        break;
3752 9c2149c8 ths
    case 13:
3753 9c2149c8 ths
        switch (sel) {
3754 9c2149c8 ths
        case 0:
3755 2423f660 ths
            gen_op_mtc0_cause();
3756 2423f660 ths
            rn = "Cause";
3757 2423f660 ths
            break;
3758 9c2149c8 ths
        default:
3759 9c2149c8 ths
            goto die;
3760 876d4b07 ths
        }
3761 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3762 876d4b07 ths
        ctx->bstate = BS_STOP;
3763 9c2149c8 ths
        break;
3764 9c2149c8 ths
    case 14:
3765 9c2149c8 ths
        switch (sel) {
3766 9c2149c8 ths
        case 0:
3767 f1b0aa5d ths
            gen_op_mtc0_epc();
3768 2423f660 ths
            rn = "EPC";
3769 2423f660 ths
            break;
3770 9c2149c8 ths
        default:
3771 9c2149c8 ths
            goto die;
3772 876d4b07 ths
        }
3773 9c2149c8 ths
        break;
3774 9c2149c8 ths
    case 15:
3775 9c2149c8 ths
        switch (sel) {
3776 9c2149c8 ths
        case 0:
3777 2423f660 ths
            /* ignored */
3778 2423f660 ths
            rn = "PRid";
3779 2423f660 ths
            break;
3780 9c2149c8 ths
        case 1:
3781 2423f660 ths
            gen_op_mtc0_ebase();
3782 2423f660 ths
            rn = "EBase";
3783 2423f660 ths
            break;
3784 9c2149c8 ths
        default:
3785 9c2149c8 ths
            goto die;
3786 876d4b07 ths
        }
3787 9c2149c8 ths
        break;
3788 9c2149c8 ths
    case 16:
3789 9c2149c8 ths
        switch (sel) {
3790 9c2149c8 ths
        case 0:
3791 9c2149c8 ths
            gen_op_mtc0_config0();
3792 9c2149c8 ths
            rn = "Config";
3793 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3794 2423f660 ths
            ctx->bstate = BS_STOP;
3795 9c2149c8 ths
            break;
3796 9c2149c8 ths
        case 1:
3797 2423f660 ths
            /* ignored */
3798 9c2149c8 ths
            rn = "Config1";
3799 9c2149c8 ths
            break;
3800 9c2149c8 ths
        case 2:
3801 9c2149c8 ths
            gen_op_mtc0_config2();
3802 9c2149c8 ths
            rn = "Config2";
3803 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3804 2423f660 ths
            ctx->bstate = BS_STOP;
3805 9c2149c8 ths
            break;
3806 9c2149c8 ths
        case 3:
3807 2423f660 ths
            /* ignored */
3808 9c2149c8 ths
            rn = "Config3";
3809 9c2149c8 ths
            break;
3810 9c2149c8 ths
        /* 6,7 are implementation dependent */
3811 9c2149c8 ths
        default:
3812 9c2149c8 ths
            rn = "Invalid config selector";
3813 9c2149c8 ths
            goto die;
3814 9c2149c8 ths
        }
3815 9c2149c8 ths
        break;
3816 9c2149c8 ths
    case 17:
3817 9c2149c8 ths
        switch (sel) {
3818 9c2149c8 ths
        case 0:
3819 2423f660 ths
            /* ignored */
3820 2423f660 ths
            rn = "LLAddr";
3821 2423f660 ths
            break;
3822 9c2149c8 ths
        default:
3823 9c2149c8 ths
            goto die;
3824 9c2149c8 ths
        }
3825 9c2149c8 ths
        break;
3826 9c2149c8 ths
    case 18:
3827 9c2149c8 ths
        switch (sel) {
3828 fd88b6ab ths
        case 0 ... 7:
3829 fd88b6ab ths
            gen_op_mtc0_watchlo(sel);
3830 2423f660 ths
            rn = "WatchLo";
3831 2423f660 ths
            break;
3832 9c2149c8 ths
        default:
3833 9c2149c8 ths
            goto die;
3834 9c2149c8 ths
        }
3835 9c2149c8 ths
        break;
3836 9c2149c8 ths
    case 19:
3837 9c2149c8 ths
        switch (sel) {
3838 fd88b6ab ths
        case 0 ... 7:
3839 fd88b6ab ths
            gen_op_mtc0_watchhi(sel);
3840 2423f660 ths
            rn = "WatchHi";
3841 2423f660 ths
            break;
3842 9c2149c8 ths
        default:
3843 9c2149c8 ths
            goto die;
3844 9c2149c8 ths
        }
3845 9c2149c8 ths
        break;
3846 9c2149c8 ths
    case 20:
3847 9c2149c8 ths
        switch (sel) {
3848 9c2149c8 ths
        case 0:
3849 703eaf37 ths
#ifdef TARGET_MIPS64
3850 f1b0aa5d ths
            gen_op_mtc0_xcontext();
3851 2423f660 ths
            rn = "XContext";
3852 2423f660 ths
            break;
3853 703eaf37 ths
#endif
3854 9c2149c8 ths
        default:
3855 9c2149c8 ths
            goto die;
3856 9c2149c8 ths
        }
3857 9c2149c8 ths
        break;
3858 9c2149c8 ths
    case 21:
3859 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3860 9c2149c8 ths
        switch (sel) {
3861 9c2149c8 ths
        case 0:
3862 2423f660 ths
            gen_op_mtc0_framemask();
3863 2423f660 ths
            rn = "Framemask";
3864 2423f660 ths
            break;
3865 9c2149c8 ths
        default:
3866 9c2149c8 ths
            goto die;
3867 9c2149c8 ths
        }
3868 9c2149c8 ths
        break;
3869 9c2149c8 ths
    case 22:
3870 9c2149c8 ths
        /* ignored */
3871 9c2149c8 ths
        rn = "Diagnostic"; /* implementation dependent */
3872 876d4b07 ths
        break;
3873 9c2149c8 ths
    case 23:
3874 9c2149c8 ths
        switch (sel) {
3875 9c2149c8 ths
        case 0:
3876 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
3877 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
3878 8487327a ths
            gen_save_pc(ctx->pc + 4);
3879 8487327a ths
            ctx->bstate = BS_EXCP;
3880 2423f660 ths
            rn = "Debug";
3881 2423f660 ths
            break;
3882 9c2149c8 ths
        case 1:
3883 f1b0aa5d ths
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3884 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3885 8487327a ths
            ctx->bstate = BS_STOP;
3886 2423f660 ths
            rn = "TraceControl";
3887 2423f660 ths
//            break;
3888 9c2149c8 ths
        case 2:
3889 f1b0aa5d ths
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3890 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3891 8487327a ths
            ctx->bstate = BS_STOP;
3892 2423f660 ths
            rn = "TraceControl2";
3893 2423f660 ths
//            break;
3894 9c2149c8 ths
        case 3:
3895 f1b0aa5d ths
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3896 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3897 8487327a ths
            ctx->bstate = BS_STOP;
3898 2423f660 ths
            rn = "UserTraceData";
3899 2423f660 ths
//            break;
3900 9c2149c8 ths
        case 4:
3901 f1b0aa5d ths
//            gen_op_mtc0_debug(); /* PDtrace support */
3902 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3903 8487327a ths
            ctx->bstate = BS_STOP;
3904 2423f660 ths
            rn = "TraceBPC";
3905 2423f660 ths
//            break;
3906 9c2149c8 ths
        default:
3907 9c2149c8 ths
            goto die;
3908 9c2149c8 ths
        }
3909 9c2149c8 ths
        break;
3910 9c2149c8 ths
    case 24:
3911 9c2149c8 ths
        switch (sel) {
3912 9c2149c8 ths
        case 0:
3913 f1b0aa5d ths
            gen_op_mtc0_depc(); /* EJTAG support */
3914 2423f660 ths
            rn = "DEPC";
3915 2423f660 ths
            break;
3916 9c2149c8 ths
        default:
3917 9c2149c8 ths
            goto die;
3918 9c2149c8 ths
        }
3919 9c2149c8 ths
        break;
3920 9c2149c8 ths
    case 25:
3921 9c2149c8 ths
        switch (sel) {
3922 9c2149c8 ths
        case 0:
3923 2423f660 ths
            gen_op_mtc0_performance0();
3924 2423f660 ths
            rn = "Performance0";
3925 2423f660 ths
            break;
3926 9c2149c8 ths
        case 1:
3927 f1b0aa5d ths
//            gen_op_mtc0_performance1();
3928 2423f660 ths
            rn = "Performance1";
3929 2423f660 ths
//            break;
3930 9c2149c8 ths
        case 2:
3931 f1b0aa5d ths
//            gen_op_mtc0_performance2();
3932 2423f660 ths
            rn = "Performance2";
3933 2423f660 ths
//            break;
3934 9c2149c8 ths
        case 3:
3935 f1b0aa5d ths
//            gen_op_mtc0_performance3();
3936 2423f660 ths
            rn = "Performance3";
3937 2423f660 ths
//            break;
3938 9c2149c8 ths
        case 4:
3939 f1b0aa5d ths
//            gen_op_mtc0_performance4();
3940 2423f660 ths
            rn = "Performance4";
3941 2423f660 ths
//            break;
3942 9c2149c8 ths
        case 5:
3943 f1b0aa5d ths
//            gen_op_mtc0_performance5();
3944 2423f660 ths
            rn = "Performance5";
3945 2423f660 ths
//            break;
3946 9c2149c8 ths
        case 6:
3947 f1b0aa5d ths
//            gen_op_mtc0_performance6();
3948 2423f660 ths
            rn = "Performance6";
3949 2423f660 ths
//            break;
3950 9c2149c8 ths
        case 7:
3951 f1b0aa5d ths
//            gen_op_mtc0_performance7();
3952 2423f660 ths
            rn = "Performance7";
3953 2423f660 ths
//            break;
3954 9c2149c8 ths
        default:
3955 9c2149c8 ths
            goto die;
3956 9c2149c8 ths
        }
3957 876d4b07 ths
        break;
3958 9c2149c8 ths
    case 26:
3959 876d4b07 ths
        /* ignored */
3960 9c2149c8 ths
        rn = "ECC";
3961 876d4b07 ths
        break;
3962 9c2149c8 ths
    case 27:
3963 9c2149c8 ths
        switch (sel) {
3964 9c2149c8 ths
        case 0 ... 3:
3965 2423f660 ths
            /* ignored */
3966 2423f660 ths
            rn = "CacheErr";
3967 2423f660 ths
            break;
3968 9c2149c8 ths
        default:
3969 9c2149c8 ths
            goto die;
3970 9c2149c8 ths
        }
3971 876d4b07 ths
        break;
3972 9c2149c8 ths
    case 28:
3973 9c2149c8 ths
        switch (sel) {
3974 9c2149c8 ths
        case 0:
3975 9c2149c8 ths
        case 2:
3976 9c2149c8 ths
        case 4:
3977 9c2149c8 ths
        case 6:
3978 9c2149c8 ths
            gen_op_mtc0_taglo();
3979 9c2149c8 ths
            rn = "TagLo";
3980 9c2149c8 ths
            break;
3981 9c2149c8 ths
        case 1:
3982 9c2149c8 ths
        case 3:
3983 9c2149c8 ths
        case 5:
3984 9c2149c8 ths
        case 7:
3985 2423f660 ths
            gen_op_mtc0_datalo();
3986 9c2149c8 ths
            rn = "DataLo";
3987 9c2149c8 ths
            break;
3988 9c2149c8 ths
        default:
3989 9c2149c8 ths
            goto die;
3990 9c2149c8 ths
        }
3991 9c2149c8 ths
        break;
3992 9c2149c8 ths
    case 29:
3993 9c2149c8 ths
        switch (sel) {
3994 9c2149c8 ths
        case 0:
3995 9c2149c8 ths
        case 2:
3996 9c2149c8 ths
        case 4:
3997 9c2149c8 ths
        case 6:
3998 9c2149c8 ths
            gen_op_mtc0_taghi();
3999 9c2149c8 ths
            rn = "TagHi";
4000 9c2149c8 ths
            break;
4001 9c2149c8 ths
        case 1:
4002 9c2149c8 ths
        case 3:
4003 9c2149c8 ths
        case 5:
4004 9c2149c8 ths
        case 7:
4005 2423f660 ths
            gen_op_mtc0_datahi();
4006 9c2149c8 ths
            rn = "DataHi";
4007 9c2149c8 ths
            break;
4008 9c2149c8 ths
        default:
4009 9c2149c8 ths
            rn = "invalid sel";
4010 9c2149c8 ths
            goto die;
4011 9c2149c8 ths
        }
4012 876d4b07 ths
        break;
4013 9c2149c8 ths
    case 30:
4014 9c2149c8 ths
        switch (sel) {
4015 9c2149c8 ths
        case 0:
4016 f1b0aa5d ths
            gen_op_mtc0_errorepc();
4017 2423f660 ths
            rn = "ErrorEPC";
4018 2423f660 ths
            break;
4019 9c2149c8 ths
        default:
4020 9c2149c8 ths
            goto die;
4021 9c2149c8 ths
        }
4022 9c2149c8 ths
        break;
4023 9c2149c8 ths
    case 31:
4024 9c2149c8 ths
        switch (sel) {
4025 9c2149c8 ths
        case 0:
4026 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
4027 2423f660 ths
            rn = "DESAVE";
4028 2423f660 ths
            break;
4029 9c2149c8 ths
        default:
4030 9c2149c8 ths
            goto die;
4031 9c2149c8 ths
        }
4032 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
4033 876d4b07 ths
        ctx->bstate = BS_STOP;
4034 9c2149c8 ths
        break;
4035 9c2149c8 ths
    default:
4036 876d4b07 ths
        goto die;
4037 9c2149c8 ths
    }
4038 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4039 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4040 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4041 9c2149c8 ths
                rn, reg, sel);
4042 9c2149c8 ths
    }
4043 9c2149c8 ths
#endif
4044 9c2149c8 ths
    return;
4045 9c2149c8 ths
4046 9c2149c8 ths
die:
4047 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4048 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4049 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4050 9c2149c8 ths
                rn, reg, sel);
4051 9c2149c8 ths
    }
4052 9c2149c8 ths
#endif
4053 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
4054 9c2149c8 ths
}
4055 534ce69f ths
#endif /* TARGET_MIPS64 */
4056 9c2149c8 ths
4057 29929e34 ths
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4058 6af0bf9c bellard
{
4059 287c4b84 ths
    const char *opn = "ldst";
4060 6af0bf9c bellard
4061 6af0bf9c bellard
    switch (opc) {
4062 6af0bf9c bellard
    case OPC_MFC0:
4063 6af0bf9c bellard
        if (rt == 0) {
4064 6af0bf9c bellard
            /* Treat as NOP */
4065 6af0bf9c bellard
            return;
4066 6af0bf9c bellard
        }
4067 873eb012 ths
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4068 6af0bf9c bellard
        gen_op_store_T0_gpr(rt);
4069 6af0bf9c bellard
        opn = "mfc0";
4070 6af0bf9c bellard
        break;
4071 6af0bf9c bellard
    case OPC_MTC0:
4072 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, rt);
4073 8c0fdd85 ths
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4074 6af0bf9c bellard
        opn = "mtc0";
4075 6af0bf9c bellard
        break;
4076 534ce69f ths
#ifdef TARGET_MIPS64
4077 9c2149c8 ths
    case OPC_DMFC0:
4078 9c2149c8 ths
        if (rt == 0) {
4079 9c2149c8 ths
            /* Treat as NOP */
4080 9c2149c8 ths
            return;
4081 9c2149c8 ths
        }
4082 9c2149c8 ths
        gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4083 9c2149c8 ths
        gen_op_store_T0_gpr(rt);
4084 9c2149c8 ths
        opn = "dmfc0";
4085 9c2149c8 ths
        break;
4086 9c2149c8 ths
    case OPC_DMTC0:
4087 9c2149c8 ths
        GEN_LOAD_REG_TN(T0, rt);
4088 9c2149c8 ths
        gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4089 9c2149c8 ths
        opn = "dmtc0";
4090 9c2149c8 ths
        break;
4091 534ce69f ths
#endif
4092 6af0bf9c bellard
    case OPC_TLBWI:
4093 6af0bf9c bellard
        opn = "tlbwi";
4094 29929e34 ths
        if (!env->do_tlbwi)
4095 29929e34 ths
            goto die;
4096 29929e34 ths
        gen_op_tlbwi();
4097 6af0bf9c bellard
        break;
4098 6af0bf9c bellard
    case OPC_TLBWR:
4099 6af0bf9c bellard
        opn = "tlbwr";
4100 29929e34 ths
        if (!env->do_tlbwr)
4101 29929e34 ths
            goto die;
4102 29929e34 ths
        gen_op_tlbwr();
4103 6af0bf9c bellard
        break;
4104 6af0bf9c bellard
    case OPC_TLBP:
4105 6af0bf9c bellard
        opn = "tlbp";
4106 29929e34 ths
        if (!env->do_tlbp)
4107 29929e34 ths
            goto die;
4108 29929e34 ths
        gen_op_tlbp();
4109 6af0bf9c bellard
        break;
4110 6af0bf9c bellard
    case OPC_TLBR:
4111 6af0bf9c bellard
        opn = "tlbr";
4112 29929e34 ths
        if (!env->do_tlbr)
4113 29929e34 ths
            goto die;
4114 29929e34 ths
        gen_op_tlbr();
4115 6af0bf9c bellard
        break;
4116 6af0bf9c bellard
    case OPC_ERET:
4117 6af0bf9c bellard
        opn = "eret";
4118 6af0bf9c bellard
        gen_op_eret();
4119 6af0bf9c bellard
        ctx->bstate = BS_EXCP;
4120 6af0bf9c bellard
        break;
4121 6af0bf9c bellard
    case OPC_DERET:
4122 6af0bf9c bellard
        opn = "deret";
4123 6af0bf9c bellard
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4124 923617a3 ths
            MIPS_INVAL(opn);
4125 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
4126 6af0bf9c bellard
        } else {
4127 6af0bf9c bellard
            gen_op_deret();
4128 6af0bf9c bellard
            ctx->bstate = BS_EXCP;
4129 6af0bf9c bellard
        }
4130 6af0bf9c bellard
        break;
4131 4ad40f36 bellard
    case OPC_WAIT:
4132 4ad40f36 bellard
        opn = "wait";
4133 4ad40f36 bellard
        /* If we get an exception, we want to restart at next instruction */
4134 4ad40f36 bellard
        ctx->pc += 4;
4135 4ad40f36 bellard
        save_cpu_state(ctx, 1);
4136 4ad40f36 bellard
        ctx->pc -= 4;
4137 4ad40f36 bellard
        gen_op_wait();
4138 4ad40f36 bellard
        ctx->bstate = BS_EXCP;
4139 4ad40f36 bellard
        break;
4140 6af0bf9c bellard
    default:
4141 29929e34 ths
 die:
4142 923617a3 ths
        MIPS_INVAL(opn);
4143 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
4144 6af0bf9c bellard
        return;
4145 6af0bf9c bellard
    }
4146 6af0bf9c bellard
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4147 6af0bf9c bellard
}
4148 6af0bf9c bellard
4149 6ea83fed bellard
/* CP1 Branches (before delay slot) */
4150 7a387fff ths
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4151 5a5012ec ths
                                 int32_t cc, int32_t offset)
4152 6ea83fed bellard
{
4153 6ea83fed bellard
    target_ulong btarget;
4154 923617a3 ths
    const char *opn = "cp1 cond branch";
4155 6ea83fed bellard
4156 6ea83fed bellard
    btarget = ctx->pc + 4 + offset;
4157 6ea83fed bellard
4158 7a387fff ths
    switch (op) {
4159 7a387fff ths
    case OPC_BC1F:
4160 5a5012ec ths
        gen_op_bc1f(cc);
4161 923617a3 ths
        opn = "bc1f";
4162 6ea83fed bellard
        goto not_likely;
4163 7a387fff ths
    case OPC_BC1FL:
4164 5a5012ec ths
        gen_op_bc1f(cc);
4165 923617a3 ths
        opn = "bc1fl";
4166 6ea83fed bellard
        goto likely;
4167 7a387fff ths
    case OPC_BC1T:
4168 5a5012ec ths
        gen_op_bc1t(cc);
4169 923617a3 ths
        opn = "bc1t";
4170 5a5012ec ths
        goto not_likely;
4171 7a387fff ths
    case OPC_BC1TL:
4172 5a5012ec ths
        gen_op_bc1t(cc);
4173 923617a3 ths
        opn = "bc1tl";
4174 6ea83fed bellard
    likely:
4175 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BL;
4176 5a5012ec ths
        gen_op_set_bcond();
4177 5a5012ec ths
        gen_op_save_bcond();
4178 6ea83fed bellard
        break;
4179 5a5012ec ths
    case OPC_BC1FANY2:
4180 fd4a04eb ths
        gen_op_bc1any2f(cc);
4181 fd4a04eb ths
        opn = "bc1any2f";
4182 5a5012ec ths
        goto not_likely;
4183 5a5012ec ths
    case OPC_BC1TANY2:
4184 fd4a04eb ths
        gen_op_bc1any2t(cc);
4185 fd4a04eb ths
        opn = "bc1any2t";
4186 5a5012ec ths
        goto not_likely;
4187 5a5012ec ths
    case OPC_BC1FANY4:
4188 fd4a04eb ths
        gen_op_bc1any4f(cc);
4189 fd4a04eb ths
        opn = "bc1any4f";
4190 5a5012ec ths
        goto not_likely;
4191 5a5012ec ths
    case OPC_BC1TANY4:
4192 fd4a04eb ths
        gen_op_bc1any4t(cc);
4193 fd4a04eb ths
        opn = "bc1any4t";
4194 5a5012ec ths
    not_likely:
4195 5a5012ec ths
        ctx->hflags |= MIPS_HFLAG_BC;
4196 5a5012ec ths
        gen_op_set_bcond();
4197 5a5012ec ths
        break;
4198 5a5012ec ths
    default:
4199 923617a3 ths
        MIPS_INVAL(opn);
4200 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
4201 6ea83fed bellard
        return;
4202 6ea83fed bellard
    }
4203 923617a3 ths
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4204 6ea83fed bellard
               ctx->hflags, btarget);
4205 6ea83fed bellard
    ctx->btarget = btarget;
4206 6ea83fed bellard
}
4207 6ea83fed bellard
4208 6af0bf9c bellard
/* Coprocessor 1 (FPU) */
4209 5a5012ec ths
4210 5a5012ec ths
#define FOP(func, fmt) (((fmt) << 21) | (func))
4211 5a5012ec ths
4212 7a387fff ths
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4213 6ea83fed bellard
{
4214 923617a3 ths
    const char *opn = "cp1 move";
4215 6ea83fed bellard
4216 6ea83fed bellard
    switch (opc) {
4217 6ea83fed bellard
    case OPC_MFC1:
4218 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4219 6ea83fed bellard
        gen_op_mfc1();
4220 6ea83fed bellard
        GEN_STORE_TN_REG(rt, T0);
4221 6ea83fed bellard
        opn = "mfc1";
4222 6ea83fed bellard
        break;
4223 6ea83fed bellard
    case OPC_MTC1:
4224 6ea83fed bellard
        GEN_LOAD_REG_TN(T0, rt);
4225 6ea83fed bellard
        gen_op_mtc1();
4226 6ea83fed bellard
        GEN_STORE_FTN_FREG(fs, WT0);
4227 6ea83fed bellard
        opn = "mtc1";
4228 6ea83fed bellard
        break;
4229 6ea83fed bellard
    case OPC_CFC1:
4230 6ea83fed bellard
        GEN_LOAD_IMM_TN(T1, fs);
4231 6ea83fed bellard
        gen_op_cfc1();
4232 6ea83fed bellard
        GEN_STORE_TN_REG(rt, T0);
4233 6ea83fed bellard
        opn = "cfc1";
4234 6ea83fed bellard
        break;
4235 6ea83fed bellard
    case OPC_CTC1:
4236 6ea83fed bellard
        GEN_LOAD_IMM_TN(T1, fs);
4237 6ea83fed bellard
        GEN_LOAD_REG_TN(T0, rt);
4238 6ea83fed bellard
        gen_op_ctc1();
4239 6ea83fed bellard
        opn = "ctc1";
4240 6ea83fed bellard
        break;
4241 9c2149c8 ths
    case OPC_DMFC1:
4242 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4243 5a5012ec ths
        gen_op_dmfc1();
4244 5a5012ec ths
        GEN_STORE_TN_REG(rt, T0);
4245 5a5012ec ths
        opn = "dmfc1";
4246 5a5012ec ths
        break;
4247 9c2149c8 ths
    case OPC_DMTC1:
4248 5a5012ec ths
        GEN_LOAD_REG_TN(T0, rt);
4249 5a5012ec ths
        gen_op_dmtc1();
4250 5a5012ec ths
        GEN_STORE_FTN_FREG(fs, DT0);
4251 5a5012ec ths
        opn = "dmtc1";
4252 5a5012ec ths
        break;
4253 5a5012ec ths
    case OPC_MFHC1:
4254 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4255 5a5012ec ths
        gen_op_mfhc1();
4256 5a5012ec ths
        GEN_STORE_TN_REG(rt, T0);
4257 5a5012ec ths
        opn = "mfhc1";
4258 5a5012ec ths
        break;
4259 5a5012ec ths
    case OPC_MTHC1:
4260 5a5012ec ths
        GEN_LOAD_REG_TN(T0, rt);
4261 5a5012ec ths
        gen_op_mthc1();
4262 5a5012ec ths
        GEN_STORE_FTN_FREG(fs, WTH0);
4263 5a5012ec ths
        opn = "mthc1";
4264 5a5012ec ths
        break;
4265 6ea83fed bellard
    default:
4266 923617a3 ths
        MIPS_INVAL(opn);
4267 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
4268 6ea83fed bellard
        return;
4269 6ea83fed bellard
    }
4270 6ea83fed bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4271 6ea83fed bellard
}
4272 6ea83fed bellard
4273 5a5012ec ths
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4274 5a5012ec ths
{
4275 5a5012ec ths
    uint32_t ccbit;
4276 6ea83fed bellard
4277 5a5012ec ths
    GEN_LOAD_REG_TN(T0, rd);
4278 5a5012ec ths
    GEN_LOAD_REG_TN(T1, rs);
4279 57fa1fb3 ths
    if (cc) {
4280 5a5012ec ths
        ccbit = 1 << (24 + cc);
4281 57fa1fb3 ths
    } else
4282 5a5012ec ths
        ccbit = 1 << 23;
4283 5a5012ec ths
    if (!tf)
4284 5a5012ec ths
        gen_op_movf(ccbit);
4285 5a5012ec ths
    else
4286 5a5012ec ths
        gen_op_movt(ccbit);
4287 5a5012ec ths
    GEN_STORE_TN_REG(rd, T0);
4288 5a5012ec ths
}
4289 5a5012ec ths
4290 5a5012ec ths
#define GEN_MOVCF(fmt)                                                \
4291 5a5012ec ths
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4292 5a5012ec ths
{                                                                     \
4293 5a5012ec ths
    uint32_t ccbit;                                                   \
4294 5a5012ec ths
                                                                      \
4295 57fa1fb3 ths
    if (cc) {                                                         \
4296 5a5012ec ths
        ccbit = 1 << (24 + cc);                                       \
4297 57fa1fb3 ths
    } else                                                            \
4298 5a5012ec ths
        ccbit = 1 << 23;                                              \
4299 5a5012ec ths
    if (!tf)                                                          \
4300 5a5012ec ths
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
4301 5a5012ec ths
    else                                                              \
4302 5a5012ec ths
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
4303 5a5012ec ths
}
4304 5a5012ec ths
GEN_MOVCF(d);
4305 5a5012ec ths
GEN_MOVCF(s);
4306 5a5012ec ths
GEN_MOVCF(ps);
4307 5a5012ec ths
#undef GEN_MOVCF
4308 6ea83fed bellard
4309 5e755519 ths
static void gen_farith (DisasContext *ctx, uint32_t op1,
4310 5e755519 ths
                        int ft, int fs, int fd, int cc)
4311 6ea83fed bellard
{
4312 923617a3 ths
    const char *opn = "farith";
4313 6ea83fed bellard
    const char *condnames[] = {
4314 6ea83fed bellard
            "c.f",
4315 6ea83fed bellard
            "c.un",
4316 6ea83fed bellard
            "c.eq",
4317 6ea83fed bellard
            "c.ueq",
4318 6ea83fed bellard
            "c.olt",
4319 6ea83fed bellard
            "c.ult",
4320 6ea83fed bellard
            "c.ole",
4321 6ea83fed bellard
            "c.ule",
4322 6ea83fed bellard
            "c.sf",
4323 6ea83fed bellard
            "c.ngle",
4324 6ea83fed bellard
            "c.seq",
4325 6ea83fed bellard
            "c.ngl",
4326 6ea83fed bellard
            "c.lt",
4327 6ea83fed bellard
            "c.nge",
4328 6ea83fed bellard
            "c.le",
4329 6ea83fed bellard
            "c.ngt",
4330 6ea83fed bellard
    };
4331 5a1e8ffb ths
    const char *condnames_abs[] = {
4332 5a1e8ffb ths
            "cabs.f",
4333 5a1e8ffb ths
            "cabs.un",
4334 5a1e8ffb ths
            "cabs.eq",
4335 5a1e8ffb ths
            "cabs.ueq",
4336 5a1e8ffb ths
            "cabs.olt",
4337 5a1e8ffb ths
            "cabs.ult",
4338 5a1e8ffb ths
            "cabs.ole",
4339 5a1e8ffb ths
            "cabs.ule",
4340 5a1e8ffb ths
            "cabs.sf",
4341 5a1e8ffb ths
            "cabs.ngle",
4342 5a1e8ffb ths
            "cabs.seq",
4343 5a1e8ffb ths
            "cabs.ngl",
4344 5a1e8ffb ths
            "cabs.lt",
4345 5a1e8ffb ths
            "cabs.nge",
4346 5a1e8ffb ths
            "cabs.le",
4347 5a1e8ffb ths
            "cabs.ngt",
4348 5a1e8ffb ths
    };
4349 5a1e8ffb ths
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4350 7a387fff ths
    uint32_t func = ctx->opcode & 0x3f;
4351 7a387fff ths
4352 6ea83fed bellard
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4353 5a5012ec ths
    case FOP(0, 16):
4354 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4355 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
4356 5a5012ec ths
        gen_op_float_add_s();
4357 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4358 5a5012ec ths
        opn = "add.s";
4359 5a1e8ffb ths
        optype = BINOP;
4360 5a5012ec ths
        break;
4361 5a5012ec ths
    case FOP(1, 16):
4362 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4363 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
4364 5a5012ec ths
        gen_op_float_sub_s();
4365 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4366 5a5012ec ths
        opn = "sub.s";
4367 5a1e8ffb ths
        optype = BINOP;
4368 5a5012ec ths
        break;
4369 5a5012ec ths
    case FOP(2, 16):
4370 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4371 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
4372 5a5012ec ths
        gen_op_float_mul_s();
4373 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4374 5a5012ec ths
        opn = "mul.s";
4375 5a1e8ffb ths
        optype = BINOP;
4376 5a5012ec ths
        break;
4377 5a5012ec ths
    case FOP(3, 16):
4378 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4379 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
4380 5a5012ec ths
        gen_op_float_div_s();
4381 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4382 5a5012ec ths
        opn = "div.s";
4383 5a1e8ffb ths
        optype = BINOP;
4384 5a5012ec ths
        break;
4385 5a5012ec ths
    case FOP(4, 16):
4386 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4387 5a5012ec ths
        gen_op_float_sqrt_s();
4388 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4389 5a5012ec ths
        opn = "sqrt.s";
4390 5a5012ec ths
        break;
4391 5a5012ec ths
    case FOP(5, 16):
4392 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4393 5a5012ec ths
        gen_op_float_abs_s();
4394 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4395 5a5012ec ths
        opn = "abs.s";
4396 5a5012ec ths
        break;
4397 5a5012ec ths
    case FOP(6, 16):
4398 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4399 5a5012ec ths
        gen_op_float_mov_s();
4400 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4401 5a5012ec ths
        opn = "mov.s";
4402 5a5012ec ths
        break;
4403 5a5012ec ths
    case FOP(7, 16):
4404 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4405 5a5012ec ths
        gen_op_float_chs_s();
4406 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4407 5a5012ec ths
        opn = "neg.s";
4408 5a5012ec ths
        break;
4409 5a5012ec ths
    case FOP(8, 16):
4410 5e755519 ths
        check_cp1_64bitmode(ctx);
4411 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4412 5a5012ec ths
        gen_op_float_roundl_s();
4413 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4414 5a5012ec ths
        opn = "round.l.s";
4415 5a5012ec ths
        break;
4416 5a5012ec ths
    case FOP(9, 16):
4417 5e755519 ths
        check_cp1_64bitmode(ctx);
4418 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4419 5a5012ec ths
        gen_op_float_truncl_s();
4420 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4421 5a5012ec ths
        opn = "trunc.l.s";
4422 5a5012ec ths
        break;
4423 5a5012ec ths
    case FOP(10, 16):
4424 5e755519 ths
        check_cp1_64bitmode(ctx);
4425 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4426 5a5012ec ths
        gen_op_float_ceill_s();
4427 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4428 5a5012ec ths
        opn = "ceil.l.s";
4429 5a5012ec ths
        break;
4430 5a5012ec ths
    case FOP(11, 16):
4431 5e755519 ths
        check_cp1_64bitmode(ctx);
4432 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4433 5a5012ec ths
        gen_op_float_floorl_s();
4434 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4435 5a5012ec ths
        opn = "floor.l.s";
4436 5a5012ec ths
        break;
4437 5a5012ec ths
    case FOP(12, 16):
4438 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4439 5a5012ec ths
        gen_op_float_roundw_s();
4440 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4441 5a5012ec ths
        opn = "round.w.s";
4442 5a5012ec ths
        break;
4443 5a5012ec ths
    case FOP(13, 16):
4444 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4445 5a5012ec ths
        gen_op_float_truncw_s();
4446 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4447 5a5012ec ths
        opn = "trunc.w.s";
4448 5a5012ec ths
        break;
4449 5a5012ec ths
    case FOP(14, 16):
4450 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4451 5a5012ec ths
        gen_op_float_ceilw_s();
4452 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4453 5a5012ec ths
        opn = "ceil.w.s";
4454 5a5012ec ths
        break;
4455 5a5012ec ths
    case FOP(15, 16):
4456 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4457 5a5012ec ths
        gen_op_float_floorw_s();
4458 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4459 5a5012ec ths
        opn = "floor.w.s";
4460 5a5012ec ths
        break;
4461 5a5012ec ths
    case FOP(17, 16):
4462 5a5012ec ths
        GEN_LOAD_REG_TN(T0, ft);
4463 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4464 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
4465 5a5012ec ths
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
4466 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4467 5a5012ec ths
        opn = "movcf.s";
4468 5a5012ec ths
        break;
4469 5a5012ec ths
    case FOP(18, 16):
4470 5a5012ec ths
        GEN_LOAD_REG_TN(T0, ft);
4471 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4472 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
4473 5a5012ec ths
        gen_op_float_movz_s();
4474 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4475 5a5012ec ths
        opn = "movz.s";
4476 5a5012ec ths
        break;
4477 5a5012ec ths
    case FOP(19, 16):
4478 5a5012ec ths
        GEN_LOAD_REG_TN(T0, ft);
4479 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4480 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
4481 5a5012ec ths
        gen_op_float_movn_s();
4482 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4483 5a5012ec ths
        opn = "movn.s";
4484 5a5012ec ths
        break;
4485 57fa1fb3 ths
    case FOP(21, 16):
4486 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4487 57fa1fb3 ths
        gen_op_float_recip_s();
4488 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4489 57fa1fb3 ths
        opn = "recip.s";
4490 57fa1fb3 ths
        break;
4491 57fa1fb3 ths
    case FOP(22, 16):
4492 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4493 57fa1fb3 ths
        gen_op_float_rsqrt_s();
4494 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4495 57fa1fb3 ths
        opn = "rsqrt.s";
4496 57fa1fb3 ths
        break;
4497 57fa1fb3 ths
    case FOP(28, 16):
4498 5e755519 ths
        check_cp1_64bitmode(ctx);
4499 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4500 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT2, fd);
4501 57fa1fb3 ths
        gen_op_float_recip2_s();
4502 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4503 57fa1fb3 ths
        opn = "recip2.s";
4504 57fa1fb3 ths
        break;
4505 57fa1fb3 ths
    case FOP(29, 16):
4506 5e755519 ths
        check_cp1_64bitmode(ctx);
4507 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4508 57fa1fb3 ths
        gen_op_float_recip1_s();
4509 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4510 57fa1fb3 ths
        opn = "recip1.s";
4511 57fa1fb3 ths
        break;
4512 57fa1fb3 ths
    case FOP(30, 16):
4513 5e755519 ths
        check_cp1_64bitmode(ctx);
4514 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4515 57fa1fb3 ths
        gen_op_float_rsqrt1_s();
4516 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4517 57fa1fb3 ths
        opn = "rsqrt1.s";
4518 57fa1fb3 ths
        break;
4519 57fa1fb3 ths
    case FOP(31, 16):
4520 5e755519 ths
        check_cp1_64bitmode(ctx);
4521 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4522 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT2, fd);
4523 57fa1fb3 ths
        gen_op_float_rsqrt2_s();
4524 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4525 57fa1fb3 ths
        opn = "rsqrt2.s";
4526 57fa1fb3 ths
        break;
4527 5a5012ec ths
    case FOP(33, 16):
4528 5e755519 ths
        check_cp1_registers(ctx, fd);
4529 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4530 5a5012ec ths
        gen_op_float_cvtd_s();
4531 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4532 5a5012ec ths
        opn = "cvt.d.s";
4533 5a5012ec ths
        break;
4534 5a5012ec ths
    case FOP(36, 16):
4535 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4536 5a5012ec ths
        gen_op_float_cvtw_s();
4537 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4538 5a5012ec ths
        opn = "cvt.w.s";
4539 5a5012ec ths
        break;
4540 5a5012ec ths
    case FOP(37, 16):
4541 5e755519 ths
        check_cp1_64bitmode(ctx);
4542 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4543 5a5012ec ths
        gen_op_float_cvtl_s();
4544 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4545 5a5012ec ths
        opn = "cvt.l.s";
4546 5a5012ec ths
        break;
4547 5a5012ec ths
    case FOP(38, 16):
4548 5e755519 ths
        check_cp1_64bitmode(ctx);
4549 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, fs);
4550 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, ft);
4551 5a5012ec ths
        gen_op_float_cvtps_s();
4552 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4553 5a5012ec ths
        opn = "cvt.ps.s";
4554 5a5012ec ths
        break;
4555 5a5012ec ths
    case FOP(48, 16):
4556 5a5012ec ths
    case FOP(49, 16):
4557 5a5012ec ths
    case FOP(50, 16):
4558 5a5012ec ths
    case FOP(51, 16):
4559 5a5012ec ths
    case FOP(52, 16):
4560 5a5012ec ths
    case FOP(53, 16):
4561 5a5012ec ths
    case FOP(54, 16):
4562 5a5012ec ths
    case FOP(55, 16):
4563 5a5012ec ths
    case FOP(56, 16):
4564 5a5012ec ths
    case FOP(57, 16):
4565 5a5012ec ths
    case FOP(58, 16):
4566 5a5012ec ths
    case FOP(59, 16):
4567 5a5012ec ths
    case FOP(60, 16):
4568 5a5012ec ths
    case FOP(61, 16):
4569 5a5012ec ths
    case FOP(62, 16):
4570 5a5012ec ths
    case FOP(63, 16):
4571 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4572 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
4573 5a1e8ffb ths
        if (ctx->opcode & (1 << 6)) {
4574 5e755519 ths
            check_cp1_64bitmode(ctx);
4575 5a1e8ffb ths
            gen_cmpabs_s(func-48, cc);
4576 5a1e8ffb ths
            opn = condnames_abs[func-48];
4577 5a1e8ffb ths
        } else {
4578 5a1e8ffb ths
            gen_cmp_s(func-48, cc);
4579 5a1e8ffb ths
            opn = condnames[func-48];
4580 5a1e8ffb ths
        }
4581 5a5012ec ths
        break;
4582 6ea83fed bellard
    case FOP(0, 17):
4583 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
4584 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4585 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4586 6ea83fed bellard
        gen_op_float_add_d();
4587 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4588 6ea83fed bellard
        opn = "add.d";
4589 5a1e8ffb ths
        optype = BINOP;
4590 6ea83fed bellard
        break;
4591 6ea83fed bellard
    case FOP(1, 17):
4592 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
4593 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4594 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4595 6ea83fed bellard
        gen_op_float_sub_d();
4596 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4597 6ea83fed bellard
        opn = "sub.d";
4598 5a1e8ffb ths
        optype = BINOP;
4599 6ea83fed bellard
        break;
4600 6ea83fed bellard
    case FOP(2, 17):
4601 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
4602 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4603 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4604 6ea83fed bellard
        gen_op_float_mul_d();
4605 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4606 6ea83fed bellard
        opn = "mul.d";
4607 5a1e8ffb ths
        optype = BINOP;
4608 6ea83fed bellard
        break;
4609 6ea83fed bellard
    case FOP(3, 17):
4610 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
4611 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4612 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4613 6ea83fed bellard
        gen_op_float_div_d();
4614 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4615 6ea83fed bellard
        opn = "div.d";
4616 5a1e8ffb ths
        optype = BINOP;
4617 6ea83fed bellard
        break;
4618 6ea83fed bellard
    case FOP(4, 17):
4619 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
4620 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4621 6ea83fed bellard
        gen_op_float_sqrt_d();
4622 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4623 6ea83fed bellard
        opn = "sqrt.d";
4624 6ea83fed bellard
        break;
4625 6ea83fed bellard
    case FOP(5, 17):
4626 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
4627 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4628 6ea83fed bellard
        gen_op_float_abs_d();
4629 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4630 6ea83fed bellard
        opn = "abs.d";
4631 6ea83fed bellard
        break;
4632 6ea83fed bellard
    case FOP(6, 17):
4633 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
4634 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4635 6ea83fed bellard
        gen_op_float_mov_d();
4636 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4637 6ea83fed bellard
        opn = "mov.d";
4638 6ea83fed bellard
        break;
4639 6ea83fed bellard
    case FOP(7, 17):
4640 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
4641 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4642 6ea83fed bellard
        gen_op_float_chs_d();
4643 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4644 6ea83fed bellard
        opn = "neg.d";
4645 6ea83fed bellard
        break;
4646 5a5012ec ths
    case FOP(8, 17):
4647 5e755519 ths
        check_cp1_64bitmode(ctx);
4648 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4649 5a5012ec ths
        gen_op_float_roundl_d();
4650 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4651 5a5012ec ths
        opn = "round.l.d";
4652 5a5012ec ths
        break;
4653 5a5012ec ths
    case FOP(9, 17):
4654 5e755519 ths
        check_cp1_64bitmode(ctx);
4655 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4656 5a5012ec ths
        gen_op_float_truncl_d();
4657 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4658 5a5012ec ths
        opn = "trunc.l.d";
4659 5a5012ec ths
        break;
4660 5a5012ec ths
    case FOP(10, 17):
4661 5e755519 ths
        check_cp1_64bitmode(ctx);
4662 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4663 5a5012ec ths
        gen_op_float_ceill_d();
4664 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4665 5a5012ec ths
        opn = "ceil.l.d";
4666 5a5012ec ths
        break;
4667 5a5012ec ths
    case FOP(11, 17):
4668 5e755519 ths
        check_cp1_64bitmode(ctx);
4669 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4670 5a5012ec ths
        gen_op_float_floorl_d();
4671 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4672 5a5012ec ths
        opn = "floor.l.d";
4673 5a5012ec ths
        break;
4674 6ea83fed bellard
    case FOP(12, 17):
4675 5e755519 ths
        check_cp1_registers(ctx, fs);
4676 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4677 6ea83fed bellard
        gen_op_float_roundw_d();
4678 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4679 6ea83fed bellard
        opn = "round.w.d";
4680 6ea83fed bellard
        break;
4681 6ea83fed bellard
    case FOP(13, 17):
4682 5e755519 ths
        check_cp1_registers(ctx, fs);
4683 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4684 6ea83fed bellard
        gen_op_float_truncw_d();
4685 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4686 6ea83fed bellard
        opn = "trunc.w.d";
4687 6ea83fed bellard
        break;
4688 6ea83fed bellard
    case FOP(14, 17):
4689 5e755519 ths
        check_cp1_registers(ctx, fs);
4690 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4691 6ea83fed bellard
        gen_op_float_ceilw_d();
4692 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4693 6ea83fed bellard
        opn = "ceil.w.d";
4694 6ea83fed bellard
        break;
4695 6ea83fed bellard
    case FOP(15, 17):
4696 5e755519 ths
        check_cp1_registers(ctx, fs);
4697 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4698 6ea83fed bellard
        gen_op_float_floorw_d();
4699 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4700 7a387fff ths
        opn = "floor.w.d";
4701 6ea83fed bellard
        break;
4702 5a5012ec ths
    case FOP(17, 17):
4703 5a5012ec ths
        GEN_LOAD_REG_TN(T0, ft);
4704 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4705 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT2, fd);
4706 5a5012ec ths
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
4707 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4708 5a5012ec ths
        opn = "movcf.d";
4709 dd016883 bellard
        break;
4710 5a5012ec ths
    case FOP(18, 17):
4711 5a5012ec ths
        GEN_LOAD_REG_TN(T0, ft);
4712 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4713 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT2, fd);
4714 5a5012ec ths
        gen_op_float_movz_d();
4715 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
4716 5a5012ec ths
        opn = "movz.d";
4717 5a5012ec ths
        break;
4718 5a5012ec ths
    case FOP(19, 17):
4719 5a5012ec ths
        GEN_LOAD_REG_TN(T0, ft);
4720 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4721 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT2, fd);
4722 5a5012ec ths
        gen_op_float_movn_d();
4723 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4724 5a5012ec ths
        opn = "movn.d";
4725 6ea83fed bellard
        break;
4726 57fa1fb3 ths
    case FOP(21, 17):
4727 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
4728 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4729 57fa1fb3 ths
        gen_op_float_recip_d();
4730 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
4731 57fa1fb3 ths
        opn = "recip.d";
4732 57fa1fb3 ths
        break;
4733 57fa1fb3 ths
    case FOP(22, 17):
4734 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
4735 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4736 57fa1fb3 ths
        gen_op_float_rsqrt_d();
4737 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
4738 57fa1fb3 ths
        opn = "rsqrt.d";
4739 57fa1fb3 ths
        break;
4740 57fa1fb3 ths
    case FOP(28, 17):
4741 5e755519 ths
        check_cp1_64bitmode(ctx);
4742 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4743 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT2, ft);
4744 57fa1fb3 ths
        gen_op_float_recip2_d();
4745 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
4746 57fa1fb3 ths
        opn = "recip2.d";
4747 57fa1fb3 ths
        break;
4748 57fa1fb3 ths
    case FOP(29, 17):
4749 5e755519 ths
        check_cp1_64bitmode(ctx);
4750 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4751 57fa1fb3 ths
        gen_op_float_recip1_d();
4752 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
4753 57fa1fb3 ths
        opn = "recip1.d";
4754 57fa1fb3 ths
        break;
4755 57fa1fb3 ths
    case FOP(30, 17):
4756 5e755519 ths
        check_cp1_64bitmode(ctx);
4757 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4758 57fa1fb3 ths
        gen_op_float_rsqrt1_d();
4759 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
4760 57fa1fb3 ths
        opn = "rsqrt1.d";
4761 57fa1fb3 ths
        break;
4762 57fa1fb3 ths
    case FOP(31, 17):
4763 5e755519 ths
        check_cp1_64bitmode(ctx);
4764 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4765 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT2, ft);
4766 57fa1fb3 ths
        gen_op_float_rsqrt2_d();
4767 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
4768 57fa1fb3 ths
        opn = "rsqrt2.d";
4769 57fa1fb3 ths
        break;
4770 6ea83fed bellard
    case FOP(48, 17):
4771 6ea83fed bellard
    case FOP(49, 17):
4772 6ea83fed bellard
    case FOP(50, 17):
4773 6ea83fed bellard
    case FOP(51, 17):
4774 6ea83fed bellard
    case FOP(52, 17):
4775 6ea83fed bellard
    case FOP(53, 17):
4776 6ea83fed bellard
    case FOP(54, 17):
4777 6ea83fed bellard
    case FOP(55, 17):
4778 6ea83fed bellard
    case FOP(56, 17):
4779 6ea83fed bellard
    case FOP(57, 17):
4780 6ea83fed bellard
    case FOP(58, 17):
4781 6ea83fed bellard
    case FOP(59, 17):
4782 6ea83fed bellard
    case FOP(60, 17):
4783 6ea83fed bellard
    case FOP(61, 17):
4784 6ea83fed bellard
    case FOP(62, 17):
4785 6ea83fed bellard
    case FOP(63, 17):
4786 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
4787 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
4788 5a1e8ffb ths
        if (ctx->opcode & (1 << 6)) {
4789 5e755519 ths
            check_cp1_64bitmode(ctx);
4790 5a1e8ffb ths
            gen_cmpabs_d(func-48, cc);
4791 5a1e8ffb ths
            opn = condnames_abs[func-48];
4792 5a1e8ffb ths
        } else {
4793 5e755519 ths
            check_cp1_registers(ctx, fs | ft);
4794 5a1e8ffb ths
            gen_cmp_d(func-48, cc);
4795 5a1e8ffb ths
            opn = condnames[func-48];
4796 5a1e8ffb ths
        }
4797 6ea83fed bellard
        break;
4798 5a5012ec ths
    case FOP(32, 17):
4799 5e755519 ths
        check_cp1_registers(ctx, fs);
4800 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4801 5a5012ec ths
        gen_op_float_cvts_d();
4802 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4803 5a5012ec ths
        opn = "cvt.s.d";
4804 5a5012ec ths
        break;
4805 5a5012ec ths
    case FOP(36, 17):
4806 5e755519 ths
        check_cp1_registers(ctx, fs);
4807 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4808 5a5012ec ths
        gen_op_float_cvtw_d();
4809 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4810 5a5012ec ths
        opn = "cvt.w.d";
4811 5a5012ec ths
        break;
4812 5a5012ec ths
    case FOP(37, 17):
4813 5e755519 ths
        check_cp1_64bitmode(ctx);
4814 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4815 5a5012ec ths
        gen_op_float_cvtl_d();
4816 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4817 5a5012ec ths
        opn = "cvt.l.d";
4818 5a5012ec ths
        break;
4819 5a5012ec ths
    case FOP(32, 20):
4820 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4821 5a5012ec ths
        gen_op_float_cvts_w();
4822 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4823 5a5012ec ths
        opn = "cvt.s.w";
4824 6ea83fed bellard
        break;
4825 5a5012ec ths
    case FOP(33, 20):
4826 5e755519 ths
        check_cp1_registers(ctx, fd);
4827 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4828 5a5012ec ths
        gen_op_float_cvtd_w();
4829 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4830 5a5012ec ths
        opn = "cvt.d.w";
4831 5a5012ec ths
        break;
4832 5a5012ec ths
    case FOP(32, 21):
4833 5e755519 ths
        check_cp1_64bitmode(ctx);
4834 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4835 5a5012ec ths
        gen_op_float_cvts_l();
4836 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4837 5a5012ec ths
        opn = "cvt.s.l";
4838 5a5012ec ths
        break;
4839 5a5012ec ths
    case FOP(33, 21):
4840 5e755519 ths
        check_cp1_64bitmode(ctx);
4841 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
4842 5a5012ec ths
        gen_op_float_cvtd_l();
4843 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
4844 5a5012ec ths
        opn = "cvt.d.l";
4845 5a5012ec ths
        break;
4846 5a5012ec ths
    case FOP(38, 20):
4847 5a5012ec ths
    case FOP(38, 21):
4848 5e755519 ths
        check_cp1_64bitmode(ctx);
4849 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4850 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4851 5a5012ec ths
        gen_op_float_cvtps_pw();
4852 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
4853 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4854 5a5012ec ths
        opn = "cvt.ps.pw";
4855 5a5012ec ths
        break;
4856 5a5012ec ths
    case FOP(0, 22):
4857 5e755519 ths
        check_cp1_64bitmode(ctx);
4858 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4859 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4860 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4861 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
4862 5a5012ec ths
        gen_op_float_add_ps();
4863 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4864 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4865 5a5012ec ths
        opn = "add.ps";
4866 6ea83fed bellard
        break;
4867 5a5012ec ths
    case FOP(1, 22):
4868 5e755519 ths
        check_cp1_64bitmode(ctx);
4869 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4870 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4871 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4872 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
4873 5a5012ec ths
        gen_op_float_sub_ps();
4874 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4875 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4876 5a5012ec ths
        opn = "sub.ps";
4877 6ea83fed bellard
        break;
4878 5a5012ec ths
    case FOP(2, 22):
4879 5e755519 ths
        check_cp1_64bitmode(ctx);
4880 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4881 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4882 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
4883 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
4884 5a5012ec ths
        gen_op_float_mul_ps();
4885 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4886 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4887 5a5012ec ths
        opn = "mul.ps";
4888 6ea83fed bellard
        break;
4889 5a5012ec ths
    case FOP(5, 22):
4890 5e755519 ths
        check_cp1_64bitmode(ctx);
4891 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4892 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4893 5a5012ec ths
        gen_op_float_abs_ps();
4894 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4895 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4896 5a5012ec ths
        opn = "abs.ps";
4897 6ea83fed bellard
        break;
4898 5a5012ec ths
    case FOP(6, 22):
4899 5e755519 ths
        check_cp1_64bitmode(ctx);
4900 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4901 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4902 5a5012ec ths
        gen_op_float_mov_ps();
4903 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4904 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4905 5a5012ec ths
        opn = "mov.ps";
4906 6ea83fed bellard
        break;
4907 5a5012ec ths
    case FOP(7, 22):
4908 5e755519 ths
        check_cp1_64bitmode(ctx);
4909 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4910 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4911 5a5012ec ths
        gen_op_float_chs_ps();
4912 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4913 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4914 5a5012ec ths
        opn = "neg.ps";
4915 6ea83fed bellard
        break;
4916 5a5012ec ths
    case FOP(17, 22):
4917 5e755519 ths
        check_cp1_64bitmode(ctx);
4918 5a5012ec ths
        GEN_LOAD_REG_TN(T0, ft);
4919 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4920 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4921 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
4922 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
4923 5a5012ec ths
        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
4924 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4925 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4926 5a5012ec ths
        opn = "movcf.ps";
4927 6ea83fed bellard
        break;
4928 5a5012ec ths
    case FOP(18, 22):
4929 5e755519 ths
        check_cp1_64bitmode(ctx);
4930 5a5012ec ths
        GEN_LOAD_REG_TN(T0, ft);
4931 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4932 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4933 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
4934 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
4935 5a5012ec ths
        gen_op_float_movz_ps();
4936 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4937 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4938 5a5012ec ths
        opn = "movz.ps";
4939 6ea83fed bellard
        break;
4940 5a5012ec ths
    case FOP(19, 22):
4941 5e755519 ths
        check_cp1_64bitmode(ctx);
4942 5a5012ec ths
        GEN_LOAD_REG_TN(T0, ft);
4943 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
4944 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4945 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
4946 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
4947 5a5012ec ths
        gen_op_float_movn_ps();
4948 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
4949 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4950 5a5012ec ths
        opn = "movn.ps";
4951 6ea83fed bellard
        break;
4952 fbcc6828 ths
    case FOP(24, 22):
4953 5e755519 ths
        check_cp1_64bitmode(ctx);
4954 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT0, ft);
4955 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH0, ft);
4956 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT1, fs);
4957 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH1, fs);
4958 fbcc6828 ths
        gen_op_float_addr_ps();
4959 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4960 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4961 fbcc6828 ths
        opn = "addr.ps";
4962 fbcc6828 ths
        break;
4963 57fa1fb3 ths
    case FOP(26, 22):
4964 5e755519 ths
        check_cp1_64bitmode(ctx);
4965 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT0, ft);
4966 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH0, ft);
4967 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT1, fs);
4968 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH1, fs);
4969 57fa1fb3 ths
        gen_op_float_mulr_ps();
4970 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4971 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4972 57fa1fb3 ths
        opn = "mulr.ps";
4973 57fa1fb3 ths
        break;
4974 57fa1fb3 ths
    case FOP(28, 22):
4975 5e755519 ths
        check_cp1_64bitmode(ctx);
4976 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4977 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4978 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT2, fd);
4979 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
4980 57fa1fb3 ths
        gen_op_float_recip2_ps();
4981 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4982 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4983 57fa1fb3 ths
        opn = "recip2.ps";
4984 57fa1fb3 ths
        break;
4985 57fa1fb3 ths
    case FOP(29, 22):
4986 5e755519 ths
        check_cp1_64bitmode(ctx);
4987 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4988 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4989 57fa1fb3 ths
        gen_op_float_recip1_ps();
4990 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
4991 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
4992 57fa1fb3 ths
        opn = "recip1.ps";
4993 57fa1fb3 ths
        break;
4994 57fa1fb3 ths
    case FOP(30, 22):
4995 5e755519 ths
        check_cp1_64bitmode(ctx);
4996 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
4997 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
4998 57fa1fb3 ths
        gen_op_float_rsqrt1_ps();
4999 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5000 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
5001 57fa1fb3 ths
        opn = "rsqrt1.ps";
5002 57fa1fb3 ths
        break;
5003 57fa1fb3 ths
    case FOP(31, 22):
5004 5e755519 ths
        check_cp1_64bitmode(ctx);
5005 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5006 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5007 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT2, fd);
5008 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
5009 57fa1fb3 ths
        gen_op_float_rsqrt2_ps();
5010 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5011 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
5012 57fa1fb3 ths
        opn = "rsqrt2.ps";
5013 57fa1fb3 ths
        break;
5014 5a5012ec ths
    case FOP(32, 22):
5015 5e755519 ths
        check_cp1_64bitmode(ctx);
5016 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5017 5a5012ec ths
        gen_op_float_cvts_pu();
5018 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5019 5a5012ec ths
        opn = "cvt.s.pu";
5020 dd016883 bellard
        break;
5021 5a5012ec ths
    case FOP(36, 22):
5022 5e755519 ths
        check_cp1_64bitmode(ctx);
5023 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
5024 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5025 5a5012ec ths
        gen_op_float_cvtpw_ps();
5026 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5027 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
5028 5a5012ec ths
        opn = "cvt.pw.ps";
5029 6ea83fed bellard
        break;
5030 5a5012ec ths
    case FOP(40, 22):
5031 5e755519 ths
        check_cp1_64bitmode(ctx);
5032 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
5033 5a5012ec ths
        gen_op_float_cvts_pl();
5034 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5035 5a5012ec ths
        opn = "cvt.s.pl";
5036 6ea83fed bellard
        break;
5037 5a5012ec ths
    case FOP(44, 22):
5038 5e755519 ths
        check_cp1_64bitmode(ctx);
5039 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5040 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5041 5a5012ec ths
        gen_op_float_pll_ps();
5042 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5043 5a5012ec ths
        opn = "pll.ps";
5044 6ea83fed bellard
        break;
5045 5a5012ec ths
    case FOP(45, 22):
5046 5e755519 ths
        check_cp1_64bitmode(ctx);
5047 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
5048 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
5049 5a5012ec ths
        gen_op_float_plu_ps();
5050 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5051 5a5012ec ths
        opn = "plu.ps";
5052 5a5012ec ths
        break;
5053 5a5012ec ths
    case FOP(46, 22):
5054 5e755519 ths
        check_cp1_64bitmode(ctx);
5055 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5056 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
5057 5a5012ec ths
        gen_op_float_pul_ps();
5058 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5059 5a5012ec ths
        opn = "pul.ps";
5060 5a5012ec ths
        break;
5061 5a5012ec ths
    case FOP(47, 22):
5062 5e755519 ths
        check_cp1_64bitmode(ctx);
5063 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5064 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
5065 5a5012ec ths
        gen_op_float_puu_ps();
5066 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5067 5a5012ec ths
        opn = "puu.ps";
5068 5a5012ec ths
        break;
5069 5a5012ec ths
    case FOP(48, 22):
5070 5a5012ec ths
    case FOP(49, 22):
5071 5a5012ec ths
    case FOP(50, 22):
5072 5a5012ec ths
    case FOP(51, 22):
5073 5a5012ec ths
    case FOP(52, 22):
5074 5a5012ec ths
    case FOP(53, 22):
5075 5a5012ec ths
    case FOP(54, 22):
5076 5a5012ec ths
    case FOP(55, 22):
5077 5a5012ec ths
    case FOP(56, 22):
5078 5a5012ec ths
    case FOP(57, 22):
5079 5a5012ec ths
    case FOP(58, 22):
5080 5a5012ec ths
    case FOP(59, 22):
5081 5a5012ec ths
    case FOP(60, 22):
5082 5a5012ec ths
    case FOP(61, 22):
5083 5a5012ec ths
    case FOP(62, 22):
5084 5a5012ec ths
    case FOP(63, 22):
5085 5e755519 ths
        check_cp1_64bitmode(ctx);
5086 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5087 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5088 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5089 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
5090 5a1e8ffb ths
        if (ctx->opcode & (1 << 6)) {
5091 5a1e8ffb ths
            gen_cmpabs_ps(func-48, cc);
5092 5a1e8ffb ths
            opn = condnames_abs[func-48];
5093 5a1e8ffb ths
        } else {
5094 5a1e8ffb ths
            gen_cmp_ps(func-48, cc);
5095 5a1e8ffb ths
            opn = condnames[func-48];
5096 5a1e8ffb ths
        }
5097 6ea83fed bellard
        break;
5098 5a5012ec ths
    default:
5099 923617a3 ths
        MIPS_INVAL(opn);
5100 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
5101 6ea83fed bellard
        return;
5102 6ea83fed bellard
    }
5103 5a1e8ffb ths
    switch (optype) {
5104 5a1e8ffb ths
    case BINOP:
5105 6ea83fed bellard
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5106 5a1e8ffb ths
        break;
5107 5a1e8ffb ths
    case CMPOP:
5108 5a1e8ffb ths
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5109 5a1e8ffb ths
        break;
5110 5a1e8ffb ths
    default:
5111 6ea83fed bellard
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5112 5a1e8ffb ths
        break;
5113 5a1e8ffb ths
    }
5114 6ea83fed bellard
}
5115 6af0bf9c bellard
5116 5a5012ec ths
/* Coprocessor 3 (FPU) */
5117 5e755519 ths
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5118 5e755519 ths
                           int fd, int fs, int base, int index)
5119 7a387fff ths
{
5120 923617a3 ths
    const char *opn = "extended float load/store";
5121 93b12ccc ths
    int store = 0;
5122 7a387fff ths
5123 57fa1fb3 ths
    /* All of those work only on 64bit FPUs. */
5124 5e755519 ths
    check_cp1_64bitmode(ctx);
5125 93b12ccc ths
    if (base == 0) {
5126 93b12ccc ths
        if (index == 0)
5127 93b12ccc ths
            gen_op_reset_T0();
5128 93b12ccc ths
        else
5129 93b12ccc ths
            GEN_LOAD_REG_TN(T0, index);
5130 93b12ccc ths
    } else if (index == 0) {
5131 93b12ccc ths
        GEN_LOAD_REG_TN(T0, base);
5132 93b12ccc ths
    } else {
5133 93b12ccc ths
        GEN_LOAD_REG_TN(T0, base);
5134 93b12ccc ths
        GEN_LOAD_REG_TN(T1, index);
5135 93b12ccc ths
        gen_op_addr_add();
5136 93b12ccc ths
    }
5137 5a5012ec ths
    /* Don't do NOP if destination is zero: we must perform the actual
5138 5a5012ec ths
     * memory access
5139 5a5012ec ths
     */
5140 5a5012ec ths
    switch (opc) {
5141 5a5012ec ths
    case OPC_LWXC1:
5142 93b12ccc ths
        op_ldst(lwc1);
5143 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT0);
5144 5a5012ec ths
        opn = "lwxc1";
5145 5a5012ec ths
        break;
5146 5a5012ec ths
    case OPC_LDXC1:
5147 93b12ccc ths
        op_ldst(ldc1);
5148 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT0);
5149 5a5012ec ths
        opn = "ldxc1";
5150 5a5012ec ths
        break;
5151 5a5012ec ths
    case OPC_LUXC1:
5152 5a5012ec ths
        op_ldst(luxc1);
5153 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT0);
5154 5a5012ec ths
        opn = "luxc1";
5155 5a5012ec ths
        break;
5156 5a5012ec ths
    case OPC_SWXC1:
5157 93b12ccc ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5158 93b12ccc ths
        op_ldst(swc1);
5159 5a5012ec ths
        opn = "swxc1";
5160 93b12ccc ths
        store = 1;
5161 5a5012ec ths
        break;
5162 5a5012ec ths
    case OPC_SDXC1:
5163 93b12ccc ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5164 93b12ccc ths
        op_ldst(sdc1);
5165 5a5012ec ths
        opn = "sdxc1";
5166 93b12ccc ths
        store = 1;
5167 5a5012ec ths
        break;
5168 5a5012ec ths
    case OPC_SUXC1:
5169 93b12ccc ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5170 5a5012ec ths
        op_ldst(suxc1);
5171 5a5012ec ths
        opn = "suxc1";
5172 93b12ccc ths
        store = 1;
5173 5a5012ec ths
        break;
5174 5a5012ec ths
    default:
5175 923617a3 ths
        MIPS_INVAL(opn);
5176 5a5012ec ths
        generate_exception(ctx, EXCP_RI);
5177 5a5012ec ths
        return;
5178 5a5012ec ths
    }
5179 93b12ccc ths
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5180 93b12ccc ths
               regnames[index], regnames[base]);
5181 5a5012ec ths
}
5182 5a5012ec ths
5183 5e755519 ths
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5184 5e755519 ths
                            int fd, int fr, int fs, int ft)
5185 5a5012ec ths
{
5186 923617a3 ths
    const char *opn = "flt3_arith";
5187 5a5012ec ths
5188 5a5012ec ths
    /* All of those work only on 64bit FPUs. */
5189 5e755519 ths
    check_cp1_64bitmode(ctx);
5190 5a5012ec ths
    switch (opc) {
5191 5a5012ec ths
    case OPC_ALNV_PS:
5192 5a5012ec ths
        GEN_LOAD_REG_TN(T0, fr);
5193 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5194 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT1, ft);
5195 5a5012ec ths
        gen_op_float_alnv_ps();
5196 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5197 5a5012ec ths
        opn = "alnv.ps";
5198 5a5012ec ths
        break;
5199 5a5012ec ths
    case OPC_MADD_S:
5200 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5201 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5202 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fr);
5203 5a5012ec ths
        gen_op_float_muladd_s();
5204 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5205 5a5012ec ths
        opn = "madd.s";
5206 5a5012ec ths
        break;
5207 5a5012ec ths
    case OPC_MADD_D:
5208 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5209 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
5210 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
5211 fbcc6828 ths
        gen_op_float_muladd_d();
5212 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
5213 5a5012ec ths
        opn = "madd.d";
5214 5a5012ec ths
        break;
5215 5a5012ec ths
    case OPC_MADD_PS:
5216 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5217 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5218 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5219 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
5220 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
5221 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
5222 fbcc6828 ths
        gen_op_float_muladd_ps();
5223 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5224 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
5225 5a5012ec ths
        opn = "madd.ps";
5226 5a5012ec ths
        break;
5227 5a5012ec ths
    case OPC_MSUB_S:
5228 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5229 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5230 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
5231 fbcc6828 ths
        gen_op_float_mulsub_s();
5232 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5233 5a5012ec ths
        opn = "msub.s";
5234 5a5012ec ths
        break;
5235 5a5012ec ths
    case OPC_MSUB_D:
5236 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5237 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
5238 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
5239 fbcc6828 ths
        gen_op_float_mulsub_d();
5240 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
5241 5a5012ec ths
        opn = "msub.d";
5242 5a5012ec ths
        break;
5243 5a5012ec ths
    case OPC_MSUB_PS:
5244 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5245 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5246 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5247 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
5248 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
5249 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
5250 fbcc6828 ths
        gen_op_float_mulsub_ps();
5251 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5252 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
5253 5a5012ec ths
        opn = "msub.ps";
5254 5a5012ec ths
        break;
5255 5a5012ec ths
    case OPC_NMADD_S:
5256 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5257 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5258 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
5259 fbcc6828 ths
        gen_op_float_nmuladd_s();
5260 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5261 5a5012ec ths
        opn = "nmadd.s";
5262 5a5012ec ths
        break;
5263 5a5012ec ths
    case OPC_NMADD_D:
5264 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5265 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
5266 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
5267 fbcc6828 ths
        gen_op_float_nmuladd_d();
5268 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
5269 5a5012ec ths
        opn = "nmadd.d";
5270 5a5012ec ths
        break;
5271 5a5012ec ths
    case OPC_NMADD_PS:
5272 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5273 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5274 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5275 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
5276 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
5277 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
5278 fbcc6828 ths
        gen_op_float_nmuladd_ps();
5279 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5280 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
5281 5a5012ec ths
        opn = "nmadd.ps";
5282 5a5012ec ths
        break;
5283 5a5012ec ths
    case OPC_NMSUB_S:
5284 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5285 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5286 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
5287 fbcc6828 ths
        gen_op_float_nmulsub_s();
5288 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5289 5a5012ec ths
        opn = "nmsub.s";
5290 5a5012ec ths
        break;
5291 5a5012ec ths
    case OPC_NMSUB_D:
5292 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5293 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
5294 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
5295 fbcc6828 ths
        gen_op_float_nmulsub_d();
5296 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
5297 5a5012ec ths
        opn = "nmsub.d";
5298 5a5012ec ths
        break;
5299 5a5012ec ths
    case OPC_NMSUB_PS:
5300 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5301 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5302 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5303 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
5304 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
5305 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
5306 fbcc6828 ths
        gen_op_float_nmulsub_ps();
5307 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5308 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
5309 5a5012ec ths
        opn = "nmsub.ps";
5310 5a5012ec ths
        break;
5311 923617a3 ths
    default:
5312 923617a3 ths
        MIPS_INVAL(opn);
5313 5a5012ec ths
        generate_exception (ctx, EXCP_RI);
5314 5a5012ec ths
        return;
5315 5a5012ec ths
    }
5316 5a5012ec ths
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5317 5a5012ec ths
               fregnames[fs], fregnames[ft]);
5318 7a387fff ths
}
5319 7a387fff ths
5320 7a387fff ths
/* ISA extensions (ASEs) */
5321 6af0bf9c bellard
/* MIPS16 extension to MIPS32 */
5322 6af0bf9c bellard
/* SmartMIPS extension to MIPS32 */
5323 6af0bf9c bellard
5324 60aa19ab ths
#ifdef TARGET_MIPS64
5325 6af0bf9c bellard
5326 6af0bf9c bellard
/* MDMX extension to MIPS64 */
5327 6af0bf9c bellard
/* MIPS-3D extension to MIPS64 */
5328 6af0bf9c bellard
5329 6af0bf9c bellard
#endif
5330 6af0bf9c bellard
5331 36d23958 ths
static void decode_opc (CPUState *env, DisasContext *ctx)
5332 6af0bf9c bellard
{
5333 6af0bf9c bellard
    int32_t offset;
5334 6af0bf9c bellard
    int rs, rt, rd, sa;
5335 7a387fff ths
    uint32_t op, op1, op2;
5336 6af0bf9c bellard
    int16_t imm;
5337 6af0bf9c bellard
5338 d796321b bellard
    /* make sure instructions are on a word boundary */
5339 d796321b bellard
    if (ctx->pc & 0x3) {
5340 cbeb0857 ths
        env->CP0_BadVAddr = ctx->pc;
5341 d796321b bellard
        generate_exception(ctx, EXCP_AdEL);
5342 d796321b bellard
        return;
5343 d796321b bellard
    }
5344 d796321b bellard
5345 4ad40f36 bellard
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5346 5a5012ec ths
        int l1;
5347 6af0bf9c bellard
        /* Handle blikely not taken case */
5348 3594c774 ths
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5349 5a5012ec ths
        l1 = gen_new_label();
5350 5a5012ec ths
        gen_op_jnz_T2(l1);
5351 5a5012ec ths
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5352 5a5012ec ths
        gen_goto_tb(ctx, 1, ctx->pc + 4);
5353 5a5012ec ths
        gen_set_label(l1);
5354 6af0bf9c bellard
    }
5355 7a387fff ths
    op = MASK_OP_MAJOR(ctx->opcode);
5356 7a387fff ths
    rs = (ctx->opcode >> 21) & 0x1f;
5357 7a387fff ths
    rt = (ctx->opcode >> 16) & 0x1f;
5358 7a387fff ths
    rd = (ctx->opcode >> 11) & 0x1f;
5359 7a387fff ths
    sa = (ctx->opcode >> 6) & 0x1f;
5360 6af0bf9c bellard
    imm = (int16_t)ctx->opcode;
5361 6af0bf9c bellard
    switch (op) {
5362 7a387fff ths
    case OPC_SPECIAL:
5363 7a387fff ths
        op1 = MASK_SPECIAL(ctx->opcode);
5364 6af0bf9c bellard
        switch (op1) {
5365 7a387fff ths
        case OPC_SLL:          /* Arithmetic with immediate */
5366 7a387fff ths
        case OPC_SRL ... OPC_SRA:
5367 7a387fff ths
            gen_arith_imm(ctx, op1, rd, rt, sa);
5368 7a387fff ths
            break;
5369 7a387fff ths
        case OPC_SLLV:         /* Arithmetic */
5370 7a387fff ths
        case OPC_SRLV ... OPC_SRAV:
5371 7a387fff ths
        case OPC_MOVZ ... OPC_MOVN:
5372 7a387fff ths
        case OPC_ADD ... OPC_NOR:
5373 7a387fff ths
        case OPC_SLT ... OPC_SLTU:
5374 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
5375 7a387fff ths
            break;
5376 7a387fff ths
        case OPC_MULT ... OPC_DIVU:
5377 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
5378 7a387fff ths
            break;
5379 7a387fff ths
        case OPC_JR ... OPC_JALR:
5380 7a387fff ths
            gen_compute_branch(ctx, op1, rs, rd, sa);
5381 6af0bf9c bellard
            return;
5382 7a387fff ths
        case OPC_TGE ... OPC_TEQ: /* Traps */
5383 7a387fff ths
        case OPC_TNE:
5384 7a387fff ths
            gen_trap(ctx, op1, rs, rt, -1);
5385 6af0bf9c bellard
            break;
5386 7a387fff ths
        case OPC_MFHI:          /* Move from HI/LO */
5387 7a387fff ths
        case OPC_MFLO:
5388 7a387fff ths
            gen_HILO(ctx, op1, rd);
5389 6af0bf9c bellard
            break;
5390 7a387fff ths
        case OPC_MTHI:
5391 7a387fff ths
        case OPC_MTLO:          /* Move to HI/LO */
5392 7a387fff ths
            gen_HILO(ctx, op1, rs);
5393 6af0bf9c bellard
            break;
5394 b48cfdff ths
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5395 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
5396 b48cfdff ths
            MIPS_INVAL("PMON / selsl");
5397 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
5398 b48cfdff ths
#else
5399 7a387fff ths
            gen_op_pmon(sa);
5400 b48cfdff ths
#endif
5401 7a387fff ths
            break;
5402 7a387fff ths
        case OPC_SYSCALL:
5403 6af0bf9c bellard
            generate_exception(ctx, EXCP_SYSCALL);
5404 6af0bf9c bellard
            break;
5405 7a387fff ths
        case OPC_BREAK:
5406 df1561e2 ths
            /* XXX: Hack to work around wrong handling of self-modifying code. */
5407 df1561e2 ths
            ctx->pc += 4;
5408 df1561e2 ths
            save_cpu_state(ctx, 1);
5409 df1561e2 ths
            ctx->pc -= 4;
5410 6af0bf9c bellard
            generate_exception(ctx, EXCP_BREAK);
5411 6af0bf9c bellard
            break;
5412 b48cfdff ths
        case OPC_SPIM:
5413 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
5414 b48cfdff ths
            MIPS_INVAL("SPIM");
5415 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
5416 b48cfdff ths
#else
5417 7a387fff ths
           /* Implemented as RI exception for now. */
5418 7a387fff ths
            MIPS_INVAL("spim (unofficial)");
5419 7a387fff ths
            generate_exception(ctx, EXCP_RI);
5420 b48cfdff ths
#endif
5421 6af0bf9c bellard
            break;
5422 7a387fff ths
        case OPC_SYNC:
5423 7a387fff ths
            /* Treat as a noop. */
5424 6af0bf9c bellard
            break;
5425 4ad40f36 bellard
5426 7a387fff ths
        case OPC_MOVCI:
5427 36d23958 ths
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5428 e397ee33 ths
                save_cpu_state(ctx, 1);
5429 5e755519 ths
                check_cp1_enabled(ctx);
5430 36d23958 ths
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5431 36d23958 ths
                          (ctx->opcode >> 16) & 1);
5432 36d23958 ths
            } else {
5433 e397ee33 ths
                generate_exception_err(ctx, EXCP_CpU, 1);
5434 36d23958 ths
            }
5435 4ad40f36 bellard
            break;
5436 4ad40f36 bellard
5437 60aa19ab ths
#ifdef TARGET_MIPS64
5438 7a387fff ths
       /* MIPS64 specific opcodes */
5439 7a387fff ths
        case OPC_DSLL:
5440 7a387fff ths
        case OPC_DSRL ... OPC_DSRA:
5441 7a387fff ths
        case OPC_DSLL32:
5442 7a387fff ths
        case OPC_DSRL32 ... OPC_DSRA32:
5443 6e473128 ths
            if (!(ctx->hflags & MIPS_HFLAG_64))
5444 6e473128 ths
                generate_exception(ctx, EXCP_RI);
5445 7a387fff ths
            gen_arith_imm(ctx, op1, rd, rt, sa);
5446 7a387fff ths
            break;
5447 7a387fff ths
        case OPC_DSLLV:
5448 7a387fff ths
        case OPC_DSRLV ... OPC_DSRAV:
5449 7a387fff ths
        case OPC_DADD ... OPC_DSUBU:
5450 6e473128 ths
            if (!(ctx->hflags & MIPS_HFLAG_64))
5451 6e473128 ths
                generate_exception(ctx, EXCP_RI);
5452 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
5453 7a387fff ths
            break;
5454 7a387fff ths
        case OPC_DMULT ... OPC_DDIVU:
5455 6e473128 ths
            if (!(ctx->hflags & MIPS_HFLAG_64))
5456 6e473128 ths
                generate_exception(ctx, EXCP_RI);
5457 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
5458 7a387fff ths
            break;
5459 6af0bf9c bellard
#endif
5460 6af0bf9c bellard
        default:            /* Invalid */
5461 6af0bf9c bellard
            MIPS_INVAL("special");
5462 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
5463 6af0bf9c bellard
            break;
5464 6af0bf9c bellard
        }
5465 6af0bf9c bellard
        break;
5466 7a387fff ths
    case OPC_SPECIAL2:
5467 7a387fff ths
        op1 = MASK_SPECIAL2(ctx->opcode);
5468 6af0bf9c bellard
        switch (op1) {
5469 7a387fff ths
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
5470 7a387fff ths
        case OPC_MSUB ... OPC_MSUBU:
5471 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
5472 6af0bf9c bellard
            break;
5473 7a387fff ths
        case OPC_MUL:
5474 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
5475 6af0bf9c bellard
            break;
5476 7a387fff ths
        case OPC_CLZ ... OPC_CLO:
5477 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
5478 6af0bf9c bellard
            break;
5479 7a387fff ths
        case OPC_SDBBP:
5480 6af0bf9c bellard
            /* XXX: not clear which exception should be raised
5481 6af0bf9c bellard
             *      when in debug mode...
5482 6af0bf9c bellard
             */
5483 6af0bf9c bellard
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5484 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
5485 6af0bf9c bellard
            } else {
5486 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
5487 6af0bf9c bellard
            }
5488 6af0bf9c bellard
            /* Treat as a noop */
5489 6af0bf9c bellard
            break;
5490 60aa19ab ths
#ifdef TARGET_MIPS64
5491 7a387fff ths
        case OPC_DCLZ ... OPC_DCLO:
5492 6e473128 ths
            if (!(ctx->hflags & MIPS_HFLAG_64))
5493 6e473128 ths
                generate_exception(ctx, EXCP_RI);
5494 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
5495 7a387fff ths
            break;
5496 7a387fff ths
#endif
5497 6af0bf9c bellard
        default:            /* Invalid */
5498 6af0bf9c bellard
            MIPS_INVAL("special2");
5499 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
5500 6af0bf9c bellard
            break;
5501 6af0bf9c bellard
        }
5502 6af0bf9c bellard
        break;
5503 7a387fff ths
    case OPC_SPECIAL3:
5504 1579a72e ths
         op1 = MASK_SPECIAL3(ctx->opcode);
5505 1579a72e ths
         switch (op1) {
5506 1579a72e ths
         case OPC_EXT:
5507 1579a72e ths
         case OPC_INS:
5508 1579a72e ths
             gen_bitops(ctx, op1, rt, rs, sa, rd);
5509 1579a72e ths
             break;
5510 1579a72e ths
         case OPC_BSHFL:
5511 1579a72e ths
             op2 = MASK_BSHFL(ctx->opcode);
5512 1579a72e ths
             switch (op2) {
5513 1579a72e ths
             case OPC_WSBH:
5514 1579a72e ths
                 GEN_LOAD_REG_TN(T1, rt);
5515 1579a72e ths
                 gen_op_wsbh();
5516 1579a72e ths
                 break;
5517 1579a72e ths
             case OPC_SEB:
5518 1579a72e ths
                 GEN_LOAD_REG_TN(T1, rt);
5519 1579a72e ths
                 gen_op_seb();
5520 1579a72e ths
                 break;
5521 1579a72e ths
             case OPC_SEH:
5522 1579a72e ths
                 GEN_LOAD_REG_TN(T1, rt);
5523 1579a72e ths
                 gen_op_seh();
5524 1579a72e ths
                 break;
5525 1579a72e ths
             default:            /* Invalid */
5526 1579a72e ths
                 MIPS_INVAL("bshfl");
5527 1579a72e ths
                 generate_exception(ctx, EXCP_RI);
5528 1579a72e ths
                 break;
5529 1579a72e ths
            }
5530 1579a72e ths
            GEN_STORE_TN_REG(rd, T0);
5531 7a387fff ths
            break;
5532 1579a72e ths
        case OPC_RDHWR:
5533 1579a72e ths
            switch (rd) {
5534 1579a72e ths
            case 0:
5535 97428a4d ths
                save_cpu_state(ctx, 1);
5536 1579a72e ths
                gen_op_rdhwr_cpunum();
5537 7a387fff ths
                break;
5538 1579a72e ths
            case 1:
5539 97428a4d ths
                save_cpu_state(ctx, 1);
5540 1579a72e ths
                gen_op_rdhwr_synci_step();
5541 7a387fff ths
                break;
5542 1579a72e ths
            case 2:
5543 97428a4d ths
                save_cpu_state(ctx, 1);
5544 1579a72e ths
                gen_op_rdhwr_cc();
5545 7a387fff ths
                break;
5546 1579a72e ths
            case 3:
5547 97428a4d ths
                save_cpu_state(ctx, 1);
5548 1579a72e ths
                gen_op_rdhwr_ccres();
5549 7a387fff ths
                break;
5550 1579a72e ths
            case 29:
5551 6f5b89a0 ths
#if defined (CONFIG_USER_ONLY)
5552 1579a72e ths
                gen_op_tls_value ();
5553 1579a72e ths
                break;
5554 97428a4d ths
#endif
5555 1579a72e ths
            default:            /* Invalid */
5556 1579a72e ths
                MIPS_INVAL("rdhwr");
5557 1579a72e ths
                generate_exception(ctx, EXCP_RI);
5558 1579a72e ths
                break;
5559 1579a72e ths
            }
5560 1579a72e ths
            GEN_STORE_TN_REG(rt, T0);
5561 1579a72e ths
            break;
5562 60aa19ab ths
#ifdef TARGET_MIPS64
5563 1579a72e ths
        case OPC_DEXTM ... OPC_DEXT:
5564 1579a72e ths
        case OPC_DINSM ... OPC_DINS:
5565 6e473128 ths
            if (!(ctx->hflags & MIPS_HFLAG_64))
5566 6e473128 ths
                generate_exception(ctx, EXCP_RI);
5567 1579a72e ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
5568 7a387fff ths
            break;
5569 1579a72e ths
        case OPC_DBSHFL:
5570 6e473128 ths
            if (!(ctx->hflags & MIPS_HFLAG_64))
5571 6e473128 ths
                generate_exception(ctx, EXCP_RI);
5572 1579a72e ths
            op2 = MASK_DBSHFL(ctx->opcode);
5573 1579a72e ths
            switch (op2) {
5574 1579a72e ths
            case OPC_DSBH:
5575 1579a72e ths
                GEN_LOAD_REG_TN(T1, rt);
5576 1579a72e ths
                gen_op_dsbh();
5577 1579a72e ths
                break;
5578 1579a72e ths
            case OPC_DSHD:
5579 1579a72e ths
                GEN_LOAD_REG_TN(T1, rt);
5580 1579a72e ths
                gen_op_dshd();
5581 1579a72e ths
                break;
5582 7a387fff ths
            default:            /* Invalid */
5583 7a387fff ths
                MIPS_INVAL("dbshfl");
5584 7a387fff ths
                generate_exception(ctx, EXCP_RI);
5585 7a387fff ths
                break;
5586 1579a72e ths
            }
5587 1579a72e ths
            GEN_STORE_TN_REG(rd, T0);
5588 7a387fff ths
#endif
5589 7a387fff ths
        default:            /* Invalid */
5590 7a387fff ths
            MIPS_INVAL("special3");
5591 7a387fff ths
            generate_exception(ctx, EXCP_RI);
5592 7a387fff ths
            break;
5593 7a387fff ths
        }
5594 7a387fff ths
        break;
5595 7a387fff ths
    case OPC_REGIMM:
5596 7a387fff ths
        op1 = MASK_REGIMM(ctx->opcode);
5597 7a387fff ths
        switch (op1) {
5598 7a387fff ths
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
5599 7a387fff ths
        case OPC_BLTZAL ... OPC_BGEZALL:
5600 7a387fff ths
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
5601 6af0bf9c bellard
            return;
5602 7a387fff ths
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
5603 7a387fff ths
        case OPC_TNEI:
5604 7a387fff ths
            gen_trap(ctx, op1, rs, -1, imm);
5605 7a387fff ths
            break;
5606 7a387fff ths
        case OPC_SYNCI:
5607 24c7b0e3 ths
            /* treat as noop */
5608 6af0bf9c bellard
            break;
5609 6af0bf9c bellard
        default:            /* Invalid */
5610 923617a3 ths
            MIPS_INVAL("regimm");
5611 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
5612 6af0bf9c bellard
            break;
5613 6af0bf9c bellard
        }
5614 6af0bf9c bellard
        break;
5615 7a387fff ths
    case OPC_CP0:
5616 f41c52f1 ths
        save_cpu_state(ctx, 1);
5617 24c7b0e3 ths
        gen_op_cp0_enabled();
5618 7a387fff ths
        op1 = MASK_CP0(ctx->opcode);
5619 6af0bf9c bellard
        switch (op1) {
5620 7a387fff ths
        case OPC_MFC0:
5621 7a387fff ths
        case OPC_MTC0:
5622 60aa19ab ths
#ifdef TARGET_MIPS64
5623 7a387fff ths
        case OPC_DMFC0:
5624 7a387fff ths
        case OPC_DMTC0:
5625 7a387fff ths
#endif
5626 29929e34 ths
            gen_cp0(env, ctx, op1, rt, rd);
5627 7a387fff ths
            break;
5628 7a387fff ths
        case OPC_C0_FIRST ... OPC_C0_LAST:
5629 29929e34 ths
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
5630 7a387fff ths
            break;
5631 7a387fff ths
        case OPC_MFMC0:
5632 7a387fff ths
            op2 = MASK_MFMC0(ctx->opcode);
5633 7a387fff ths
            switch (op2) {
5634 7a387fff ths
            case OPC_DI:
5635 7a387fff ths
                gen_op_di();
5636 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
5637 7a387fff ths
                ctx->bstate = BS_STOP;
5638 7a387fff ths
                break;
5639 7a387fff ths
            case OPC_EI:
5640 7a387fff ths
                gen_op_ei();
5641 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
5642 7a387fff ths
                ctx->bstate = BS_STOP;
5643 7a387fff ths
                break;
5644 7a387fff ths
            default:            /* Invalid */
5645 923617a3 ths
                MIPS_INVAL("mfmc0");
5646 7a387fff ths
                generate_exception(ctx, EXCP_RI);
5647 7a387fff ths
                break;
5648 7a387fff ths
            }
5649 7a387fff ths
            GEN_STORE_TN_REG(rt, T0);
5650 6af0bf9c bellard
            break;
5651 7a387fff ths
        case OPC_RDPGPR:
5652 7a387fff ths
        case OPC_WRPGPR:
5653 38121543 ths
            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
5654 38121543 ths
                /* Shadow registers not implemented. */
5655 38121543 ths
                GEN_LOAD_REG_TN(T0, rt);
5656 38121543 ths
                GEN_STORE_TN_REG(rd, T0);
5657 923617a3 ths
            } else {
5658 923617a3 ths
                MIPS_INVAL("shadow register move");
5659 38121543 ths
                generate_exception(ctx, EXCP_RI);
5660 923617a3 ths
            }
5661 38121543 ths
            break;
5662 6af0bf9c bellard
        default:
5663 923617a3 ths
            MIPS_INVAL("cp0");
5664 7a387fff ths
            generate_exception(ctx, EXCP_RI);
5665 6af0bf9c bellard
            break;
5666 6af0bf9c bellard
        }
5667 6af0bf9c bellard
        break;
5668 7a387fff ths
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
5669 7a387fff ths
         gen_arith_imm(ctx, op, rt, rs, imm);
5670 7a387fff ths
         break;
5671 7a387fff ths
    case OPC_J ... OPC_JAL: /* Jump */
5672 7a387fff ths
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
5673 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, offset);
5674 7a387fff ths
         return;
5675 7a387fff ths
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
5676 7a387fff ths
    case OPC_BEQL ... OPC_BGTZL:
5677 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
5678 7a387fff ths
         return;
5679 7a387fff ths
    case OPC_LB ... OPC_LWR: /* Load and stores */
5680 7a387fff ths
    case OPC_SB ... OPC_SW:
5681 7a387fff ths
    case OPC_SWR:
5682 7a387fff ths
    case OPC_LL:
5683 7a387fff ths
    case OPC_SC:
5684 7a387fff ths
         gen_ldst(ctx, op, rt, rs, imm);
5685 7a387fff ths
         break;
5686 7a387fff ths
    case OPC_CACHE:
5687 df1561e2 ths
        /* Treat as a noop */
5688 34ae7b51 ths
        break;
5689 7a387fff ths
    case OPC_PREF:
5690 6af0bf9c bellard
        /* Treat as a noop */
5691 6af0bf9c bellard
        break;
5692 4ad40f36 bellard
5693 923617a3 ths
    /* Floating point (COP1). */
5694 7a387fff ths
    case OPC_LWC1:
5695 7a387fff ths
    case OPC_LDC1:
5696 7a387fff ths
    case OPC_SWC1:
5697 7a387fff ths
    case OPC_SDC1:
5698 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5699 36d23958 ths
            save_cpu_state(ctx, 1);
5700 5e755519 ths
            check_cp1_enabled(ctx);
5701 36d23958 ths
            gen_flt_ldst(ctx, op, rt, rs, imm);
5702 36d23958 ths
        } else {
5703 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
5704 36d23958 ths
        }
5705 6ea83fed bellard
        break;
5706 6ea83fed bellard
5707 7a387fff ths
    case OPC_CP1:
5708 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5709 36d23958 ths
            save_cpu_state(ctx, 1);
5710 5e755519 ths
            check_cp1_enabled(ctx);
5711 36d23958 ths
            op1 = MASK_CP1(ctx->opcode);
5712 36d23958 ths
            switch (op1) {
5713 36d23958 ths
            case OPC_MFC1:
5714 36d23958 ths
            case OPC_CFC1:
5715 36d23958 ths
            case OPC_MTC1:
5716 36d23958 ths
            case OPC_CTC1:
5717 60aa19ab ths
#ifdef TARGET_MIPS64
5718 36d23958 ths
            case OPC_DMFC1:
5719 36d23958 ths
            case OPC_DMTC1:
5720 9c2149c8 ths
#endif
5721 5a5012ec ths
            case OPC_MFHC1:
5722 5a5012ec ths
            case OPC_MTHC1:
5723 36d23958 ths
                gen_cp1(ctx, op1, rt, rd);
5724 36d23958 ths
                break;
5725 36d23958 ths
            case OPC_BC1:
5726 fbcc6828 ths
            case OPC_BC1ANY2:
5727 fbcc6828 ths
            case OPC_BC1ANY4:
5728 5a5012ec ths
                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5729 5a5012ec ths
                                    (rt >> 2) & 0x7, imm << 2);
5730 36d23958 ths
                return;
5731 36d23958 ths
            case OPC_S_FMT:
5732 36d23958 ths
            case OPC_D_FMT:
5733 36d23958 ths
            case OPC_W_FMT:
5734 36d23958 ths
            case OPC_L_FMT:
5735 5a5012ec ths
            case OPC_PS_FMT:
5736 5a5012ec ths
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
5737 5a5012ec ths
                           (imm >> 8) & 0x7);
5738 36d23958 ths
                break;
5739 36d23958 ths
            default:
5740 923617a3 ths
                MIPS_INVAL("cp1");
5741 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
5742 36d23958 ths
                break;
5743 36d23958 ths
            }
5744 36d23958 ths
        } else {
5745 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
5746 6ea83fed bellard
        }
5747 4ad40f36 bellard
        break;
5748 4ad40f36 bellard
5749 4ad40f36 bellard
    /* COP2.  */
5750 7a387fff ths
    case OPC_LWC2:
5751 7a387fff ths
    case OPC_LDC2:
5752 7a387fff ths
    case OPC_SWC2:
5753 7a387fff ths
    case OPC_SDC2:
5754 7a387fff ths
    case OPC_CP2:
5755 7a387fff ths
        /* COP2: Not implemented. */
5756 4ad40f36 bellard
        generate_exception_err(ctx, EXCP_CpU, 2);
5757 4ad40f36 bellard
        break;
5758 4ad40f36 bellard
5759 7a387fff ths
    case OPC_CP3:
5760 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5761 e397ee33 ths
            save_cpu_state(ctx, 1);
5762 5e755519 ths
            check_cp1_enabled(ctx);
5763 36d23958 ths
            op1 = MASK_CP3(ctx->opcode);
5764 36d23958 ths
            switch (op1) {
5765 5a5012ec ths
            case OPC_LWXC1:
5766 5a5012ec ths
            case OPC_LDXC1:
5767 5a5012ec ths
            case OPC_LUXC1:
5768 5a5012ec ths
            case OPC_SWXC1:
5769 5a5012ec ths
            case OPC_SDXC1:
5770 5a5012ec ths
            case OPC_SUXC1:
5771 93b12ccc ths
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5772 5a5012ec ths
                break;
5773 e0c84da7 ths
            case OPC_PREFX:
5774 e0c84da7 ths
                /* treat as noop */
5775 e0c84da7 ths
                break;
5776 5a5012ec ths
            case OPC_ALNV_PS:
5777 5a5012ec ths
            case OPC_MADD_S:
5778 5a5012ec ths
            case OPC_MADD_D:
5779 5a5012ec ths
            case OPC_MADD_PS:
5780 5a5012ec ths
            case OPC_MSUB_S:
5781 5a5012ec ths
            case OPC_MSUB_D:
5782 5a5012ec ths
            case OPC_MSUB_PS:
5783 5a5012ec ths
            case OPC_NMADD_S:
5784 5a5012ec ths
            case OPC_NMADD_D:
5785 5a5012ec ths
            case OPC_NMADD_PS:
5786 5a5012ec ths
            case OPC_NMSUB_S:
5787 5a5012ec ths
            case OPC_NMSUB_D:
5788 5a5012ec ths
            case OPC_NMSUB_PS:
5789 5a5012ec ths
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
5790 5a5012ec ths
                break;
5791 36d23958 ths
            default:
5792 923617a3 ths
                MIPS_INVAL("cp3");
5793 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
5794 36d23958 ths
                break;
5795 36d23958 ths
            }
5796 36d23958 ths
        } else {
5797 e397ee33 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
5798 7a387fff ths
        }
5799 4ad40f36 bellard
        break;
5800 4ad40f36 bellard
5801 60aa19ab ths
#ifdef TARGET_MIPS64
5802 7a387fff ths
    /* MIPS64 opcodes */
5803 7a387fff ths
    case OPC_LWU:
5804 7a387fff ths
    case OPC_LDL ... OPC_LDR:
5805 7a387fff ths
    case OPC_SDL ... OPC_SDR:
5806 7a387fff ths
    case OPC_LLD:
5807 7a387fff ths
    case OPC_LD:
5808 7a387fff ths
    case OPC_SCD:
5809 7a387fff ths
    case OPC_SD:
5810 6e473128 ths
        if (!(ctx->hflags & MIPS_HFLAG_64))
5811 6e473128 ths
            generate_exception(ctx, EXCP_RI);
5812 7a387fff ths
        gen_ldst(ctx, op, rt, rs, imm);
5813 7a387fff ths
        break;
5814 7a387fff ths
    case OPC_DADDI ... OPC_DADDIU:
5815 6e473128 ths
        if (!(ctx->hflags & MIPS_HFLAG_64))
5816 6e473128 ths
            generate_exception(ctx, EXCP_RI);
5817 7a387fff ths
        gen_arith_imm(ctx, op, rt, rs, imm);
5818 7a387fff ths
        break;
5819 6af0bf9c bellard
#endif
5820 7a387fff ths
#ifdef MIPS_HAS_MIPS16
5821 7a387fff ths
    case OPC_JALX:
5822 7a387fff ths
        /* MIPS16: Not implemented. */
5823 7a387fff ths
#endif
5824 7a387fff ths
#ifdef MIPS_HAS_MDMX
5825 7a387fff ths
    case OPC_MDMX:
5826 7a387fff ths
        /* MDMX: Not implemented. */
5827 6af0bf9c bellard
#endif
5828 6af0bf9c bellard
    default:            /* Invalid */
5829 923617a3 ths
        MIPS_INVAL("major opcode");
5830 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
5831 6af0bf9c bellard
        break;
5832 6af0bf9c bellard
    }
5833 4ad40f36 bellard
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5834 c53f4a62 ths
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5835 6af0bf9c bellard
        /* Branches completion */
5836 4ad40f36 bellard
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
5837 6af0bf9c bellard
        ctx->bstate = BS_BRANCH;
5838 6af0bf9c bellard
        save_cpu_state(ctx, 0);
5839 5a5012ec ths
        switch (hflags) {
5840 6af0bf9c bellard
        case MIPS_HFLAG_B:
5841 6af0bf9c bellard
            /* unconditional branch */
5842 6af0bf9c bellard
            MIPS_DEBUG("unconditional branch");
5843 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
5844 6af0bf9c bellard
            break;
5845 6af0bf9c bellard
        case MIPS_HFLAG_BL:
5846 6af0bf9c bellard
            /* blikely taken case */
5847 6af0bf9c bellard
            MIPS_DEBUG("blikely branch taken");
5848 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
5849 6af0bf9c bellard
            break;
5850 6af0bf9c bellard
        case MIPS_HFLAG_BC:
5851 6af0bf9c bellard
            /* Conditional branch */
5852 6af0bf9c bellard
            MIPS_DEBUG("conditional branch");
5853 c53be334 bellard
            {
5854 c53be334 bellard
              int l1;
5855 c53be334 bellard
              l1 = gen_new_label();
5856 c53be334 bellard
              gen_op_jnz_T2(l1);
5857 6e256c93 bellard
              gen_goto_tb(ctx, 1, ctx->pc + 4);
5858 eeef26cd bellard
              gen_set_label(l1);
5859 eeef26cd bellard
              gen_goto_tb(ctx, 0, ctx->btarget);
5860 c53be334 bellard
            }
5861 6af0bf9c bellard
            break;
5862 6af0bf9c bellard
        case MIPS_HFLAG_BR:
5863 6af0bf9c bellard
            /* unconditional branch to register */
5864 6af0bf9c bellard
            MIPS_DEBUG("branch to register");
5865 6af0bf9c bellard
            gen_op_breg();
5866 5a5012ec ths
            gen_op_reset_T0();
5867 5a5012ec ths
            gen_op_exit_tb();
5868 6af0bf9c bellard
            break;
5869 6af0bf9c bellard
        default:
5870 6af0bf9c bellard
            MIPS_DEBUG("unknown branch");
5871 6af0bf9c bellard
            break;
5872 6af0bf9c bellard
        }
5873 6af0bf9c bellard
    }
5874 6af0bf9c bellard
}
5875 6af0bf9c bellard
5876 820e00f2 ths
static inline int
5877 820e00f2 ths
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5878 820e00f2 ths
                                int search_pc)
5879 6af0bf9c bellard
{
5880 278d0702 ths
    DisasContext ctx;
5881 6af0bf9c bellard
    target_ulong pc_start;
5882 6af0bf9c bellard
    uint16_t *gen_opc_end;
5883 6af0bf9c bellard
    int j, lj = -1;
5884 6af0bf9c bellard
5885 4ad40f36 bellard
    if (search_pc && loglevel)
5886 6ea83fed bellard
        fprintf (logfile, "search pc %d\n", search_pc);
5887 4ad40f36 bellard
5888 6af0bf9c bellard
    pc_start = tb->pc;
5889 6af0bf9c bellard
    gen_opc_ptr = gen_opc_buf;
5890 6af0bf9c bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5891 6af0bf9c bellard
    gen_opparam_ptr = gen_opparam_buf;
5892 c53be334 bellard
    nb_gen_labels = 0;
5893 6af0bf9c bellard
    ctx.pc = pc_start;
5894 4ad40f36 bellard
    ctx.saved_pc = -1;
5895 6af0bf9c bellard
    ctx.tb = tb;
5896 6af0bf9c bellard
    ctx.bstate = BS_NONE;
5897 4ad40f36 bellard
    /* Restore delay slot state from the tb context.  */
5898 4ad40f36 bellard
    ctx.hflags = tb->flags;
5899 fd4a04eb ths
    restore_cpu_state(env, &ctx);
5900 6af0bf9c bellard
#if defined(CONFIG_USER_ONLY)
5901 6af0bf9c bellard
    ctx.mem_idx = 0;
5902 6af0bf9c bellard
#else
5903 3d9fb9fe bellard
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5904 6af0bf9c bellard
#endif
5905 6af0bf9c bellard
#ifdef DEBUG_DISAS
5906 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
5907 6af0bf9c bellard
        fprintf(logfile, "------------------------------------------------\n");
5908 4ad40f36 bellard
        /* FIXME: This may print out stale hflags from env... */
5909 6af0bf9c bellard
        cpu_dump_state(env, logfile, fprintf, 0);
5910 6af0bf9c bellard
    }
5911 6af0bf9c bellard
#endif
5912 923617a3 ths
#ifdef MIPS_DEBUG_DISAS
5913 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
5914 4ad40f36 bellard
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
5915 4ad40f36 bellard
                tb, ctx.mem_idx, ctx.hflags);
5916 6af0bf9c bellard
#endif
5917 6af0bf9c bellard
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5918 4ad40f36 bellard
        if (env->nb_breakpoints > 0) {
5919 4ad40f36 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
5920 4ad40f36 bellard
                if (env->breakpoints[j] == ctx.pc) {
5921 278d0702 ths
                    save_cpu_state(&ctx, 1);
5922 4ad40f36 bellard
                    ctx.bstate = BS_BRANCH;
5923 4ad40f36 bellard
                    gen_op_debug();
5924 4ad40f36 bellard
                    goto done_generating;
5925 4ad40f36 bellard
                }
5926 4ad40f36 bellard
            }
5927 4ad40f36 bellard
        }
5928 4ad40f36 bellard
5929 6af0bf9c bellard
        if (search_pc) {
5930 6af0bf9c bellard
            j = gen_opc_ptr - gen_opc_buf;
5931 6af0bf9c bellard
            if (lj < j) {
5932 6af0bf9c bellard
                lj++;
5933 6af0bf9c bellard
                while (lj < j)
5934 6af0bf9c bellard
                    gen_opc_instr_start[lj++] = 0;
5935 6af0bf9c bellard
            }
5936 4ad40f36 bellard
            gen_opc_pc[lj] = ctx.pc;
5937 4ad40f36 bellard
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5938 4ad40f36 bellard
            gen_opc_instr_start[lj] = 1;
5939 6af0bf9c bellard
        }
5940 6af0bf9c bellard
        ctx.opcode = ldl_code(ctx.pc);
5941 36d23958 ths
        decode_opc(env, &ctx);
5942 6af0bf9c bellard
        ctx.pc += 4;
5943 4ad40f36 bellard
5944 4ad40f36 bellard
        if (env->singlestep_enabled)
5945 4ad40f36 bellard
            break;
5946 4ad40f36 bellard
5947 6af0bf9c bellard
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5948 6af0bf9c bellard
            break;
5949 4ad40f36 bellard
5950 6af0bf9c bellard
#if defined (MIPS_SINGLE_STEP)
5951 6af0bf9c bellard
        break;
5952 6af0bf9c bellard
#endif
5953 6af0bf9c bellard
    }
5954 4ad40f36 bellard
    if (env->singlestep_enabled) {
5955 278d0702 ths
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
5956 4ad40f36 bellard
        gen_op_debug();
5957 16c00cb2 ths
    } else {
5958 16c00cb2 ths
        switch (ctx.bstate) {
5959 16c00cb2 ths
        case BS_STOP:
5960 16c00cb2 ths
            gen_op_interrupt_restart();
5961 df1561e2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
5962 df1561e2 ths
            break;
5963 16c00cb2 ths
        case BS_NONE:
5964 278d0702 ths
            save_cpu_state(&ctx, 0);
5965 16c00cb2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
5966 16c00cb2 ths
            break;
5967 5a5012ec ths
        case BS_EXCP:
5968 5a5012ec ths
            gen_op_interrupt_restart();
5969 a85427b1 ths
            gen_op_reset_T0();
5970 a85427b1 ths
            gen_op_exit_tb();
5971 16c00cb2 ths
            break;
5972 5a5012ec ths
        case BS_BRANCH:
5973 5a5012ec ths
        default:
5974 5a5012ec ths
            break;
5975 16c00cb2 ths
        }
5976 6af0bf9c bellard
    }
5977 4ad40f36 bellard
done_generating:
5978 6af0bf9c bellard
    *gen_opc_ptr = INDEX_op_end;
5979 6af0bf9c bellard
    if (search_pc) {
5980 6af0bf9c bellard
        j = gen_opc_ptr - gen_opc_buf;
5981 6af0bf9c bellard
        lj++;
5982 6af0bf9c bellard
        while (lj <= j)
5983 6af0bf9c bellard
            gen_opc_instr_start[lj++] = 0;
5984 6af0bf9c bellard
        tb->size = 0;
5985 6af0bf9c bellard
    } else {
5986 6af0bf9c bellard
        tb->size = ctx.pc - pc_start;
5987 6af0bf9c bellard
    }
5988 6af0bf9c bellard
#ifdef DEBUG_DISAS
5989 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
5990 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
5991 6af0bf9c bellard
        fprintf(logfile, "\n");
5992 6af0bf9c bellard
#endif
5993 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5994 6af0bf9c bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5995 9898128f ths
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5996 6af0bf9c bellard
        fprintf(logfile, "\n");
5997 6af0bf9c bellard
    }
5998 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_OP) {
5999 6af0bf9c bellard
        fprintf(logfile, "OP:\n");
6000 6af0bf9c bellard
        dump_ops(gen_opc_buf, gen_opparam_buf);
6001 6af0bf9c bellard
        fprintf(logfile, "\n");
6002 6af0bf9c bellard
    }
6003 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
6004 6af0bf9c bellard
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
6005 6af0bf9c bellard
    }
6006 6af0bf9c bellard
#endif
6007 6af0bf9c bellard
    
6008 6af0bf9c bellard
    return 0;
6009 6af0bf9c bellard
}
6010 6af0bf9c bellard
6011 6af0bf9c bellard
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6012 6af0bf9c bellard
{
6013 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 0);
6014 6af0bf9c bellard
}
6015 6af0bf9c bellard
6016 6af0bf9c bellard
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6017 6af0bf9c bellard
{
6018 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 1);
6019 6af0bf9c bellard
}
6020 6af0bf9c bellard
6021 6ea83fed bellard
void fpu_dump_state(CPUState *env, FILE *f, 
6022 6ea83fed bellard
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
6023 6ea83fed bellard
                    int flags)
6024 6ea83fed bellard
{
6025 6ea83fed bellard
    int i;
6026 5e755519 ths
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
6027 5a5012ec ths
6028 5a5012ec ths
#define printfpr(fp)                                                        \
6029 5a5012ec ths
    do {                                                                    \
6030 5a5012ec ths
        if (is_fpu64)                                                       \
6031 5a5012ec ths
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
6032 5a5012ec ths
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
6033 5a5012ec ths
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6034 5a5012ec ths
        else {                                                              \
6035 5a5012ec ths
            fpr_t tmp;                                                      \
6036 5a5012ec ths
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6037 5a5012ec ths
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6038 5a5012ec ths
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6039 5a5012ec ths
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6040 5a5012ec ths
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6041 5a5012ec ths
        }                                                                   \
6042 6ea83fed bellard
    } while(0)
6043 6ea83fed bellard
6044 5a5012ec ths
6045 5a5012ec ths
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6046 5a5012ec ths
                env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
6047 6ea83fed bellard
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
6048 6ea83fed bellard
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
6049 6ea83fed bellard
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
6050 5a5012ec ths
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6051 5a5012ec ths
        fpu_fprintf(f, "%3s: ", fregnames[i]);
6052 5a5012ec ths
        printfpr(&env->fpr[i]);
6053 6ea83fed bellard
    }
6054 6ea83fed bellard
6055 6ea83fed bellard
#undef printfpr
6056 6ea83fed bellard
}
6057 6ea83fed bellard
6058 7a387fff ths
void dump_fpu (CPUState *env)
6059 6ea83fed bellard
{
6060 6ea83fed bellard
    if (loglevel) { 
6061 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",
6062 6ea83fed bellard
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6063 6ea83fed bellard
       fpu_dump_state(env, logfile, fprintf, 0);
6064 6ea83fed bellard
    }
6065 6ea83fed bellard
}
6066 6ea83fed bellard
6067 60aa19ab ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6068 c570fd16 ths
/* Debug help: The architecture requires 32bit code to maintain proper
6069 c570fd16 ths
   sign-extened values on 64bit machines.  */
6070 c570fd16 ths
6071 c570fd16 ths
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6072 c570fd16 ths
6073 c570fd16 ths
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6074 c570fd16 ths
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6075 c570fd16 ths
                     int flags)
6076 c570fd16 ths
{
6077 c570fd16 ths
    int i;
6078 c570fd16 ths
6079 c570fd16 ths
    if (!SIGN_EXT_P(env->PC))
6080 3594c774 ths
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
6081 c570fd16 ths
    if (!SIGN_EXT_P(env->HI))
6082 3594c774 ths
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
6083 c570fd16 ths
    if (!SIGN_EXT_P(env->LO))
6084 3594c774 ths
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
6085 c570fd16 ths
    if (!SIGN_EXT_P(env->btarget))
6086 3594c774 ths
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6087 c570fd16 ths
6088 c570fd16 ths
    for (i = 0; i < 32; i++) {
6089 c570fd16 ths
        if (!SIGN_EXT_P(env->gpr[i]))
6090 3594c774 ths
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
6091 c570fd16 ths
    }
6092 c570fd16 ths
6093 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_EPC))
6094 3594c774 ths
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6095 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_LLAddr))
6096 3594c774 ths
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6097 c570fd16 ths
}
6098 c570fd16 ths
#endif
6099 c570fd16 ths
6100 6af0bf9c bellard
void cpu_dump_state (CPUState *env, FILE *f, 
6101 6af0bf9c bellard
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6102 6af0bf9c bellard
                     int flags)
6103 6af0bf9c bellard
{
6104 6af0bf9c bellard
    int i;
6105 6af0bf9c bellard
    
6106 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",
6107 6af0bf9c bellard
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6108 6af0bf9c bellard
    for (i = 0; i < 32; i++) {
6109 6af0bf9c bellard
        if ((i & 3) == 0)
6110 6af0bf9c bellard
            cpu_fprintf(f, "GPR%02d:", i);
6111 3594c774 ths
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
6112 6af0bf9c bellard
        if ((i & 3) == 3)
6113 6af0bf9c bellard
            cpu_fprintf(f, "\n");
6114 6af0bf9c bellard
    }
6115 568b600d bellard
6116 3594c774 ths
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6117 5e755519 ths
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6118 3594c774 ths
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6119 6af0bf9c bellard
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6120 5e755519 ths
    if (env->hflags & MIPS_HFLAG_FPU)
6121 7a387fff ths
        fpu_dump_state(env, f, cpu_fprintf, flags);
6122 60aa19ab ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6123 c570fd16 ths
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6124 c570fd16 ths
#endif
6125 6af0bf9c bellard
}
6126 6af0bf9c bellard
6127 6af0bf9c bellard
CPUMIPSState *cpu_mips_init (void)
6128 6af0bf9c bellard
{
6129 6af0bf9c bellard
    CPUMIPSState *env;
6130 6af0bf9c bellard
6131 6af0bf9c bellard
    env = qemu_mallocz(sizeof(CPUMIPSState));
6132 6af0bf9c bellard
    if (!env)
6133 6af0bf9c bellard
        return NULL;
6134 173d6cfe bellard
    cpu_exec_init(env);
6135 6ae81775 ths
    cpu_reset(env);
6136 6ae81775 ths
    return env;
6137 6ae81775 ths
}
6138 6ae81775 ths
6139 6ae81775 ths
void cpu_reset (CPUMIPSState *env)
6140 6ae81775 ths
{
6141 6ae81775 ths
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6142 6ae81775 ths
6143 6af0bf9c bellard
    tlb_flush(env, 1);
6144 6ae81775 ths
6145 6af0bf9c bellard
    /* Minimal init */
6146 ca7c2b1b ths
#if !defined(CONFIG_USER_ONLY)
6147 aa328add ths
    if (env->hflags & MIPS_HFLAG_BMASK) {
6148 aa328add ths
        /* If the exception was raised from a delay slot,
6149 aa328add ths
         * come back to the jump.  */
6150 aa328add ths
        env->CP0_ErrorEPC = env->PC - 4;
6151 aa328add ths
    } else {
6152 aa328add ths
        env->CP0_ErrorEPC = env->PC;
6153 aa328add ths
    }
6154 6e473128 ths
#ifdef TARGET_MIPS64
6155 6e473128 ths
    env->hflags = MIPS_HFLAG_64;
6156 6e473128 ths
#else
6157 24c7b0e3 ths
    env->hflags = 0;
6158 6e473128 ths
#endif
6159 5dc4b744 ths
    env->PC = (int32_t)0xBFC00000;
6160 6af0bf9c bellard
    env->CP0_Wired = 0;
6161 7a387fff ths
    /* SMP not implemented */
6162 b29a0341 ths
    env->CP0_EBase = 0x80000000;
6163 aa328add ths
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6164 c090a8f4 ths
    /* vectored interrupts not implemented, timer on int 7,
6165 c090a8f4 ths
       no performance counters. */
6166 c090a8f4 ths
    env->CP0_IntCtl = 0xe0000000;
6167 fd88b6ab ths
    {
6168 fd88b6ab ths
        int i;
6169 fd88b6ab ths
6170 fd88b6ab ths
        for (i = 0; i < 7; i++) {
6171 fd88b6ab ths
            env->CP0_WatchLo[i] = 0;
6172 fd88b6ab ths
            env->CP0_WatchHi[i] = 0x80000000;
6173 fd88b6ab ths
        }
6174 fd88b6ab ths
        env->CP0_WatchLo[7] = 0;
6175 fd88b6ab ths
        env->CP0_WatchHi[7] = 0;
6176 fd88b6ab ths
    }
6177 6af0bf9c bellard
    /* Count register increments in debug mode, EJTAG version 1 */
6178 6af0bf9c bellard
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6179 ca7c2b1b ths
#endif
6180 6af0bf9c bellard
    env->exception_index = EXCP_NONE;
6181 eeef26cd bellard
#if defined(CONFIG_USER_ONLY)
6182 eeef26cd bellard
    env->hflags |= MIPS_HFLAG_UM;
6183 ca7c2b1b ths
    env->user_mode_only = 1;
6184 eeef26cd bellard
#endif
6185 6af0bf9c bellard
}
6186 33d68b5f ths
6187 33d68b5f ths
#include "translate_init.c"