Statistics
| Branch: | Revision:

root / target-mips / translate.c @ e6bb7d7e

History | View | Annotate | Download (221 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 cb63669a pbrook
    tcg_gen_brcondi_tl(cond, cpu_T[0], 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 cb63669a pbrook
    tcg_gen_brcondi_tl(cond, cpu_T[0], 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 cb63669a pbrook
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 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 cb63669a pbrook
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 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 cb63669a pbrook
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
999 aaa9128a ths
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1000 f0b3f3ae 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 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 cb63669a pbrook
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 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 cb63669a pbrook
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 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 cb63669a pbrook
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 1ULL << 63, l2);
1962 cb63669a pbrook
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 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 f0b3f3ae ths
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2572 f0b3f3ae ths
    TCGv r_tmp64 = tcg_temp_new(TCG_TYPE_I64);
2573 873eb012 ths
2574 e189e748 ths
    if (sel != 0)
2575 e189e748 ths
        check_insn(env, ctx, ISA_MIPS32);
2576 e189e748 ths
2577 873eb012 ths
    switch (reg) {
2578 873eb012 ths
    case 0:
2579 7a387fff ths
        switch (sel) {
2580 7a387fff ths
        case 0:
2581 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
2582 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2583 7a387fff ths
            rn = "Index";
2584 7a387fff ths
            break;
2585 7a387fff ths
        case 1:
2586 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2587 ead9360e ths
            gen_op_mfc0_mvpcontrol();
2588 7a387fff ths
            rn = "MVPControl";
2589 ead9360e ths
            break;
2590 7a387fff ths
        case 2:
2591 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2592 ead9360e ths
            gen_op_mfc0_mvpconf0();
2593 7a387fff ths
            rn = "MVPConf0";
2594 ead9360e ths
            break;
2595 7a387fff ths
        case 3:
2596 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2597 ead9360e ths
            gen_op_mfc0_mvpconf1();
2598 7a387fff ths
            rn = "MVPConf1";
2599 ead9360e ths
            break;
2600 7a387fff ths
        default:
2601 7a387fff ths
            goto die;
2602 7a387fff ths
        }
2603 873eb012 ths
        break;
2604 873eb012 ths
    case 1:
2605 7a387fff ths
        switch (sel) {
2606 7a387fff ths
        case 0:
2607 7a387fff ths
            gen_op_mfc0_random();
2608 7a387fff ths
            rn = "Random";
2609 2423f660 ths
            break;
2610 7a387fff ths
        case 1:
2611 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2612 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
2613 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2614 7a387fff ths
            rn = "VPEControl";
2615 ead9360e ths
            break;
2616 7a387fff ths
        case 2:
2617 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2618 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
2619 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2620 7a387fff ths
            rn = "VPEConf0";
2621 ead9360e ths
            break;
2622 7a387fff ths
        case 3:
2623 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2624 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
2625 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2626 7a387fff ths
            rn = "VPEConf1";
2627 ead9360e ths
            break;
2628 7a387fff ths
        case 4:
2629 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2630 f0b3f3ae ths
            tcg_gen_ld_i64(r_tmp64, cpu_env, offsetof(CPUState, CP0_YQMask));
2631 f0b3f3ae ths
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2632 7a387fff ths
            rn = "YQMask";
2633 ead9360e ths
            break;
2634 7a387fff ths
        case 5:
2635 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2636 f0b3f3ae ths
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPESchedule));
2637 f0b3f3ae ths
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2638 7a387fff ths
            rn = "VPESchedule";
2639 ead9360e ths
            break;
2640 7a387fff ths
        case 6:
2641 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2642 f0b3f3ae ths
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
2643 f0b3f3ae ths
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2644 7a387fff ths
            rn = "VPEScheFBack";
2645 ead9360e ths
            break;
2646 7a387fff ths
        case 7:
2647 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2648 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
2649 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2650 7a387fff ths
            rn = "VPEOpt";
2651 ead9360e ths
            break;
2652 7a387fff ths
        default:
2653 7a387fff ths
            goto die;
2654 7a387fff ths
        }
2655 873eb012 ths
        break;
2656 873eb012 ths
    case 2:
2657 7a387fff ths
        switch (sel) {
2658 7a387fff ths
        case 0:
2659 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
2660 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2661 2423f660 ths
            rn = "EntryLo0";
2662 2423f660 ths
            break;
2663 7a387fff ths
        case 1:
2664 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2665 ead9360e ths
            gen_op_mfc0_tcstatus();
2666 2423f660 ths
            rn = "TCStatus";
2667 ead9360e ths
            break;
2668 7a387fff ths
        case 2:
2669 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2670 ead9360e ths
            gen_op_mfc0_tcbind();
2671 2423f660 ths
            rn = "TCBind";
2672 ead9360e ths
            break;
2673 7a387fff ths
        case 3:
2674 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2675 ead9360e ths
            gen_op_mfc0_tcrestart();
2676 2423f660 ths
            rn = "TCRestart";
2677 ead9360e ths
            break;
2678 7a387fff ths
        case 4:
2679 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2680 ead9360e ths
            gen_op_mfc0_tchalt();
2681 2423f660 ths
            rn = "TCHalt";
2682 ead9360e ths
            break;
2683 7a387fff ths
        case 5:
2684 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2685 ead9360e ths
            gen_op_mfc0_tccontext();
2686 2423f660 ths
            rn = "TCContext";
2687 ead9360e ths
            break;
2688 7a387fff ths
        case 6:
2689 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2690 ead9360e ths
            gen_op_mfc0_tcschedule();
2691 2423f660 ths
            rn = "TCSchedule";
2692 ead9360e ths
            break;
2693 7a387fff ths
        case 7:
2694 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2695 ead9360e ths
            gen_op_mfc0_tcschefback();
2696 2423f660 ths
            rn = "TCScheFBack";
2697 ead9360e ths
            break;
2698 7a387fff ths
        default:
2699 7a387fff ths
            goto die;
2700 7a387fff ths
        }
2701 873eb012 ths
        break;
2702 873eb012 ths
    case 3:
2703 7a387fff ths
        switch (sel) {
2704 7a387fff ths
        case 0:
2705 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
2706 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2707 2423f660 ths
            rn = "EntryLo1";
2708 2423f660 ths
            break;
2709 7a387fff ths
        default:
2710 7a387fff ths
            goto die;
2711 1579a72e ths
        }
2712 873eb012 ths
        break;
2713 873eb012 ths
    case 4:
2714 7a387fff ths
        switch (sel) {
2715 7a387fff ths
        case 0:
2716 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
2717 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2718 2423f660 ths
            rn = "Context";
2719 2423f660 ths
            break;
2720 7a387fff ths
        case 1:
2721 2423f660 ths
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2722 2423f660 ths
            rn = "ContextConfig";
2723 2423f660 ths
//            break;
2724 7a387fff ths
        default:
2725 7a387fff ths
            goto die;
2726 1579a72e ths
        }
2727 873eb012 ths
        break;
2728 873eb012 ths
    case 5:
2729 7a387fff ths
        switch (sel) {
2730 7a387fff ths
        case 0:
2731 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
2732 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2733 2423f660 ths
            rn = "PageMask";
2734 2423f660 ths
            break;
2735 7a387fff ths
        case 1:
2736 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2737 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
2738 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2739 2423f660 ths
            rn = "PageGrain";
2740 2423f660 ths
            break;
2741 7a387fff ths
        default:
2742 7a387fff ths
            goto die;
2743 1579a72e ths
        }
2744 873eb012 ths
        break;
2745 873eb012 ths
    case 6:
2746 7a387fff ths
        switch (sel) {
2747 7a387fff ths
        case 0:
2748 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
2749 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2750 2423f660 ths
            rn = "Wired";
2751 2423f660 ths
            break;
2752 7a387fff ths
        case 1:
2753 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2754 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
2755 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2756 2423f660 ths
            rn = "SRSConf0";
2757 ead9360e ths
            break;
2758 7a387fff ths
        case 2:
2759 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2760 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
2761 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2762 2423f660 ths
            rn = "SRSConf1";
2763 ead9360e ths
            break;
2764 7a387fff ths
        case 3:
2765 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2766 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
2767 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2768 2423f660 ths
            rn = "SRSConf2";
2769 ead9360e ths
            break;
2770 7a387fff ths
        case 4:
2771 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2772 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
2773 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2774 2423f660 ths
            rn = "SRSConf3";
2775 ead9360e ths
            break;
2776 7a387fff ths
        case 5:
2777 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2778 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
2779 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2780 2423f660 ths
            rn = "SRSConf4";
2781 ead9360e ths
            break;
2782 7a387fff ths
        default:
2783 7a387fff ths
            goto die;
2784 1579a72e ths
        }
2785 873eb012 ths
        break;
2786 8c0fdd85 ths
    case 7:
2787 7a387fff ths
        switch (sel) {
2788 7a387fff ths
        case 0:
2789 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2790 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
2791 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2792 2423f660 ths
            rn = "HWREna";
2793 2423f660 ths
            break;
2794 7a387fff ths
        default:
2795 7a387fff ths
            goto die;
2796 1579a72e ths
        }
2797 8c0fdd85 ths
        break;
2798 873eb012 ths
    case 8:
2799 7a387fff ths
        switch (sel) {
2800 7a387fff ths
        case 0:
2801 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
2802 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2803 f0b3f3ae ths
            rn = "BadVAddr";
2804 2423f660 ths
            break;
2805 7a387fff ths
        default:
2806 7a387fff ths
            goto die;
2807 7a387fff ths
       }
2808 873eb012 ths
        break;
2809 873eb012 ths
    case 9:
2810 7a387fff ths
        switch (sel) {
2811 7a387fff ths
        case 0:
2812 2423f660 ths
            gen_op_mfc0_count();
2813 2423f660 ths
            rn = "Count";
2814 2423f660 ths
            break;
2815 2423f660 ths
        /* 6,7 are implementation dependent */
2816 7a387fff ths
        default:
2817 7a387fff ths
            goto die;
2818 2423f660 ths
        }
2819 873eb012 ths
        break;
2820 873eb012 ths
    case 10:
2821 7a387fff ths
        switch (sel) {
2822 7a387fff ths
        case 0:
2823 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
2824 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2825 2423f660 ths
            rn = "EntryHi";
2826 2423f660 ths
            break;
2827 7a387fff ths
        default:
2828 7a387fff ths
            goto die;
2829 1579a72e ths
        }
2830 873eb012 ths
        break;
2831 873eb012 ths
    case 11:
2832 7a387fff ths
        switch (sel) {
2833 7a387fff ths
        case 0:
2834 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
2835 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2836 2423f660 ths
            rn = "Compare";
2837 2423f660 ths
            break;
2838 2423f660 ths
        /* 6,7 are implementation dependent */
2839 7a387fff ths
        default:
2840 7a387fff ths
            goto die;
2841 2423f660 ths
        }
2842 873eb012 ths
        break;
2843 873eb012 ths
    case 12:
2844 7a387fff ths
        switch (sel) {
2845 7a387fff ths
        case 0:
2846 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
2847 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2848 2423f660 ths
            rn = "Status";
2849 2423f660 ths
            break;
2850 7a387fff ths
        case 1:
2851 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2852 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
2853 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2854 2423f660 ths
            rn = "IntCtl";
2855 2423f660 ths
            break;
2856 7a387fff ths
        case 2:
2857 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2858 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
2859 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2860 2423f660 ths
            rn = "SRSCtl";
2861 2423f660 ths
            break;
2862 7a387fff ths
        case 3:
2863 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2864 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
2865 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2866 2423f660 ths
            rn = "SRSMap";
2867 fd88b6ab ths
            break;
2868 7a387fff ths
        default:
2869 7a387fff ths
            goto die;
2870 7a387fff ths
       }
2871 873eb012 ths
        break;
2872 873eb012 ths
    case 13:
2873 7a387fff ths
        switch (sel) {
2874 7a387fff ths
        case 0:
2875 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
2876 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2877 2423f660 ths
            rn = "Cause";
2878 2423f660 ths
            break;
2879 7a387fff ths
        default:
2880 7a387fff ths
            goto die;
2881 7a387fff ths
       }
2882 873eb012 ths
        break;
2883 873eb012 ths
    case 14:
2884 7a387fff ths
        switch (sel) {
2885 7a387fff ths
        case 0:
2886 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
2887 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2888 2423f660 ths
            rn = "EPC";
2889 2423f660 ths
            break;
2890 7a387fff ths
        default:
2891 7a387fff ths
            goto die;
2892 1579a72e ths
        }
2893 873eb012 ths
        break;
2894 873eb012 ths
    case 15:
2895 7a387fff ths
        switch (sel) {
2896 7a387fff ths
        case 0:
2897 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
2898 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2899 2423f660 ths
            rn = "PRid";
2900 2423f660 ths
            break;
2901 7a387fff ths
        case 1:
2902 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2903 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
2904 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2905 2423f660 ths
            rn = "EBase";
2906 2423f660 ths
            break;
2907 7a387fff ths
        default:
2908 7a387fff ths
            goto die;
2909 7a387fff ths
       }
2910 873eb012 ths
        break;
2911 873eb012 ths
    case 16:
2912 873eb012 ths
        switch (sel) {
2913 873eb012 ths
        case 0:
2914 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
2915 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2916 873eb012 ths
            rn = "Config";
2917 873eb012 ths
            break;
2918 873eb012 ths
        case 1:
2919 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
2920 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2921 873eb012 ths
            rn = "Config1";
2922 873eb012 ths
            break;
2923 7a387fff ths
        case 2:
2924 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
2925 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2926 7a387fff ths
            rn = "Config2";
2927 7a387fff ths
            break;
2928 7a387fff ths
        case 3:
2929 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
2930 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2931 7a387fff ths
            rn = "Config3";
2932 7a387fff ths
            break;
2933 e397ee33 ths
        /* 4,5 are reserved */
2934 e397ee33 ths
        /* 6,7 are implementation dependent */
2935 e397ee33 ths
        case 6:
2936 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
2937 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2938 e397ee33 ths
            rn = "Config6";
2939 e397ee33 ths
            break;
2940 e397ee33 ths
        case 7:
2941 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
2942 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2943 e397ee33 ths
            rn = "Config7";
2944 e397ee33 ths
            break;
2945 873eb012 ths
        default:
2946 873eb012 ths
            goto die;
2947 873eb012 ths
        }
2948 873eb012 ths
        break;
2949 873eb012 ths
    case 17:
2950 7a387fff ths
        switch (sel) {
2951 7a387fff ths
        case 0:
2952 2423f660 ths
            gen_op_mfc0_lladdr();
2953 2423f660 ths
            rn = "LLAddr";
2954 2423f660 ths
            break;
2955 7a387fff ths
        default:
2956 7a387fff ths
            goto die;
2957 7a387fff ths
        }
2958 873eb012 ths
        break;
2959 873eb012 ths
    case 18:
2960 7a387fff ths
        switch (sel) {
2961 fd88b6ab ths
        case 0 ... 7:
2962 fd88b6ab ths
            gen_op_mfc0_watchlo(sel);
2963 2423f660 ths
            rn = "WatchLo";
2964 2423f660 ths
            break;
2965 7a387fff ths
        default:
2966 7a387fff ths
            goto die;
2967 7a387fff ths
        }
2968 873eb012 ths
        break;
2969 873eb012 ths
    case 19:
2970 7a387fff ths
        switch (sel) {
2971 fd88b6ab ths
        case 0 ...7:
2972 fd88b6ab ths
            gen_op_mfc0_watchhi(sel);
2973 2423f660 ths
            rn = "WatchHi";
2974 2423f660 ths
            break;
2975 7a387fff ths
        default:
2976 7a387fff ths
            goto die;
2977 7a387fff ths
        }
2978 873eb012 ths
        break;
2979 8c0fdd85 ths
    case 20:
2980 7a387fff ths
        switch (sel) {
2981 7a387fff ths
        case 0:
2982 d26bc211 ths
#if defined(TARGET_MIPS64)
2983 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
2984 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
2985 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2986 2423f660 ths
            rn = "XContext";
2987 2423f660 ths
            break;
2988 703eaf37 ths
#endif
2989 7a387fff ths
        default:
2990 7a387fff ths
            goto die;
2991 7a387fff ths
        }
2992 8c0fdd85 ths
        break;
2993 8c0fdd85 ths
    case 21:
2994 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2995 7a387fff ths
        switch (sel) {
2996 7a387fff ths
        case 0:
2997 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
2998 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2999 2423f660 ths
            rn = "Framemask";
3000 2423f660 ths
            break;
3001 7a387fff ths
        default:
3002 7a387fff ths
            goto die;
3003 7a387fff ths
        }
3004 8c0fdd85 ths
        break;
3005 8c0fdd85 ths
    case 22:
3006 2423f660 ths
        /* ignored */
3007 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
3008 2423f660 ths
        break;
3009 873eb012 ths
    case 23:
3010 7a387fff ths
        switch (sel) {
3011 7a387fff ths
        case 0:
3012 2423f660 ths
            gen_op_mfc0_debug(); /* EJTAG support */
3013 2423f660 ths
            rn = "Debug";
3014 2423f660 ths
            break;
3015 7a387fff ths
        case 1:
3016 2423f660 ths
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
3017 2423f660 ths
            rn = "TraceControl";
3018 2423f660 ths
//            break;
3019 7a387fff ths
        case 2:
3020 2423f660 ths
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
3021 2423f660 ths
            rn = "TraceControl2";
3022 2423f660 ths
//            break;
3023 7a387fff ths
        case 3:
3024 2423f660 ths
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
3025 2423f660 ths
            rn = "UserTraceData";
3026 2423f660 ths
//            break;
3027 7a387fff ths
        case 4:
3028 2423f660 ths
//            gen_op_mfc0_debug(); /* PDtrace support */
3029 2423f660 ths
            rn = "TraceBPC";
3030 2423f660 ths
//            break;
3031 7a387fff ths
        default:
3032 7a387fff ths
            goto die;
3033 7a387fff ths
        }
3034 873eb012 ths
        break;
3035 873eb012 ths
    case 24:
3036 7a387fff ths
        switch (sel) {
3037 7a387fff ths
        case 0:
3038 f0b3f3ae ths
            /* EJTAG support */
3039 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
3040 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3041 2423f660 ths
            rn = "DEPC";
3042 2423f660 ths
            break;
3043 7a387fff ths
        default:
3044 7a387fff ths
            goto die;
3045 7a387fff ths
        }
3046 873eb012 ths
        break;
3047 8c0fdd85 ths
    case 25:
3048 7a387fff ths
        switch (sel) {
3049 7a387fff ths
        case 0:
3050 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
3051 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3052 2423f660 ths
            rn = "Performance0";
3053 7a387fff ths
            break;
3054 7a387fff ths
        case 1:
3055 2423f660 ths
//            gen_op_mfc0_performance1();
3056 2423f660 ths
            rn = "Performance1";
3057 2423f660 ths
//            break;
3058 7a387fff ths
        case 2:
3059 2423f660 ths
//            gen_op_mfc0_performance2();
3060 2423f660 ths
            rn = "Performance2";
3061 2423f660 ths
//            break;
3062 7a387fff ths
        case 3:
3063 2423f660 ths
//            gen_op_mfc0_performance3();
3064 2423f660 ths
            rn = "Performance3";
3065 2423f660 ths
//            break;
3066 7a387fff ths
        case 4:
3067 2423f660 ths
//            gen_op_mfc0_performance4();
3068 2423f660 ths
            rn = "Performance4";
3069 2423f660 ths
//            break;
3070 7a387fff ths
        case 5:
3071 2423f660 ths
//            gen_op_mfc0_performance5();
3072 2423f660 ths
            rn = "Performance5";
3073 2423f660 ths
//            break;
3074 7a387fff ths
        case 6:
3075 2423f660 ths
//            gen_op_mfc0_performance6();
3076 2423f660 ths
            rn = "Performance6";
3077 2423f660 ths
//            break;
3078 7a387fff ths
        case 7:
3079 2423f660 ths
//            gen_op_mfc0_performance7();
3080 2423f660 ths
            rn = "Performance7";
3081 2423f660 ths
//            break;
3082 7a387fff ths
        default:
3083 7a387fff ths
            goto die;
3084 7a387fff ths
        }
3085 8c0fdd85 ths
        break;
3086 8c0fdd85 ths
    case 26:
3087 7a387fff ths
       rn = "ECC";
3088 7a387fff ths
       break;
3089 8c0fdd85 ths
    case 27:
3090 7a387fff ths
        switch (sel) {
3091 7a387fff ths
        /* ignored */
3092 7a387fff ths
        case 0 ... 3:
3093 2423f660 ths
            rn = "CacheErr";
3094 2423f660 ths
            break;
3095 7a387fff ths
        default:
3096 7a387fff ths
            goto die;
3097 7a387fff ths
        }
3098 8c0fdd85 ths
        break;
3099 873eb012 ths
    case 28:
3100 873eb012 ths
        switch (sel) {
3101 873eb012 ths
        case 0:
3102 7a387fff ths
        case 2:
3103 7a387fff ths
        case 4:
3104 7a387fff ths
        case 6:
3105 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
3106 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3107 873eb012 ths
            rn = "TagLo";
3108 873eb012 ths
            break;
3109 873eb012 ths
        case 1:
3110 7a387fff ths
        case 3:
3111 7a387fff ths
        case 5:
3112 7a387fff ths
        case 7:
3113 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
3114 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3115 873eb012 ths
            rn = "DataLo";
3116 873eb012 ths
            break;
3117 873eb012 ths
        default:
3118 873eb012 ths
            goto die;
3119 873eb012 ths
        }
3120 873eb012 ths
        break;
3121 8c0fdd85 ths
    case 29:
3122 7a387fff ths
        switch (sel) {
3123 7a387fff ths
        case 0:
3124 7a387fff ths
        case 2:
3125 7a387fff ths
        case 4:
3126 7a387fff ths
        case 6:
3127 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
3128 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3129 7a387fff ths
            rn = "TagHi";
3130 7a387fff ths
            break;
3131 7a387fff ths
        case 1:
3132 7a387fff ths
        case 3:
3133 7a387fff ths
        case 5:
3134 7a387fff ths
        case 7:
3135 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
3136 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3137 7a387fff ths
            rn = "DataHi";
3138 7a387fff ths
            break;
3139 7a387fff ths
        default:
3140 7a387fff ths
            goto die;
3141 7a387fff ths
        }
3142 8c0fdd85 ths
        break;
3143 873eb012 ths
    case 30:
3144 7a387fff ths
        switch (sel) {
3145 7a387fff ths
        case 0:
3146 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3147 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3148 2423f660 ths
            rn = "ErrorEPC";
3149 2423f660 ths
            break;
3150 7a387fff ths
        default:
3151 7a387fff ths
            goto die;
3152 7a387fff ths
        }
3153 873eb012 ths
        break;
3154 873eb012 ths
    case 31:
3155 7a387fff ths
        switch (sel) {
3156 7a387fff ths
        case 0:
3157 f0b3f3ae ths
            /* EJTAG support */
3158 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
3159 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3160 2423f660 ths
            rn = "DESAVE";
3161 2423f660 ths
            break;
3162 7a387fff ths
        default:
3163 7a387fff ths
            goto die;
3164 7a387fff ths
        }
3165 873eb012 ths
        break;
3166 873eb012 ths
    default:
3167 873eb012 ths
       goto die;
3168 873eb012 ths
    }
3169 873eb012 ths
#if defined MIPS_DEBUG_DISAS
3170 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3171 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3172 7a387fff ths
                rn, reg, sel);
3173 873eb012 ths
    }
3174 873eb012 ths
#endif
3175 873eb012 ths
    return;
3176 873eb012 ths
3177 873eb012 ths
die:
3178 873eb012 ths
#if defined MIPS_DEBUG_DISAS
3179 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3180 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3181 7a387fff ths
                rn, reg, sel);
3182 873eb012 ths
    }
3183 873eb012 ths
#endif
3184 873eb012 ths
    generate_exception(ctx, EXCP_RI);
