Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d8a5950a

History | View | Annotate | Download (185.7 kB)

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