Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a7812ae4

History | View | Annotate | Download (247.2 kB)

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