3185 873eb012 ths
}
3186 873eb012 ths
3187 3a95e3a7 ths
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3188 8c0fdd85 ths
{
3189 7a387fff ths
    const char *rn = "invalid";
3190 7a387fff ths
3191 e189e748 ths
    if (sel != 0)
3192 e189e748 ths
        check_insn(env, ctx, ISA_MIPS32);
3193 e189e748 ths
3194 8c0fdd85 ths
    switch (reg) {
3195 8c0fdd85 ths
    case 0:
3196 7a387fff ths
        switch (sel) {
3197 7a387fff ths
        case 0:
3198 855cea8c ths
            gen_op_mtc0_index();
3199 7a387fff ths
            rn = "Index";
3200 7a387fff ths
            break;
3201 7a387fff ths
        case 1:
3202 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3203 ead9360e ths
            gen_op_mtc0_mvpcontrol();
3204 7a387fff ths
            rn = "MVPControl";
3205 ead9360e ths
            break;
3206 7a387fff ths
        case 2:
3207 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3208 ead9360e ths
            /* ignored */
3209 7a387fff ths
            rn = "MVPConf0";
3210 ead9360e ths
            break;
3211 7a387fff ths
        case 3:
3212 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3213 ead9360e ths
            /* ignored */
3214 7a387fff ths
            rn = "MVPConf1";
3215 ead9360e ths
            break;
3216 7a387fff ths
        default:
3217 7a387fff ths
            goto die;
3218 7a387fff ths
        }
3219 8c0fdd85 ths
        break;
3220 8c0fdd85 ths
    case 1:
3221 7a387fff ths
        switch (sel) {
3222 7a387fff ths
        case 0:
3223 2423f660 ths
            /* ignored */
3224 7a387fff ths
            rn = "Random";
3225 2423f660 ths
            break;
3226 7a387fff ths
        case 1:
3227 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3228 ead9360e ths
            gen_op_mtc0_vpecontrol();
3229 7a387fff ths
            rn = "VPEControl";
3230 ead9360e ths
            break;
3231 7a387fff ths
        case 2:
3232 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3233 ead9360e ths
            gen_op_mtc0_vpeconf0();
3234 7a387fff ths
            rn = "VPEConf0";
3235 ead9360e ths
            break;
3236 7a387fff ths
        case 3:
3237 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3238 ead9360e ths
            gen_op_mtc0_vpeconf1();
3239 7a387fff ths
            rn = "VPEConf1";
3240 ead9360e ths
            break;
3241 7a387fff ths
        case 4:
3242 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3243 ead9360e ths
            gen_op_mtc0_yqmask();
3244 7a387fff ths
            rn = "YQMask";
3245 ead9360e ths
            break;
3246 7a387fff ths
        case 5:
3247 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3248 ead9360e ths
            gen_op_mtc0_vpeschedule();
3249 7a387fff ths
            rn = "VPESchedule";
3250 ead9360e ths
            break;
3251 7a387fff ths
        case 6:
3252 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3253 ead9360e ths
            gen_op_mtc0_vpeschefback();
3254 7a387fff ths
            rn = "VPEScheFBack";
3255 ead9360e ths
            break;
3256 7a387fff ths
        case 7:
3257 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3258 ead9360e ths
            gen_op_mtc0_vpeopt();
3259 7a387fff ths
            rn = "VPEOpt";
3260 ead9360e ths
            break;
3261 7a387fff ths
        default:
3262 7a387fff ths
            goto die;
3263 7a387fff ths
        }
3264 8c0fdd85 ths
        break;
3265 8c0fdd85 ths
    case 2:
3266 7a387fff ths
        switch (sel) {
3267 7a387fff ths
        case 0:
3268 2423f660 ths
            gen_op_mtc0_entrylo0();
3269 2423f660 ths
            rn = "EntryLo0";
3270 2423f660 ths
            break;
3271 7a387fff ths
        case 1:
3272 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3273 ead9360e ths
            gen_op_mtc0_tcstatus();
3274 2423f660 ths
            rn = "TCStatus";
3275 ead9360e ths
            break;
3276 7a387fff ths
        case 2:
3277 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3278 ead9360e ths
            gen_op_mtc0_tcbind();
3279 2423f660 ths
            rn = "TCBind";
3280 ead9360e ths
            break;
3281 7a387fff ths
        case 3:
3282 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3283 ead9360e ths
            gen_op_mtc0_tcrestart();
3284 2423f660 ths
            rn = "TCRestart";
3285 ead9360e ths
            break;
3286 7a387fff ths
        case 4:
3287 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3288 ead9360e ths
            gen_op_mtc0_tchalt();
3289 2423f660 ths
            rn = "TCHalt";
3290 ead9360e ths
            break;
3291 7a387fff ths
        case 5:
3292 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3293 ead9360e ths
            gen_op_mtc0_tccontext();
3294 2423f660 ths
            rn = "TCContext";
3295 ead9360e ths
            break;
3296 7a387fff ths
        case 6:
3297 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3298 ead9360e ths
            gen_op_mtc0_tcschedule();
3299 2423f660 ths
            rn = "TCSchedule";
3300 ead9360e ths
            break;
3301 7a387fff ths
        case 7:
3302 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3303 ead9360e ths
            gen_op_mtc0_tcschefback();
3304 2423f660 ths
            rn = "TCScheFBack";
3305 ead9360e ths
            break;
3306 7a387fff ths
        default:
3307 7a387fff ths
            goto die;
3308 7a387fff ths
        }
3309 8c0fdd85 ths
        break;
3310 8c0fdd85 ths
    case 3:
3311 7a387fff ths
        switch (sel) {
3312 7a387fff ths
        case 0:
3313 2423f660 ths
            gen_op_mtc0_entrylo1();
3314 2423f660 ths
            rn = "EntryLo1";
3315 2423f660 ths
            break;
3316 7a387fff ths
        default:
3317 7a387fff ths
            goto die;
3318 876d4b07 ths
        }
3319 8c0fdd85 ths
        break;
3320 8c0fdd85 ths
    case 4:
3321 7a387fff ths
        switch (sel) {
3322 7a387fff ths
        case 0:
3323 2423f660 ths
            gen_op_mtc0_context();
3324 2423f660 ths
            rn = "Context";
3325 2423f660 ths
            break;
3326 7a387fff ths
        case 1:
3327 2423f660 ths
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3328 2423f660 ths
            rn = "ContextConfig";
3329 2423f660 ths
//            break;
3330 7a387fff ths
        default:
3331 7a387fff ths
            goto die;
3332 876d4b07 ths
        }
3333 8c0fdd85 ths
        break;
3334 8c0fdd85 ths
    case 5:
3335 7a387fff ths
        switch (sel) {
3336 7a387fff ths
        case 0:
3337 2423f660 ths
            gen_op_mtc0_pagemask();
3338 2423f660 ths
            rn = "PageMask";
3339 2423f660 ths
            break;
3340 7a387fff ths
        case 1:
3341 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3342 2423f660 ths
            gen_op_mtc0_pagegrain();
3343 2423f660 ths
            rn = "PageGrain";
3344 2423f660 ths
            break;
3345 7a387fff ths
        default:
3346 7a387fff ths
            goto die;
3347 876d4b07 ths
        }
3348 8c0fdd85 ths
        break;
3349 8c0fdd85 ths
    case 6:
3350 7a387fff ths
        switch (sel) {
3351 7a387fff ths
        case 0:
3352 2423f660 ths
            gen_op_mtc0_wired();
3353 2423f660 ths
            rn = "Wired";
3354 2423f660 ths
            break;
3355 7a387fff ths
        case 1:
3356 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3357 ead9360e ths
            gen_op_mtc0_srsconf0();
3358 2423f660 ths
            rn = "SRSConf0";
3359 ead9360e ths
            break;
3360 7a387fff ths
        case 2:
3361 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3362 ead9360e ths
            gen_op_mtc0_srsconf1();
3363 2423f660 ths
            rn = "SRSConf1";
3364 ead9360e ths
            break;
3365 7a387fff ths
        case 3:
3366 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3367 ead9360e ths
            gen_op_mtc0_srsconf2();
3368 2423f660 ths
            rn = "SRSConf2";
3369 ead9360e ths
            break;
3370 7a387fff ths
        case 4:
3371 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3372 ead9360e ths
            gen_op_mtc0_srsconf3();
3373 2423f660 ths
            rn = "SRSConf3";
3374 ead9360e ths
            break;
3375 7a387fff ths
        case 5:
3376 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3377 ead9360e ths
            gen_op_mtc0_srsconf4();
3378 2423f660 ths
            rn = "SRSConf4";
3379 ead9360e ths
            break;
3380 7a387fff ths
        default:
3381 7a387fff ths
            goto die;
3382 876d4b07 ths
        }
3383 8c0fdd85 ths
        break;
3384 8c0fdd85 ths
    case 7:
3385 7a387fff ths
        switch (sel) {
3386 7a387fff ths
        case 0:
3387 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3388 2423f660 ths
            gen_op_mtc0_hwrena();
3389 2423f660 ths
            rn = "HWREna";
3390 2423f660 ths
            break;
3391 7a387fff ths
        default:
3392 7a387fff ths
            goto die;
3393 876d4b07 ths
        }
3394 8c0fdd85 ths
        break;
3395 8c0fdd85 ths
    case 8:
3396 7a387fff ths
        /* ignored */
3397 f0b3f3ae ths
        rn = "BadVAddr";
3398 8c0fdd85 ths
        break;
3399 8c0fdd85 ths
    case 9:
3400 7a387fff ths
        switch (sel) {
3401 7a387fff ths
        case 0:
3402 2423f660 ths
            gen_op_mtc0_count();
3403 2423f660 ths
            rn = "Count";
3404 2423f660 ths
            break;
3405 876d4b07 ths
        /* 6,7 are implementation dependent */
3406 7a387fff ths
        default:
3407 7a387fff ths
            goto die;
3408 876d4b07 ths
        }
3409 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3410 876d4b07 ths
        ctx->bstate = BS_STOP;
3411 8c0fdd85 ths
        break;
3412 8c0fdd85 ths
    case 10:
3413 7a387fff ths
        switch (sel) {
3414 7a387fff ths
        case 0:
3415 2423f660 ths
            gen_op_mtc0_entryhi();
3416 2423f660 ths
            rn = "EntryHi";
3417 2423f660 ths
            break;
3418 7a387fff ths
        default:
3419 7a387fff ths
            goto die;
3420 876d4b07 ths
        }
3421 8c0fdd85 ths
        break;
3422 8c0fdd85 ths
    case 11:
3423 7a387fff ths
        switch (sel) {
3424 7a387fff ths
        case 0:
3425 2423f660 ths
            gen_op_mtc0_compare();
3426 2423f660 ths
            rn = "Compare";
3427 2423f660 ths
            break;
3428 2423f660 ths
        /* 6,7 are implementation dependent */
3429 7a387fff ths
        default:
3430 7a387fff ths
            goto die;
3431 876d4b07 ths
        }
3432 4586f9e9 aurel32
        /* Stop translation as we may have switched the execution mode */
3433 4586f9e9 aurel32
        ctx->bstate = BS_STOP;
3434 8c0fdd85 ths
        break;
3435 8c0fdd85 ths
    case 12:
3436 7a387fff ths
        switch (sel) {
3437 7a387fff ths
        case 0:
3438 2423f660 ths
            gen_op_mtc0_status();
3439 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
3440 8487327a ths
            gen_save_pc(ctx->pc + 4);
3441 8487327a ths
            ctx->bstate = BS_EXCP;
3442 2423f660 ths
            rn = "Status";
3443 2423f660 ths
            break;
3444 7a387fff ths
        case 1:
3445 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3446 2423f660 ths
            gen_op_mtc0_intctl();
3447 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3448 8487327a ths
            ctx->bstate = BS_STOP;
3449 2423f660 ths
            rn = "IntCtl";
3450 2423f660 ths
            break;
3451 7a387fff ths
        case 2:
3452 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3453 2423f660 ths
            gen_op_mtc0_srsctl();
3454 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3455 8487327a ths
            ctx->bstate = BS_STOP;
3456 2423f660 ths
            rn = "SRSCtl";
3457 2423f660 ths
            break;
3458 7a387fff ths
        case 3:
3459 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3460 fd88b6ab ths
            gen_op_mtc0_srsmap();
3461 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3462 8487327a ths
            ctx->bstate = BS_STOP;
3463 2423f660 ths
            rn = "SRSMap";
3464 fd88b6ab ths
            break;
3465 7a387fff ths
        default:
3466 7a387fff ths
            goto die;
3467 876d4b07 ths
        }
3468 8c0fdd85 ths
        break;
3469 8c0fdd85 ths
    case 13:
3470 7a387fff ths
        switch (sel) {
3471 7a387fff ths
        case 0:
3472 2423f660 ths
            gen_op_mtc0_cause();
3473 2423f660 ths
            rn = "Cause";
3474 2423f660 ths
            break;
3475 7a387fff ths
        default:
3476 7a387fff ths
            goto die;
3477 876d4b07 ths
        }
3478 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3479 876d4b07 ths
        ctx->bstate = BS_STOP;
3480 8c0fdd85 ths
        break;
3481 8c0fdd85 ths
    case 14:
3482 7a387fff ths
        switch (sel) {
3483 7a387fff ths
        case 0:
3484 2423f660 ths
            gen_op_mtc0_epc();
3485 2423f660 ths
            rn = "EPC";
3486 2423f660 ths
            break;
3487 7a387fff ths
        default:
3488 7a387fff ths
            goto die;
3489 876d4b07 ths
        }
3490 8c0fdd85 ths
        break;
3491 8c0fdd85 ths
    case 15:
3492 7a387fff ths
        switch (sel) {
3493 7a387fff ths
        case 0:
3494 2423f660 ths
            /* ignored */
3495 2423f660 ths
            rn = "PRid";
3496 2423f660 ths
            break;
3497 7a387fff ths
        case 1:
3498 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3499 2423f660 ths
            gen_op_mtc0_ebase();
3500 2423f660 ths
            rn = "EBase";
3501 2423f660 ths
            break;
3502 7a387fff ths
        default:
3503 7a387fff ths
            goto die;
3504 1579a72e ths
        }
3505 8c0fdd85 ths
        break;
3506 8c0fdd85 ths
    case 16:
3507 8c0fdd85 ths
        switch (sel) {
3508 8c0fdd85 ths
        case 0:
3509 e397ee33 ths
            gen_op_mtc0_config0();
3510 7a387fff ths
            rn = "Config";
3511 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3512 2423f660 ths
            ctx->bstate = BS_STOP;
3513 7a387fff ths
            break;
3514 7a387fff ths
        case 1:
3515 e397ee33 ths
            /* ignored, read only */
3516 7a387fff ths
            rn = "Config1";
3517 7a387fff ths
            break;
3518 7a387fff ths
        case 2:
3519 e397ee33 ths
            gen_op_mtc0_config2();
3520 7a387fff ths
            rn = "Config2";
3521 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3522 2423f660 ths
            ctx->bstate = BS_STOP;
3523 8c0fdd85 ths
            break;
3524 7a387fff ths
        case 3:
3525 e397ee33 ths
            /* ignored, read only */
3526 7a387fff ths
            rn = "Config3";
3527 7a387fff ths
            break;
3528 e397ee33 ths
        /* 4,5 are reserved */
3529 e397ee33 ths
        /* 6,7 are implementation dependent */
3530 e397ee33 ths
        case 6:
3531 e397ee33 ths
            /* ignored */
3532 e397ee33 ths
            rn = "Config6";
3533 e397ee33 ths
            break;
3534 e397ee33 ths
        case 7:
3535 e397ee33 ths
            /* ignored */
3536 e397ee33 ths
            rn = "Config7";
3537 e397ee33 ths
            break;
3538 8c0fdd85 ths
        default:
3539 8c0fdd85 ths
            rn = "Invalid config selector";
3540 8c0fdd85 ths
            goto die;
3541 8c0fdd85 ths
        }
3542 8c0fdd85 ths
        break;
3543 8c0fdd85 ths
    case 17:
3544 7a387fff ths
        switch (sel) {
3545 7a387fff ths
        case 0:
3546 2423f660 ths
            /* ignored */
3547 2423f660 ths
            rn = "LLAddr";
3548 2423f660 ths
            break;
3549 7a387fff ths
        default:
3550 7a387fff ths
            goto die;
3551 7a387fff ths
        }
3552 8c0fdd85 ths
        break;
3553 8c0fdd85 ths
    case 18:
3554 7a387fff ths
        switch (sel) {
3555 fd88b6ab ths
        case 0 ... 7:
3556 fd88b6ab ths
            gen_op_mtc0_watchlo(sel);
3557 2423f660 ths
            rn = "WatchLo";
3558 2423f660 ths
            break;
3559 7a387fff ths
        default:
3560 7a387fff ths
            goto die;
3561 7a387fff ths
        }
3562 8c0fdd85 ths
        break;
3563 8c0fdd85 ths
    case 19:
3564 7a387fff ths
        switch (sel) {
3565 fd88b6ab ths
        case 0 ... 7:
3566 fd88b6ab ths
            gen_op_mtc0_watchhi(sel);
3567 2423f660 ths
            rn = "WatchHi";
3568 2423f660 ths
            break;
3569 7a387fff ths
        default:
3570 7a387fff ths
            goto die;
3571 7a387fff ths
        }
3572 8c0fdd85 ths
        break;
3573 8c0fdd85 ths
    case 20:
3574 7a387fff ths
        switch (sel) {
3575 7a387fff ths
        case 0:
3576 d26bc211 ths
#if defined(TARGET_MIPS64)
3577 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
3578 f1b0aa5d ths
            gen_op_mtc0_xcontext();
3579 2423f660 ths
            rn = "XContext";
3580 2423f660 ths
            break;
3581 703eaf37 ths
#endif
3582 7a387fff ths
        default:
3583 7a387fff ths
            goto die;
3584 7a387fff ths
        }
3585 8c0fdd85 ths
        break;
3586 8c0fdd85 ths
    case 21:
3587 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3588 7a387fff ths
        switch (sel) {
3589 7a387fff ths
        case 0:
3590 2423f660 ths
            gen_op_mtc0_framemask();
3591 2423f660 ths
            rn = "Framemask";
3592 2423f660 ths
            break;
3593 7a387fff ths
        default:
3594 7a387fff ths
            goto die;
3595 7a387fff ths
        }
3596 7a387fff ths
        break;
3597 8c0fdd85 ths
    case 22:
3598 7a387fff ths
        /* ignored */
3599 7a387fff ths
        rn = "Diagnostic"; /* implementation dependent */
3600 2423f660 ths
        break;
3601 8c0fdd85 ths
    case 23:
3602 7a387fff ths
        switch (sel) {
3603 7a387fff ths
        case 0:
3604 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
3605 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
3606 8487327a ths
            gen_save_pc(ctx->pc + 4);
3607 8487327a ths
            ctx->bstate = BS_EXCP;
3608 2423f660 ths
            rn = "Debug";
3609 2423f660 ths
            break;
3610 7a387fff ths
        case 1:
3611 2423f660 ths
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3612 2423f660 ths
            rn = "TraceControl";
3613 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3614 8487327a ths
            ctx->bstate = BS_STOP;
3615 2423f660 ths
//            break;
3616 7a387fff ths
        case 2:
3617 2423f660 ths
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3618 2423f660 ths
            rn = "TraceControl2";
3619 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3620 8487327a ths
            ctx->bstate = BS_STOP;
3621 2423f660 ths
//            break;
3622 7a387fff ths
        case 3:
3623 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3624 8487327a ths
            ctx->bstate = BS_STOP;
3625 2423f660 ths
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3626 2423f660 ths
            rn = "UserTraceData";
3627 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3628 8487327a ths
            ctx->bstate = BS_STOP;
3629 2423f660 ths
//            break;
3630 7a387fff ths
        case 4:
3631 2423f660 ths
//            gen_op_mtc0_debug(); /* PDtrace support */
3632 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3633 8487327a ths
            ctx->bstate = BS_STOP;
3634 2423f660 ths
            rn = "TraceBPC";
3635 2423f660 ths
//            break;
3636 7a387fff ths
        default:
3637 7a387fff ths
            goto die;
3638 7a387fff ths
        }
3639 8c0fdd85 ths
        break;
3640 8c0fdd85 ths
    case 24:
3641 7a387fff ths
        switch (sel) {
3642 7a387fff ths
        case 0:
3643 2423f660 ths
            gen_op_mtc0_depc(); /* EJTAG support */
3644 2423f660 ths
            rn = "DEPC";
3645 2423f660 ths
            break;
3646 7a387fff ths
        default:
3647 7a387fff ths
            goto die;
3648 7a387fff ths
        }
3649 8c0fdd85 ths
        break;
3650 8c0fdd85 ths
    case 25:
3651 7a387fff ths
        switch (sel) {
3652 7a387fff ths
        case 0:
3653 2423f660 ths
            gen_op_mtc0_performance0();
3654 2423f660 ths
            rn = "Performance0";
3655 2423f660 ths
            break;
3656 7a387fff ths
        case 1:
3657 2423f660 ths
//            gen_op_mtc0_performance1();
3658 2423f660 ths
            rn = "Performance1";
3659 2423f660 ths
//            break;
3660 7a387fff ths
        case 2:
3661 2423f660 ths
//            gen_op_mtc0_performance2();
3662 2423f660 ths
            rn = "Performance2";
3663 2423f660 ths
//            break;
3664 7a387fff ths
        case 3:
3665 2423f660 ths
//            gen_op_mtc0_performance3();
3666 2423f660 ths
            rn = "Performance3";
3667 2423f660 ths
//            break;
3668 7a387fff ths
        case 4:
3669 2423f660 ths
//            gen_op_mtc0_performance4();
3670 2423f660 ths
            rn = "Performance4";
3671 2423f660 ths
//            break;
3672 7a387fff ths
        case 5:
3673 2423f660 ths
//            gen_op_mtc0_performance5();
3674 2423f660 ths
            rn = "Performance5";
3675 2423f660 ths
//            break;
3676 7a387fff ths
        case 6:
3677 2423f660 ths
//            gen_op_mtc0_performance6();
3678 2423f660 ths
            rn = "Performance6";
3679 2423f660 ths
//            break;
3680 7a387fff ths
        case 7:
3681 2423f660 ths
//            gen_op_mtc0_performance7();
3682 2423f660 ths
            rn = "Performance7";
3683 2423f660 ths
//            break;
3684 7a387fff ths
        default:
3685 7a387fff ths
            goto die;
3686 7a387fff ths
        }
3687 8c0fdd85 ths
       break;
3688 8c0fdd85 ths
    case 26:
3689 2423f660 ths
        /* ignored */
3690 8c0fdd85 ths
        rn = "ECC";
3691 2423f660 ths
        break;
3692 8c0fdd85 ths
    case 27:
3693 7a387fff ths
        switch (sel) {
3694 7a387fff ths
        case 0 ... 3:
3695 2423f660 ths
            /* ignored */
3696 2423f660 ths
            rn = "CacheErr";
3697 2423f660 ths
            break;
3698 7a387fff ths
        default:
3699 7a387fff ths
            goto die;
3700 7a387fff ths
        }
3701 8c0fdd85 ths
       break;
3702 8c0fdd85 ths
    case 28:
3703 8c0fdd85 ths
        switch (sel) {
3704 8c0fdd85 ths
        case 0:
3705 7a387fff ths
        case 2:
3706 7a387fff ths
        case 4:
3707 7a387fff ths
        case 6:
3708 8c0fdd85 ths
            gen_op_mtc0_taglo();
3709 8c0fdd85 ths
            rn = "TagLo";
3710 8c0fdd85 ths
            break;
3711 7a387fff ths
        case 1:
3712 7a387fff ths
        case 3:
3713 7a387fff ths
        case 5:
3714 7a387fff ths
        case 7:
3715 2423f660 ths
            gen_op_mtc0_datalo();
3716 7a387fff ths
            rn = "DataLo";
3717 7a387fff ths
            break;
3718 8c0fdd85 ths
        default:
3719 8c0fdd85 ths
            goto die;
3720 8c0fdd85 ths
        }
3721 8c0fdd85 ths
        break;
3722 8c0fdd85 ths
    case 29:
3723 7a387fff ths
        switch (sel) {
3724 7a387fff ths
        case 0:
3725 7a387fff ths
        case 2:
3726 7a387fff ths
        case 4:
3727 7a387fff ths
        case 6:
3728 7a387fff ths
            gen_op_mtc0_taghi();
3729 7a387fff ths
            rn = "TagHi";
3730 7a387fff ths
            break;
3731 7a387fff ths
        case 1:
3732 7a387fff ths
        case 3:
3733 7a387fff ths
        case 5:
3734 7a387fff ths
        case 7:
3735 2423f660 ths
            gen_op_mtc0_datahi();
3736 7a387fff ths
            rn = "DataHi";
3737 7a387fff ths
            break;
3738 7a387fff ths
        default:
3739 7a387fff ths
            rn = "invalid sel";
3740 7a387fff ths
            goto die;
3741 7a387fff ths
        }
3742 8c0fdd85 ths
       break;
3743 8c0fdd85 ths
    case 30:
3744 7a387fff ths
        switch (sel) {
3745 7a387fff ths
        case 0:
3746 2423f660 ths
            gen_op_mtc0_errorepc();
3747 2423f660 ths
            rn = "ErrorEPC";
3748 2423f660 ths
            break;
3749 7a387fff ths
        default:
3750 7a387fff ths
            goto die;
3751 7a387fff ths
        }
3752 8c0fdd85 ths
        break;
3753 8c0fdd85 ths
    case 31:
3754 7a387fff ths
        switch (sel) {
3755 7a387fff ths
        case 0:
3756 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
3757 2423f660 ths
            rn = "DESAVE";
3758 2423f660 ths
            break;
3759 7a387fff ths
        default:
3760 7a387fff ths
            goto die;
3761 7a387fff ths
        }
3762 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
3763 2423f660 ths
        ctx->bstate = BS_STOP;
3764 8c0fdd85 ths
        break;
3765 8c0fdd85 ths
    default:
3766 8c0fdd85 ths
       goto die;
3767 8c0fdd85 ths
    }
3768 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
3769 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3770 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3771 7a387fff ths
                rn, reg, sel);
3772 8c0fdd85 ths
    }
3773 8c0fdd85 ths
#endif
3774 8c0fdd85 ths
    return;
3775 8c0fdd85 ths
3776 8c0fdd85 ths
die:
3777 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
3778 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3779 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3780 7a387fff ths
                rn, reg, sel);
3781 8c0fdd85 ths
    }
3782 8c0fdd85 ths
#endif
3783 8c0fdd85 ths
    generate_exception(ctx, EXCP_RI);
3784 8c0fdd85 ths
}
3785 8c0fdd85 ths
3786 d26bc211 ths
#if defined(TARGET_MIPS64)
3787 3a95e3a7 ths
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3788 9c2149c8 ths
{
3789 9c2149c8 ths
    const char *rn = "invalid";
3790 f0b3f3ae ths
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
3791 9c2149c8 ths
3792 e189e748 ths
    if (sel != 0)
3793 e189e748 ths
        check_insn(env, ctx, ISA_MIPS64);
3794 e189e748 ths
3795 9c2149c8 ths
    switch (reg) {
3796 9c2149c8 ths
    case 0:
3797 9c2149c8 ths
        switch (sel) {
3798 9c2149c8 ths
        case 0:
3799 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
3800 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3801 9c2149c8 ths
            rn = "Index";
3802 9c2149c8 ths
            break;
3803 9c2149c8 ths
        case 1:
3804 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3805 ead9360e ths
            gen_op_mfc0_mvpcontrol();
3806 9c2149c8 ths
            rn = "MVPControl";
3807 ead9360e ths
            break;
3808 9c2149c8 ths
        case 2:
3809 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3810 ead9360e ths
            gen_op_mfc0_mvpconf0();
3811 9c2149c8 ths
            rn = "MVPConf0";
3812 ead9360e ths
            break;
3813 9c2149c8 ths
        case 3:
3814 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3815 ead9360e ths
            gen_op_mfc0_mvpconf1();
3816 9c2149c8 ths
            rn = "MVPConf1";
3817 ead9360e ths
            break;
3818 9c2149c8 ths
        default:
3819 9c2149c8 ths
            goto die;
3820 9c2149c8 ths
        }
3821 9c2149c8 ths
        break;
3822 9c2149c8 ths
    case 1:
3823 9c2149c8 ths
        switch (sel) {
3824 9c2149c8 ths
        case 0:
3825 9c2149c8 ths
            gen_op_mfc0_random();
3826 9c2149c8 ths
            rn = "Random";
3827 2423f660 ths
            break;
3828 9c2149c8 ths
        case 1:
3829 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3830 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
3831 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3832 9c2149c8 ths
            rn = "VPEControl";
3833 ead9360e ths
            break;
3834 9c2149c8 ths
        case 2:
3835 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3836 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
3837 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3838 9c2149c8 ths
            rn = "VPEConf0";
3839 ead9360e ths
            break;
3840 9c2149c8 ths
        case 3:
3841 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3842 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
3843 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3844 9c2149c8 ths
            rn = "VPEConf1";
3845 ead9360e ths
            break;
3846 9c2149c8 ths
        case 4:
3847 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3848 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask));
3849 9c2149c8 ths
            rn = "YQMask";
3850 ead9360e ths
            break;
3851 9c2149c8 ths
        case 5:
3852 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3853 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
3854 9c2149c8 ths
            rn = "VPESchedule";
3855 ead9360e ths
            break;
3856 9c2149c8 ths
        case 6:
3857 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3858 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3859 9c2149c8 ths
            rn = "VPEScheFBack";
3860 ead9360e ths
            break;
3861 9c2149c8 ths
        case 7:
3862 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3863 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
3864 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3865 9c2149c8 ths
            rn = "VPEOpt";
3866 ead9360e ths
            break;
3867 9c2149c8 ths
        default:
3868 9c2149c8 ths
            goto die;
3869 9c2149c8 ths
        }
3870 9c2149c8 ths
        break;
3871 9c2149c8 ths
    case 2:
3872 9c2149c8 ths
        switch (sel) {
3873 9c2149c8 ths
        case 0:
3874 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
3875 2423f660 ths
            rn = "EntryLo0";
3876 2423f660 ths
            break;
3877 9c2149c8 ths
        case 1:
3878 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3879 ead9360e ths
            gen_op_mfc0_tcstatus();
3880 2423f660 ths
            rn = "TCStatus";
3881 ead9360e ths
            break;
3882 9c2149c8 ths
        case 2:
3883 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3884 ead9360e ths
            gen_op_mfc0_tcbind();
3885 2423f660 ths
            rn = "TCBind";
3886 ead9360e ths
            break;
3887 9c2149c8 ths
        case 3:
3888 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3889 ead9360e ths
            gen_op_dmfc0_tcrestart();
3890 2423f660 ths
            rn = "TCRestart";
3891 ead9360e ths
            break;
3892 9c2149c8 ths
        case 4:
3893 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3894 ead9360e ths
            gen_op_dmfc0_tchalt();
3895 2423f660 ths
            rn = "TCHalt";
3896 ead9360e ths
            break;
3897 9c2149c8 ths
        case 5:
3898 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3899 ead9360e ths
            gen_op_dmfc0_tccontext();
3900 2423f660 ths
            rn = "TCContext";
3901 ead9360e ths
            break;
3902 9c2149c8 ths
        case 6:
3903 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3904 ead9360e ths
            gen_op_dmfc0_tcschedule();
3905 2423f660 ths
            rn = "TCSchedule";
3906 ead9360e ths
            break;
3907 9c2149c8 ths
        case 7:
3908 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3909 ead9360e ths
            gen_op_dmfc0_tcschefback();
3910 2423f660 ths
            rn = "TCScheFBack";
3911 ead9360e ths
            break;
3912 9c2149c8 ths
        default:
3913 9c2149c8 ths
            goto die;
3914 9c2149c8 ths
        }
3915 9c2149c8 ths
        break;
3916 9c2149c8 ths
    case 3:
3917 9c2149c8 ths
        switch (sel) {
3918 9c2149c8 ths
        case 0:
3919 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
3920 2423f660 ths
            rn = "EntryLo1";
3921 2423f660 ths
            break;
3922 9c2149c8 ths
        default:
3923 9c2149c8 ths
            goto die;
3924 1579a72e ths
        }
