Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 42388c4b

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