Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 651721b2

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