3925 9c2149c8 ths
        break;
3926 9c2149c8 ths
    case 4:
3927 9c2149c8 ths
        switch (sel) {
3928 9c2149c8 ths
        case 0:
3929 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
3930 2423f660 ths
            rn = "Context";
3931 2423f660 ths
            break;
3932 9c2149c8 ths
        case 1:
3933 2423f660 ths
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3934 2423f660 ths
            rn = "ContextConfig";
3935 2423f660 ths
//            break;
3936 9c2149c8 ths
        default:
3937 9c2149c8 ths
            goto die;
3938 876d4b07 ths
        }
3939 9c2149c8 ths
        break;
3940 9c2149c8 ths
    case 5:
3941 9c2149c8 ths
        switch (sel) {
3942 9c2149c8 ths
        case 0:
3943 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
3944 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3945 2423f660 ths
            rn = "PageMask";
3946 2423f660 ths
            break;
3947 9c2149c8 ths
        case 1:
3948 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3949 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
3950 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3951 2423f660 ths
            rn = "PageGrain";
3952 2423f660 ths
            break;
3953 9c2149c8 ths
        default:
3954 9c2149c8 ths
            goto die;
3955 876d4b07 ths
        }
3956 9c2149c8 ths
        break;
3957 9c2149c8 ths
    case 6:
3958 9c2149c8 ths
        switch (sel) {
3959 9c2149c8 ths
        case 0:
3960 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
3961 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3962 2423f660 ths
            rn = "Wired";
3963 2423f660 ths
            break;
3964 9c2149c8 ths
        case 1:
3965 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3966 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
3967 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3968 2423f660 ths
            rn = "SRSConf0";
3969 ead9360e ths
            break;
3970 9c2149c8 ths
        case 2:
3971 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3972 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
3973 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3974 2423f660 ths
            rn = "SRSConf1";
3975 ead9360e ths
            break;
3976 9c2149c8 ths
        case 3:
3977 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3978 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
3979 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3980 2423f660 ths
            rn = "SRSConf2";
3981 ead9360e ths
            break;
3982 9c2149c8 ths
        case 4:
3983 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3984 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
3985 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3986 2423f660 ths
            rn = "SRSConf3";
3987 ead9360e ths
            break;
3988 9c2149c8 ths
        case 5:
3989 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3990 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
3991 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3992 2423f660 ths
            rn = "SRSConf4";
3993 ead9360e ths
            break;
3994 9c2149c8 ths
        default:
3995 9c2149c8 ths
            goto die;
3996 876d4b07 ths
        }
3997 9c2149c8 ths
        break;
3998 9c2149c8 ths
    case 7:
3999 9c2149c8 ths
        switch (sel) {
4000 9c2149c8 ths
        case 0:
4001 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4002 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
4003 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4004 2423f660 ths
            rn = "HWREna";
4005 2423f660 ths
            break;
4006 9c2149c8 ths
        default:
4007 9c2149c8 ths
            goto die;
4008 876d4b07 ths
        }
4009 9c2149c8 ths
        break;
4010 9c2149c8 ths
    case 8:
4011 9c2149c8 ths
        switch (sel) {
4012 9c2149c8 ths
        case 0:
4013 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
4014 f0b3f3ae ths
            rn = "BadVAddr";
4015 2423f660 ths
            break;
4016 9c2149c8 ths
        default:
4017 9c2149c8 ths
            goto die;
4018 876d4b07 ths
        }
4019 9c2149c8 ths
        break;
4020 9c2149c8 ths
    case 9:
4021 9c2149c8 ths
        switch (sel) {
4022 9c2149c8 ths
        case 0:
4023 2423f660 ths
            gen_op_mfc0_count();
4024 2423f660 ths
            rn = "Count";
4025 2423f660 ths
            break;
4026 2423f660 ths
        /* 6,7 are implementation dependent */
4027 9c2149c8 ths
        default:
4028 9c2149c8 ths
            goto die;
4029 876d4b07 ths
        }
4030 9c2149c8 ths
        break;
4031 9c2149c8 ths
    case 10:
4032 9c2149c8 ths
        switch (sel) {
4033 9c2149c8 ths
        case 0:
4034 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
4035 2423f660 ths
            rn = "EntryHi";
4036 2423f660 ths
            break;
4037 9c2149c8 ths
        default:
4038 9c2149c8 ths
            goto die;
4039 876d4b07 ths
        }
4040 9c2149c8 ths
        break;
4041 9c2149c8 ths
    case 11:
4042 9c2149c8 ths
        switch (sel) {
4043 9c2149c8 ths
        case 0:
4044 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
4045 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4046 2423f660 ths
            rn = "Compare";
4047 2423f660 ths
            break;
4048 876d4b07 ths
        /* 6,7 are implementation dependent */
4049 9c2149c8 ths
        default:
4050 9c2149c8 ths
            goto die;
4051 876d4b07 ths
        }
4052 9c2149c8 ths
        break;
4053 9c2149c8 ths
    case 12:
4054 9c2149c8 ths
        switch (sel) {
4055 9c2149c8 ths
        case 0:
4056 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
4057 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4058 2423f660 ths
            rn = "Status";
4059 2423f660 ths
            break;
4060 9c2149c8 ths
        case 1:
4061 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4062 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
4063 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4064 2423f660 ths
            rn = "IntCtl";
4065 2423f660 ths
            break;
4066 9c2149c8 ths
        case 2:
4067 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4068 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
4069 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4070 2423f660 ths
            rn = "SRSCtl";
4071 2423f660 ths
            break;
4072 9c2149c8 ths
        case 3:
4073 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4074 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
4075 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4076 2423f660 ths
            rn = "SRSMap";
4077 2423f660 ths
            break;
4078 9c2149c8 ths
        default:
4079 9c2149c8 ths
            goto die;
4080 876d4b07 ths
        }
4081 9c2149c8 ths
        break;
4082 9c2149c8 ths
    case 13:
4083 9c2149c8 ths
        switch (sel) {
4084 9c2149c8 ths
        case 0:
4085 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
4086 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4087 2423f660 ths
            rn = "Cause";
4088 2423f660 ths
            break;
4089 9c2149c8 ths
        default:
4090 9c2149c8 ths
            goto die;
4091 876d4b07 ths
        }
4092 9c2149c8 ths
        break;
4093 9c2149c8 ths
    case 14:
4094 9c2149c8 ths
        switch (sel) {
4095 9c2149c8 ths
        case 0:
4096 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4097 2423f660 ths
            rn = "EPC";
4098 2423f660 ths
            break;
4099 9c2149c8 ths
        default:
4100 9c2149c8 ths
            goto die;
4101 876d4b07 ths
        }
4102 9c2149c8 ths
        break;
4103 9c2149c8 ths
    case 15:
4104 9c2149c8 ths
        switch (sel) {
4105 9c2149c8 ths
        case 0:
4106 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
4107 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4108 2423f660 ths
            rn = "PRid";
4109 2423f660 ths
            break;
4110 9c2149c8 ths
        case 1:
4111 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4112 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
4113 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4114 2423f660 ths
            rn = "EBase";
4115 2423f660 ths
            break;
4116 9c2149c8 ths
        default:
4117 9c2149c8 ths
            goto die;
4118 876d4b07 ths
        }
4119 9c2149c8 ths
        break;
4120 9c2149c8 ths
    case 16:
4121 9c2149c8 ths
        switch (sel) {
4122 9c2149c8 ths
        case 0:
4123 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
4124 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4125 9c2149c8 ths
            rn = "Config";
4126 9c2149c8 ths
            break;
4127 9c2149c8 ths
        case 1:
4128 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
4129 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4130 9c2149c8 ths
            rn = "Config1";
4131 9c2149c8 ths
            break;
4132 9c2149c8 ths
        case 2:
4133 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
4134 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4135 9c2149c8 ths
            rn = "Config2";
4136 9c2149c8 ths
            break;
4137 9c2149c8 ths
        case 3:
4138 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
4139 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4140 9c2149c8 ths
            rn = "Config3";
4141 9c2149c8 ths
            break;
4142 9c2149c8 ths
       /* 6,7 are implementation dependent */
4143 f0b3f3ae ths
        case 6:
4144 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
4145 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4146 f0b3f3ae ths
            rn = "Config6";
4147 f0b3f3ae ths
            break;
4148 f0b3f3ae ths
        case 7:
4149 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
4150 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4151 f0b3f3ae ths
            rn = "Config7";
4152 f0b3f3ae ths
            break;
4153 9c2149c8 ths
        default:
4154 9c2149c8 ths
            goto die;
4155 9c2149c8 ths
        }
4156 9c2149c8 ths
        break;
4157 9c2149c8 ths
    case 17:
4158 9c2149c8 ths
        switch (sel) {
4159 9c2149c8 ths
        case 0:
4160 2423f660 ths
            gen_op_dmfc0_lladdr();
4161 2423f660 ths
            rn = "LLAddr";
4162 2423f660 ths
            break;
4163 9c2149c8 ths
        default:
4164 9c2149c8 ths
            goto die;
4165 9c2149c8 ths
        }
4166 9c2149c8 ths
        break;
4167 9c2149c8 ths
    case 18:
4168 9c2149c8 ths
        switch (sel) {
4169 fd88b6ab ths
        case 0 ... 7:
4170 fd88b6ab ths
            gen_op_dmfc0_watchlo(sel);
4171 2423f660 ths
            rn = "WatchLo";
4172 2423f660 ths
            break;
4173 9c2149c8 ths
        default:
4174 9c2149c8 ths
            goto die;
4175 9c2149c8 ths
        }
4176 9c2149c8 ths
        break;
4177 9c2149c8 ths
    case 19:
4178 9c2149c8 ths
        switch (sel) {
4179 fd88b6ab ths
        case 0 ... 7:
4180 fd88b6ab ths
            gen_op_mfc0_watchhi(sel);
4181 2423f660 ths
            rn = "WatchHi";
4182 2423f660 ths
            break;
4183 9c2149c8 ths
        default:
4184 9c2149c8 ths
            goto die;
4185 9c2149c8 ths
        }
4186 9c2149c8 ths
        break;
4187 9c2149c8 ths
    case 20:
4188 9c2149c8 ths
        switch (sel) {
4189 9c2149c8 ths
        case 0:
4190 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
4191 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
4192 2423f660 ths
            rn = "XContext";
4193 2423f660 ths
            break;
4194 9c2149c8 ths
        default:
4195 9c2149c8 ths
            goto die;
4196 9c2149c8 ths
        }
4197 9c2149c8 ths
        break;
4198 9c2149c8 ths
    case 21:
4199 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4200 9c2149c8 ths
        switch (sel) {
4201 9c2149c8 ths
        case 0:
4202 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
4203 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4204 2423f660 ths
            rn = "Framemask";
4205 2423f660 ths
            break;
4206 9c2149c8 ths
        default:
4207 9c2149c8 ths
            goto die;
4208 9c2149c8 ths
        }
4209 9c2149c8 ths
        break;
4210 9c2149c8 ths
    case 22:
4211 2423f660 ths
        /* ignored */
4212 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
4213 2423f660 ths
        break;
4214 9c2149c8 ths
    case 23:
4215 9c2149c8 ths
        switch (sel) {
4216 9c2149c8 ths
        case 0:
4217 2423f660 ths
            gen_op_mfc0_debug(); /* EJTAG support */
4218 2423f660 ths
            rn = "Debug";
4219 2423f660 ths
            break;
4220 9c2149c8 ths
        case 1:
4221 2423f660 ths
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
4222 2423f660 ths
            rn = "TraceControl";
4223 2423f660 ths
//            break;
4224 9c2149c8 ths
        case 2:
4225 2423f660 ths
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
4226 2423f660 ths
            rn = "TraceControl2";
4227 2423f660 ths
//            break;
4228 9c2149c8 ths
        case 3:
4229 2423f660 ths
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
4230 2423f660 ths
            rn = "UserTraceData";
4231 2423f660 ths
//            break;
4232 9c2149c8 ths
        case 4:
4233 2423f660 ths
//            gen_op_dmfc0_debug(); /* PDtrace support */
4234 2423f660 ths
            rn = "TraceBPC";
4235 2423f660 ths
//            break;
4236 9c2149c8 ths
        default:
4237 9c2149c8 ths
            goto die;
4238 9c2149c8 ths
        }
4239 9c2149c8 ths
        break;
4240 9c2149c8 ths
    case 24:
4241 9c2149c8 ths
        switch (sel) {
4242 9c2149c8 ths
        case 0:
4243 f0b3f3ae ths
            /* EJTAG support */
4244 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4245 2423f660 ths
            rn = "DEPC";
4246 2423f660 ths
            break;
4247 9c2149c8 ths
        default:
4248 9c2149c8 ths
            goto die;
4249 9c2149c8 ths
        }
4250 9c2149c8 ths
        break;
4251 9c2149c8 ths
    case 25:
4252 9c2149c8 ths
        switch (sel) {
4253 9c2149c8 ths
        case 0:
4254 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
4255 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4256 2423f660 ths
            rn = "Performance0";
4257 9c2149c8 ths
            break;
4258 9c2149c8 ths
        case 1:
4259 2423f660 ths
//            gen_op_dmfc0_performance1();
4260 2423f660 ths
            rn = "Performance1";
4261 2423f660 ths
//            break;
4262 9c2149c8 ths
        case 2:
4263 2423f660 ths
//            gen_op_dmfc0_performance2();
4264 2423f660 ths
            rn = "Performance2";
4265 2423f660 ths
//            break;
4266 9c2149c8 ths
        case 3:
4267 2423f660 ths
//            gen_op_dmfc0_performance3();
4268 2423f660 ths
            rn = "Performance3";
4269 2423f660 ths
//            break;
4270 9c2149c8 ths
        case 4:
4271 2423f660 ths
//            gen_op_dmfc0_performance4();
4272 2423f660 ths
            rn = "Performance4";
4273 2423f660 ths
//            break;
4274 9c2149c8 ths
        case 5:
4275 2423f660 ths
//            gen_op_dmfc0_performance5();
4276 2423f660 ths
            rn = "Performance5";
4277 2423f660 ths
//            break;
4278 9c2149c8 ths
        case 6:
4279 2423f660 ths
//            gen_op_dmfc0_performance6();
4280 2423f660 ths
            rn = "Performance6";
4281 2423f660 ths
//            break;
4282 9c2149c8 ths
        case 7:
4283 2423f660 ths
//            gen_op_dmfc0_performance7();
4284 2423f660 ths
            rn = "Performance7";
4285 2423f660 ths
//            break;
4286 9c2149c8 ths
        default:
4287 9c2149c8 ths
            goto die;
4288 9c2149c8 ths
        }
4289 9c2149c8 ths
        break;
4290 9c2149c8 ths
    case 26:
4291 9c2149c8 ths
       rn = "ECC";
4292 9c2149c8 ths
       break;
4293 9c2149c8 ths
    case 27:
4294 9c2149c8 ths
        switch (sel) {
4295 9c2149c8 ths
        /* ignored */
4296 9c2149c8 ths
        case 0 ... 3:
4297 2423f660 ths
            rn = "CacheErr";
4298 2423f660 ths
            break;
4299 9c2149c8 ths
        default:
4300 9c2149c8 ths
            goto die;
4301 9c2149c8 ths
        }
4302 9c2149c8 ths
        break;
4303 9c2149c8 ths
    case 28:
4304 9c2149c8 ths
        switch (sel) {
4305 9c2149c8 ths
        case 0:
4306 9c2149c8 ths
        case 2:
4307 9c2149c8 ths
        case 4:
4308 9c2149c8 ths
        case 6:
4309 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
4310 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4311 9c2149c8 ths
            rn = "TagLo";
4312 9c2149c8 ths
            break;
4313 9c2149c8 ths
        case 1:
4314 9c2149c8 ths
        case 3:
4315 9c2149c8 ths
        case 5:
4316 9c2149c8 ths
        case 7:
4317 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
4318 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4319 9c2149c8 ths
            rn = "DataLo";
4320 9c2149c8 ths
            break;
4321 9c2149c8 ths
        default:
4322 9c2149c8 ths
            goto die;
4323 9c2149c8 ths
        }
4324 9c2149c8 ths
        break;
4325 9c2149c8 ths
    case 29:
4326 9c2149c8 ths
        switch (sel) {
4327 9c2149c8 ths
        case 0:
4328 9c2149c8 ths
        case 2:
4329 9c2149c8 ths
        case 4:
4330 9c2149c8 ths
        case 6:
4331 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
4332 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4333 9c2149c8 ths
            rn = "TagHi";
4334 9c2149c8 ths
            break;
4335 9c2149c8 ths
        case 1:
4336 9c2149c8 ths
        case 3:
4337 9c2149c8 ths
        case 5:
4338 9c2149c8 ths
        case 7:
4339 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
4340 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4341 9c2149c8 ths
            rn = "DataHi";
4342 9c2149c8 ths
            break;
4343 9c2149c8 ths
        default:
4344 9c2149c8 ths
            goto die;
4345 9c2149c8 ths
        }
4346 9c2149c8 ths
        break;
4347 9c2149c8 ths
    case 30:
4348 9c2149c8 ths
        switch (sel) {
4349 9c2149c8 ths
        case 0:
4350 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4351 2423f660 ths
            rn = "ErrorEPC";
4352 2423f660 ths
            break;
4353 9c2149c8 ths
        default:
4354 9c2149c8 ths
            goto die;
4355 9c2149c8 ths
        }
4356 9c2149c8 ths
        break;
4357 9c2149c8 ths
    case 31:
4358 9c2149c8 ths
        switch (sel) {
4359 9c2149c8 ths
        case 0:
4360 f0b3f3ae ths
            /* EJTAG support */
4361 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
4362 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4363 2423f660 ths
            rn = "DESAVE";
4364 2423f660 ths
            break;
4365 9c2149c8 ths
        default:
4366 9c2149c8 ths
            goto die;
4367 9c2149c8 ths
        }
4368 9c2149c8 ths
        break;
4369 9c2149c8 ths
    default:
4370 876d4b07 ths
        goto die;
4371 9c2149c8 ths
    }
4372 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4373 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4374 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4375 9c2149c8 ths
                rn, reg, sel);
4376 9c2149c8 ths
    }
4377 9c2149c8 ths
#endif
4378 9c2149c8 ths
    return;
4379 9c2149c8 ths
4380 9c2149c8 ths
die:
4381 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4382 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4383 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4384 9c2149c8 ths
                rn, reg, sel);
4385 9c2149c8 ths
    }
