Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 855cea8c

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