Statistics
| Branch: | Revision:

root / target-mips / translate.c @ aa0bf00b

History | View | Annotate | Download (224.6 kB)

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