4386 9c2149c8 ths
#endif
4387 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
4388 9c2149c8 ths
}
4389 9c2149c8 ths
4390 3a95e3a7 ths
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4391 9c2149c8 ths
{
4392 9c2149c8 ths
    const char *rn = "invalid";
4393 9c2149c8 ths
4394 e189e748 ths
    if (sel != 0)
4395 e189e748 ths
        check_insn(env, ctx, ISA_MIPS64);
4396 e189e748 ths
4397 9c2149c8 ths
    switch (reg) {
4398 9c2149c8 ths
    case 0:
4399 9c2149c8 ths
        switch (sel) {
4400 9c2149c8 ths
        case 0:
4401 9c2149c8 ths
            gen_op_mtc0_index();
4402 9c2149c8 ths
            rn = "Index";
4403 9c2149c8 ths
            break;
4404 9c2149c8 ths
        case 1:
4405 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4406 ead9360e ths
            gen_op_mtc0_mvpcontrol();
4407 9c2149c8 ths
            rn = "MVPControl";
4408 ead9360e ths
            break;
4409 9c2149c8 ths
        case 2:
4410 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4411 ead9360e ths
            /* ignored */
4412 9c2149c8 ths
            rn = "MVPConf0";
4413 ead9360e ths
            break;
4414 9c2149c8 ths
        case 3:
4415 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4416 ead9360e ths
            /* ignored */
4417 9c2149c8 ths
            rn = "MVPConf1";
4418 ead9360e ths
            break;
4419 9c2149c8 ths
        default:
4420 9c2149c8 ths
            goto die;
4421 9c2149c8 ths
        }
4422 9c2149c8 ths
        break;
4423 9c2149c8 ths
    case 1:
4424 9c2149c8 ths
        switch (sel) {
4425 9c2149c8 ths
        case 0:
4426 2423f660 ths
            /* ignored */
4427 9c2149c8 ths
            rn = "Random";
4428 2423f660 ths
            break;
4429 9c2149c8 ths
        case 1:
4430 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4431 ead9360e ths
            gen_op_mtc0_vpecontrol();
4432 9c2149c8 ths
            rn = "VPEControl";
4433 ead9360e ths
            break;
4434 9c2149c8 ths
        case 2:
4435 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4436 ead9360e ths
            gen_op_mtc0_vpeconf0();
4437 9c2149c8 ths
            rn = "VPEConf0";
4438 ead9360e ths
            break;
4439 9c2149c8 ths
        case 3:
4440 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4441 ead9360e ths
            gen_op_mtc0_vpeconf1();
4442 9c2149c8 ths
            rn = "VPEConf1";
4443 ead9360e ths
            break;
4444 9c2149c8 ths
        case 4:
4445 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4446 ead9360e ths
            gen_op_mtc0_yqmask();
4447 9c2149c8 ths
            rn = "YQMask";
4448 ead9360e ths
            break;
4449 9c2149c8 ths
        case 5:
4450 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4451 ead9360e ths
            gen_op_mtc0_vpeschedule();
4452 9c2149c8 ths
            rn = "VPESchedule";
4453 ead9360e ths
            break;
4454 9c2149c8 ths
        case 6:
4455 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4456 ead9360e ths
            gen_op_mtc0_vpeschefback();
4457 9c2149c8 ths
            rn = "VPEScheFBack";
4458 ead9360e ths
            break;
4459 9c2149c8 ths
        case 7:
4460 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4461 ead9360e ths
            gen_op_mtc0_vpeopt();
4462 9c2149c8 ths
            rn = "VPEOpt";
4463 ead9360e ths
            break;
4464 9c2149c8 ths
        default:
4465 9c2149c8 ths
            goto die;
4466 9c2149c8 ths
        }
4467 9c2149c8 ths
        break;
4468 9c2149c8 ths
    case 2:
4469 9c2149c8 ths
        switch (sel) {
4470 9c2149c8 ths
        case 0:
4471 f1b0aa5d ths
            gen_op_mtc0_entrylo0();
4472 2423f660 ths
            rn = "EntryLo0";
4473 2423f660 ths
            break;
4474 9c2149c8 ths
        case 1:
4475 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4476 ead9360e ths
            gen_op_mtc0_tcstatus();
4477 2423f660 ths
            rn = "TCStatus";
4478 ead9360e ths
            break;
4479 9c2149c8 ths
        case 2:
4480 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4481 ead9360e ths
            gen_op_mtc0_tcbind();
4482 2423f660 ths
            rn = "TCBind";
4483 ead9360e ths
            break;
4484 9c2149c8 ths
        case 3:
4485 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4486 ead9360e ths
            gen_op_mtc0_tcrestart();
4487 2423f660 ths
            rn = "TCRestart";
4488 ead9360e ths
            break;
4489 9c2149c8 ths
        case 4:
4490 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4491 ead9360e ths
            gen_op_mtc0_tchalt();
4492 2423f660 ths
            rn = "TCHalt";
4493 ead9360e ths
            break;
4494 9c2149c8 ths
        case 5:
4495 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4496 ead9360e ths
            gen_op_mtc0_tccontext();
4497 2423f660 ths
            rn = "TCContext";
4498 ead9360e ths
            break;
4499 9c2149c8 ths
        case 6:
4500 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4501 ead9360e ths
            gen_op_mtc0_tcschedule();
4502 2423f660 ths
            rn = "TCSchedule";
4503 ead9360e ths
            break;
4504 9c2149c8 ths
        case 7:
4505 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4506 ead9360e ths
            gen_op_mtc0_tcschefback();
4507 2423f660 ths
            rn = "TCScheFBack";
4508 ead9360e ths
            break;
4509 9c2149c8 ths
        default:
4510 9c2149c8 ths
            goto die;
4511 9c2149c8 ths
        }
4512 9c2149c8 ths
        break;
4513 9c2149c8 ths
    case 3:
4514 9c2149c8 ths
        switch (sel) {
4515 9c2149c8 ths
        case 0:
4516 f1b0aa5d ths
            gen_op_mtc0_entrylo1();
4517 2423f660 ths
            rn = "EntryLo1";
4518 2423f660 ths
            break;
4519 9c2149c8 ths
        default:
4520 9c2149c8 ths
            goto die;
4521 876d4b07 ths
        }
4522 9c2149c8 ths
        break;
4523 9c2149c8 ths
    case 4:
4524 9c2149c8 ths
        switch (sel) {
4525 9c2149c8 ths
        case 0:
4526 f1b0aa5d ths
            gen_op_mtc0_context();
4527 2423f660 ths
            rn = "Context";
4528 2423f660 ths
            break;
4529 9c2149c8 ths
        case 1:
4530 f1b0aa5d ths
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
4531 2423f660 ths
            rn = "ContextConfig";
4532 2423f660 ths
//           break;
4533 9c2149c8 ths
        default:
4534 9c2149c8 ths
            goto die;
4535 876d4b07 ths
        }
4536 9c2149c8 ths
        break;
4537 9c2149c8 ths
    case 5:
4538 9c2149c8 ths
        switch (sel) {
4539 9c2149c8 ths
        case 0:
4540 2423f660 ths
            gen_op_mtc0_pagemask();
4541 2423f660 ths
            rn = "PageMask";
4542 2423f660 ths
            break;
4543 9c2149c8 ths
        case 1:
4544 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4545 2423f660 ths
            gen_op_mtc0_pagegrain();
4546 2423f660 ths
            rn = "PageGrain";
4547 2423f660 ths
            break;
4548 9c2149c8 ths
        default:
4549 9c2149c8 ths
            goto die;
4550 876d4b07 ths
        }
4551 9c2149c8 ths
        break;
4552 9c2149c8 ths
    case 6:
4553 9c2149c8 ths
        switch (sel) {
4554 9c2149c8 ths
        case 0:
4555 2423f660 ths
            gen_op_mtc0_wired();
4556 2423f660 ths
            rn = "Wired";
4557 2423f660 ths
            break;
4558 9c2149c8 ths
        case 1:
4559 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4560 ead9360e ths
            gen_op_mtc0_srsconf0();
4561 2423f660 ths
            rn = "SRSConf0";
4562 ead9360e ths
            break;
4563 9c2149c8 ths
        case 2:
4564 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4565 ead9360e ths
            gen_op_mtc0_srsconf1();
4566 2423f660 ths
            rn = "SRSConf1";
4567 ead9360e ths
            break;
4568 9c2149c8 ths
        case 3:
4569 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4570 ead9360e ths
            gen_op_mtc0_srsconf2();
4571 2423f660 ths
            rn = "SRSConf2";
4572 ead9360e ths
            break;
4573 9c2149c8 ths
        case 4:
4574 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4575 ead9360e ths
            gen_op_mtc0_srsconf3();
4576 2423f660 ths
            rn = "SRSConf3";
4577 ead9360e ths
            break;
4578 9c2149c8 ths
        case 5:
4579 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4580 ead9360e ths
            gen_op_mtc0_srsconf4();
4581 2423f660 ths
            rn = "SRSConf4";
4582 ead9360e ths
            break;
4583 9c2149c8 ths
        default:
4584 9c2149c8 ths
            goto die;
4585 876d4b07 ths
        }
4586 9c2149c8 ths
        break;
4587 9c2149c8 ths
    case 7:
4588 9c2149c8 ths
        switch (sel) {
4589 9c2149c8 ths
        case 0:
4590 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4591 2423f660 ths
            gen_op_mtc0_hwrena();
4592 2423f660 ths
            rn = "HWREna";
4593 2423f660 ths
            break;
4594 9c2149c8 ths
        default:
4595 9c2149c8 ths
            goto die;
4596 876d4b07 ths
        }
4597 9c2149c8 ths
        break;
4598 9c2149c8 ths
    case 8:
4599 9c2149c8 ths
        /* ignored */
4600 f0b3f3ae ths
        rn = "BadVAddr";
4601 9c2149c8 ths
        break;
4602 9c2149c8 ths
    case 9:
4603 9c2149c8 ths
        switch (sel) {
4604 9c2149c8 ths
        case 0:
4605 2423f660 ths
            gen_op_mtc0_count();
4606 2423f660 ths
            rn = "Count";
4607 2423f660 ths
            break;
4608 876d4b07 ths
        /* 6,7 are implementation dependent */
4609 9c2149c8 ths
        default:
4610 9c2149c8 ths
            goto die;
4611 876d4b07 ths
        }
4612 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
4613 876d4b07 ths
        ctx->bstate = BS_STOP;
4614 9c2149c8 ths
        break;
4615 9c2149c8 ths
    case 10:
4616 9c2149c8 ths
        switch (sel) {
4617 9c2149c8 ths
        case 0:
4618 2423f660 ths
            gen_op_mtc0_entryhi();
4619 2423f660 ths
            rn = "EntryHi";
4620 2423f660 ths
            break;
4621 9c2149c8 ths
        default:
4622 9c2149c8 ths
            goto die;
4623 876d4b07 ths
        }
4624 9c2149c8 ths
        break;
4625 9c2149c8 ths
    case 11:
4626 9c2149c8 ths
        switch (sel) {
4627 9c2149c8 ths
        case 0:
4628 2423f660 ths
            gen_op_mtc0_compare();
4629 2423f660 ths
            rn = "Compare";
4630 2423f660 ths
            break;
4631 876d4b07 ths
        /* 6,7 are implementation dependent */
4632 9c2149c8 ths
        default:
4633 9c2149c8 ths
            goto die;
4634 876d4b07 ths
        }
4635 4586f9e9 aurel32
        /* Stop translation as we may have switched the execution mode */
4636 4586f9e9 aurel32
        ctx->bstate = BS_STOP;
4637 9c2149c8 ths
        break;
4638 9c2149c8 ths
    case 12:
4639 9c2149c8 ths
        switch (sel) {
4640 9c2149c8 ths
        case 0:
4641 2423f660 ths
            gen_op_mtc0_status();
4642 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
4643 8487327a ths
            gen_save_pc(ctx->pc + 4);
4644 8487327a ths
            ctx->bstate = BS_EXCP;
4645 2423f660 ths
            rn = "Status";
4646 2423f660 ths
            break;
4647 9c2149c8 ths
        case 1:
4648 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4649 2423f660 ths
            gen_op_mtc0_intctl();
4650 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4651 8487327a ths
            ctx->bstate = BS_STOP;
4652 2423f660 ths
            rn = "IntCtl";
4653 2423f660 ths
            break;
4654 9c2149c8 ths
        case 2:
4655 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4656 2423f660 ths
            gen_op_mtc0_srsctl();
4657 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4658 8487327a ths
            ctx->bstate = BS_STOP;
4659 2423f660 ths
            rn = "SRSCtl";
4660 2423f660 ths
            break;
4661 9c2149c8 ths
        case 3:
4662 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4663 fd88b6ab ths
            gen_op_mtc0_srsmap();
4664 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4665 8487327a ths
            ctx->bstate = BS_STOP;
4666 2423f660 ths
            rn = "SRSMap";
4667 2423f660 ths
            break;
4668 2423f660 ths
        default:
4669 9c2149c8 ths
            goto die;
4670 876d4b07 ths
        }
4671 9c2149c8 ths
        break;
4672 9c2149c8 ths
    case 13:
4673 9c2149c8 ths
        switch (sel) {
4674 9c2149c8 ths
        case 0:
4675 2423f660 ths
            gen_op_mtc0_cause();
4676 2423f660 ths
            rn = "Cause";
4677 2423f660 ths
            break;
4678 9c2149c8 ths
        default:
4679 9c2149c8 ths
            goto die;
4680 876d4b07 ths
        }
4681 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
4682 876d4b07 ths
        ctx->bstate = BS_STOP;
4683 9c2149c8 ths
        break;
4684 9c2149c8 ths
    case 14:
4685 9c2149c8 ths
        switch (sel) {
4686 9c2149c8 ths
        case 0:
4687 f1b0aa5d ths
            gen_op_mtc0_epc();
4688 2423f660 ths
            rn = "EPC";
4689 2423f660 ths
            break;
4690 9c2149c8 ths
        default:
4691 9c2149c8 ths
            goto die;
4692 876d4b07 ths
        }
4693 9c2149c8 ths
        break;
4694 9c2149c8 ths
    case 15:
4695 9c2149c8 ths
        switch (sel) {
4696 9c2149c8 ths
        case 0:
4697 2423f660 ths
            /* ignored */
4698 2423f660 ths
            rn = "PRid";
4699 2423f660 ths
            break;
4700 9c2149c8 ths
        case 1:
4701 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4702 2423f660 ths
            gen_op_mtc0_ebase();
4703 2423f660 ths
            rn = "EBase";
4704 2423f660 ths
            break;
4705 9c2149c8 ths
        default:
4706 9c2149c8 ths
            goto die;
4707 876d4b07 ths
        }
4708 9c2149c8 ths
        break;
4709 9c2149c8 ths
    case 16:
4710 9c2149c8 ths
        switch (sel) {
4711 9c2149c8 ths
        case 0:
4712 9c2149c8 ths
            gen_op_mtc0_config0();
4713 9c2149c8 ths
            rn = "Config";
4714 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
4715 2423f660 ths
            ctx->bstate = BS_STOP;
4716 9c2149c8 ths
            break;
4717 9c2149c8 ths
        case 1:
4718 2423f660 ths
            /* ignored */
4719 9c2149c8 ths
            rn = "Config1";
4720 9c2149c8 ths
            break;
4721 9c2149c8 ths
        case 2:
4722 9c2149c8 ths
            gen_op_mtc0_config2();
4723 9c2149c8 ths
            rn = "Config2";
4724 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
4725 2423f660 ths
            ctx->bstate = BS_STOP;
4726 9c2149c8 ths
            break;
4727 9c2149c8 ths
        case 3:
4728 2423f660 ths
            /* ignored */
4729 9c2149c8 ths
            rn = "Config3";
4730 9c2149c8 ths
            break;
4731 9c2149c8 ths
        /* 6,7 are implementation dependent */
4732 9c2149c8 ths
        default:
4733 9c2149c8 ths
            rn = "Invalid config selector";
4734 9c2149c8 ths
            goto die;
4735 9c2149c8 ths
        }
4736 9c2149c8 ths
        break;
4737 9c2149c8 ths
    case 17:
4738 9c2149c8 ths
        switch (sel) {
4739 9c2149c8 ths
        case 0:
4740 2423f660 ths
            /* ignored */
4741 2423f660 ths
            rn = "LLAddr";
4742 2423f660 ths
            break;
4743 9c2149c8 ths
        default:
4744 9c2149c8 ths
            goto die;
4745 9c2149c8 ths
        }
4746 9c2149c8 ths
        break;
4747 9c2149c8 ths
    case 18:
4748 9c2149c8 ths
        switch (sel) {
4749 fd88b6ab ths
        case 0 ... 7:
4750 fd88b6ab ths
            gen_op_mtc0_watchlo(sel);
4751 2423f660 ths
            rn = "WatchLo";
4752 2423f660 ths
            break;
4753 9c2149c8 ths
        default:
4754 9c2149c8 ths
            goto die;
4755 9c2149c8 ths
        }
4756 9c2149c8 ths
        break;
4757 9c2149c8 ths
    case 19:
4758 9c2149c8 ths
        switch (sel) {
4759 fd88b6ab ths
        case 0 ... 7:
4760 fd88b6ab ths
            gen_op_mtc0_watchhi(sel);
4761 2423f660 ths
            rn = "WatchHi";
4762 2423f660 ths
            break;
4763 9c2149c8 ths
        default:
4764 9c2149c8 ths
            goto die;
4765 9c2149c8 ths
        }
4766 9c2149c8 ths
        break;
4767 9c2149c8 ths
    case 20:
4768 9c2149c8 ths
        switch (sel) {
4769 9c2149c8 ths
        case 0:
4770 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
4771 f1b0aa5d ths
            gen_op_mtc0_xcontext();
4772 2423f660 ths
            rn = "XContext";
4773 2423f660 ths
            break;
4774 9c2149c8 ths
        default:
4775 9c2149c8 ths
            goto die;
4776 9c2149c8 ths
        }
4777 9c2149c8 ths
        break;
4778 9c2149c8 ths
    case 21:
4779 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4780 9c2149c8 ths
        switch (sel) {
4781 9c2149c8 ths
        case 0:
4782 2423f660 ths
            gen_op_mtc0_framemask();
4783 2423f660 ths
            rn = "Framemask";
4784 2423f660 ths
            break;
4785 9c2149c8 ths
        default:
4786 9c2149c8 ths
            goto die;
4787 9c2149c8 ths
        }
4788 9c2149c8 ths
        break;
4789 9c2149c8 ths
    case 22:
4790 9c2149c8 ths
        /* ignored */
4791 9c2149c8 ths
        rn = "Diagnostic"; /* implementation dependent */
4792 876d4b07 ths
        break;
4793 9c2149c8 ths
    case 23:
4794 9c2149c8 ths
        switch (sel) {
4795 9c2149c8 ths
        case 0:
4796 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
4797 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
4798 8487327a ths
            gen_save_pc(ctx->pc + 4);
4799 8487327a ths
            ctx->bstate = BS_EXCP;
4800 2423f660 ths
            rn = "Debug";
4801 2423f660 ths
            break;
4802 9c2149c8 ths
        case 1:
4803 f1b0aa5d ths
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4804 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4805 8487327a ths
            ctx->bstate = BS_STOP;
4806 2423f660 ths
            rn = "TraceControl";
4807 2423f660 ths
//            break;
4808 9c2149c8 ths
        case 2:
4809 f1b0aa5d ths
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4810 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4811 8487327a ths
            ctx->bstate = BS_STOP;
4812 2423f660 ths
            rn = "TraceControl2";
4813 2423f660 ths
//            break;
4814 9c2149c8 ths
        case 3:
4815 f1b0aa5d ths
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4816 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4817 8487327a ths
            ctx->bstate = BS_STOP;
4818 2423f660 ths
            rn = "UserTraceData";
4819 2423f660 ths
//            break;
4820 9c2149c8 ths
        case 4:
4821 f1b0aa5d ths
//            gen_op_mtc0_debug(); /* PDtrace support */
4822 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4823 8487327a ths
            ctx->bstate = BS_STOP;
4824 2423f660 ths
            rn = "TraceBPC";
4825 2423f660 ths
//            break;
4826 9c2149c8 ths
        default:
4827 9c2149c8 ths
            goto die;
4828 9c2149c8 ths
        }
4829 9c2149c8 ths
        break;
4830 9c2149c8 ths
    case 24:
4831 9c2149c8 ths
        switch (sel) {
4832 9c2149c8 ths
        case 0:
4833 f1b0aa5d ths
            gen_op_mtc0_depc(); /* EJTAG support */
4834 2423f660 ths
            rn = "DEPC";
4835 2423f660 ths
            break;
4836 9c2149c8 ths
        default:
4837 9c2149c8 ths
            goto die;
4838 9c2149c8 ths
        }
4839 9c2149c8 ths
        break;
4840 9c2149c8 ths
    case 25:
4841 9c2149c8 ths
        switch (sel) {
4842 9c2149c8 ths
        case 0:
4843 2423f660 ths
            gen_op_mtc0_performance0();
4844 2423f660 ths
            rn = "Performance0";
4845 2423f660 ths
            break;
4846 9c2149c8 ths
        case 1:
4847 f1b0aa5d ths
//            gen_op_mtc0_performance1();
4848 2423f660 ths
            rn = "Performance1";
4849 2423f660 ths
//            break;
4850 9c2149c8 ths
        case 2:
4851 f1b0aa5d ths
//            gen_op_mtc0_performance2();
4852 2423f660 ths
            rn = "Performance2";
4853 2423f660 ths
//            break;
4854 9c2149c8 ths
        case 3:
4855 f1b0aa5d ths
//            gen_op_mtc0_performance3();
4856 2423f660 ths
            rn = "Performance3";
4857 2423f660 ths
//            break;
4858 9c2149c8 ths
        case 4:
4859 f1b0aa5d ths
//            gen_op_mtc0_performance4();
4860 2423f660 ths
            rn = "Performance4";
4861 2423f660 ths
//            break;
4862 9c2149c8 ths
        case 5:
4863 f1b0aa5d ths
//            gen_op_mtc0_performance5();
4864 2423f660 ths
            rn = "Performance5";
4865 2423f660 ths
//            break;
4866 9c2149c8 ths
        case 6:
4867 f1b0aa5d ths
//            gen_op_mtc0_performance6();
4868 2423f660 ths
            rn = "Performance6";
4869 2423f660 ths
//            break;
4870 9c2149c8 ths
        case 7:
4871 f1b0aa5d ths
//            gen_op_mtc0_performance7();
4872 2423f660 ths
            rn = "Performance7";
4873 2423f660 ths
//            break;
4874 9c2149c8 ths
        default:
4875 9c2149c8 ths
            goto die;
4876 9c2149c8 ths
        }
4877 876d4b07 ths
        break;
4878 9c2149c8 ths
    case 26:
4879 876d4b07 ths
        /* ignored */
4880 9c2149c8 ths
        rn = "ECC";
4881 876d4b07 ths
        break;
4882 9c2149c8 ths
    case 27:
4883 9c2149c8 ths
        switch (sel) {
4884 9c2149c8 ths
        case 0 ... 3:
4885 2423f660 ths
            /* ignored */
4886 2423f660 ths
            rn = "CacheErr";
4887 2423f660 ths
            break;
4888 9c2149c8 ths
        default:
4889 9c2149c8 ths
            goto die;
4890 9c2149c8 ths
        }
4891 876d4b07 ths
        break;
4892 9c2149c8 ths
    case 28:
4893 9c2149c8 ths
        switch (sel) {
4894 9c2149c8 ths
        case 0:
4895 9c2149c8 ths
        case 2:
4896 9c2149c8 ths
        case 4:
4897 9c2149c8 ths
        case 6:
4898 9c2149c8 ths
            gen_op_mtc0_taglo();
4899 9c2149c8 ths
            rn = "TagLo";
4900 9c2149c8 ths
            break;
4901 9c2149c8 ths
        case 1:
4902 9c2149c8 ths
        case 3:
4903 9c2149c8 ths
        case 5:
4904 9c2149c8 ths
        case 7:
4905 2423f660 ths
            gen_op_mtc0_datalo();
4906 9c2149c8 ths
            rn = "DataLo";
4907 9c2149c8 ths
            break;
4908 9c2149c8 ths
        default:
4909 9c2149c8 ths
            goto die;
4910 9c2149c8 ths
        }
4911 9c2149c8 ths
        break;
4912 9c2149c8 ths
    case 29:
4913 9c2149c8 ths
        switch (sel) {
4914 9c2149c8 ths
        case 0:
4915 9c2149c8 ths
        case 2:
4916 9c2149c8 ths
        case 4:
4917 9c2149c8 ths
        case 6:
4918 9c2149c8 ths
            gen_op_mtc0_taghi();
4919 9c2149c8 ths
            rn = "TagHi";
4920 9c2149c8 ths
            break;
4921 9c2149c8 ths
        case 1:
4922 9c2149c8 ths
        case 3:
4923 9c2149c8 ths
        case 5:
4924 9c2149c8 ths
        case 7:
4925 2423f660 ths
            gen_op_mtc0_datahi();
4926 9c2149c8 ths
            rn = "DataHi";
4927 9c2149c8 ths
            break;
4928 9c2149c8 ths
        default:
4929 9c2149c8 ths
            rn = "invalid sel";
4930 9c2149c8 ths
            goto die;
4931 9c2149c8 ths
        }
4932 876d4b07 ths
        break;
4933 9c2149c8 ths
    case 30:
4934 9c2149c8 ths
        switch (sel) {
4935 9c2149c8 ths
        case 0:
4936 f1b0aa5d ths
            gen_op_mtc0_errorepc();
4937 2423f660 ths
            rn = "ErrorEPC";
4938 2423f660 ths
            break;
4939 9c2149c8 ths
        default:
4940 9c2149c8 ths
            goto die;
4941 9c2149c8 ths
        }
4942 9c2149c8 ths
        break;
4943 9c2149c8 ths
    case 31:
4944 9c2149c8 ths
        switch (sel) {
4945 9c2149c8 ths
        case 0:
4946 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
4947 2423f660 ths
            rn = "DESAVE";
4948 2423f660 ths
            break;
4949 9c2149c8 ths
        default:
4950 9c2149c8 ths
            goto die;
4951 9c2149c8 ths
        }
4952 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
4953 876d4b07 ths
        ctx->bstate = BS_STOP;
4954 9c2149c8 ths
        break;
4955 9c2149c8 ths
    default:
4956 876d4b07 ths
        goto die;
4957 9c2149c8 ths
    }
4958 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4959 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4960 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4961 9c2149c8 ths
                rn, reg, sel);
4962 9c2149c8 ths
    }
4963 9c2149c8 ths
#endif
4964 9c2149c8 ths
    return;
4965 9c2149c8 ths
4966 9c2149c8 ths
die:
4967 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4968 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4969 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4970 9c2149c8 ths
                rn, reg, sel);
4971 9c2149c8 ths
    }
4972 9c2149c8 ths
#endif
4973 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
4974 9c2149c8 ths
}
4975 d26bc211 ths
#endif /* TARGET_MIPS64 */
4976 9c2149c8 ths
4977 ead9360e ths
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4978 ead9360e ths
                     int u, int sel, int h)
4979 ead9360e ths
{
4980 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4981 ead9360e ths
4982 ead9360e ths
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4983 ead9360e ths
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4984 ead9360e ths
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4985 8e9ade68 ths
        tcg_gen_movi_tl(cpu_T[0], -1);
4986 ead9360e ths
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4987 ead9360e ths
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4988 8e9ade68 ths
        tcg_gen_movi_tl(cpu_T[0], -1);
4989 ead9360e ths
    else if (u == 0) {
4990 ead9360e ths
        switch (rt) {
4991 ead9360e ths
        case 2:
4992 ead9360e ths
            switch (sel) {
4993 ead9360e ths
            case 1:
4994 ead9360e ths
                gen_op_mftc0_tcstatus();
4995 ead9360e ths
                break;
4996 ead9360e ths
            case 2:
4997 ead9360e ths
                gen_op_mftc0_tcbind();
4998 ead9360e ths
                break;
4999 ead9360e ths
            case 3:
5000 ead9360e ths
                gen_op_mftc0_tcrestart();
5001 ead9360e ths
                break;
5002 ead9360e ths
            case 4:
5003 ead9360e ths
                gen_op_mftc0_tchalt();
5004 ead9360e ths
                break;
5005 ead9360e ths
            case 5:
5006 ead9360e ths
                gen_op_mftc0_tccontext();
5007 ead9360e ths
                break;
5008 ead9360e ths
            case 6:
5009 ead9360e ths
                gen_op_mftc0_tcschedule();
5010 ead9360e ths
                break;
5011 ead9360e ths
            case 7:
5012 ead9360e ths
                gen_op_mftc0_tcschefback();
5013 ead9360e ths
                break;
5014 ead9360e ths
            default:
5015 ead9360e ths
                gen_mfc0(env, ctx, rt, sel);
5016 ead9360e ths
                break;
5017 ead9360e ths
            }
5018 ead9360e ths
            break;
5019 ead9360e ths
        case 10:
5020 ead9360e ths
            switch (sel) {
5021 ead9360e ths
            case 0:
5022 ead9360e ths
                gen_op_mftc0_entryhi();
5023 ead9360e ths
                break;
5024 ead9360e ths
            default:
5025 ead9360e ths
                gen_mfc0(env, ctx, rt, sel);
5026 ead9360e ths
                break;
5027 ead9360e ths
            }
5028 ead9360e ths
        case 12:
5029 ead9360e ths
            switch (sel) {
5030 ead9360e ths
            case 0:
5031 ead9360e ths
                gen_op_mftc0_status();
5032 ead9360e ths
                break;
5033 ead9360e ths
            default:
5034 ead9360e ths
                gen_mfc0(env, ctx, rt, sel);
5035 ead9360e ths
                break;
5036 ead9360e ths
            }
5037 ead9360e ths
        case 23:
5038 ead9360e ths
            switch (sel) {
5039 ead9360e ths
            case 0:
5040 ead9360e ths
                gen_op_mftc0_debug();
5041 ead9360e ths
                break;
5042 ead9360e ths
            default:
5043 ead9360e ths
                gen_mfc0(env, ctx, rt, sel);
5044 ead9360e ths
                break;
5045 ead9360e ths
            }
5046 ead9360e ths
            break;
5047 ead9360e ths
        default:
5048 ead9360e ths
            gen_mfc0(env, ctx, rt, sel);
5049 ead9360e ths
        }
5050 ead9360e ths
    } else switch (sel) {
5051 ead9360e ths
    /* GPR registers. */
5052 ead9360e ths
    case 0:
5053 ead9360e ths
        gen_op_mftgpr(rt);
5054 ead9360e ths
        break;
5055 ead9360e ths
    /* Auxiliary CPU registers */
5056 ead9360e ths
    case 1:
5057 ead9360e ths
        switch (rt) {
5058 ead9360e ths
        case 0:
5059 ead9360e ths
            gen_op_mftlo(0);
5060 ead9360e ths
            break;
5061 ead9360e ths
        case 1:
5062 ead9360e ths
            gen_op_mfthi(0);
5063 ead9360e ths
            break;
5064 ead9360e ths
        case 2:
5065 ead9360e ths
            gen_op_mftacx(0);
5066 ead9360e ths
            break;
5067 ead9360e ths
        case 4:
5068 ead9360e ths
            gen_op_mftlo(1);
5069 ead9360e ths
            break;
5070 ead9360e ths
        case 5:
5071 ead9360e ths
            gen_op_mfthi(1);
5072 ead9360e ths
            break;
5073 ead9360e ths
        case 6:
5074 ead9360e ths
            gen_op_mftacx(1);
5075 ead9360e ths
            break;
5076 ead9360e ths
        case 8:
5077 ead9360e ths
            gen_op_mftlo(2);
5078 ead9360e ths
            break;
5079 ead9360e ths
        case 9:
5080 ead9360e ths
            gen_op_mfthi(2);
5081 ead9360e ths
            break;
5082 ead9360e ths
        case 10:
5083 ead9360e ths
            gen_op_mftacx(2);
5084 ead9360e ths
            break;
5085 ead9360e ths
        case 12:
5086 ead9360e ths
            gen_op_mftlo(3);
5087 ead9360e ths
            break;
5088 ead9360e ths
        case 13:
5089 ead9360e ths
            gen_op_mfthi(3);
5090 ead9360e ths
            break;
5091 ead9360e ths
        case 14:
5092 ead9360e ths
            gen_op_mftacx(3);
5093 ead9360e ths
            break;
5094 ead9360e ths
        case 16:
5095 ead9360e ths
            gen_op_mftdsp();
5096 ead9360e ths
            break;
5097 ead9360e ths
        default:
5098 ead9360e ths
            goto die;
5099 ead9360e ths
        }
5100 ead9360e ths
        break;
5101 ead9360e ths
    /* Floating point (COP1). */
5102 ead9360e ths
    case 2:
5103 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5104 ead9360e ths
        if (h == 0) {
5105 ead9360e ths
            GEN_LOAD_FREG_FTN(WT0, rt);
5106 ead9360e ths
            gen_op_mfc1();
5107 ead9360e ths
        } else {
5108 ead9360e ths
            GEN_LOAD_FREG_FTN(WTH0, rt);
5109 ead9360e ths
            gen_op_mfhc1();
5110 ead9360e ths
        }
5111 ead9360e ths
        break;
5112 ead9360e ths
    case 3:
5113 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5114 ead9360e ths
        gen_op_cfc1(rt);
5115 ead9360e ths
        break;
5116 ead9360e ths
    /* COP2: Not implemented. */
5117 ead9360e ths
    case 4:
5118 ead9360e ths
    case 5:
5119 ead9360e ths
        /* fall through */
5120 ead9360e ths
    default:
5121 ead9360e ths
        goto die;
5122 ead9360e ths
    }
5123 ead9360e ths
#if defined MIPS_DEBUG_DISAS
5124 ead9360e ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5125 ead9360e ths
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5126 ead9360e ths
                rt, u, sel, h);
5127 ead9360e ths
    }
5128 ead9360e ths
#endif
5129 ead9360e ths
    return;
5130 ead9360e ths
5131 ead9360e ths
die:
5132 ead9360e ths
#if defined MIPS_DEBUG_DISAS
5133 ead9360e ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5134 ead9360e ths
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5135 ead9360e ths
                rt, u, sel, h);
5136 ead9360e ths
    }
5137 ead9360e ths
#endif
5138 ead9360e ths
    generate_exception(ctx, EXCP_RI);
5139 ead9360e ths
}
5140 ead9360e ths
5141 ead9360e ths
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5142 ead9360e ths
                     int u, int sel, int h)
