Statistics
| Branch: | Revision:

root / target-mips / translate.c @ ce62e5ba

History | View | Annotate | Download (180.6 kB)

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