Statistics
| Branch: | Revision:

root / target-mips / translate.c @ df357f0e

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