5143 ead9360e ths
{
5144 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5145 ead9360e ths
5146 ead9360e ths
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5147 ead9360e ths
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
5148 ead9360e ths
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
5149 ead9360e ths
        /* NOP */ ;
5150 ead9360e ths
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5151 ead9360e ths
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5152 ead9360e ths
        /* NOP */ ;
5153 ead9360e ths
    else if (u == 0) {
5154 ead9360e ths
        switch (rd) {
5155 ead9360e ths
        case 2:
5156 ead9360e ths
            switch (sel) {
5157 ead9360e ths
            case 1:
5158 ead9360e ths
                gen_op_mttc0_tcstatus();
5159 ead9360e ths
                break;
5160 ead9360e ths
            case 2:
5161 ead9360e ths
                gen_op_mttc0_tcbind();
5162 ead9360e ths
                break;
5163 ead9360e ths
            case 3:
5164 ead9360e ths
                gen_op_mttc0_tcrestart();
5165 ead9360e ths
                break;
5166 ead9360e ths
            case 4:
5167 ead9360e ths
                gen_op_mttc0_tchalt();
5168 ead9360e ths
                break;
5169 ead9360e ths
            case 5:
5170 ead9360e ths
                gen_op_mttc0_tccontext();
5171 ead9360e ths
                break;
5172 ead9360e ths
            case 6:
5173 ead9360e ths
                gen_op_mttc0_tcschedule();
5174 ead9360e ths
                break;
5175 ead9360e ths
            case 7:
5176 ead9360e ths
                gen_op_mttc0_tcschefback();
5177 ead9360e ths
                break;
5178 ead9360e ths
            default:
5179 ead9360e ths
                gen_mtc0(env, ctx, rd, sel);
5180 ead9360e ths
                break;
5181 ead9360e ths
            }
5182 ead9360e ths
            break;
5183 ead9360e ths
        case 10:
5184 ead9360e ths
            switch (sel) {
5185 ead9360e ths
            case 0:
5186 ead9360e ths
                gen_op_mttc0_entryhi();
5187 ead9360e ths
                break;
5188 ead9360e ths
            default:
5189 ead9360e ths
                gen_mtc0(env, ctx, rd, sel);
5190 ead9360e ths
                break;
5191 ead9360e ths
            }
5192 ead9360e ths
        case 12:
5193 ead9360e ths
            switch (sel) {
5194 ead9360e ths
            case 0:
5195 ead9360e ths
                gen_op_mttc0_status();
5196 ead9360e ths
                break;
5197 ead9360e ths
            default:
5198 ead9360e ths
                gen_mtc0(env, ctx, rd, sel);
5199 ead9360e ths
                break;
5200 ead9360e ths
            }
5201 ead9360e ths
        case 23:
5202 ead9360e ths
            switch (sel) {
5203 ead9360e ths
            case 0:
5204 ead9360e ths
                gen_op_mttc0_debug();
5205 ead9360e ths
                break;
5206 ead9360e ths
            default:
5207 ead9360e ths
                gen_mtc0(env, ctx, rd, sel);
5208 ead9360e ths
                break;
5209 ead9360e ths
            }
5210 ead9360e ths
            break;
5211 ead9360e ths
        default:
5212 ead9360e ths
            gen_mtc0(env, ctx, rd, sel);
5213 ead9360e ths
        }
5214 ead9360e ths
    } else switch (sel) {
5215 ead9360e ths
    /* GPR registers. */
5216 ead9360e ths
    case 0:
5217 ead9360e ths
        gen_op_mttgpr(rd);
5218 ead9360e ths
        break;
5219 ead9360e ths
    /* Auxiliary CPU registers */
5220 ead9360e ths
    case 1:
5221 ead9360e ths
        switch (rd) {
5222 ead9360e ths
        case 0:
5223 ead9360e ths
            gen_op_mttlo(0);
5224 ead9360e ths
            break;
5225 ead9360e ths
        case 1:
5226 ead9360e ths
            gen_op_mtthi(0);
5227 ead9360e ths
            break;
5228 ead9360e ths
        case 2:
5229 ead9360e ths
            gen_op_mttacx(0);
5230 ead9360e ths
            break;
5231 ead9360e ths
        case 4:
5232 ead9360e ths
            gen_op_mttlo(1);
5233 ead9360e ths
            break;
5234 ead9360e ths
        case 5:
5235 ead9360e ths
            gen_op_mtthi(1);
5236 ead9360e ths
            break;
5237 ead9360e ths
        case 6:
5238 ead9360e ths
            gen_op_mttacx(1);
5239 ead9360e ths
            break;
5240 ead9360e ths
        case 8:
5241 ead9360e ths
            gen_op_mttlo(2);
5242 ead9360e ths
            break;
5243 ead9360e ths
        case 9:
5244 ead9360e ths
            gen_op_mtthi(2);
5245 ead9360e ths
            break;
5246 ead9360e ths
        case 10:
5247 ead9360e ths
            gen_op_mttacx(2);
5248 ead9360e ths
            break;
5249 ead9360e ths
        case 12:
5250 ead9360e ths
            gen_op_mttlo(3);
5251 ead9360e ths
            break;
5252 ead9360e ths
        case 13:
5253 ead9360e ths
            gen_op_mtthi(3);
5254 ead9360e ths
            break;
5255 ead9360e ths
        case 14:
5256 ead9360e ths
            gen_op_mttacx(3);
5257 ead9360e ths
            break;
5258 ead9360e ths
        case 16:
5259 ead9360e ths
            gen_op_mttdsp();
5260 ead9360e ths
            break;
5261 ead9360e ths
        default:
5262 ead9360e ths
            goto die;
5263 ead9360e ths
        }
5264 ead9360e ths
        break;
5265 ead9360e ths
    /* Floating point (COP1). */
5266 ead9360e ths
    case 2:
5267 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5268 ead9360e ths
        if (h == 0) {
5269 ead9360e ths
            gen_op_mtc1();
5270 ead9360e ths
            GEN_STORE_FTN_FREG(rd, WT0);
5271 ead9360e ths
        } else {
5272 ead9360e ths
            gen_op_mthc1();
5273 ead9360e ths
            GEN_STORE_FTN_FREG(rd, WTH0);
5274 ead9360e ths
        }
5275 ead9360e ths
        break;
5276 ead9360e ths
    case 3:
5277 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5278 ead9360e ths
        gen_op_ctc1(rd);
5279 ead9360e ths
        break;
5280 ead9360e ths
    /* COP2: Not implemented. */
5281 ead9360e ths
    case 4:
5282 ead9360e ths
    case 5:
5283 ead9360e ths
        /* fall through */
5284 ead9360e ths
    default:
5285 ead9360e ths
        goto die;
5286 ead9360e ths
    }
5287 ead9360e ths
#if defined MIPS_DEBUG_DISAS
5288 ead9360e ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5289 ead9360e ths
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5290 ead9360e ths
                rd, u, sel, h);
5291 ead9360e ths
    }
5292 ead9360e ths
#endif
5293 ead9360e ths
    return;
5294 ead9360e ths
5295 ead9360e ths
die:
5296 ead9360e ths
#if defined MIPS_DEBUG_DISAS
5297 ead9360e ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5298 ead9360e ths
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5299 ead9360e ths
                rd, u, sel, h);
5300 ead9360e ths
    }
5301 ead9360e ths
#endif
5302 ead9360e ths
    generate_exception(ctx, EXCP_RI);
5303 ead9360e ths
}
5304 ead9360e ths
5305 29929e34 ths
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5306 6af0bf9c bellard
{
5307 287c4b84 ths
    const char *opn = "ldst";
5308 6af0bf9c bellard
5309 6af0bf9c bellard
    switch (opc) {
5310 6af0bf9c bellard
    case OPC_MFC0:
5311 6af0bf9c bellard
        if (rt == 0) {
5312 ead9360e ths
            /* Treat as NOP. */
5313 6af0bf9c bellard
            return;
5314 6af0bf9c bellard
        }
5315 3a95e3a7 ths
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
5316 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5317 6af0bf9c bellard
        opn = "mfc0";
5318 6af0bf9c bellard
        break;
5319 6af0bf9c bellard
    case OPC_MTC0:
5320 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5321 387a8fe5 ths
        save_cpu_state(ctx, 1);
5322 3a95e3a7 ths
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
5323 6af0bf9c bellard
        opn = "mtc0";
5324 6af0bf9c bellard
        break;
5325 d26bc211 ths
#if defined(TARGET_MIPS64)
5326 9c2149c8 ths
    case OPC_DMFC0:
5327 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
5328 9c2149c8 ths
        if (rt == 0) {
5329 ead9360e ths
            /* Treat as NOP. */
5330 9c2149c8 ths
            return;
5331 9c2149c8 ths
        }
5332 3a95e3a7 ths
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
5333 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5334 9c2149c8 ths
        opn = "dmfc0";
5335 9c2149c8 ths
        break;
5336 9c2149c8 ths
    case OPC_DMTC0:
5337 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
5338 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5339 387a8fe5 ths
        save_cpu_state(ctx, 1);
5340 ead9360e ths
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
5341 9c2149c8 ths
        opn = "dmtc0";
5342 9c2149c8 ths
        break;
5343 534ce69f ths
#endif
5344 ead9360e ths
    case OPC_MFTR:
5345 7385ac0b ths
        check_insn(env, ctx, ASE_MT);
5346 ead9360e ths
        if (rd == 0) {
5347 ead9360e ths
            /* Treat as NOP. */
5348 ead9360e ths
            return;
5349 ead9360e ths
        }
5350 ead9360e ths
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
5351 ead9360e ths
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5352 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rd);
5353 ead9360e ths
        opn = "mftr";
5354 ead9360e ths
        break;
5355 ead9360e ths
    case OPC_MTTR:
5356 7385ac0b ths
        check_insn(env, ctx, ASE_MT);
5357 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5358 ead9360e ths
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
5359 ead9360e ths
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5360 ead9360e ths
        opn = "mttr";
5361 ead9360e ths
        break;
5362 6af0bf9c bellard
    case OPC_TLBWI:
5363 6af0bf9c bellard
        opn = "tlbwi";
5364 ead9360e ths
        if (!env->tlb->do_tlbwi)
5365 29929e34 ths
            goto die;
5366 29929e34 ths
        gen_op_tlbwi();
5367 6af0bf9c bellard
        break;
5368 6af0bf9c bellard
    case OPC_TLBWR:
5369 6af0bf9c bellard
        opn = "tlbwr";
5370 ead9360e ths
        if (!env->tlb->do_tlbwr)
5371 29929e34 ths
            goto die;
5372 29929e34 ths
        gen_op_tlbwr();
5373 6af0bf9c bellard
        break;
5374 6af0bf9c bellard
    case OPC_TLBP:
5375 6af0bf9c bellard
        opn = "tlbp";
5376 ead9360e ths
        if (!env->tlb->do_tlbp)
5377 29929e34 ths
            goto die;
5378 29929e34 ths
        gen_op_tlbp();
5379 6af0bf9c bellard
        break;
5380 6af0bf9c bellard
    case OPC_TLBR:
5381 6af0bf9c bellard
        opn = "tlbr";
5382 ead9360e ths
        if (!env->tlb->do_tlbr)
5383 29929e34 ths
            goto die;
5384 29929e34 ths
        gen_op_tlbr();
5385 6af0bf9c bellard
        break;
5386 6af0bf9c bellard
    case OPC_ERET:
5387 6af0bf9c bellard
        opn = "eret";
5388 e189e748 ths
        check_insn(env, ctx, ISA_MIPS2);
5389 387a8fe5 ths
        save_cpu_state(ctx, 1);
5390 6af0bf9c bellard
        gen_op_eret();
5391 6af0bf9c bellard
        ctx->bstate = BS_EXCP;
5392 6af0bf9c bellard
        break;
5393 6af0bf9c bellard
    case OPC_DERET:
5394 6af0bf9c bellard
        opn = "deret";
5395 e189e748 ths
        check_insn(env, ctx, ISA_MIPS32);
5396 6af0bf9c bellard
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5397 923617a3 ths
            MIPS_INVAL(opn);
5398 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
5399 6af0bf9c bellard
        } else {
5400 387a8fe5 ths
            save_cpu_state(ctx, 1);
5401 6af0bf9c bellard
            gen_op_deret();
5402 6af0bf9c bellard
            ctx->bstate = BS_EXCP;
5403 6af0bf9c bellard
        }
5404 6af0bf9c bellard
        break;
5405 4ad40f36 bellard
    case OPC_WAIT:
5406 4ad40f36 bellard
        opn = "wait";
5407 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5408 4ad40f36 bellard
        /* If we get an exception, we want to restart at next instruction */
5409 4ad40f36 bellard
        ctx->pc += 4;
5410 4ad40f36 bellard
        save_cpu_state(ctx, 1);
5411 4ad40f36 bellard
        ctx->pc -= 4;
5412 4ad40f36 bellard
        gen_op_wait();
5413 4ad40f36 bellard
        ctx->bstate = BS_EXCP;
5414 4ad40f36 bellard
        break;
5415 6af0bf9c bellard
    default:
5416 29929e34 ths
 die:
5417 923617a3 ths
        MIPS_INVAL(opn);
5418 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
5419 6af0bf9c bellard
        return;
5420 6af0bf9c bellard
    }
5421 6af0bf9c bellard
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5422 6af0bf9c bellard
}
5423 6af0bf9c bellard
5424 6ea83fed bellard
/* CP1 Branches (before delay slot) */
5425 e189e748 ths
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5426 5a5012ec ths
                                 int32_t cc, int32_t offset)
5427 6ea83fed bellard
{
5428 6ea83fed bellard
    target_ulong btarget;
5429 923617a3 ths
    const char *opn = "cp1 cond branch";
5430 6ea83fed bellard
5431 e189e748 ths
    if (cc != 0)
5432 e189e748 ths
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5433 e189e748 ths
5434 6ea83fed bellard
    btarget = ctx->pc + 4 + offset;
5435 6ea83fed bellard
5436 7a387fff ths
    switch (op) {
5437 7a387fff ths
    case OPC_BC1F:
5438 5a5012ec ths
        gen_op_bc1f(cc);
5439 923617a3 ths
        opn = "bc1f";
5440 6ea83fed bellard
        goto not_likely;
5441 7a387fff ths
    case OPC_BC1FL:
5442 5a5012ec ths
        gen_op_bc1f(cc);
5443 923617a3 ths
        opn = "bc1fl";
5444 6ea83fed bellard
        goto likely;
5445 7a387fff ths
    case OPC_BC1T:
5446 5a5012ec ths
        gen_op_bc1t(cc);
5447 923617a3 ths
        opn = "bc1t";
5448 5a5012ec ths
        goto not_likely;
5449 7a387fff ths
    case OPC_BC1TL:
5450 5a5012ec ths
        gen_op_bc1t(cc);
5451 923617a3 ths
        opn = "bc1tl";
5452 6ea83fed bellard
    likely:
5453 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BL;
5454 8e9ade68 ths
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5455 6ea83fed bellard
        break;
5456 5a5012ec ths
    case OPC_BC1FANY2:
5457 fd4a04eb ths
        gen_op_bc1any2f(cc);
5458 fd4a04eb ths
        opn = "bc1any2f";
5459 5a5012ec ths
        goto not_likely;
5460 5a5012ec ths
    case OPC_BC1TANY2:
5461 fd4a04eb ths
        gen_op_bc1any2t(cc);
5462 fd4a04eb ths
        opn = "bc1any2t";
5463 5a5012ec ths
        goto not_likely;
5464 5a5012ec ths
    case OPC_BC1FANY4:
5465 fd4a04eb ths
        gen_op_bc1any4f(cc);
5466 fd4a04eb ths
        opn = "bc1any4f";
5467 5a5012ec ths
        goto not_likely;
5468 5a5012ec ths
    case OPC_BC1TANY4:
5469 fd4a04eb ths
        gen_op_bc1any4t(cc);
5470 fd4a04eb ths
        opn = "bc1any4t";
5471 5a5012ec ths
    not_likely:
5472 5a5012ec ths
        ctx->hflags |= MIPS_HFLAG_BC;
5473 8e9ade68 ths
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5474 5a5012ec ths
        break;
5475 5a5012ec ths
    default:
5476 923617a3 ths
        MIPS_INVAL(opn);
5477 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
5478 6ea83fed bellard
        return;
5479 6ea83fed bellard
    }
5480 923617a3 ths
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5481 6ea83fed bellard
               ctx->hflags, btarget);
5482 6ea83fed bellard
    ctx->btarget = btarget;
5483 6ea83fed bellard
}
5484 6ea83fed bellard
5485 6af0bf9c bellard
/* Coprocessor 1 (FPU) */
5486 5a5012ec ths
5487 5a5012ec ths
#define FOP(func, fmt) (((fmt) << 21) | (func))
5488 5a5012ec ths
5489 7a387fff ths
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5490 6ea83fed bellard
{
5491 923617a3 ths
    const char *opn = "cp1 move";
5492 6ea83fed bellard
5493 6ea83fed bellard
    switch (opc) {
5494 6ea83fed bellard
    case OPC_MFC1:
5495 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
5496 6ea83fed bellard
        gen_op_mfc1();
5497 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5498 6ea83fed bellard
        opn = "mfc1";
5499 6ea83fed bellard
        break;
5500 6ea83fed bellard
    case OPC_MTC1:
5501 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5502 6ea83fed bellard
        gen_op_mtc1();
5503 6ea83fed bellard
        GEN_STORE_FTN_FREG(fs, WT0);
5504 6ea83fed bellard
        opn = "mtc1";
5505 6ea83fed bellard
        break;
5506 6ea83fed bellard
    case OPC_CFC1:
5507 ead9360e ths
        gen_op_cfc1(fs);
5508 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5509 6ea83fed bellard
        opn = "cfc1";
5510 6ea83fed bellard
        break;
5511 6ea83fed bellard
    case OPC_CTC1:
5512 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5513 ead9360e ths
        gen_op_ctc1(fs);
5514 6ea83fed bellard
        opn = "ctc1";
5515 6ea83fed bellard
        break;
5516 9c2149c8 ths
    case OPC_DMFC1:
5517 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5518 5a5012ec ths
        gen_op_dmfc1();
5519 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5520 5a5012ec ths
        opn = "dmfc1";
5521 5a5012ec ths
        break;
5522 9c2149c8 ths
    case OPC_DMTC1:
5523 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5524 5a5012ec ths
        gen_op_dmtc1();
5525 5a5012ec ths
        GEN_STORE_FTN_FREG(fs, DT0);
5526 5a5012ec ths
        opn = "dmtc1";
5527 5a5012ec ths
        break;
5528 5a5012ec ths
    case OPC_MFHC1:
5529 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5530 5a5012ec ths
        gen_op_mfhc1();
5531 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5532 5a5012ec ths
        opn = "mfhc1";
5533 5a5012ec ths
        break;
5534 5a5012ec ths
    case OPC_MTHC1:
5535 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5536 5a5012ec ths
        gen_op_mthc1();
5537 5a5012ec ths
        GEN_STORE_FTN_FREG(fs, WTH0);
5538 5a5012ec ths
        opn = "mthc1";
5539 5a5012ec ths
        break;
5540 6ea83fed bellard
    default:
5541 923617a3 ths
        MIPS_INVAL(opn);
5542 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
5543 6ea83fed bellard
        return;
5544 6ea83fed bellard
    }
5545 6ea83fed bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5546 6ea83fed bellard
}
5547 6ea83fed bellard
5548 5a5012ec ths
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5549 5a5012ec ths
{
5550 e214b9bb ths
    int l1 = gen_new_label();
5551 5a5012ec ths
    uint32_t ccbit;
5552 e214b9bb ths
    TCGCond cond;
5553 6ea83fed bellard
5554 e214b9bb ths
    if (cc)
5555 5a5012ec ths
        ccbit = 1 << (24 + cc);
5556 e214b9bb ths
    else
5557 5a5012ec ths
        ccbit = 1 << 23;
5558 e214b9bb ths
    if (tf)
5559 e214b9bb ths
        cond = TCG_COND_EQ;
5560 27848470 ths
    else
5561 27848470 ths
        cond = TCG_COND_NE;
5562 27848470 ths
5563 27848470 ths
    gen_load_gpr(cpu_T[0], rd);
5564 27848470 ths
    gen_load_gpr(cpu_T[1], rs);
5565 27848470 ths
    {
5566 27848470 ths
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5567 27848470 ths
        TCGv r_tmp = new_tmp();
5568 27848470 ths
5569 27848470 ths
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5570 27848470 ths
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5571 27848470 ths
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5572 27848470 ths
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5573 27848470 ths
        dead_tmp(r_tmp);
5574 27848470 ths
    }
5575 27848470 ths
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
5576 e214b9bb ths
5577 e214b9bb ths
    gen_set_label(l1);
5578 27848470 ths
    gen_store_gpr(cpu_T[0], rd);
5579 5a5012ec ths
}
5580 5a5012ec ths
5581 5a5012ec ths
#define GEN_MOVCF(fmt)                                                \
5582 5a5012ec ths
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5583 5a5012ec ths
{                                                                     \
5584 5a5012ec ths
    uint32_t ccbit;                                                   \
5585 5a5012ec ths
                                                                      \
5586 57fa1fb3 ths
    if (cc) {                                                         \
5587 5a5012ec ths
        ccbit = 1 << (24 + cc);                                       \
5588 57fa1fb3 ths
    } else                                                            \
5589 5a5012ec ths
        ccbit = 1 << 23;                                              \
5590 5a5012ec ths
    if (!tf)                                                          \
5591 5a5012ec ths
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5592 5a5012ec ths
    else                                                              \
5593 5a5012ec ths
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5594 5a5012ec ths
}
5595 5a5012ec ths
GEN_MOVCF(d);
5596 5a5012ec ths
GEN_MOVCF(s);
5597 5a5012ec ths
#undef GEN_MOVCF
5598 6ea83fed bellard
5599 5e755519 ths
static void gen_farith (DisasContext *ctx, uint32_t op1,
5600 5e755519 ths
                        int ft, int fs, int fd, int cc)
5601 6ea83fed bellard
{
5602 923617a3 ths
    const char *opn = "farith";
5603 6ea83fed bellard
    const char *condnames[] = {
5604 6ea83fed bellard
            "c.f",
5605 6ea83fed bellard
            "c.un",
5606 6ea83fed bellard
            "c.eq",
5607 6ea83fed bellard
            "c.ueq",
5608 6ea83fed bellard
            "c.olt",
5609 6ea83fed bellard
            "c.ult",
5610 6ea83fed bellard
            "c.ole",
5611 6ea83fed bellard
            "c.ule",
5612 6ea83fed bellard
            "c.sf",
5613 6ea83fed bellard
            "c.ngle",
5614 6ea83fed bellard
            "c.seq",
5615 6ea83fed bellard
            "c.ngl",
5616 6ea83fed bellard
            "c.lt",
5617 6ea83fed bellard
            "c.nge",
5618 6ea83fed bellard
            "c.le",
5619 6ea83fed bellard
            "c.ngt",
5620 6ea83fed bellard
    };
5621 5a1e8ffb ths
    const char *condnames_abs[] = {
5622 5a1e8ffb ths
            "cabs.f",
5623 5a1e8ffb ths
            "cabs.un",
5624 5a1e8ffb ths
            "cabs.eq",
5625 5a1e8ffb ths
            "cabs.ueq",
5626 5a1e8ffb ths
            "cabs.olt",
5627 5a1e8ffb ths
            "cabs.ult",
5628 5a1e8ffb ths
            "cabs.ole",
5629 5a1e8ffb ths
            "cabs.ule",
5630 5a1e8ffb ths
            "cabs.sf",
5631 5a1e8ffb ths
            "cabs.ngle",
5632 5a1e8ffb ths
            "cabs.seq",
5633 5a1e8ffb ths
            "cabs.ngl",
5634 5a1e8ffb ths
            "cabs.lt",
5635 5a1e8ffb ths
            "cabs.nge",
5636 5a1e8ffb ths
            "cabs.le",
5637 5a1e8ffb ths
            "cabs.ngt",
5638 5a1e8ffb ths
    };
5639 5a1e8ffb ths
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5640 7a387fff ths
    uint32_t func = ctx->opcode & 0x3f;
5641 7a387fff ths
5642 6ea83fed bellard
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5643 5a5012ec ths
    case FOP(0, 16):
5644 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5645 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5646 5a5012ec ths
        gen_op_float_add_s();
5647 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5648 5a5012ec ths
        opn = "add.s";
5649 5a1e8ffb ths
        optype = BINOP;
5650 5a5012ec ths
        break;
5651 5a5012ec ths
    case FOP(1, 16):
5652 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5653 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5654 5a5012ec ths
        gen_op_float_sub_s();
5655 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5656 5a5012ec ths
        opn = "sub.s";
5657 5a1e8ffb ths
        optype = BINOP;
5658 5a5012ec ths
        break;
5659 5a5012ec ths
    case FOP(2, 16):
5660 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5661 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5662 5a5012ec ths
        gen_op_float_mul_s();
5663 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5664 5a5012ec ths
        opn = "mul.s";
5665 5a1e8ffb ths
        optype = BINOP;
5666 5a5012ec ths
        break;
5667 5a5012ec ths
    case FOP(3, 16):
5668 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5669 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5670 5a5012ec ths
        gen_op_float_div_s();
5671 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5672 5a5012ec ths
        opn = "div.s";
5673 5a1e8ffb ths
        optype = BINOP;
5674 5a5012ec ths
        break;
5675 5a5012ec ths
    case FOP(4, 16):
5676 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5677 5a5012ec ths
        gen_op_float_sqrt_s();
5678 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5679 5a5012ec ths
        opn = "sqrt.s";
5680 5a5012ec ths
        break;
5681 5a5012ec ths
    case FOP(5, 16):
5682 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5683 5a5012ec ths
        gen_op_float_abs_s();
5684 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5685 5a5012ec ths
        opn = "abs.s";
5686 5a5012ec ths
        break;
5687 5a5012ec ths
    case FOP(6, 16):
5688 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5689 5a5012ec ths
        gen_op_float_mov_s();
5690 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5691 5a5012ec ths
        opn = "mov.s";
5692 5a5012ec ths
        break;
5693 5a5012ec ths
    case FOP(7, 16):
5694 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5695 5a5012ec ths
        gen_op_float_chs_s();
5696 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5697 5a5012ec ths
        opn = "neg.s";
5698 5a5012ec ths
        break;
5699 5a5012ec ths
    case FOP(8, 16):
5700 5e755519 ths
        check_cp1_64bitmode(ctx);
5701 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5702 5a5012ec ths
        gen_op_float_roundl_s();
5703 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5704 5a5012ec ths
        opn = "round.l.s";
5705 5a5012ec ths
        break;
5706 5a5012ec ths
    case FOP(9, 16):
5707 5e755519 ths
        check_cp1_64bitmode(ctx);
5708 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5709 5a5012ec ths
        gen_op_float_truncl_s();
5710 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5711 5a5012ec ths
        opn = "trunc.l.s";
5712 5a5012ec ths
        break;
5713 5a5012ec ths
    case FOP(10, 16):
5714 5e755519 ths
        check_cp1_64bitmode(ctx);
5715 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5716 5a5012ec ths
        gen_op_float_ceill_s();
5717 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5718 5a5012ec ths
        opn = "ceil.l.s";
5719 5a5012ec ths
        break;
5720 5a5012ec ths
    case FOP(11, 16):
5721 5e755519 ths
        check_cp1_64bitmode(ctx);
5722 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5723 5a5012ec ths
        gen_op_float_floorl_s();
5724 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5725 5a5012ec ths
        opn = "floor.l.s";
5726 5a5012ec ths
        break;
5727 5a5012ec ths
    case FOP(12, 16):
5728 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5729 5a5012ec ths
        gen_op_float_roundw_s();
5730 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5731 5a5012ec ths
        opn = "round.w.s";
5732 5a5012ec ths
        break;
5733 5a5012ec ths
    case FOP(13, 16):
5734 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5735 5a5012ec ths
        gen_op_float_truncw_s();
5736 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5737 5a5012ec ths
        opn = "trunc.w.s";
5738 5a5012ec ths
        break;
5739 5a5012ec ths
    case FOP(14, 16):
5740 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5741 5a5012ec ths
        gen_op_float_ceilw_s();
5742 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5743 5a5012ec ths
        opn = "ceil.w.s";
5744 5a5012ec ths
        break;
5745 5a5012ec ths
    case FOP(15, 16):
5746 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5747 5a5012ec ths
        gen_op_float_floorw_s();
5748 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5749 5a5012ec ths
        opn = "floor.w.s";
5750 5a5012ec ths
        break;
5751 5a5012ec ths
    case FOP(17, 16):
5752 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
5753 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5754 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
5755 5a5012ec ths
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5756 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5757 5a5012ec ths
        opn = "movcf.s";
5758 5a5012ec ths
        break;
5759 5a5012ec ths
    case FOP(18, 16):
5760 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
5761 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5762 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
5763 5a5012ec ths
        gen_op_float_movz_s();
5764 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5765 5a5012ec ths
        opn = "movz.s";
5766 5a5012ec ths
        break;
5767 5a5012ec ths
    case FOP(19, 16):
5768 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
5769 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5770 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
5771 5a5012ec ths
        gen_op_float_movn_s();
5772 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5773 5a5012ec ths
        opn = "movn.s";
5774 5a5012ec ths
        break;
5775 57fa1fb3 ths
    case FOP(21, 16):
5776 b8aa4598 ths
        check_cop1x(ctx);
5777 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5778 57fa1fb3 ths
        gen_op_float_recip_s();
5779 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5780 57fa1fb3 ths
        opn = "recip.s";
5781 57fa1fb3 ths
        break;
5782 57fa1fb3 ths
    case FOP(22, 16):
5783 b8aa4598 ths
        check_cop1x(ctx);
5784 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5785 57fa1fb3 ths
        gen_op_float_rsqrt_s();
5786 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5787 57fa1fb3 ths
        opn = "rsqrt.s";
5788 57fa1fb3 ths
        break;
5789 57fa1fb3 ths
    case FOP(28, 16):
5790 5e755519 ths
        check_cp1_64bitmode(ctx);
5791 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5792 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT2, fd);
5793 57fa1fb3 ths
        gen_op_float_recip2_s();
5794 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5795 57fa1fb3 ths
        opn = "recip2.s";
5796 57fa1fb3 ths
        break;
5797 57fa1fb3 ths
    case FOP(29, 16):
5798 5e755519 ths
        check_cp1_64bitmode(ctx);
5799 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5800 57fa1fb3 ths
        gen_op_float_recip1_s();
5801 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5802 57fa1fb3 ths
        opn = "recip1.s";
5803 57fa1fb3 ths
        break;
5804 57fa1fb3 ths
    case FOP(30, 16):
5805 5e755519 ths
        check_cp1_64bitmode(ctx);
5806 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5807 57fa1fb3 ths
        gen_op_float_rsqrt1_s();
5808 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5809 57fa1fb3 ths
        opn = "rsqrt1.s";
5810 57fa1fb3 ths
        break;
