Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d66c7132

History | View | Annotate | Download (247.5 kB)

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