Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 7385ac0b

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