5811 57fa1fb3 ths
    case FOP(31, 16):
5812 5e755519 ths
        check_cp1_64bitmode(ctx);
5813 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5814 8dfdb87c ths
        GEN_LOAD_FREG_FTN(WT2, ft);
5815 57fa1fb3 ths
        gen_op_float_rsqrt2_s();
5816 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5817 57fa1fb3 ths
        opn = "rsqrt2.s";
5818 57fa1fb3 ths
        break;
5819 5a5012ec ths
    case FOP(33, 16):
5820 5e755519 ths
        check_cp1_registers(ctx, fd);
5821 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5822 5a5012ec ths
        gen_op_float_cvtd_s();
5823 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5824 5a5012ec ths
        opn = "cvt.d.s";
5825 5a5012ec ths
        break;
5826 5a5012ec ths
    case FOP(36, 16):
5827 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5828 5a5012ec ths
        gen_op_float_cvtw_s();
5829 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5830 5a5012ec ths
        opn = "cvt.w.s";
5831 5a5012ec ths
        break;
5832 5a5012ec ths
    case FOP(37, 16):
5833 5e755519 ths
        check_cp1_64bitmode(ctx);
5834 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5835 5a5012ec ths
        gen_op_float_cvtl_s();
5836 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5837 5a5012ec ths
        opn = "cvt.l.s";
5838 5a5012ec ths
        break;
5839 5a5012ec ths
    case FOP(38, 16):
5840 5e755519 ths
        check_cp1_64bitmode(ctx);
5841 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, fs);
5842 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, ft);
5843 5a5012ec ths
        gen_op_float_cvtps_s();
5844 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5845 5a5012ec ths
        opn = "cvt.ps.s";
5846 5a5012ec ths
        break;
5847 5a5012ec ths
    case FOP(48, 16):
5848 5a5012ec ths
    case FOP(49, 16):
5849 5a5012ec ths
    case FOP(50, 16):
5850 5a5012ec ths
    case FOP(51, 16):
5851 5a5012ec ths
    case FOP(52, 16):
5852 5a5012ec ths
    case FOP(53, 16):
5853 5a5012ec ths
    case FOP(54, 16):
5854 5a5012ec ths
    case FOP(55, 16):
5855 5a5012ec ths
    case FOP(56, 16):
5856 5a5012ec ths
    case FOP(57, 16):
5857 5a5012ec ths
    case FOP(58, 16):
5858 5a5012ec ths
    case FOP(59, 16):
5859 5a5012ec ths
    case FOP(60, 16):
5860 5a5012ec ths
    case FOP(61, 16):
5861 5a5012ec ths
    case FOP(62, 16):
5862 5a5012ec ths
    case FOP(63, 16):
5863 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5864 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5865 5a1e8ffb ths
        if (ctx->opcode & (1 << 6)) {
5866 b8aa4598 ths
            check_cop1x(ctx);
5867 5a1e8ffb ths
            gen_cmpabs_s(func-48, cc);
5868 5a1e8ffb ths
            opn = condnames_abs[func-48];
5869 5a1e8ffb ths
        } else {
5870 5a1e8ffb ths
            gen_cmp_s(func-48, cc);
5871 5a1e8ffb ths
            opn = condnames[func-48];
5872 5a1e8ffb ths
        }
5873 5a5012ec ths
        break;
5874 6ea83fed bellard
    case FOP(0, 17):
5875 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
5876 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5877 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
5878 6ea83fed bellard
        gen_op_float_add_d();
5879 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5880 6ea83fed bellard
        opn = "add.d";
5881 5a1e8ffb ths
        optype = BINOP;
5882 6ea83fed bellard
        break;
5883 6ea83fed bellard
    case FOP(1, 17):
5884 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
5885 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5886 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
5887 6ea83fed bellard
        gen_op_float_sub_d();
5888 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5889 6ea83fed bellard
        opn = "sub.d";
5890 5a1e8ffb ths
        optype = BINOP;
5891 6ea83fed bellard
        break;
5892 6ea83fed bellard
    case FOP(2, 17):
5893 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
5894 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5895 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
5896 6ea83fed bellard
        gen_op_float_mul_d();
5897 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5898 6ea83fed bellard
        opn = "mul.d";
5899 5a1e8ffb ths
        optype = BINOP;
5900 6ea83fed bellard
        break;
5901 6ea83fed bellard
    case FOP(3, 17):
5902 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
5903 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5904 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
5905 6ea83fed bellard
        gen_op_float_div_d();
5906 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5907 6ea83fed bellard
        opn = "div.d";
5908 5a1e8ffb ths
        optype = BINOP;
5909 6ea83fed bellard
        break;
5910 6ea83fed bellard
    case FOP(4, 17):
5911 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
5912 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5913 6ea83fed bellard
        gen_op_float_sqrt_d();
5914 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5915 6ea83fed bellard
        opn = "sqrt.d";
5916 6ea83fed bellard
        break;
5917 6ea83fed bellard
    case FOP(5, 17):
5918 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
5919 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5920 6ea83fed bellard
        gen_op_float_abs_d();
5921 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5922 6ea83fed bellard
        opn = "abs.d";
5923 6ea83fed bellard
        break;
5924 6ea83fed bellard
    case FOP(6, 17):
5925 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
5926 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5927 6ea83fed bellard
        gen_op_float_mov_d();
5928 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5929 6ea83fed bellard
        opn = "mov.d";
5930 6ea83fed bellard
        break;
5931 6ea83fed bellard
    case FOP(7, 17):
5932 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
5933 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5934 6ea83fed bellard
        gen_op_float_chs_d();
5935 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5936 6ea83fed bellard
        opn = "neg.d";
5937 6ea83fed bellard
        break;
5938 5a5012ec ths
    case FOP(8, 17):
5939 5e755519 ths
        check_cp1_64bitmode(ctx);
5940 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5941 5a5012ec ths
        gen_op_float_roundl_d();
5942 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5943 5a5012ec ths
        opn = "round.l.d";
5944 5a5012ec ths
        break;
5945 5a5012ec ths
    case FOP(9, 17):
5946 5e755519 ths
        check_cp1_64bitmode(ctx);
5947 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5948 5a5012ec ths
        gen_op_float_truncl_d();
5949 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5950 5a5012ec ths
        opn = "trunc.l.d";
5951 5a5012ec ths
        break;
5952 5a5012ec ths
    case FOP(10, 17):
5953 5e755519 ths
        check_cp1_64bitmode(ctx);
5954 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5955 5a5012ec ths
        gen_op_float_ceill_d();
5956 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5957 5a5012ec ths
        opn = "ceil.l.d";
5958 5a5012ec ths
        break;
5959 5a5012ec ths
    case FOP(11, 17):
5960 5e755519 ths
        check_cp1_64bitmode(ctx);
5961 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5962 5a5012ec ths
        gen_op_float_floorl_d();
5963 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5964 5a5012ec ths
        opn = "floor.l.d";
5965 5a5012ec ths
        break;
5966 6ea83fed bellard
    case FOP(12, 17):
5967 5e755519 ths
        check_cp1_registers(ctx, fs);
5968 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5969 6ea83fed bellard
        gen_op_float_roundw_d();
5970 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5971 6ea83fed bellard
        opn = "round.w.d";
5972 6ea83fed bellard
        break;
5973 6ea83fed bellard
    case FOP(13, 17):
5974 5e755519 ths
        check_cp1_registers(ctx, fs);
5975 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5976 6ea83fed bellard
        gen_op_float_truncw_d();
5977 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5978 6ea83fed bellard
        opn = "trunc.w.d";
5979 6ea83fed bellard
        break;
5980 6ea83fed bellard
    case FOP(14, 17):
5981 5e755519 ths
        check_cp1_registers(ctx, fs);
5982 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5983 6ea83fed bellard
        gen_op_float_ceilw_d();
5984 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5985 6ea83fed bellard
        opn = "ceil.w.d";
5986 6ea83fed bellard
        break;
5987 6ea83fed bellard
    case FOP(15, 17):
5988 5e755519 ths
        check_cp1_registers(ctx, fs);
5989 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5990 6ea83fed bellard
        gen_op_float_floorw_d();
5991 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5992 7a387fff ths
        opn = "floor.w.d";
5993 6ea83fed bellard
        break;
5994 5a5012ec ths
    case FOP(17, 17):
5995 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
5996 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5997 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT2, fd);
5998 5a5012ec ths
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5999 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, DT2);
6000 5a5012ec ths
        opn = "movcf.d";
6001 dd016883 bellard
        break;
6002 5a5012ec ths
    case FOP(18, 17):
6003 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6004 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6005 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT2, fd);
6006 5a5012ec ths
        gen_op_float_movz_d();
6007 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
6008 5a5012ec ths
        opn = "movz.d";
6009 5a5012ec ths
        break;
6010 5a5012ec ths
    case FOP(19, 17):
6011 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6012 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6013 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT2, fd);
6014 5a5012ec ths
        gen_op_float_movn_d();
6015 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6016 5a5012ec ths
        opn = "movn.d";
6017 6ea83fed bellard
        break;
6018 57fa1fb3 ths
    case FOP(21, 17):
6019 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6020 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6021 57fa1fb3 ths
        gen_op_float_recip_d();
6022 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6023 57fa1fb3 ths
        opn = "recip.d";
6024 57fa1fb3 ths
        break;
6025 57fa1fb3 ths
    case FOP(22, 17):
6026 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6027 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6028 57fa1fb3 ths
        gen_op_float_rsqrt_d();
6029 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6030 57fa1fb3 ths
        opn = "rsqrt.d";
6031 57fa1fb3 ths
        break;
6032 57fa1fb3 ths
    case FOP(28, 17):
6033 5e755519 ths
        check_cp1_64bitmode(ctx);
6034 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6035 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT2, ft);
6036 57fa1fb3 ths
        gen_op_float_recip2_d();
6037 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6038 57fa1fb3 ths
        opn = "recip2.d";
6039 57fa1fb3 ths
        break;
6040 57fa1fb3 ths
    case FOP(29, 17):
6041 5e755519 ths
        check_cp1_64bitmode(ctx);
6042 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6043 57fa1fb3 ths
        gen_op_float_recip1_d();
6044 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6045 57fa1fb3 ths
        opn = "recip1.d";
6046 57fa1fb3 ths
        break;
6047 57fa1fb3 ths
    case FOP(30, 17):
6048 5e755519 ths
        check_cp1_64bitmode(ctx);
6049 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6050 57fa1fb3 ths
        gen_op_float_rsqrt1_d();
6051 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6052 57fa1fb3 ths
        opn = "rsqrt1.d";
6053 57fa1fb3 ths
        break;
6054 57fa1fb3 ths
    case FOP(31, 17):
6055 5e755519 ths
        check_cp1_64bitmode(ctx);
6056 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6057 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT2, ft);
6058 57fa1fb3 ths
        gen_op_float_rsqrt2_d();
6059 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6060 57fa1fb3 ths
        opn = "rsqrt2.d";
6061 57fa1fb3 ths
        break;
6062 6ea83fed bellard
    case FOP(48, 17):
6063 6ea83fed bellard
    case FOP(49, 17):
6064 6ea83fed bellard
    case FOP(50, 17):
6065 6ea83fed bellard
    case FOP(51, 17):
6066 6ea83fed bellard
    case FOP(52, 17):
6067 6ea83fed bellard
    case FOP(53, 17):
6068 6ea83fed bellard
    case FOP(54, 17):
6069 6ea83fed bellard
    case FOP(55, 17):
6070 6ea83fed bellard
    case FOP(56, 17):
6071 6ea83fed bellard
    case FOP(57, 17):
6072 6ea83fed bellard
    case FOP(58, 17):
6073 6ea83fed bellard
    case FOP(59, 17):
6074 6ea83fed bellard
    case FOP(60, 17):
6075 6ea83fed bellard
    case FOP(61, 17):
6076 6ea83fed bellard
    case FOP(62, 17):
6077 6ea83fed bellard
    case FOP(63, 17):
6078 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
6079 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
6080 5a1e8ffb ths
        if (ctx->opcode & (1 << 6)) {
6081 b8aa4598 ths
            check_cop1x(ctx);
6082 b8aa4598 ths
            check_cp1_registers(ctx, fs | ft);
6083 5a1e8ffb ths
            gen_cmpabs_d(func-48, cc);
6084 5a1e8ffb ths
            opn = condnames_abs[func-48];
6085 5a1e8ffb ths
        } else {
6086 5e755519 ths
            check_cp1_registers(ctx, fs | ft);
6087 5a1e8ffb ths
            gen_cmp_d(func-48, cc);
6088 5a1e8ffb ths
            opn = condnames[func-48];
6089 5a1e8ffb ths
        }
6090 6ea83fed bellard
        break;
6091 5a5012ec ths
    case FOP(32, 17):
6092 5e755519 ths
        check_cp1_registers(ctx, fs);
6093 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6094 5a5012ec ths
        gen_op_float_cvts_d();
6095 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6096 5a5012ec ths
        opn = "cvt.s.d";
6097 5a5012ec ths
        break;
6098 5a5012ec ths
    case FOP(36, 17):
6099 5e755519 ths
        check_cp1_registers(ctx, fs);
6100 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6101 5a5012ec ths
        gen_op_float_cvtw_d();
6102 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6103 5a5012ec ths
        opn = "cvt.w.d";
6104 5a5012ec ths
        break;
6105 5a5012ec ths
    case FOP(37, 17):
6106 5e755519 ths
        check_cp1_64bitmode(ctx);
6107 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6108 5a5012ec ths
        gen_op_float_cvtl_d();
6109 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6110 5a5012ec ths
        opn = "cvt.l.d";
6111 5a5012ec ths
        break;
6112 5a5012ec ths
    case FOP(32, 20):
6113 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6114 5a5012ec ths
        gen_op_float_cvts_w();
6115 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6116 5a5012ec ths
        opn = "cvt.s.w";
6117 6ea83fed bellard
        break;
6118 5a5012ec ths
    case FOP(33, 20):
6119 5e755519 ths
        check_cp1_registers(ctx, fd);
6120 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6121 5a5012ec ths
        gen_op_float_cvtd_w();
6122 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6123 5a5012ec ths
        opn = "cvt.d.w";
6124 5a5012ec ths
        break;
6125 5a5012ec ths
    case FOP(32, 21):
6126 5e755519 ths
        check_cp1_64bitmode(ctx);
6127 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6128 5a5012ec ths
        gen_op_float_cvts_l();
6129 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6130 5a5012ec ths
        opn = "cvt.s.l";
6131 5a5012ec ths
        break;
6132 5a5012ec ths
    case FOP(33, 21):
6133 5e755519 ths
        check_cp1_64bitmode(ctx);
6134 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6135 5a5012ec ths
        gen_op_float_cvtd_l();
6136 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6137 5a5012ec ths
        opn = "cvt.d.l";
6138 5a5012ec ths
        break;
6139 5a5012ec ths
    case FOP(38, 20):
6140 5e755519 ths
        check_cp1_64bitmode(ctx);
6141 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6142 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6143 5a5012ec ths
        gen_op_float_cvtps_pw();
6144 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6145 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6146 5a5012ec ths
        opn = "cvt.ps.pw";
6147 5a5012ec ths
        break;
6148 5a5012ec ths
    case FOP(0, 22):
6149 5e755519 ths
        check_cp1_64bitmode(ctx);
6150 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6151 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6152 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
6153 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6154 5a5012ec ths
        gen_op_float_add_ps();
6155 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6156 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6157 5a5012ec ths
        opn = "add.ps";
6158 6ea83fed bellard
        break;
6159 5a5012ec ths
    case FOP(1, 22):
6160 5e755519 ths
        check_cp1_64bitmode(ctx);
6161 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6162 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6163 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
6164 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6165 5a5012ec ths
        gen_op_float_sub_ps();
6166 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6167 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6168 5a5012ec ths
        opn = "sub.ps";
6169 6ea83fed bellard
        break;
6170 5a5012ec ths
    case FOP(2, 22):
6171 5e755519 ths
        check_cp1_64bitmode(ctx);
6172 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6173 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6174 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
6175 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6176 5a5012ec ths
        gen_op_float_mul_ps();
6177 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6178 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6179 5a5012ec ths
        opn = "mul.ps";
6180 6ea83fed bellard
        break;
6181 5a5012ec ths
    case FOP(5, 22):
6182 5e755519 ths
        check_cp1_64bitmode(ctx);
6183 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6184 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6185 5a5012ec ths
        gen_op_float_abs_ps();
6186 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6187 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6188 5a5012ec ths
        opn = "abs.ps";
6189 6ea83fed bellard
        break;
6190 5a5012ec ths
    case FOP(6, 22):
6191 5e755519 ths
        check_cp1_64bitmode(ctx);
6192 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6193 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6194 5a5012ec ths
        gen_op_float_mov_ps();
6195 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6196 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6197 5a5012ec ths
        opn = "mov.ps";
6198 6ea83fed bellard
        break;
6199 5a5012ec ths
    case FOP(7, 22):
6200 5e755519 ths
        check_cp1_64bitmode(ctx);
6201 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6202 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6203 5a5012ec ths
        gen_op_float_chs_ps();
6204 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6205 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6206 5a5012ec ths
        opn = "neg.ps";
6207 6ea83fed bellard
        break;
6208 5a5012ec ths
    case FOP(17, 22):
6209 5e755519 ths
        check_cp1_64bitmode(ctx);
6210 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6211 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6212 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6213 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
6214 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
6215 e6bb7d7e ths
        if (ft & 0x1)
6216 e6bb7d7e ths
            gen_op_float_movt_ps ((ft >> 2) & 0x7);
6217 e6bb7d7e ths
        else
6218 e6bb7d7e ths
            gen_op_float_movf_ps ((ft >> 2) & 0x7);
6219 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6220 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6221 5a5012ec ths
        opn = "movcf.ps";
6222 6ea83fed bellard
        break;
6223 5a5012ec ths
    case FOP(18, 22):
6224 5e755519 ths
        check_cp1_64bitmode(ctx);
6225 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6226 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6227 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6228 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
6229 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
6230 5a5012ec ths
        gen_op_float_movz_ps();
6231 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6232 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6233 5a5012ec ths
        opn = "movz.ps";
6234 6ea83fed bellard
        break;
6235 5a5012ec ths
    case FOP(19, 22):
6236 5e755519 ths
        check_cp1_64bitmode(ctx);
6237 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6238 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6239 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6240 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
6241 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
6242 5a5012ec ths
        gen_op_float_movn_ps();
6243 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6244 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6245 5a5012ec ths
        opn = "movn.ps";
6246 6ea83fed bellard
        break;
6247 fbcc6828 ths
    case FOP(24, 22):
6248 5e755519 ths
        check_cp1_64bitmode(ctx);
6249 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT0, ft);
6250 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH0, ft);
6251 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT1, fs);
6252 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH1, fs);
6253 fbcc6828 ths
        gen_op_float_addr_ps();
6254 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6255 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6256 fbcc6828 ths
        opn = "addr.ps";
6257 fbcc6828 ths
        break;
6258 57fa1fb3 ths
    case FOP(26, 22):
6259 5e755519 ths
        check_cp1_64bitmode(ctx);
6260 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT0, ft);
6261 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH0, ft);
6262 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT1, fs);
6263 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH1, fs);
6264 57fa1fb3 ths
        gen_op_float_mulr_ps();
6265 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6266 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6267 57fa1fb3 ths
        opn = "mulr.ps";
6268 57fa1fb3 ths
        break;
6269 57fa1fb3 ths
    case FOP(28, 22):
6270 5e755519 ths
        check_cp1_64bitmode(ctx);
6271 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6272 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6273 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT2, fd);
6274 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
6275 57fa1fb3 ths
        gen_op_float_recip2_ps();
6276 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6277 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6278 57fa1fb3 ths
        opn = "recip2.ps";
6279 57fa1fb3 ths
        break;
6280 57fa1fb3 ths
    case FOP(29, 22):
6281 5e755519 ths
        check_cp1_64bitmode(ctx);
6282 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6283 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6284 57fa1fb3 ths
        gen_op_float_recip1_ps();
6285 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6286 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6287 57fa1fb3 ths
        opn = "recip1.ps";
6288 57fa1fb3 ths
        break;
6289 57fa1fb3 ths
    case FOP(30, 22):
6290 5e755519 ths
        check_cp1_64bitmode(ctx);
6291 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6292 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6293 57fa1fb3 ths
        gen_op_float_rsqrt1_ps();
6294 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6295 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6296 57fa1fb3 ths
        opn = "rsqrt1.ps";
6297 57fa1fb3 ths
        break;
6298 57fa1fb3 ths
    case FOP(31, 22):
6299 5e755519 ths
        check_cp1_64bitmode(ctx);
6300 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6301 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6302 8dfdb87c ths
        GEN_LOAD_FREG_FTN(WT2, ft);
6303 8dfdb87c ths
        GEN_LOAD_FREG_FTN(WTH2, ft);
6304 57fa1fb3 ths
        gen_op_float_rsqrt2_ps();
6305 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6306 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6307 57fa1fb3 ths
        opn = "rsqrt2.ps";
6308 57fa1fb3 ths
        break;
6309 5a5012ec ths
    case FOP(32, 22):
6310 5e755519 ths
        check_cp1_64bitmode(ctx);
6311 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6312 5a5012ec ths
        gen_op_float_cvts_pu();
6313 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6314 5a5012ec ths
        opn = "cvt.s.pu";
6315 dd016883 bellard
        break;
6316 5a5012ec ths
    case FOP(36, 22):
6317 5e755519 ths
        check_cp1_64bitmode(ctx);
6318 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6319 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6320 5a5012ec ths
        gen_op_float_cvtpw_ps();
6321 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6322 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6323 5a5012ec ths
        opn = "cvt.pw.ps";
6324 6ea83fed bellard
        break;
6325 5a5012ec ths
    case FOP(40, 22):
6326 5e755519 ths
        check_cp1_64bitmode(ctx);
6327 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6328 5a5012ec ths
        gen_op_float_cvts_pl();
6329 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6330 5a5012ec ths
        opn = "cvt.s.pl";
6331 6ea83fed bellard
        break;
6332 5a5012ec ths
    case FOP(44, 22):
6333 5e755519 ths
        check_cp1_64bitmode(ctx);
6334 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6335 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6336 5a5012ec ths
        gen_op_float_pll_ps();
6337 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6338 5a5012ec ths
        opn = "pll.ps";
6339 6ea83fed bellard
        break;
6340 5a5012ec ths
    case FOP(45, 22):
6341 5e755519 ths
        check_cp1_64bitmode(ctx);
6342 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6343 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6344 5a5012ec ths
        gen_op_float_plu_ps();
6345 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6346 5a5012ec ths
        opn = "plu.ps";
6347 5a5012ec ths
        break;
6348 5a5012ec ths
    case FOP(46, 22):
6349 5e755519 ths
        check_cp1_64bitmode(ctx);
6350 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6351 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
6352 5a5012ec ths
        gen_op_float_pul_ps();
6353 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6354 5a5012ec ths
        opn = "pul.ps";
6355 5a5012ec ths
        break;
6356 5a5012ec ths
    case FOP(47, 22):
6357 5e755519 ths
        check_cp1_64bitmode(ctx);
6358 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6359 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6360 5a5012ec ths
        gen_op_float_puu_ps();
6361 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6362 5a5012ec ths
        opn = "puu.ps";
6363 5a5012ec ths
        break;
6364 5a5012ec ths
    case FOP(48, 22):
6365 5a5012ec ths
    case FOP(49, 22):
6366 5a5012ec ths
    case FOP(50, 22):
6367 5a5012ec ths
    case FOP(51, 22):
6368 5a5012ec ths
    case FOP(52, 22):
6369 5a5012ec ths
    case FOP(53, 22):
6370 5a5012ec ths
    case FOP(54, 22):
6371 5a5012ec ths
    case FOP(55, 22):
6372 5a5012ec ths
    case FOP(56, 22):
6373 5a5012ec ths
    case FOP(57, 22):
6374 5a5012ec ths
    case FOP(58, 22):
6375 5a5012ec ths
    case FOP(59, 22):
6376 5a5012ec ths
    case FOP(60, 22):
6377 5a5012ec ths
    case FOP(61, 22):
6378 5a5012ec ths
    case FOP(62, 22):
6379 5a5012ec ths
    case FOP(63, 22):
6380 5e755519 ths
        check_cp1_64bitmode(ctx);
6381 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6382 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6383 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6384 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6385 5a1e8ffb ths
        if (ctx->opcode & (1 << 6)) {
6386 5a1e8ffb ths
            gen_cmpabs_ps(func-48, cc);
6387 5a1e8ffb ths
            opn = condnames_abs[func-48];
6388 5a1e8ffb ths
        } else {
6389 5a1e8ffb ths
            gen_cmp_ps(func-48, cc);
6390 5a1e8ffb ths
            opn = condnames[func-48];
6391 5a1e8ffb ths
        }
6392 6ea83fed bellard
        break;
6393 5a5012ec ths
    default:
6394 923617a3 ths
        MIPS_INVAL(opn);
6395 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
6396 6ea83fed bellard
        return;
6397 6ea83fed bellard
    }
6398 5a1e8ffb ths
    switch (optype) {
6399 5a1e8ffb ths
    case BINOP:
6400 6ea83fed bellard
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
6401 5a1e8ffb ths
        break;
6402 5a1e8ffb ths
    case CMPOP:
6403 5a1e8ffb ths
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
6404 5a1e8ffb ths
        break;
6405 5a1e8ffb ths
    default:
6406 6ea83fed bellard
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
6407 5a1e8ffb ths
        break;
6408 5a1e8ffb ths
    }
6409 6ea83fed bellard
}
6410 6af0bf9c bellard
6411 5a5012ec ths
/* Coprocessor 3 (FPU) */
6412 5e755519 ths
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6413 5e755519 ths
                           int fd, int fs, int base, int index)
6414 7a387fff ths
{
6415 923617a3 ths
    const char *opn = "extended float load/store";
6416 93b12ccc ths
    int store = 0;
6417 7a387fff ths
6418 93b12ccc ths
    if (base == 0) {
6419 8e9ade68 ths
        gen_load_gpr(cpu_T[0], index);
6420 93b12ccc ths
    } else if (index == 0) {
6421 8e9ade68 ths
        gen_load_gpr(cpu_T[0], base);
6422 93b12ccc ths
    } else {
6423 8e9ade68 ths
        gen_load_gpr(cpu_T[0], base);
6424 8e9ade68 ths
        gen_load_gpr(cpu_T[1], index);
6425 93b12ccc ths
        gen_op_addr_add();
6426 93b12ccc ths
    }
6427 5a5012ec ths
    /* Don't do NOP if destination is zero: we must perform the actual
6428 ead9360e ths
       memory access. */
6429 5a5012ec ths
    switch (opc) {
6430 5a5012ec ths
    case OPC_LWXC1:
6431 b8aa4598 ths
        check_cop1x(ctx);
6432 aaa9128a ths
        op_ldst_lwc1(ctx);
6433 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT0);
6434 5a5012ec ths
        opn = "lwxc1";
6435 5a5012ec ths
        break;
6436 5a5012ec ths
    case OPC_LDXC1:
6437 b8aa4598 ths
        check_cop1x(ctx);
6438 b8aa4598 ths
        check_cp1_registers(ctx, fd);
6439 aaa9128a ths
        op_ldst_ldc1(ctx);
6440 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT0);
6441 5a5012ec ths
        opn = "ldxc1";
6442 5a5012ec ths
        break;
6443 5a5012ec ths
    case OPC_LUXC1:
6444 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6445 5a5012ec ths
        op_ldst(luxc1);
6446 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT0);
6447 5a5012ec ths
        opn = "luxc1";
6448 5a5012ec ths
        break;
6449 5a5012ec ths
    case OPC_SWXC1:
6450 b8aa4598 ths
        check_cop1x(ctx);
6451 93b12ccc ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6452 aaa9128a ths
        op_ldst_swc1(ctx);
6453 5a5012ec ths
        opn = "swxc1";
6454 93b12ccc ths
        store = 1;
6455 5a5012ec ths
        break;
