Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a3fe9013

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