Statistics
| Branch: | Revision:

root / target-mips / translate.c @ ca10f867

History | View | Annotate | Download (190.3 kB)

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