6456 5a5012ec ths
    case OPC_SDXC1:
6457 b8aa4598 ths
        check_cop1x(ctx);
6458 b8aa4598 ths
        check_cp1_registers(ctx, fs);
6459 93b12ccc ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6460 aaa9128a ths
        op_ldst_sdc1(ctx);
6461 5a5012ec ths
        opn = "sdxc1";
6462 93b12ccc ths
        store = 1;
6463 5a5012ec ths
        break;
6464 5a5012ec ths
    case OPC_SUXC1:
6465 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6466 93b12ccc ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6467 5a5012ec ths
        op_ldst(suxc1);
6468 5a5012ec ths
        opn = "suxc1";
6469 93b12ccc ths
        store = 1;
6470 5a5012ec ths
        break;
6471 5a5012ec ths
    default:
6472 923617a3 ths
        MIPS_INVAL(opn);
6473 5a5012ec ths
        generate_exception(ctx, EXCP_RI);
6474 5a5012ec ths
        return;
6475 5a5012ec ths
    }
6476 93b12ccc ths
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6477 93b12ccc ths
               regnames[index], regnames[base]);
6478 5a5012ec ths
}
6479 5a5012ec ths
6480 5e755519 ths
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6481 5e755519 ths
                            int fd, int fr, int fs, int ft)
6482 5a5012ec ths
{
6483 923617a3 ths
    const char *opn = "flt3_arith";
6484 5a5012ec ths
6485 5a5012ec ths
    switch (opc) {
6486 5a5012ec ths
    case OPC_ALNV_PS:
6487 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6488 8e9ade68 ths
        gen_load_gpr(cpu_T[0], fr);
6489 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6490 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6491 5a5012ec ths
        gen_op_float_alnv_ps();
6492 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6493 5a5012ec ths
        opn = "alnv.ps";
6494 5a5012ec ths
        break;
6495 5a5012ec ths
    case OPC_MADD_S:
6496 b8aa4598 ths
        check_cop1x(ctx);
6497 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6498 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6499 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6500 5a5012ec ths
        gen_op_float_muladd_s();
6501 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6502 5a5012ec ths
        opn = "madd.s";
6503 5a5012ec ths
        break;
6504 5a5012ec ths
    case OPC_MADD_D:
6505 b8aa4598 ths
        check_cop1x(ctx);
6506 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
6507 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6508 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6509 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
6510 fbcc6828 ths
        gen_op_float_muladd_d();
6511 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6512 5a5012ec ths
        opn = "madd.d";
6513 5a5012ec ths
        break;
6514 5a5012ec ths
    case OPC_MADD_PS:
6515 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6516 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6517 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6518 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6519 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6520 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6521 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
6522 fbcc6828 ths
        gen_op_float_muladd_ps();
6523 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6524 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6525 5a5012ec ths
        opn = "madd.ps";
6526 5a5012ec ths
        break;
6527 5a5012ec ths
    case OPC_MSUB_S:
6528 b8aa4598 ths
        check_cop1x(ctx);
6529 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6530 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6531 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6532 fbcc6828 ths
        gen_op_float_mulsub_s();
6533 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6534 5a5012ec ths
        opn = "msub.s";
6535 5a5012ec ths
        break;
6536 5a5012ec ths
    case OPC_MSUB_D:
6537 b8aa4598 ths
        check_cop1x(ctx);
6538 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
6539 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6540 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6541 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
6542 fbcc6828 ths
        gen_op_float_mulsub_d();
6543 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6544 5a5012ec ths
        opn = "msub.d";
6545 5a5012ec ths
        break;
6546 5a5012ec ths
    case OPC_MSUB_PS:
6547 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6548 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6549 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6550 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6551 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6552 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6553 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
6554 fbcc6828 ths
        gen_op_float_mulsub_ps();
6555 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6556 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6557 5a5012ec ths
        opn = "msub.ps";
6558 5a5012ec ths
        break;
6559 5a5012ec ths
    case OPC_NMADD_S:
6560 b8aa4598 ths
        check_cop1x(ctx);
6561 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6562 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6563 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6564 fbcc6828 ths
        gen_op_float_nmuladd_s();
6565 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6566 5a5012ec ths
        opn = "nmadd.s";
6567 5a5012ec ths
        break;
6568 5a5012ec ths
    case OPC_NMADD_D:
6569 b8aa4598 ths
        check_cop1x(ctx);
6570 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
6571 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6572 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6573 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
6574 fbcc6828 ths
        gen_op_float_nmuladd_d();
6575 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6576 5a5012ec ths
        opn = "nmadd.d";
6577 5a5012ec ths
        break;
6578 5a5012ec ths
    case OPC_NMADD_PS:
6579 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6580 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6581 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6582 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6583 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6584 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6585 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
6586 fbcc6828 ths
        gen_op_float_nmuladd_ps();
6587 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6588 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6589 5a5012ec ths
        opn = "nmadd.ps";
6590 5a5012ec ths
        break;
6591 5a5012ec ths
    case OPC_NMSUB_S:
6592 b8aa4598 ths
        check_cop1x(ctx);
6593 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6594 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6595 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6596 fbcc6828 ths
        gen_op_float_nmulsub_s();
6597 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6598 5a5012ec ths
        opn = "nmsub.s";
6599 5a5012ec ths
        break;
6600 5a5012ec ths
    case OPC_NMSUB_D:
6601 b8aa4598 ths
        check_cop1x(ctx);
6602 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
6603 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6604 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6605 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
6606 fbcc6828 ths
        gen_op_float_nmulsub_d();
6607 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6608 5a5012ec ths
        opn = "nmsub.d";
6609 5a5012ec ths
        break;
6610 5a5012ec ths
    case OPC_NMSUB_PS:
6611 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6612 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6613 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6614 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6615 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6616 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6617 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
6618 fbcc6828 ths
        gen_op_float_nmulsub_ps();
6619 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6620 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6621 5a5012ec ths
        opn = "nmsub.ps";
6622 5a5012ec ths
        break;
6623 923617a3 ths
    default:
6624 923617a3 ths
        MIPS_INVAL(opn);
6625 5a5012ec ths
        generate_exception (ctx, EXCP_RI);
6626 5a5012ec ths
        return;
6627 5a5012ec ths
    }
6628 5a5012ec ths
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6629 5a5012ec ths
               fregnames[fs], fregnames[ft]);
6630 7a387fff ths
}
6631 7a387fff ths
6632 7a387fff ths
/* ISA extensions (ASEs) */
6633 6af0bf9c bellard
/* MIPS16 extension to MIPS32 */
6634 6af0bf9c bellard
/* SmartMIPS extension to MIPS32 */
6635 6af0bf9c bellard
6636 d26bc211 ths
#if defined(TARGET_MIPS64)
6637 6af0bf9c bellard
6638 6af0bf9c bellard
/* MDMX extension to MIPS64 */
6639 6af0bf9c bellard
6640 6af0bf9c bellard
#endif
6641 6af0bf9c bellard
6642 36d23958 ths
static void decode_opc (CPUState *env, DisasContext *ctx)
6643 6af0bf9c bellard
{
6644 6af0bf9c bellard
    int32_t offset;
6645 6af0bf9c bellard
    int rs, rt, rd, sa;
6646 7a387fff ths
    uint32_t op, op1, op2;
6647 6af0bf9c bellard
    int16_t imm;
6648 6af0bf9c bellard
6649 d796321b bellard
    /* make sure instructions are on a word boundary */
6650 d796321b bellard
    if (ctx->pc & 0x3) {
6651 cbeb0857 ths
        env->CP0_BadVAddr = ctx->pc;
6652 d796321b bellard
        generate_exception(ctx, EXCP_AdEL);
6653 d796321b bellard
        return;
6654 d796321b bellard
    }
6655 d796321b bellard
6656 8e9ade68 ths
    /* Handle blikely not taken case */
6657 4ad40f36 bellard
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6658 8e9ade68 ths
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
6659 8e9ade68 ths
        int l1 = gen_new_label();
6660 8e9ade68 ths
6661 3594c774 ths
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6662 8e9ade68 ths
        tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
6663 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
6664 5a5012ec ths
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6665 5a5012ec ths
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6666 5a5012ec ths
        gen_set_label(l1);
6667 6af0bf9c bellard
    }
6668 7a387fff ths
    op = MASK_OP_MAJOR(ctx->opcode);
6669 7a387fff ths
    rs = (ctx->opcode >> 21) & 0x1f;
6670 7a387fff ths
    rt = (ctx->opcode >> 16) & 0x1f;
6671 7a387fff ths
    rd = (ctx->opcode >> 11) & 0x1f;
6672 7a387fff ths
    sa = (ctx->opcode >> 6) & 0x1f;
6673 6af0bf9c bellard
    imm = (int16_t)ctx->opcode;
6674 6af0bf9c bellard
    switch (op) {
6675 7a387fff ths
    case OPC_SPECIAL:
6676 7a387fff ths
        op1 = MASK_SPECIAL(ctx->opcode);
6677 6af0bf9c bellard
        switch (op1) {
6678 7a387fff ths
        case OPC_SLL:          /* Arithmetic with immediate */
6679 7a387fff ths
        case OPC_SRL ... OPC_SRA:
6680 e189e748 ths
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6681 7a387fff ths
            break;
6682 e189e748 ths
        case OPC_MOVZ ... OPC_MOVN:
6683 e189e748 ths
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6684 7a387fff ths
        case OPC_SLLV:         /* Arithmetic */
6685 7a387fff ths
        case OPC_SRLV ... OPC_SRAV:
6686 7a387fff ths
        case OPC_ADD ... OPC_NOR:
6687 7a387fff ths
        case OPC_SLT ... OPC_SLTU:
6688 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
6689 7a387fff ths
            break;
6690 7a387fff ths
        case OPC_MULT ... OPC_DIVU:
6691 e9c71dd1 ths
            if (sa) {
6692 e9c71dd1 ths
                check_insn(env, ctx, INSN_VR54XX);
6693 e9c71dd1 ths
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6694 e9c71dd1 ths
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6695 e9c71dd1 ths
            } else
6696 e9c71dd1 ths
                gen_muldiv(ctx, op1, rs, rt);
6697 7a387fff ths
            break;
6698 7a387fff ths
        case OPC_JR ... OPC_JALR:
6699 7a387fff ths
            gen_compute_branch(ctx, op1, rs, rd, sa);
6700 6af0bf9c bellard
            return;
6701 7a387fff ths
        case OPC_TGE ... OPC_TEQ: /* Traps */
6702 7a387fff ths
        case OPC_TNE:
6703 7a387fff ths
            gen_trap(ctx, op1, rs, rt, -1);
6704 6af0bf9c bellard
            break;
6705 7a387fff ths
        case OPC_MFHI:          /* Move from HI/LO */
6706 7a387fff ths
        case OPC_MFLO:
6707 7a387fff ths
            gen_HILO(ctx, op1, rd);
6708 6af0bf9c bellard
            break;
6709 7a387fff ths
        case OPC_MTHI:
6710 7a387fff ths
        case OPC_MTLO:          /* Move to HI/LO */
6711 7a387fff ths
            gen_HILO(ctx, op1, rs);
6712 6af0bf9c bellard
            break;
6713 b48cfdff ths
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6714 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
6715 b48cfdff ths
            MIPS_INVAL("PMON / selsl");
6716 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
6717 b48cfdff ths
#else
6718 7a387fff ths
            gen_op_pmon(sa);
6719 b48cfdff ths
#endif
6720 7a387fff ths
            break;
6721 7a387fff ths
        case OPC_SYSCALL:
6722 6af0bf9c bellard
            generate_exception(ctx, EXCP_SYSCALL);
6723 6af0bf9c bellard
            break;
6724 7a387fff ths
        case OPC_BREAK:
6725 6af0bf9c bellard
            generate_exception(ctx, EXCP_BREAK);
6726 6af0bf9c bellard
            break;
6727 b48cfdff ths
        case OPC_SPIM:
6728 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
6729 b48cfdff ths
            MIPS_INVAL("SPIM");
6730 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
6731 b48cfdff ths
#else
6732 7a387fff ths
           /* Implemented as RI exception for now. */
6733 7a387fff ths
            MIPS_INVAL("spim (unofficial)");
6734 7a387fff ths
            generate_exception(ctx, EXCP_RI);
6735 b48cfdff ths
#endif
6736 6af0bf9c bellard
            break;
6737 7a387fff ths
        case OPC_SYNC:
6738 ead9360e ths
            /* Treat as NOP. */
6739 6af0bf9c bellard
            break;
6740 4ad40f36 bellard
6741 7a387fff ths
        case OPC_MOVCI:
6742 e189e748 ths
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6743 36d23958 ths
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6744 e397ee33 ths
                save_cpu_state(ctx, 1);
6745 5e755519 ths
                check_cp1_enabled(ctx);
6746 36d23958 ths
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6747 36d23958 ths
                          (ctx->opcode >> 16) & 1);
6748 36d23958 ths
            } else {
6749 e397ee33 ths
                generate_exception_err(ctx, EXCP_CpU, 1);
6750 36d23958 ths
            }
6751 4ad40f36 bellard
            break;
6752 4ad40f36 bellard
6753 d26bc211 ths
#if defined(TARGET_MIPS64)
6754 7a387fff ths
       /* MIPS64 specific opcodes */
6755 7a387fff ths
        case OPC_DSLL:
6756 7a387fff ths
        case OPC_DSRL ... OPC_DSRA:
6757 7a387fff ths
        case OPC_DSLL32:
6758 7a387fff ths
        case OPC_DSRL32 ... OPC_DSRA32:
6759 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
6760 e189e748 ths
            check_mips_64(ctx);
6761 e189e748 ths
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6762 7a387fff ths
            break;
6763 7a387fff ths
        case OPC_DSLLV:
6764 7a387fff ths
        case OPC_DSRLV ... OPC_DSRAV:
6765 7a387fff ths
        case OPC_DADD ... OPC_DSUBU:
6766 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
6767 e189e748 ths
            check_mips_64(ctx);
6768 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
6769 7a387fff ths
            break;
6770 7a387fff ths
        case OPC_DMULT ... OPC_DDIVU:
6771 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
6772 e189e748 ths
            check_mips_64(ctx);
6773 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
6774 7a387fff ths
            break;
6775 6af0bf9c bellard
#endif
6776 6af0bf9c bellard
        default:            /* Invalid */
6777 6af0bf9c bellard
            MIPS_INVAL("special");
6778 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
6779 6af0bf9c bellard
            break;
6780 6af0bf9c bellard
        }
6781 6af0bf9c bellard
        break;
6782 7a387fff ths
    case OPC_SPECIAL2:
6783 7a387fff ths
        op1 = MASK_SPECIAL2(ctx->opcode);
6784 6af0bf9c bellard
        switch (op1) {
6785 7a387fff ths
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6786 7a387fff ths
        case OPC_MSUB ... OPC_MSUBU:
6787 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
6788 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
6789 6af0bf9c bellard
            break;
6790 7a387fff ths
        case OPC_MUL:
6791 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
6792 6af0bf9c bellard
            break;
6793 7a387fff ths
        case OPC_CLZ ... OPC_CLO:
6794 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
6795 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
6796 6af0bf9c bellard
            break;
6797 7a387fff ths
        case OPC_SDBBP:
6798 6af0bf9c bellard
            /* XXX: not clear which exception should be raised
6799 6af0bf9c bellard
             *      when in debug mode...
6800 6af0bf9c bellard
             */
6801 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
6802 6af0bf9c bellard
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6803 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
6804 6af0bf9c bellard
            } else {
6805 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
6806 6af0bf9c bellard
            }
6807 ead9360e ths
            /* Treat as NOP. */
6808 6af0bf9c bellard
            break;
6809 d26bc211 ths
#if defined(TARGET_MIPS64)
6810 7a387fff ths
        case OPC_DCLZ ... OPC_DCLO:
6811 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64);
6812 e189e748 ths
            check_mips_64(ctx);
6813 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
6814 7a387fff ths
            break;
6815 7a387fff ths
#endif
6816 6af0bf9c bellard
        default:            /* Invalid */
6817 6af0bf9c bellard
            MIPS_INVAL("special2");
6818 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
6819 6af0bf9c bellard
            break;
6820 6af0bf9c bellard
        }
6821 6af0bf9c bellard
        break;
6822 7a387fff ths
    case OPC_SPECIAL3:
6823 1579a72e ths
         op1 = MASK_SPECIAL3(ctx->opcode);
6824 1579a72e ths
         switch (op1) {
6825 1579a72e ths
         case OPC_EXT:
6826 1579a72e ths
         case OPC_INS:
6827 e189e748 ths
             check_insn(env, ctx, ISA_MIPS32R2);
6828 1579a72e ths
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6829 1579a72e ths
             break;
6830 1579a72e ths
         case OPC_BSHFL:
6831 e189e748 ths
             check_insn(env, ctx, ISA_MIPS32R2);
6832 1579a72e ths
             op2 = MASK_BSHFL(ctx->opcode);
6833 1579a72e ths
             switch (op2) {
6834 1579a72e ths
             case OPC_WSBH:
6835 8e9ade68 ths
                 gen_load_gpr(cpu_T[1], rt);
6836 1579a72e ths
                 gen_op_wsbh();
6837 1579a72e ths
                 break;
6838 1579a72e ths
             case OPC_SEB:
6839 8e9ade68 ths
                 gen_load_gpr(cpu_T[1], rt);
6840 48d38ca5 ths
                 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
6841 1579a72e ths
                 break;
6842 1579a72e ths
             case OPC_SEH:
6843 8e9ade68 ths
                 gen_load_gpr(cpu_T[1], rt);
6844 48d38ca5 ths
                 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
6845 1579a72e ths
                 break;
6846 1579a72e ths
             default:            /* Invalid */
6847 1579a72e ths
                 MIPS_INVAL("bshfl");
6848 1579a72e ths
                 generate_exception(ctx, EXCP_RI);
6849 1579a72e ths
                 break;
6850 1579a72e ths
            }
6851 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rd);
6852 7a387fff ths
            break;
6853 1579a72e ths
        case OPC_RDHWR:
6854 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
6855 1579a72e ths
            switch (rd) {
6856 1579a72e ths
            case 0:
6857 97428a4d ths
                save_cpu_state(ctx, 1);
6858 1579a72e ths
                gen_op_rdhwr_cpunum();
6859 7a387fff ths
                break;
6860 1579a72e ths
            case 1:
6861 97428a4d ths
                save_cpu_state(ctx, 1);
6862 1579a72e ths
                gen_op_rdhwr_synci_step();
6863 7a387fff ths
                break;
6864 1579a72e ths
            case 2:
6865 97428a4d ths
                save_cpu_state(ctx, 1);
6866 1579a72e ths
                gen_op_rdhwr_cc();
6867 7a387fff ths
                break;
6868 1579a72e ths
            case 3:
6869 97428a4d ths
                save_cpu_state(ctx, 1);
6870 1579a72e ths
                gen_op_rdhwr_ccres();
6871 7a387fff ths
                break;
6872 1579a72e ths
            case 29:
6873 6f5b89a0 ths
#if defined (CONFIG_USER_ONLY)
6874 ead9360e ths
                gen_op_tls_value();
6875 1579a72e ths
                break;
6876 97428a4d ths
#endif
6877 1579a72e ths
            default:            /* Invalid */
6878 1579a72e ths
                MIPS_INVAL("rdhwr");
6879 1579a72e ths
                generate_exception(ctx, EXCP_RI);
6880 1579a72e ths
                break;
6881 1579a72e ths
            }
6882 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rt);
6883 1579a72e ths
            break;
6884 ead9360e ths
        case OPC_FORK:
6885 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
6886 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rt);
6887 8e9ade68 ths
            gen_load_gpr(cpu_T[1], rs);
6888 ead9360e ths
            gen_op_fork();
6889 ead9360e ths
            break;
6890 ead9360e ths
        case OPC_YIELD:
6891 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
6892 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rs);
6893 ead9360e ths
            gen_op_yield();
6894 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rd);
6895 ead9360e ths
            break;
6896 d26bc211 ths
#if defined(TARGET_MIPS64)
6897 1579a72e ths
        case OPC_DEXTM ... OPC_DEXT:
6898 1579a72e ths
        case OPC_DINSM ... OPC_DINS:
6899 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64R2);
6900 e189e748 ths
            check_mips_64(ctx);
6901 1579a72e ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6902 7a387fff ths
            break;
6903 1579a72e ths
        case OPC_DBSHFL:
6904 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64R2);
6905 e189e748 ths
            check_mips_64(ctx);
6906 1579a72e ths
            op2 = MASK_DBSHFL(ctx->opcode);
6907 1579a72e ths
            switch (op2) {
6908 1579a72e ths
            case OPC_DSBH:
6909 8e9ade68 ths
                gen_load_gpr(cpu_T[1], rt);
6910 1579a72e ths
                gen_op_dsbh();
6911 1579a72e ths
                break;
6912 1579a72e ths
            case OPC_DSHD:
6913 8e9ade68 ths
                gen_load_gpr(cpu_T[1], rt);
6914 1579a72e ths
                gen_op_dshd();
6915 1579a72e ths
                break;
6916 7a387fff ths
            default:            /* Invalid */
6917 7a387fff ths
                MIPS_INVAL("dbshfl");
6918 7a387fff ths
                generate_exception(ctx, EXCP_RI);
6919 7a387fff ths
                break;
6920 1579a72e ths
            }
6921 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rd);
6922 c6d6dd7c ths
            break;
6923 7a387fff ths
#endif
6924 7a387fff ths
        default:            /* Invalid */
6925 7a387fff ths
            MIPS_INVAL("special3");
6926 7a387fff ths
            generate_exception(ctx, EXCP_RI);
6927 7a387fff ths
            break;
6928 7a387fff ths
        }
6929 7a387fff ths
        break;
6930 7a387fff ths
    case OPC_REGIMM:
6931 7a387fff ths
        op1 = MASK_REGIMM(ctx->opcode);
6932 7a387fff ths
        switch (op1) {
6933 7a387fff ths
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6934 7a387fff ths
        case OPC_BLTZAL ... OPC_BGEZALL:
6935 7a387fff ths
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6936 6af0bf9c bellard
            return;
6937 7a387fff ths
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6938 7a387fff ths
        case OPC_TNEI:
6939 7a387fff ths
            gen_trap(ctx, op1, rs, -1, imm);
6940 7a387fff ths
            break;
6941 7a387fff ths
        case OPC_SYNCI:
6942 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
6943 ead9360e ths
            /* Treat as NOP. */
6944 6af0bf9c bellard
            break;
6945 6af0bf9c bellard
        default:            /* Invalid */
6946 923617a3 ths
            MIPS_INVAL("regimm");
6947 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
6948 6af0bf9c bellard
            break;
6949 6af0bf9c bellard
        }
6950 6af0bf9c bellard
        break;
6951 7a387fff ths
    case OPC_CP0:
6952 387a8fe5 ths
        check_cp0_enabled(ctx);
6953 7a387fff ths
        op1 = MASK_CP0(ctx->opcode);
6954 6af0bf9c bellard
        switch (op1) {
6955 7a387fff ths
        case OPC_MFC0:
6956 7a387fff ths
        case OPC_MTC0:
6957 ead9360e ths
        case OPC_MFTR:
6958 ead9360e ths
        case OPC_MTTR:
6959 d26bc211 ths
#if defined(TARGET_MIPS64)
6960 7a387fff ths
        case OPC_DMFC0:
6961 7a387fff ths
        case OPC_DMTC0:
6962 7a387fff ths
#endif
6963 29929e34 ths
            gen_cp0(env, ctx, op1, rt, rd);
6964 7a387fff ths
            break;
6965 7a387fff ths
        case OPC_C0_FIRST ... OPC_C0_LAST:
6966 29929e34 ths
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6967 7a387fff ths
            break;
6968 7a387fff ths
        case OPC_MFMC0:
6969 7a387fff ths
            op2 = MASK_MFMC0(ctx->opcode);
6970 7a387fff ths
            switch (op2) {
6971 ead9360e ths
            case OPC_DMT:
6972 7385ac0b ths
                check_insn(env, ctx, ASE_MT);
6973 ead9360e ths
                gen_op_dmt();
6974 ead9360e ths
                break;
6975 ead9360e ths
            case OPC_EMT:
6976 7385ac0b ths
                check_insn(env, ctx, ASE_MT);
6977 ead9360e ths
                gen_op_emt();
6978 ead9360e ths
                break;
6979 ead9360e ths
            case OPC_DVPE:
6980 7385ac0b ths
                check_insn(env, ctx, ASE_MT);
6981 ead9360e ths
                gen_op_dvpe();
6982 ead9360e ths
                break;
6983 ead9360e ths
            case OPC_EVPE:
6984 7385ac0b ths
                check_insn(env, ctx, ASE_MT);
6985 ead9360e ths
                gen_op_evpe();
6986 ead9360e ths
                break;
6987 7a387fff ths
            case OPC_DI:
6988 e189e748 ths
                check_insn(env, ctx, ISA_MIPS32R2);
6989 387a8fe5 ths
                save_cpu_state(ctx, 1);
6990 7a387fff ths
                gen_op_di();
6991 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
6992 7a387fff ths
                ctx->bstate = BS_STOP;
6993 7a387fff ths
                break;
6994 7a387fff ths
            case OPC_EI:
6995 e189e748 ths
                check_insn(env, ctx, ISA_MIPS32R2);
6996 387a8fe5 ths
                save_cpu_state(ctx, 1);
6997 7a387fff ths
                gen_op_ei();
6998 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
6999 7a387fff ths
                ctx->bstate = BS_STOP;
7000 7a387fff ths
                break;
7001 7a387fff ths
            default:            /* Invalid */
7002 923617a3 ths
                MIPS_INVAL("mfmc0");
7003 7a387fff ths
                generate_exception(ctx, EXCP_RI);
7004 7a387fff ths
                break;
7005 7a387fff ths
            }
7006 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rt);
7007 6af0bf9c bellard
            break;
7008 7a387fff ths
        case OPC_RDPGPR:
7009 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
7010 8e9ade68 ths
            gen_load_srsgpr(cpu_T[0], rt);
7011 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rd);
7012 ead9360e ths
            break;
7013 7a387fff ths
        case OPC_WRPGPR:
7014 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
7015 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rt);
7016 8e9ade68 ths
            gen_store_srsgpr(cpu_T[0], rd);
7017 38121543 ths
            break;
7018 6af0bf9c bellard
        default:
7019 923617a3 ths
            MIPS_INVAL("cp0");
7020 7a387fff ths
            generate_exception(ctx, EXCP_RI);
7021 6af0bf9c bellard
            break;
7022 6af0bf9c bellard
        }
7023 6af0bf9c bellard
        break;
7024 7a387fff ths
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7025 e189e748 ths
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7026 7a387fff ths
         break;
7027 7a387fff ths
    case OPC_J ... OPC_JAL: /* Jump */
7028 7a387fff ths
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7029 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, offset);
7030 7a387fff ths
         return;
7031 7a387fff ths
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7032 7a387fff ths
    case OPC_BEQL ... OPC_BGTZL:
7033 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7034 7a387fff ths
         return;
7035 7a387fff ths
    case OPC_LB ... OPC_LWR: /* Load and stores */
7036 7a387fff ths
    case OPC_SB ... OPC_SW:
7037 7a387fff ths
    case OPC_SWR:
7038 7a387fff ths
    case OPC_LL:
7039 7a387fff ths
    case OPC_SC:
7040 7a387fff ths
         gen_ldst(ctx, op, rt, rs, imm);
7041 7a387fff ths
         break;
7042 7a387fff ths
    case OPC_CACHE:
7043 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7044 ead9360e ths
        /* Treat as NOP. */
7045 34ae7b51 ths
        break;
7046 7a387fff ths
    case OPC_PREF:
7047 e189e748 ths
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7048 ead9360e ths
        /* Treat as NOP. */
7049 6af0bf9c bellard
        break;
7050 4ad40f36 bellard
7051 923617a3 ths
    /* Floating point (COP1). */
7052 7a387fff ths
    case OPC_LWC1:
7053 7a387fff ths
    case OPC_LDC1:
7054 7a387fff ths
    case OPC_SWC1:
7055 7a387fff ths
    case OPC_SDC1:
7056 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7057 36d23958 ths
            save_cpu_state(ctx, 1);
7058 5e755519 ths
            check_cp1_enabled(ctx);
7059 36d23958 ths
            gen_flt_ldst(ctx, op, rt, rs, imm);
7060 36d23958 ths
        } else {
7061 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
7062 36d23958 ths
        }
7063 6ea83fed bellard
        break;
7064 6ea83fed bellard
7065 7a387fff ths
    case OPC_CP1:
7066 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7067 36d23958 ths
            save_cpu_state(ctx, 1);
7068 5e755519 ths
            check_cp1_enabled(ctx);
7069 36d23958 ths
            op1 = MASK_CP1(ctx->opcode);
7070 36d23958 ths
            switch (op1) {
7071 3a95e3a7 ths
            case OPC_MFHC1:
7072 3a95e3a7 ths
            case OPC_MTHC1:
7073 e189e748 ths
                check_insn(env, ctx, ISA_MIPS32R2);
7074 36d23958 ths
            case OPC_MFC1:
7075 36d23958 ths
            case OPC_CFC1:
7076 36d23958 ths
            case OPC_MTC1:
7077 36d23958 ths
            case OPC_CTC1:
7078 e189e748 ths
                gen_cp1(ctx, op1, rt, rd);
7079 e189e748 ths
                break;
7080 d26bc211 ths
#if defined(TARGET_MIPS64)
7081 36d23958 ths
            case OPC_DMFC1:
7082 36d23958 ths
            case OPC_DMTC1:
7083 e189e748 ths
                check_insn(env, ctx, ISA_MIPS3);
7084 36d23958 ths
                gen_cp1(ctx, op1, rt, rd);
7085 36d23958 ths
                break;
7086 e189e748 ths
#endif
7087 fbcc6828 ths
            case OPC_BC1ANY2:
7088 fbcc6828 ths
            case OPC_BC1ANY4:
7089 b8aa4598 ths
                check_cop1x(ctx);
7090 7385ac0b ths
                check_insn(env, ctx, ASE_MIPS3D);
7091 d8a5950a ths
                /* fall through */
7092 d8a5950a ths
            case OPC_BC1:
7093 e189e748 ths
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7094 5a5012ec ths
                                    (rt >> 2) & 0x7, imm << 2);
7095 36d23958 ths
                return;
7096 36d23958 ths
            case OPC_S_FMT:
7097 36d23958 ths
            case OPC_D_FMT:
7098 36d23958 ths
            case OPC_W_FMT:
7099 36d23958 ths
            case OPC_L_FMT:
7100 5a5012ec ths
            case OPC_PS_FMT:
7101 5a5012ec ths
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7102 5a5012ec ths
                           (imm >> 8) & 0x7);
7103 36d23958 ths
                break;
7104 36d23958 ths
            default:
7105 923617a3 ths
                MIPS_INVAL("cp1");
7106 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
7107 36d23958 ths
                break;
7108 36d23958 ths
            }
7109 36d23958 ths
        } else {
7110 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
7111 6ea83fed bellard
        }
7112 4ad40f36 bellard
        break;
7113 4ad40f36 bellard
7114 4ad40f36 bellard
    /* COP2.  */
7115 7a387fff ths
    case OPC_LWC2:
7116 7a387fff ths
    case OPC_LDC2:
7117 7a387fff ths
    case OPC_SWC2:
7118 7a387fff ths
    case OPC_SDC2:
7119 7a387fff ths
    case OPC_CP2:
7120 7a387fff ths
        /* COP2: Not implemented. */
7121 4ad40f36 bellard
        generate_exception_err(ctx, EXCP_CpU, 2);
7122 4ad40f36 bellard
        break;
7123 4ad40f36 bellard
7124 7a387fff ths
    case OPC_CP3:
7125 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7126 e397ee33 ths
            save_cpu_state(ctx, 1);
7127 5e755519 ths
            check_cp1_enabled(ctx);
7128 36d23958 ths
            op1 = MASK_CP3(ctx->opcode);
7129 36d23958 ths
            switch (op1) {
7130 5a5012ec ths
            case OPC_LWXC1:
7131 5a5012ec ths
            case OPC_LDXC1:
7132 5a5012ec ths
            case OPC_LUXC1:
7133 5a5012ec ths
            case OPC_SWXC1:
7134 5a5012ec ths
            case OPC_SDXC1:
7135 5a5012ec ths
            case OPC_SUXC1:
7136 93b12ccc ths
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7137 5a5012ec ths
                break;
7138 e0c84da7 ths
            case OPC_PREFX:
7139 ead9360e ths
                /* Treat as NOP. */
7140 e0c84da7 ths
                break;
7141 5a5012ec ths
            case OPC_ALNV_PS:
7142 5a5012ec ths
            case OPC_MADD_S:
7143 5a5012ec ths
            case OPC_MADD_D:
7144 5a5012ec ths
            case OPC_MADD_PS:
7145 5a5012ec ths
            case OPC_MSUB_S:
7146 5a5012ec ths
            case OPC_MSUB_D:
7147 5a5012ec ths
            case OPC_MSUB_PS:
7148 5a5012ec ths
            case OPC_NMADD_S:
7149 5a5012ec ths
            case OPC_NMADD_D:
7150 5a5012ec ths
            case OPC_NMADD_PS:
7151 5a5012ec ths
            case OPC_NMSUB_S:
7152 5a5012ec ths
            case OPC_NMSUB_D:
7153 5a5012ec ths
            case OPC_NMSUB_PS:
7154 5a5012ec ths
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7155 5a5012ec ths
                break;
7156 36d23958 ths
            default:
7157 923617a3 ths
                MIPS_INVAL("cp3");
7158 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
7159 36d23958 ths
                break;
7160 36d23958 ths
            }
7161 36d23958 ths
        } else {
7162 e397ee33 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
7163 7a387fff ths
        }
7164 4ad40f36 bellard
        break;
7165 4ad40f36 bellard
7166 d26bc211 ths
#if defined(TARGET_MIPS64)
7167 7a387fff ths
    /* MIPS64 opcodes */
7168 7a387fff ths
    case OPC_LWU:
7169 7a387fff ths
    case OPC_LDL ... OPC_LDR:
7170 7a387fff ths
    case OPC_SDL ... OPC_SDR:
7171 7a387fff ths
    case OPC_LLD:
7172 7a387fff ths
    case OPC_LD:
7173 7a387fff ths
    case OPC_SCD:
7174 7a387fff ths
    case OPC_SD:
7175 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
7176 e189e748 ths
        check_mips_64(ctx);
7177 7a387fff ths
        gen_ldst(ctx, op, rt, rs, imm);
7178 7a387fff ths
        break;
7179 7a387fff ths
    case OPC_DADDI ... OPC_DADDIU:
7180 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
7181 e189e748 ths
        check_mips_64(ctx);
7182 e189e748 ths
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7183 7a387fff ths
        break;
7184 6af0bf9c bellard
#endif
7185 7a387fff ths
    case OPC_JALX:
7186 e189e748 ths
        check_insn(env, ctx, ASE_MIPS16);
7187 7a387fff ths
        /* MIPS16: Not implemented. */
7188 7a387fff ths
    case OPC_MDMX:
7189 e189e748 ths
        check_insn(env, ctx, ASE_MDMX);
7190 7a387fff ths
        /* MDMX: Not implemented. */
7191 6af0bf9c bellard
    default:            /* Invalid */
7192 923617a3 ths
        MIPS_INVAL("major opcode");
7193 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
7194 6af0bf9c bellard
        break;
7195 6af0bf9c bellard
    }
7196 4ad40f36 bellard
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7197 c53f4a62 ths
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7198 6af0bf9c bellard
        /* Branches completion */
7199 4ad40f36 bellard
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7200 6af0bf9c bellard
        ctx->bstate = BS_BRANCH;
7201 6af0bf9c bellard
        save_cpu_state(ctx, 0);
7202 5a5012ec ths
        switch (hflags) {
7203 6af0bf9c bellard
        case MIPS_HFLAG_B:
7204 6af0bf9c bellard
            /* unconditional branch */
7205 6af0bf9c bellard
            MIPS_DEBUG("unconditional branch");
7206 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
7207 6af0bf9c bellard
            break;
7208 6af0bf9c bellard
        case MIPS_HFLAG_BL:
7209 6af0bf9c bellard
            /* blikely taken case */
7210 6af0bf9c bellard
            MIPS_DEBUG("blikely branch taken");
7211 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
7212 6af0bf9c bellard
            break;
7213 6af0bf9c bellard
        case MIPS_HFLAG_BC:
7214 6af0bf9c bellard
            /* Conditional branch */
7215 6af0bf9c bellard
            MIPS_DEBUG("conditional branch");
7216 c53be334 bellard
            {
7217 8e9ade68 ths
                TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
7218 8e9ade68 ths
                int l1 = gen_new_label();
7219 8e9ade68 ths
7220 8e9ade68 ths
                tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7221 cb63669a pbrook
                tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7222 8e9ade68 ths
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7223 8e9ade68 ths
                gen_set_label(l1);
7224 8e9ade68 ths
                gen_goto_tb(ctx, 0, ctx->btarget);
7225 c53be334 bellard
            }
7226 6af0bf9c bellard
            break;
7227 6af0bf9c bellard
        case MIPS_HFLAG_BR:
7228 6af0bf9c bellard
            /* unconditional branch to register */
7229 6af0bf9c bellard
            MIPS_DEBUG("branch to register");
7230 8e9ade68 ths
            gen_breg_pc();
7231 57fec1fe bellard
            tcg_gen_exit_tb(0);
7232 6af0bf9c bellard
            break;
7233 6af0bf9c bellard
        default:
7234 6af0bf9c bellard
            MIPS_DEBUG("unknown branch");
7235 6af0bf9c bellard
            break;
7236 6af0bf9c bellard
        }
7237 6af0bf9c bellard
    }
7238 6af0bf9c bellard
}
7239 6af0bf9c bellard
7240 aa343735 ths
static always_inline int
7241 820e00f2 ths
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7242 820e00f2 ths
                                int search_pc)
7243 6af0bf9c bellard
{
7244 278d0702 ths
    DisasContext ctx;
7245 6af0bf9c bellard
    target_ulong pc_start;
7246 6af0bf9c bellard
    uint16_t *gen_opc_end;
7247 6af0bf9c bellard
    int j, lj = -1;
7248 6af0bf9c bellard
7249 4ad40f36 bellard
    if (search_pc && loglevel)
7250 6ea83fed bellard
        fprintf (logfile, "search pc %d\n", search_pc);
7251 4ad40f36 bellard
7252 8c99506c ths
    num_temps = 0;
7253 8c99506c ths
    memset(temps, 0, sizeof(temps));
7254 8c99506c ths
7255 48d38ca5 ths
    num_temps = 0;
7256 48d38ca5 ths
    memset(temps, 0, sizeof(temps));
7257 48d38ca5 ths
7258 6af0bf9c bellard
    pc_start = tb->pc;
7259 6af0bf9c bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7260 6af0bf9c bellard
    ctx.pc = pc_start;
7261 4ad40f36 bellard
    ctx.saved_pc = -1;
7262 6af0bf9c bellard
    ctx.tb = tb;
7263 6af0bf9c bellard
    ctx.bstate = BS_NONE;
7264 4ad40f36 bellard
    /* Restore delay slot state from the tb context.  */
7265 c068688b j_mayer
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7266 fd4a04eb ths
    restore_cpu_state(env, &ctx);
7267 6af0bf9c bellard
#if defined(CONFIG_USER_ONLY)
7268 623a930e ths
    ctx.mem_idx = MIPS_HFLAG_UM;
7269 6af0bf9c bellard
#else
7270 623a930e ths
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7271 6af0bf9c bellard
#endif
7272 6af0bf9c bellard
#ifdef DEBUG_DISAS
7273 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
7274 6af0bf9c bellard
        fprintf(logfile, "------------------------------------------------\n");
7275 4ad40f36 bellard
        /* FIXME: This may print out stale hflags from env... */
7276 6af0bf9c bellard
        cpu_dump_state(env, logfile, fprintf, 0);
7277 6af0bf9c bellard
    }
7278 6af0bf9c bellard
#endif
7279 923617a3 ths
#ifdef MIPS_DEBUG_DISAS
7280 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
7281 623a930e ths
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7282 4ad40f36 bellard
                tb, ctx.mem_idx, ctx.hflags);
7283 6af0bf9c bellard
#endif
7284 6af0bf9c bellard
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
7285 4ad40f36 bellard
        if (env->nb_breakpoints > 0) {
7286 4ad40f36 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
7287 4ad40f36 bellard
                if (env->breakpoints[j] == ctx.pc) {
7288 278d0702 ths
                    save_cpu_state(&ctx, 1);
7289 4ad40f36 bellard
                    ctx.bstate = BS_BRANCH;
7290 4ad40f36 bellard
                    gen_op_debug();
7291 ce62e5ba ths
                    /* Include the breakpoint location or the tb won't
7292 ce62e5ba ths
                     * be flushed when it must be.  */
7293 ce62e5ba ths
                    ctx.pc += 4;
7294 4ad40f36 bellard
                    goto done_generating;
7295 4ad40f36 bellard
                }
7296 4ad40f36 bellard
            }
7297 4ad40f36 bellard
        }
7298 4ad40f36 bellard
7299 6af0bf9c bellard
        if (search_pc) {
7300 6af0bf9c bellard
            j = gen_opc_ptr - gen_opc_buf;
7301 6af0bf9c bellard
            if (lj < j) {
7302 6af0bf9c bellard
                lj++;
7303 6af0bf9c bellard
                while (lj < j)
7304 6af0bf9c bellard
                    gen_opc_instr_start[lj++] = 0;
7305 6af0bf9c bellard
            }
7306 4ad40f36 bellard
            gen_opc_pc[lj] = ctx.pc;
7307 4ad40f36 bellard
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7308 4ad40f36 bellard
            gen_opc_instr_start[lj] = 1;
7309 6af0bf9c bellard
        }
7310 6af0bf9c bellard
        ctx.opcode = ldl_code(ctx.pc);
7311 36d23958 ths
        decode_opc(env, &ctx);
7312 8c99506c ths
        if (num_temps) {
7313 8c99506c ths
            fprintf(stderr,
7314 8c99506c ths
                    "Internal resource leak before " TARGET_FMT_lx "\n",
7315 8c99506c ths
                    ctx.pc);
7316 8c99506c ths
            num_temps = 0;
7317 8c99506c ths
        }
7318 6af0bf9c bellard
        ctx.pc += 4;
7319 4ad40f36 bellard
7320 4ad40f36 bellard
        if (env->singlestep_enabled)
7321 4ad40f36 bellard
            break;
7322 4ad40f36 bellard
7323 6af0bf9c bellard
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7324 6af0bf9c bellard
            break;
7325 4ad40f36 bellard
7326 6af0bf9c bellard
#if defined (MIPS_SINGLE_STEP)
7327 6af0bf9c bellard
        break;
7328 6af0bf9c bellard
#endif
7329 6af0bf9c bellard
    }
7330 4ad40f36 bellard
    if (env->singlestep_enabled) {
7331 278d0702 ths
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7332 4ad40f36 bellard
        gen_op_debug();
7333 16c00cb2 ths
    } else {
7334 16c00cb2 ths
        switch (ctx.bstate) {
7335 16c00cb2 ths
        case BS_STOP:
7336 48d38ca5 ths
            tcg_gen_helper_0_0(do_interrupt_restart);
7337 df1561e2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
7338 df1561e2 ths
            break;
7339 16c00cb2 ths
        case BS_NONE:
7340 278d0702 ths
            save_cpu_state(&ctx, 0);
7341 16c00cb2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
7342 16c00cb2 ths
            break;
7343 5a5012ec ths
        case BS_EXCP:
7344 48d38ca5 ths
            tcg_gen_helper_0_0(do_interrupt_restart);
7345 57fec1fe bellard
            tcg_gen_exit_tb(0);
7346 16c00cb2 ths
            break;
7347 5a5012ec ths
        case BS_BRANCH:
7348 5a5012ec ths
        default:
7349 5a5012ec ths
            break;
7350 16c00cb2 ths
        }
7351 6af0bf9c bellard
    }
7352 4ad40f36 bellard
done_generating:
7353 6af0bf9c bellard
    *gen_opc_ptr = INDEX_op_end;
7354 6af0bf9c bellard
    if (search_pc) {
7355 6af0bf9c bellard
        j = gen_opc_ptr - gen_opc_buf;
7356 6af0bf9c bellard
        lj++;
7357 6af0bf9c bellard
        while (lj <= j)
7358 6af0bf9c bellard
            gen_opc_instr_start[lj++] = 0;
7359 6af0bf9c bellard
    } else {
7360 6af0bf9c bellard
        tb->size = ctx.pc - pc_start;
7361 6af0bf9c bellard
    }
7362 6af0bf9c bellard
#ifdef DEBUG_DISAS
7363 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
7364 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
7365 6af0bf9c bellard
        fprintf(logfile, "\n");
7366 6af0bf9c bellard
#endif
7367 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7368 6af0bf9c bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7369 9898128f ths
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7370 6af0bf9c bellard
        fprintf(logfile, "\n");
7371 6af0bf9c bellard
    }
7372 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
7373 6af0bf9c bellard
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7374 6af0bf9c bellard
    }
7375 6af0bf9c bellard
#endif
7376 3b46e624 ths
7377 6af0bf9c bellard
    return 0;
7378 6af0bf9c bellard
}
7379 6af0bf9c bellard
7380 6af0bf9c bellard
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7381 6af0bf9c bellard
{
7382 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 0);
7383 6af0bf9c bellard
}
7384 6af0bf9c bellard
7385 6af0bf9c bellard
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7386 6af0bf9c bellard
{
7387 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 1);
7388 6af0bf9c bellard
}
7389 6af0bf9c bellard
7390 5fafdf24 ths
void fpu_dump_state(CPUState *env, FILE *f,
7391 6ea83fed bellard
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7392 6ea83fed bellard
                    int flags)
7393 6ea83fed bellard
{
7394 6ea83fed bellard
    int i;
7395 5e755519 ths
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7396 5a5012ec ths
7397 5a5012ec ths
#define printfpr(fp)                                                        \
7398 5a5012ec ths
    do {                                                                    \
7399 5a5012ec ths
        if (is_fpu64)                                                       \
7400 5a5012ec ths
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
7401 5a5012ec ths
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
7402 5a5012ec ths
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7403 5a5012ec ths
        else {                                                              \
7404 5a5012ec ths
            fpr_t tmp;                                                      \
7405 5a5012ec ths
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
7406 5a5012ec ths
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
7407 5a5012ec ths
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
7408 5a5012ec ths
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
7409 5a5012ec ths
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
7410 5a5012ec ths
        }                                                                   \
7411 6ea83fed bellard
    } while(0)
7412 6ea83fed bellard
7413 5a5012ec ths
7414 5a5012ec ths
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
7415 ead9360e ths
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7416 ead9360e ths
                get_float_exception_flags(&env->fpu->fp_status));
7417 ead9360e ths
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
7418 ead9360e ths
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
7419 ead9360e ths
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
7420 5a5012ec ths
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7421 5a5012ec ths
        fpu_fprintf(f, "%3s: ", fregnames[i]);
7422 ead9360e ths
        printfpr(&env->fpu->fpr[i]);
7423 6ea83fed bellard
    }
7424 6ea83fed bellard
7425 6ea83fed bellard
#undef printfpr
7426 6ea83fed bellard
}
7427 6ea83fed bellard
7428 7a387fff ths
void dump_fpu (CPUState *env)
7429 6ea83fed bellard
{
7430 5fafdf24 ths
    if (loglevel) {
7431 958fb4a9 ths
        fprintf(logfile,
7432 958fb4a9 ths
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7433 958fb4a9 ths
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7434 958fb4a9 ths
                " %04x\n",
7435 958fb4a9 ths
                env->PC[env->current_tc], env->HI[env->current_tc][0],
7436 958fb4a9 ths
                env->LO[env->current_tc][0], env->hflags, env->btarget,
7437 958fb4a9 ths
                env->bcond);
7438 6ea83fed bellard
       fpu_dump_state(env, logfile, fprintf, 0);
7439 6ea83fed bellard
    }
7440 6ea83fed bellard
}
7441 6ea83fed bellard
7442 d26bc211 ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7443 c570fd16 ths
/* Debug help: The architecture requires 32bit code to maintain proper
7444 c570fd16 ths
   sign-extened values on 64bit machines.  */
7445 c570fd16 ths
7446 c570fd16 ths
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7447 c570fd16 ths
7448 c570fd16 ths
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7449 c570fd16 ths
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7450 c570fd16 ths
                     int flags)
7451 c570fd16 ths
{
7452 c570fd16 ths
    int i;
7453 c570fd16 ths
7454 ead9360e ths
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7455 ead9360e ths
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7456 d0dc7dc3 ths
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7457 d0dc7dc3 ths
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7458 d0dc7dc3 ths
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7459 d0dc7dc3 ths
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7460 c570fd16 ths
    if (!SIGN_EXT_P(env->btarget))
7461 3594c774 ths
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7462 c570fd16 ths
7463 c570fd16 ths
    for (i = 0; i < 32; i++) {
7464 d0dc7dc3 ths
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7465 d0dc7dc3 ths
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7466 c570fd16 ths
    }
7467 c570fd16 ths
7468 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_EPC))
7469 3594c774 ths
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7470 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7471 3594c774 ths
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7472 c570fd16 ths
}
7473 c570fd16 ths
#endif
7474 c570fd16 ths
7475 5fafdf24 ths
void cpu_dump_state (CPUState *env, FILE *f,
7476 6af0bf9c bellard
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7477 6af0bf9c bellard
                     int flags)
7478 6af0bf9c bellard
{
7479 6af0bf9c bellard
    int i;
7480 3b46e624 ths
7481 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",
7482 ead9360e ths
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7483 6af0bf9c bellard
    for (i = 0; i < 32; i++) {
7484 6af0bf9c bellard
        if ((i & 3) == 0)
7485 6af0bf9c bellard
            cpu_fprintf(f, "GPR%02d:", i);
7486 d0dc7dc3 ths
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7487 6af0bf9c bellard
        if ((i & 3) == 3)
7488 6af0bf9c bellard
            cpu_fprintf(f, "\n");
7489 6af0bf9c bellard
    }
7490 568b600d bellard
7491 3594c774 ths
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7492 5e755519 ths
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7493 3594c774 ths
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7494 6af0bf9c bellard
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7495 5e755519 ths
    if (env->hflags & MIPS_HFLAG_FPU)
7496 7a387fff ths
        fpu_dump_state(env, f, cpu_fprintf, flags);
7497 d26bc211 ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7498 c570fd16 ths
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7499 c570fd16 ths
#endif
7500 6af0bf9c bellard
}
7501 6af0bf9c bellard
7502 39454628 ths
static void mips_tcg_init(void)
7503 39454628 ths
{
7504 39454628 ths
    static int inited;
7505 39454628 ths
7506 39454628 ths
    /* Initialize various static tables. */
7507 39454628 ths
    if (inited)
7508 39454628 ths
        return;
7509 39454628 ths
7510 39454628 ths
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7511 958fb4a9 ths
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7512 958fb4a9 ths
                                         TCG_AREG0,
7513 958fb4a9 ths
                                         offsetof(CPUState, current_tc_gprs),
7514 958fb4a9 ths
                                         "current_tc_gprs");
7515 39454628 ths
#if TARGET_LONG_BITS > HOST_LONG_BITS
7516 39454628 ths
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7517 39454628 ths
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7518 39454628 ths
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7519 39454628 ths
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7520 39454628 ths
#else
7521 958fb4a9 ths
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7522 958fb4a9 ths
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7523 39454628 ths
#endif
7524 39454628 ths
7525 39454628 ths
    inited = 1;
7526 39454628 ths
}
7527 39454628 ths
7528 aaed909a bellard
#include "translate_init.c"
7529 aaed909a bellard
7530 aaed909a bellard
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7531 6af0bf9c bellard
{
7532 6af0bf9c bellard
    CPUMIPSState *env;
7533 aaed909a bellard
    const mips_def_t *def;
7534 6af0bf9c bellard
7535 aaed909a bellard
    def = cpu_mips_find_by_name(cpu_model);
7536 aaed909a bellard
    if (!def)
7537 aaed909a bellard
        return NULL;
7538 6af0bf9c bellard
    env = qemu_mallocz(sizeof(CPUMIPSState));
7539 6af0bf9c bellard
    if (!env)
7540 6af0bf9c bellard
        return NULL;
7541 aaed909a bellard
    env->cpu_model = def;
7542 aaed909a bellard
7543 173d6cfe bellard
    cpu_exec_init(env);
7544 01ba9816 ths
    env->cpu_model_str = cpu_model;
7545 39454628 ths
    mips_tcg_init();
7546 6ae81775 ths
    cpu_reset(env);
7547 6ae81775 ths
    return env;
7548 6ae81775 ths
}
7549 6ae81775 ths
7550 6ae81775 ths
void cpu_reset (CPUMIPSState *env)
7551 6ae81775 ths
{
7552 6ae81775 ths
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7553 6ae81775 ths
7554 6af0bf9c bellard
    tlb_flush(env, 1);
7555 6ae81775 ths
7556 6af0bf9c bellard
    /* Minimal init */
7557 ca7c2b1b ths
#if !defined(CONFIG_USER_ONLY)
7558 aa328add ths
    if (env->hflags & MIPS_HFLAG_BMASK) {
7559 aa328add ths
        /* If the exception was raised from a delay slot,
7560 aa328add ths
         * come back to the jump.  */
7561 ead9360e ths
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7562 aa328add ths
    } else {
7563 ead9360e ths
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7564 aa328add ths
    }
7565 ead9360e ths
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7566 6af0bf9c bellard
    env->CP0_Wired = 0;
7567 7a387fff ths
    /* SMP not implemented */
7568 b29a0341 ths
    env->CP0_EBase = 0x80000000;
7569 aa328add ths
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7570 c090a8f4 ths
    /* vectored interrupts not implemented, timer on int 7,
7571 c090a8f4 ths
       no performance counters. */
7572 c090a8f4 ths
    env->CP0_IntCtl = 0xe0000000;
7573 fd88b6ab ths
    {
7574 fd88b6ab ths
        int i;
7575 fd88b6ab ths
7576 fd88b6ab ths
        for (i = 0; i < 7; i++) {
7577 fd88b6ab ths
            env->CP0_WatchLo[i] = 0;
7578 fd88b6ab ths
            env->CP0_WatchHi[i] = 0x80000000;
7579 fd88b6ab ths
        }
7580 fd88b6ab ths
        env->CP0_WatchLo[7] = 0;
7581 fd88b6ab ths
        env->CP0_WatchHi[7] = 0;
7582 fd88b6ab ths
    }
7583 6af0bf9c bellard
    /* Count register increments in debug mode, EJTAG version 1 */
7584 6af0bf9c bellard
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7585 ca7c2b1b ths
#endif
7586 6af0bf9c bellard
    env->exception_index = EXCP_NONE;
7587 eeef26cd bellard
#if defined(CONFIG_USER_ONLY)
7588 387a8fe5 ths
    env->hflags = MIPS_HFLAG_UM;
7589 ca7c2b1b ths
    env->user_mode_only = 1;
7590 387a8fe5 ths
#else
7591 387a8fe5 ths
    env->hflags = MIPS_HFLAG_CP0;
7592 eeef26cd bellard
#endif
7593 aaed909a bellard
    cpu_mips_register(env, env->cpu_model);
7594 6af0bf9c bellard
}
7595 d2856f1a aurel32
7596 d2856f1a aurel32
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7597 d2856f1a aurel32
                unsigned long searched_pc, int pc_pos, void *puc)
7598 d2856f1a aurel32
{
7599 d2856f1a aurel32
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7600 d2856f1a aurel32
    env->hflags &= ~MIPS_HFLAG_BMASK;
7601 d2856f1a aurel32
    env->hflags |= gen_opc_hflags[pc_pos];
7602 d2856f1a aurel32
}