Statistics
| Branch: | Revision:

root / target-mips / translate.c @ aefbc83e

History | View | Annotate | Download (248.4 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 007ac6fa aurel32
            if (ctx->opcode & (1 << 6)) {
6382 007ac6fa aurel32
                check_cop1x(ctx);
6383 007ac6fa aurel32
            }
6384 007ac6fa aurel32
6385 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6386 b6d96bed ths
            gen_load_fpr32(fp1, ft);
6387 b6d96bed ths
            if (ctx->opcode & (1 << 6)) {
6388 b6d96bed ths
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6389 b6d96bed ths
                opn = condnames_abs[func-48];
6390 b6d96bed ths
            } else {
6391 b6d96bed ths
                gen_cmp_s(func-48, fp0, fp1, cc);
6392 b6d96bed ths
                opn = condnames[func-48];
6393 b6d96bed ths
            }
6394 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6395 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
6396 5a1e8ffb ths
        }
6397 5a5012ec ths
        break;
6398 6ea83fed bellard
    case FOP(0, 17):
6399 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
6400 b6d96bed ths
        {
6401 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6402 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6403 b6d96bed ths
6404 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6405 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6406 a7812ae4 pbrook
            gen_helper_float_add_d(fp0, fp0, fp1);
6407 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6408 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6409 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6410 b6d96bed ths
        }
6411 6ea83fed bellard
        opn = "add.d";
6412 5a1e8ffb ths
        optype = BINOP;
6413 6ea83fed bellard
        break;
6414 6ea83fed bellard
    case FOP(1, 17):
6415 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
6416 b6d96bed ths
        {
6417 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6418 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6419 b6d96bed ths
6420 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6421 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6422 a7812ae4 pbrook
            gen_helper_float_sub_d(fp0, fp0, fp1);
6423 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6424 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6425 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6426 b6d96bed ths
        }
6427 6ea83fed bellard
        opn = "sub.d";
6428 5a1e8ffb ths
        optype = BINOP;
6429 6ea83fed bellard
        break;
6430 6ea83fed bellard
    case FOP(2, 17):
6431 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
6432 b6d96bed ths
        {
6433 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6434 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6435 b6d96bed ths
6436 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6437 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6438 a7812ae4 pbrook
            gen_helper_float_mul_d(fp0, fp0, fp1);
6439 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6440 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6441 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6442 b6d96bed ths
        }
6443 6ea83fed bellard
        opn = "mul.d";
6444 5a1e8ffb ths
        optype = BINOP;
6445 6ea83fed bellard
        break;
6446 6ea83fed bellard
    case FOP(3, 17):
6447 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
6448 b6d96bed ths
        {
6449 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6450 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6451 b6d96bed ths
6452 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6453 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6454 a7812ae4 pbrook
            gen_helper_float_div_d(fp0, fp0, fp1);
6455 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6456 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6457 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6458 b6d96bed ths
        }
6459 6ea83fed bellard
        opn = "div.d";
6460 5a1e8ffb ths
        optype = BINOP;
6461 6ea83fed bellard
        break;
6462 6ea83fed bellard
    case FOP(4, 17):
6463 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
6464 b6d96bed ths
        {
6465 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6466 b6d96bed ths
6467 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6468 a7812ae4 pbrook
            gen_helper_float_sqrt_d(fp0, fp0);
6469 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6470 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6471 b6d96bed ths
        }
6472 6ea83fed bellard
        opn = "sqrt.d";
6473 6ea83fed bellard
        break;
6474 6ea83fed bellard
    case FOP(5, 17):
6475 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
6476 b6d96bed ths
        {
6477 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6478 b6d96bed ths
6479 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6480 a7812ae4 pbrook
            gen_helper_float_abs_d(fp0, fp0);
6481 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6482 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6483 b6d96bed ths
        }
6484 6ea83fed bellard
        opn = "abs.d";
6485 6ea83fed bellard
        break;
6486 6ea83fed bellard
    case FOP(6, 17):
6487 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
6488 b6d96bed ths
        {
6489 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6490 b6d96bed ths
6491 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6492 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6493 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6494 b6d96bed ths
        }
6495 6ea83fed bellard
        opn = "mov.d";
6496 6ea83fed bellard
        break;
6497 6ea83fed bellard
    case FOP(7, 17):
6498 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
6499 b6d96bed ths
        {
6500 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6501 b6d96bed ths
6502 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6503 a7812ae4 pbrook
            gen_helper_float_chs_d(fp0, fp0);
6504 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6505 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6506 b6d96bed ths
        }
6507 6ea83fed bellard
        opn = "neg.d";
6508 6ea83fed bellard
        break;
6509 5a5012ec ths
    case FOP(8, 17):
6510 5e755519 ths
        check_cp1_64bitmode(ctx);
6511 b6d96bed ths
        {
6512 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6513 b6d96bed ths
6514 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6515 a7812ae4 pbrook
            gen_helper_float_roundl_d(fp0, fp0);
6516 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6517 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6518 b6d96bed ths
        }
6519 5a5012ec ths
        opn = "round.l.d";
6520 5a5012ec ths
        break;
6521 5a5012ec ths
    case FOP(9, 17):
6522 5e755519 ths
        check_cp1_64bitmode(ctx);
6523 b6d96bed ths
        {
6524 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6525 b6d96bed ths
6526 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6527 a7812ae4 pbrook
            gen_helper_float_truncl_d(fp0, fp0);
6528 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6529 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6530 b6d96bed ths
        }
6531 5a5012ec ths
        opn = "trunc.l.d";
6532 5a5012ec ths
        break;
6533 5a5012ec ths
    case FOP(10, 17):
6534 5e755519 ths
        check_cp1_64bitmode(ctx);
6535 b6d96bed ths
        {
6536 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6537 b6d96bed ths
6538 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6539 a7812ae4 pbrook
            gen_helper_float_ceill_d(fp0, fp0);
6540 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6541 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6542 b6d96bed ths
        }
6543 5a5012ec ths
        opn = "ceil.l.d";
6544 5a5012ec ths
        break;
6545 5a5012ec ths
    case FOP(11, 17):
6546 5e755519 ths
        check_cp1_64bitmode(ctx);
6547 b6d96bed ths
        {
6548 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6549 b6d96bed ths
6550 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6551 a7812ae4 pbrook
            gen_helper_float_floorl_d(fp0, fp0);
6552 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6553 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6554 b6d96bed ths
        }
6555 5a5012ec ths
        opn = "floor.l.d";
6556 5a5012ec ths
        break;
6557 6ea83fed bellard
    case FOP(12, 17):
6558 5e755519 ths
        check_cp1_registers(ctx, fs);
6559 b6d96bed ths
        {
6560 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6561 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6562 b6d96bed ths
6563 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
6564 a7812ae4 pbrook
            gen_helper_float_roundw_d(fp32, fp64);
6565 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6566 b6d96bed ths
            gen_store_fpr32(fp32, fd);
6567 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6568 b6d96bed ths
        }
6569 6ea83fed bellard
        opn = "round.w.d";
6570 6ea83fed bellard
        break;
6571 6ea83fed bellard
    case FOP(13, 17):
6572 5e755519 ths
        check_cp1_registers(ctx, fs);
6573 b6d96bed ths
        {
6574 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6575 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6576 b6d96bed ths
6577 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
6578 a7812ae4 pbrook
            gen_helper_float_truncw_d(fp32, fp64);
6579 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6580 b6d96bed ths
            gen_store_fpr32(fp32, fd);
6581 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6582 b6d96bed ths
        }
6583 6ea83fed bellard
        opn = "trunc.w.d";
6584 6ea83fed bellard
        break;
6585 6ea83fed bellard
    case FOP(14, 17):
6586 5e755519 ths
        check_cp1_registers(ctx, fs);
6587 b6d96bed ths
        {
6588 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6589 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6590 b6d96bed ths
6591 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
6592 a7812ae4 pbrook
            gen_helper_float_ceilw_d(fp32, fp64);
6593 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6594 b6d96bed ths
            gen_store_fpr32(fp32, fd);
6595 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6596 b6d96bed ths
        }
6597 6ea83fed bellard
        opn = "ceil.w.d";
6598 6ea83fed bellard
        break;
6599 6ea83fed bellard
    case FOP(15, 17):
6600 5e755519 ths
        check_cp1_registers(ctx, fs);
6601 b6d96bed ths
        {
6602 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6603 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6604 b6d96bed ths
6605 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
6606 a7812ae4 pbrook
            gen_helper_float_floorw_d(fp32, fp64);
6607 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6608 b6d96bed ths
            gen_store_fpr32(fp32, fd);
6609 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6610 b6d96bed ths
        }
6611 7a387fff ths
        opn = "floor.w.d";
6612 6ea83fed bellard
        break;
6613 5a5012ec ths
    case FOP(17, 17):
6614 b6d96bed ths
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6615 5a5012ec ths
        opn = "movcf.d";
6616 dd016883 bellard
        break;
6617 5a5012ec ths
    case FOP(18, 17):
6618 a16336e4 ths
        {
6619 a16336e4 ths
            int l1 = gen_new_label();
6620 c9297f4d aurel32
            TCGv_i64 fp0;
6621 a16336e4 ths
6622 c9297f4d aurel32
            if (ft != 0) {
6623 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6624 c9297f4d aurel32
            }
6625 c9297f4d aurel32
            fp0 = tcg_temp_new_i64();
6626 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6627 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6628 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6629 a16336e4 ths
            gen_set_label(l1);
6630 a16336e4 ths
        }
6631 5a5012ec ths
        opn = "movz.d";
6632 5a5012ec ths
        break;
6633 5a5012ec ths
    case FOP(19, 17):
6634 a16336e4 ths
        {
6635 a16336e4 ths
            int l1 = gen_new_label();
6636 c9297f4d aurel32
            TCGv_i64 fp0;
6637 c9297f4d aurel32
6638 c9297f4d aurel32
            if (ft != 0) {
6639 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6640 c9297f4d aurel32
                fp0 = tcg_temp_new_i64();
6641 c9297f4d aurel32
                gen_load_fpr64(ctx, fp0, fs);
6642 c9297f4d aurel32
                gen_store_fpr64(ctx, fp0, fd);
6643 c9297f4d aurel32
                tcg_temp_free_i64(fp0);
6644 c9297f4d aurel32
                gen_set_label(l1);
6645 c9297f4d aurel32
            }
6646 a16336e4 ths
        }
6647 5a5012ec ths
        opn = "movn.d";
6648 6ea83fed bellard
        break;
6649 57fa1fb3 ths
    case FOP(21, 17):
6650 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6651 b6d96bed ths
        {
6652 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6653 b6d96bed ths
6654 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6655 a7812ae4 pbrook
            gen_helper_float_recip_d(fp0, fp0);
6656 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6657 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6658 b6d96bed ths
        }
6659 57fa1fb3 ths
        opn = "recip.d";
6660 57fa1fb3 ths
        break;
6661 57fa1fb3 ths
    case FOP(22, 17):
6662 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6663 b6d96bed ths
        {
6664 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6665 b6d96bed ths
6666 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6667 a7812ae4 pbrook
            gen_helper_float_rsqrt_d(fp0, fp0);
6668 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6669 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6670 b6d96bed ths
        }
6671 57fa1fb3 ths
        opn = "rsqrt.d";
6672 57fa1fb3 ths
        break;
6673 57fa1fb3 ths
    case FOP(28, 17):
6674 5e755519 ths
        check_cp1_64bitmode(ctx);
6675 b6d96bed ths
        {
6676 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6677 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6678 b6d96bed ths
6679 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6680 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6681 a7812ae4 pbrook
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6682 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6683 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6684 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6685 b6d96bed ths
        }
6686 57fa1fb3 ths
        opn = "recip2.d";
6687 57fa1fb3 ths
        break;
6688 57fa1fb3 ths
    case FOP(29, 17):
6689 5e755519 ths
        check_cp1_64bitmode(ctx);
6690 b6d96bed ths
        {
6691 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6692 b6d96bed ths
6693 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6694 a7812ae4 pbrook
            gen_helper_float_recip1_d(fp0, fp0);
6695 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6696 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6697 b6d96bed ths
        }
6698 57fa1fb3 ths
        opn = "recip1.d";
6699 57fa1fb3 ths
        break;
6700 57fa1fb3 ths
    case FOP(30, 17):
6701 5e755519 ths
        check_cp1_64bitmode(ctx);
6702 b6d96bed ths
        {
6703 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6704 b6d96bed ths
6705 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6706 a7812ae4 pbrook
            gen_helper_float_rsqrt1_d(fp0, fp0);
6707 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6708 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6709 b6d96bed ths
        }
6710 57fa1fb3 ths
        opn = "rsqrt1.d";
6711 57fa1fb3 ths
        break;
6712 57fa1fb3 ths
    case FOP(31, 17):
6713 5e755519 ths
        check_cp1_64bitmode(ctx);
6714 b6d96bed ths
        {
6715 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6716 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6717 b6d96bed ths
6718 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6719 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6720 a7812ae4 pbrook
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6721 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6722 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6723 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6724 b6d96bed ths
        }
6725 57fa1fb3 ths
        opn = "rsqrt2.d";
6726 57fa1fb3 ths
        break;
6727 6ea83fed bellard
    case FOP(48, 17):
6728 6ea83fed bellard
    case FOP(49, 17):
6729 6ea83fed bellard
    case FOP(50, 17):
6730 6ea83fed bellard
    case FOP(51, 17):
6731 6ea83fed bellard
    case FOP(52, 17):
6732 6ea83fed bellard
    case FOP(53, 17):
6733 6ea83fed bellard
    case FOP(54, 17):
6734 6ea83fed bellard
    case FOP(55, 17):
6735 6ea83fed bellard
    case FOP(56, 17):
6736 6ea83fed bellard
    case FOP(57, 17):
6737 6ea83fed bellard
    case FOP(58, 17):
6738 6ea83fed bellard
    case FOP(59, 17):
6739 6ea83fed bellard
    case FOP(60, 17):
6740 6ea83fed bellard
    case FOP(61, 17):
6741 6ea83fed bellard
    case FOP(62, 17):
6742 6ea83fed bellard
    case FOP(63, 17):
6743 b6d96bed ths
        {
6744 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6745 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6746 007ac6fa aurel32
            if (ctx->opcode & (1 << 6)) {
6747 007ac6fa aurel32
                check_cop1x(ctx);
6748 007ac6fa aurel32
            }
6749 007ac6fa aurel32
            check_cp1_registers(ctx, fs | ft);
6750 b6d96bed ths
6751 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6752 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6753 b6d96bed ths
            if (ctx->opcode & (1 << 6)) {
6754 b6d96bed ths
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6755 b6d96bed ths
                opn = condnames_abs[func-48];
6756 b6d96bed ths
            } else {
6757 b6d96bed ths
                gen_cmp_d(func-48, fp0, fp1, cc);
6758 b6d96bed ths
                opn = condnames[func-48];
6759 b6d96bed ths
            }
6760 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6761 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6762 5a1e8ffb ths
        }
6763 6ea83fed bellard
        break;
6764 5a5012ec ths
    case FOP(32, 17):
6765 5e755519 ths
        check_cp1_registers(ctx, fs);
6766 b6d96bed ths
        {
6767 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6768 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6769 b6d96bed ths
6770 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
6771 a7812ae4 pbrook
            gen_helper_float_cvts_d(fp32, fp64);
6772 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6773 b6d96bed ths
            gen_store_fpr32(fp32, fd);
6774 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6775 b6d96bed ths
        }
6776 5a5012ec ths
        opn = "cvt.s.d";
6777 5a5012ec ths
        break;
6778 5a5012ec ths
    case FOP(36, 17):
6779 5e755519 ths
        check_cp1_registers(ctx, fs);
6780 b6d96bed ths
        {
6781 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6782 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6783 b6d96bed ths
6784 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
6785 a7812ae4 pbrook
            gen_helper_float_cvtw_d(fp32, fp64);
6786 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6787 b6d96bed ths
            gen_store_fpr32(fp32, fd);
6788 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6789 b6d96bed ths
        }
6790 5a5012ec ths
        opn = "cvt.w.d";
6791 5a5012ec ths
        break;
6792 5a5012ec ths
    case FOP(37, 17):
6793 5e755519 ths
        check_cp1_64bitmode(ctx);
6794 b6d96bed ths
        {
6795 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6796 b6d96bed ths
6797 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6798 a7812ae4 pbrook
            gen_helper_float_cvtl_d(fp0, fp0);
6799 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6800 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6801 b6d96bed ths
        }
6802 5a5012ec ths
        opn = "cvt.l.d";
6803 5a5012ec ths
        break;
6804 5a5012ec ths
    case FOP(32, 20):
6805 b6d96bed ths
        {
6806 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6807 b6d96bed ths
6808 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6809 a7812ae4 pbrook
            gen_helper_float_cvts_w(fp0, fp0);
6810 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6811 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6812 b6d96bed ths
        }
6813 5a5012ec ths
        opn = "cvt.s.w";
6814 6ea83fed bellard
        break;
6815 5a5012ec ths
    case FOP(33, 20):
6816 5e755519 ths
        check_cp1_registers(ctx, fd);
6817 b6d96bed ths
        {
6818 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6819 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6820 b6d96bed ths
6821 b6d96bed ths
            gen_load_fpr32(fp32, fs);
6822 a7812ae4 pbrook
            gen_helper_float_cvtd_w(fp64, fp32);
6823 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6824 b6d96bed ths
            gen_store_fpr64(ctx, fp64, fd);
6825 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6826 b6d96bed ths
        }
6827 5a5012ec ths
        opn = "cvt.d.w";
6828 5a5012ec ths
        break;
6829 5a5012ec ths
    case FOP(32, 21):
6830 5e755519 ths
        check_cp1_64bitmode(ctx);
6831 b6d96bed ths
        {
6832 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6833 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6834 b6d96bed ths
6835 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
6836 a7812ae4 pbrook
            gen_helper_float_cvts_l(fp32, fp64);
6837 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6838 b6d96bed ths
            gen_store_fpr32(fp32, fd);
6839 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6840 b6d96bed ths
        }
6841 5a5012ec ths
        opn = "cvt.s.l";
6842 5a5012ec ths
        break;
6843 5a5012ec ths
    case FOP(33, 21):
6844 5e755519 ths
        check_cp1_64bitmode(ctx);
6845 b6d96bed ths
        {
6846 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6847 b6d96bed ths
6848 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6849 a7812ae4 pbrook
            gen_helper_float_cvtd_l(fp0, fp0);
6850 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6851 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6852 b6d96bed ths
        }
6853 5a5012ec ths
        opn = "cvt.d.l";
6854 5a5012ec ths
        break;
6855 5a5012ec ths
    case FOP(38, 20):
6856 5e755519 ths
        check_cp1_64bitmode(ctx);
6857 b6d96bed ths
        {
6858 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6859 b6d96bed ths
6860 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6861 a7812ae4 pbrook
            gen_helper_float_cvtps_pw(fp0, fp0);
6862 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6863 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6864 b6d96bed ths
        }
6865 5a5012ec ths
        opn = "cvt.ps.pw";
6866 5a5012ec ths
        break;
6867 5a5012ec ths
    case FOP(0, 22):
6868 5e755519 ths
        check_cp1_64bitmode(ctx);
6869 b6d96bed ths
        {
6870 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6871 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6872 b6d96bed ths
6873 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6874 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6875 a7812ae4 pbrook
            gen_helper_float_add_ps(fp0, fp0, fp1);
6876 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6877 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6878 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6879 b6d96bed ths
        }
6880 5a5012ec ths
        opn = "add.ps";
6881 6ea83fed bellard
        break;
6882 5a5012ec ths
    case FOP(1, 22):
6883 5e755519 ths
        check_cp1_64bitmode(ctx);
6884 b6d96bed ths
        {
6885 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6886 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6887 b6d96bed ths
6888 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6889 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6890 a7812ae4 pbrook
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6891 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6892 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6893 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6894 b6d96bed ths
        }
6895 5a5012ec ths
        opn = "sub.ps";
6896 6ea83fed bellard
        break;
6897 5a5012ec ths
    case FOP(2, 22):
6898 5e755519 ths
        check_cp1_64bitmode(ctx);
6899 b6d96bed ths
        {
6900 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6901 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6902 b6d96bed ths
6903 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6904 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6905 a7812ae4 pbrook
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6906 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6907 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6908 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6909 b6d96bed ths
        }
6910 5a5012ec ths
        opn = "mul.ps";
6911 6ea83fed bellard
        break;
6912 5a5012ec ths
    case FOP(5, 22):
6913 5e755519 ths
        check_cp1_64bitmode(ctx);
6914 b6d96bed ths
        {
6915 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6916 b6d96bed ths
6917 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6918 a7812ae4 pbrook
            gen_helper_float_abs_ps(fp0, fp0);
6919 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6920 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6921 b6d96bed ths
        }
6922 5a5012ec ths
        opn = "abs.ps";
6923 6ea83fed bellard
        break;
6924 5a5012ec ths
    case FOP(6, 22):
6925 5e755519 ths
        check_cp1_64bitmode(ctx);
6926 b6d96bed ths
        {
6927 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6928 b6d96bed ths
6929 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6930 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6931 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6932 b6d96bed ths
        }
6933 5a5012ec ths
        opn = "mov.ps";
6934 6ea83fed bellard
        break;
6935 5a5012ec ths
    case FOP(7, 22):
6936 5e755519 ths
        check_cp1_64bitmode(ctx);
6937 b6d96bed ths
        {
6938 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6939 b6d96bed ths
6940 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6941 a7812ae4 pbrook
            gen_helper_float_chs_ps(fp0, fp0);
6942 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6943 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6944 b6d96bed ths
        }
6945 5a5012ec ths
        opn = "neg.ps";
6946 6ea83fed bellard
        break;
6947 5a5012ec ths
    case FOP(17, 22):
6948 5e755519 ths
        check_cp1_64bitmode(ctx);
6949 b6d96bed ths
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6950 5a5012ec ths
        opn = "movcf.ps";
6951 6ea83fed bellard
        break;
6952 5a5012ec ths
    case FOP(18, 22):
6953 5e755519 ths
        check_cp1_64bitmode(ctx);
6954 a16336e4 ths
        {
6955 a16336e4 ths
            int l1 = gen_new_label();
6956 30a3848b aurel32
            TCGv_i64 fp0;
6957 a16336e4 ths
6958 c9297f4d aurel32
            if (ft != 0)
6959 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6960 c9297f4d aurel32
            fp0 = tcg_temp_new_i64();
6961 c9297f4d aurel32
            gen_load_fpr64(ctx, fp0, fs);
6962 c9297f4d aurel32
            gen_store_fpr64(ctx, fp0, fd);
6963 c9297f4d aurel32
            tcg_temp_free_i64(fp0);
6964 a16336e4 ths
            gen_set_label(l1);
6965 a16336e4 ths
        }
6966 5a5012ec ths
        opn = "movz.ps";
6967 6ea83fed bellard
        break;
6968 5a5012ec ths
    case FOP(19, 22):
6969 5e755519 ths
        check_cp1_64bitmode(ctx);
6970 a16336e4 ths
        {
6971 a16336e4 ths
            int l1 = gen_new_label();
6972 30a3848b aurel32
            TCGv_i64 fp0;
6973 c9297f4d aurel32
6974 c9297f4d aurel32
            if (ft != 0) {
6975 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6976 c9297f4d aurel32
                fp0 = tcg_temp_new_i64();
6977 c9297f4d aurel32
                gen_load_fpr64(ctx, fp0, fs);
6978 c9297f4d aurel32
                gen_store_fpr64(ctx, fp0, fd);
6979 c9297f4d aurel32
                tcg_temp_free_i64(fp0);
6980 c9297f4d aurel32
                gen_set_label(l1);
6981 c9297f4d aurel32
            }
6982 a16336e4 ths
        }
6983 5a5012ec ths
        opn = "movn.ps";
6984 6ea83fed bellard
        break;
6985 fbcc6828 ths
    case FOP(24, 22):
6986 5e755519 ths
        check_cp1_64bitmode(ctx);
6987 b6d96bed ths
        {
6988 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6989 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6990 b6d96bed ths
6991 b6d96bed ths
            gen_load_fpr64(ctx, fp0, ft);
6992 b6d96bed ths
            gen_load_fpr64(ctx, fp1, fs);
6993 a7812ae4 pbrook
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6994 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6995 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6996 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6997 b6d96bed ths
        }
6998 fbcc6828 ths
        opn = "addr.ps";
6999 fbcc6828 ths
        break;
7000 57fa1fb3 ths
    case FOP(26, 22):
7001 5e755519 ths
        check_cp1_64bitmode(ctx);
7002 b6d96bed ths
        {
7003 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7004 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7005 b6d96bed ths
7006 b6d96bed ths
            gen_load_fpr64(ctx, fp0, ft);
7007 b6d96bed ths
            gen_load_fpr64(ctx, fp1, fs);
7008 a7812ae4 pbrook
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7009 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7010 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7011 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7012 b6d96bed ths
        }
7013 57fa1fb3 ths
        opn = "mulr.ps";
7014 57fa1fb3 ths
        break;
7015 57fa1fb3 ths
    case FOP(28, 22):
7016 5e755519 ths
        check_cp1_64bitmode(ctx);
7017 b6d96bed ths
        {
7018 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7019 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7020 b6d96bed ths
7021 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7022 b6d96bed ths
            gen_load_fpr64(ctx, fp1, fd);
7023 a7812ae4 pbrook
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7024 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7025 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7026 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7027 b6d96bed ths
        }
7028 57fa1fb3 ths
        opn = "recip2.ps";
7029 57fa1fb3 ths
        break;
7030 57fa1fb3 ths
    case FOP(29, 22):
7031 5e755519 ths
        check_cp1_64bitmode(ctx);
7032 b6d96bed ths
        {
7033 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7034 b6d96bed ths
7035 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7036 a7812ae4 pbrook
            gen_helper_float_recip1_ps(fp0, fp0);
7037 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7038 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7039 b6d96bed ths
        }
7040 57fa1fb3 ths
        opn = "recip1.ps";
7041 57fa1fb3 ths
        break;
7042 57fa1fb3 ths
    case FOP(30, 22):
7043 5e755519 ths
        check_cp1_64bitmode(ctx);
7044 b6d96bed ths
        {
7045 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7046 b6d96bed ths
7047 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7048 a7812ae4 pbrook
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7049 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7050 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7051 b6d96bed ths
        }
7052 57fa1fb3 ths
        opn = "rsqrt1.ps";
7053 57fa1fb3 ths
        break;
7054 57fa1fb3 ths
    case FOP(31, 22):
7055 5e755519 ths
        check_cp1_64bitmode(ctx);
7056 b6d96bed ths
        {
7057 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7058 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7059 b6d96bed ths
7060 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7061 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7062 a7812ae4 pbrook
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7063 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7064 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7065 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7066 b6d96bed ths
        }
7067 57fa1fb3 ths
        opn = "rsqrt2.ps";
7068 57fa1fb3 ths
        break;
7069 5a5012ec ths
    case FOP(32, 22):
7070 5e755519 ths
        check_cp1_64bitmode(ctx);
7071 b6d96bed ths
        {
7072 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7073 b6d96bed ths
7074 b6d96bed ths
            gen_load_fpr32h(fp0, fs);
7075 a7812ae4 pbrook
            gen_helper_float_cvts_pu(fp0, fp0);
7076 b6d96bed ths
            gen_store_fpr32(fp0, fd);
7077 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7078 b6d96bed ths
        }
7079 5a5012ec ths
        opn = "cvt.s.pu";
7080 dd016883 bellard
        break;
7081 5a5012ec ths
    case FOP(36, 22):
7082 5e755519 ths
        check_cp1_64bitmode(ctx);
7083 b6d96bed ths
        {
7084 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7085 b6d96bed ths
7086 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7087 a7812ae4 pbrook
            gen_helper_float_cvtpw_ps(fp0, fp0);
7088 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7089 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7090 b6d96bed ths
        }
7091 5a5012ec ths
        opn = "cvt.pw.ps";
7092 6ea83fed bellard
        break;
7093 5a5012ec ths
    case FOP(40, 22):
7094 5e755519 ths
        check_cp1_64bitmode(ctx);
7095 b6d96bed ths
        {
7096 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7097 b6d96bed ths
7098 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7099 a7812ae4 pbrook
            gen_helper_float_cvts_pl(fp0, fp0);
7100 b6d96bed ths
            gen_store_fpr32(fp0, fd);
7101 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7102 b6d96bed ths
        }
7103 5a5012ec ths
        opn = "cvt.s.pl";
7104 6ea83fed bellard
        break;
7105 5a5012ec ths
    case FOP(44, 22):
7106 5e755519 ths
        check_cp1_64bitmode(ctx);
7107 b6d96bed ths
        {
7108 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7109 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7110 b6d96bed ths
7111 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7112 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7113 b6d96bed ths
            gen_store_fpr32h(fp0, fd);
7114 b6d96bed ths
            gen_store_fpr32(fp1, fd);
7115 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7116 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7117 b6d96bed ths
        }
7118 5a5012ec ths
        opn = "pll.ps";
7119 6ea83fed bellard
        break;
7120 5a5012ec ths
    case FOP(45, 22):
7121 5e755519 ths
        check_cp1_64bitmode(ctx);
7122 b6d96bed ths
        {
7123 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7124 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7125 b6d96bed ths
7126 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7127 b6d96bed ths
            gen_load_fpr32h(fp1, ft);
7128 b6d96bed ths
            gen_store_fpr32(fp1, fd);
7129 b6d96bed ths
            gen_store_fpr32h(fp0, fd);
7130 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7131 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7132 b6d96bed ths
        }
7133 5a5012ec ths
        opn = "plu.ps";
7134 5a5012ec ths
        break;
7135 5a5012ec ths
    case FOP(46, 22):
7136 5e755519 ths
        check_cp1_64bitmode(ctx);
7137 b6d96bed ths
        {
7138 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7139 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7140 b6d96bed ths
7141 b6d96bed ths
            gen_load_fpr32h(fp0, fs);
7142 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7143 b6d96bed ths
            gen_store_fpr32(fp1, fd);
7144 b6d96bed ths
            gen_store_fpr32h(fp0, fd);
7145 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7146 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7147 b6d96bed ths
        }
7148 5a5012ec ths
        opn = "pul.ps";
7149 5a5012ec ths
        break;
7150 5a5012ec ths
    case FOP(47, 22):
7151 5e755519 ths
        check_cp1_64bitmode(ctx);
7152 b6d96bed ths
        {
7153 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7154 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7155 b6d96bed ths
7156 b6d96bed ths
            gen_load_fpr32h(fp0, fs);
7157 b6d96bed ths
            gen_load_fpr32h(fp1, ft);
7158 b6d96bed ths
            gen_store_fpr32(fp1, fd);
7159 b6d96bed ths
            gen_store_fpr32h(fp0, fd);
7160 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7161 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7162 b6d96bed ths
        }
7163 5a5012ec ths
        opn = "puu.ps";
7164 5a5012ec ths
        break;
7165 5a5012ec ths
    case FOP(48, 22):
7166 5a5012ec ths
    case FOP(49, 22):
7167 5a5012ec ths
    case FOP(50, 22):
7168 5a5012ec ths
    case FOP(51, 22):
7169 5a5012ec ths
    case FOP(52, 22):
7170 5a5012ec ths
    case FOP(53, 22):
7171 5a5012ec ths
    case FOP(54, 22):
7172 5a5012ec ths
    case FOP(55, 22):
7173 5a5012ec ths
    case FOP(56, 22):
7174 5a5012ec ths
    case FOP(57, 22):
7175 5a5012ec ths
    case FOP(58, 22):
7176 5a5012ec ths
    case FOP(59, 22):
7177 5a5012ec ths
    case FOP(60, 22):
7178 5a5012ec ths
    case FOP(61, 22):
7179 5a5012ec ths
    case FOP(62, 22):
7180 5a5012ec ths
    case FOP(63, 22):
7181 5e755519 ths
        check_cp1_64bitmode(ctx);
7182 b6d96bed ths
        {
7183 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7184 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7185 b6d96bed ths
7186 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7187 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7188 b6d96bed ths
            if (ctx->opcode & (1 << 6)) {
7189 b6d96bed ths
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7190 b6d96bed ths
                opn = condnames_abs[func-48];
7191 b6d96bed ths
            } else {
7192 b6d96bed ths
                gen_cmp_ps(func-48, fp0, fp1, cc);
7193 b6d96bed ths
                opn = condnames[func-48];
7194 b6d96bed ths
            }
7195 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7196 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7197 5a1e8ffb ths
        }
7198 6ea83fed bellard
        break;
7199 5a5012ec ths
    default:
7200 923617a3 ths
        MIPS_INVAL(opn);
7201 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
7202 6ea83fed bellard
        return;
7203 6ea83fed bellard
    }
7204 5a1e8ffb ths
    switch (optype) {
7205 5a1e8ffb ths
    case BINOP:
7206 6ea83fed bellard
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7207 5a1e8ffb ths
        break;
7208 5a1e8ffb ths
    case CMPOP:
7209 5a1e8ffb ths
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7210 5a1e8ffb ths
        break;
7211 5a1e8ffb ths
    default:
7212 6ea83fed bellard
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7213 5a1e8ffb ths
        break;
7214 5a1e8ffb ths
    }
7215 6ea83fed bellard
}
7216 6af0bf9c bellard
7217 5a5012ec ths
/* Coprocessor 3 (FPU) */
7218 5e755519 ths
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7219 5e755519 ths
                           int fd, int fs, int base, int index)
7220 7a387fff ths
{
7221 923617a3 ths
    const char *opn = "extended float load/store";
7222 93b12ccc ths
    int store = 0;
7223 4e2474d6 aurel32
    TCGv t0 = tcg_temp_new();
7224 7a387fff ths
7225 007ac6fa aurel32
    switch (opc) {
7226 007ac6fa aurel32
    case OPC_LWXC1:
7227 007ac6fa aurel32
    case OPC_SWXC1:
7228 007ac6fa aurel32
        check_cop1x(ctx);
7229 007ac6fa aurel32
        break;
7230 007ac6fa aurel32
    case OPC_LDXC1:
7231 007ac6fa aurel32
    case OPC_SDXC1:
7232 007ac6fa aurel32
        check_cop1x(ctx);
7233 007ac6fa aurel32
        check_cp1_registers(ctx, fd);
7234 007ac6fa aurel32
        break;
7235 007ac6fa aurel32
    case OPC_LUXC1:
7236 007ac6fa aurel32
    case OPC_SUXC1:
7237 007ac6fa aurel32
        check_cp1_64bitmode(ctx);
7238 007ac6fa aurel32
        break;
7239 007ac6fa aurel32
    }
7240 007ac6fa aurel32
7241 93b12ccc ths
    if (base == 0) {
7242 6c5c1e20 ths
        gen_load_gpr(t0, index);
7243 93b12ccc ths
    } else if (index == 0) {
7244 6c5c1e20 ths
        gen_load_gpr(t0, base);
7245 93b12ccc ths
    } else {
7246 e9203484 aurel32
        gen_load_gpr(t0, index);
7247 e9203484 aurel32
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7248 93b12ccc ths
    }
7249 5a5012ec ths
    /* Don't do NOP if destination is zero: we must perform the actual
7250 ead9360e ths
       memory access. */
7251 4e2474d6 aurel32
    save_cpu_state(ctx, 0);
7252 5a5012ec ths
    switch (opc) {
7253 5a5012ec ths
    case OPC_LWXC1:
7254 b6d96bed ths
        {
7255 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7256 b6d96bed ths
7257 585c88d5 aurel32
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7258 585c88d5 aurel32
            tcg_gen_trunc_tl_i32(fp0, t0);
7259 b6d96bed ths
            gen_store_fpr32(fp0, fd);
7260 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7261 b6d96bed ths
        }
7262 5a5012ec ths
        opn = "lwxc1";
7263 5a5012ec ths
        break;
7264 5a5012ec ths
    case OPC_LDXC1:
7265 b6d96bed ths
        {
7266 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7267 b6d96bed ths
7268 b6d96bed ths
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7269 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7270 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7271 b6d96bed ths
        }
7272 5a5012ec ths
        opn = "ldxc1";
7273 5a5012ec ths
        break;
7274 5a5012ec ths
    case OPC_LUXC1:
7275 6c5c1e20 ths
        tcg_gen_andi_tl(t0, t0, ~0x7);
7276 b6d96bed ths
        {
7277 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7278 b6d96bed ths
7279 b6d96bed ths
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7280 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7281 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7282 b6d96bed ths
        }
7283 5a5012ec ths
        opn = "luxc1";
7284 5a5012ec ths
        break;
7285 5a5012ec ths
    case OPC_SWXC1:
7286 b6d96bed ths
        {
7287 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7288 585c88d5 aurel32
            TCGv t1 = tcg_temp_new();
7289 b6d96bed ths
7290 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7291 a7812ae4 pbrook
            tcg_gen_extu_i32_tl(t1, fp0);
7292 a7812ae4 pbrook
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7293 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7294 a6035857 aurel32
            tcg_temp_free(t1);
7295 b6d96bed ths
        }
7296 5a5012ec ths
        opn = "swxc1";
7297 93b12ccc ths
        store = 1;
7298 5a5012ec ths
        break;
7299 5a5012ec ths
    case OPC_SDXC1:
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 = "sdxc1";
7308 93b12ccc ths
        store = 1;
7309 5a5012ec ths
        break;
7310 5a5012ec ths
    case OPC_SUXC1:
7311 6c5c1e20 ths
        tcg_gen_andi_tl(t0, t0, ~0x7);
7312 b6d96bed ths
        {
7313 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7314 b6d96bed ths
7315 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7316 b6d96bed ths
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7317 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7318 b6d96bed ths
        }
7319 5a5012ec ths
        opn = "suxc1";
7320 93b12ccc ths
        store = 1;
7321 5a5012ec ths
        break;
7322 5a5012ec ths
    }
7323 6c5c1e20 ths
    tcg_temp_free(t0);
7324 93b12ccc ths
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7325 93b12ccc ths
               regnames[index], regnames[base]);
7326 5a5012ec ths
}
7327 5a5012ec ths
7328 5e755519 ths
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7329 5e755519 ths
                            int fd, int fr, int fs, int ft)
7330 5a5012ec ths
{
7331 923617a3 ths
    const char *opn = "flt3_arith";
7332 5a5012ec ths
7333 5a5012ec ths
    switch (opc) {
7334 5a5012ec ths
    case OPC_ALNV_PS:
7335 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7336 a16336e4 ths
        {
7337 a7812ae4 pbrook
            TCGv t0 = tcg_temp_local_new();
7338 c905fdac aurel32
            TCGv_i32 fp = tcg_temp_new_i32();
7339 c905fdac aurel32
            TCGv_i32 fph = tcg_temp_new_i32();
7340 a16336e4 ths
            int l1 = gen_new_label();
7341 a16336e4 ths
            int l2 = gen_new_label();
7342 a16336e4 ths
7343 6c5c1e20 ths
            gen_load_gpr(t0, fr);
7344 6c5c1e20 ths
            tcg_gen_andi_tl(t0, t0, 0x7);
7345 6c5c1e20 ths
7346 6c5c1e20 ths
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7347 c905fdac aurel32
            gen_load_fpr32(fp, fs);
7348 c905fdac aurel32
            gen_load_fpr32h(fph, fs);
7349 c905fdac aurel32
            gen_store_fpr32(fp, fd);
7350 c905fdac aurel32
            gen_store_fpr32h(fph, fd);
7351 a16336e4 ths
            tcg_gen_br(l2);
7352 a16336e4 ths
            gen_set_label(l1);
7353 6c5c1e20 ths
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7354 6c5c1e20 ths
            tcg_temp_free(t0);
7355 a16336e4 ths
#ifdef TARGET_WORDS_BIGENDIAN
7356 c905fdac aurel32
            gen_load_fpr32(fp, fs);
7357 c905fdac aurel32
            gen_load_fpr32h(fph, ft);
7358 c905fdac aurel32
            gen_store_fpr32h(fp, fd);
7359 c905fdac aurel32
            gen_store_fpr32(fph, fd);
7360 a16336e4 ths
#else
7361 c905fdac aurel32
            gen_load_fpr32h(fph, fs);
7362 c905fdac aurel32
            gen_load_fpr32(fp, ft);
7363 c905fdac aurel32
            gen_store_fpr32(fph, fd);
7364 c905fdac aurel32
            gen_store_fpr32h(fp, fd);
7365 a16336e4 ths
#endif
7366 a16336e4 ths
            gen_set_label(l2);
7367 c905fdac aurel32
            tcg_temp_free_i32(fp);
7368 c905fdac aurel32
            tcg_temp_free_i32(fph);
7369 a16336e4 ths
        }
7370 5a5012ec ths
        opn = "alnv.ps";
7371 5a5012ec ths
        break;
7372 5a5012ec ths
    case OPC_MADD_S:
7373 b8aa4598 ths
        check_cop1x(ctx);
7374 b6d96bed ths
        {
7375 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7376 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7377 a7812ae4 pbrook
            TCGv_i32 fp2 = tcg_temp_new_i32();
7378 b6d96bed ths
7379 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7380 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7381 b6d96bed ths
            gen_load_fpr32(fp2, fr);
7382 a7812ae4 pbrook
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7383 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7384 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7385 b6d96bed ths
            gen_store_fpr32(fp2, fd);
7386 a7812ae4 pbrook
            tcg_temp_free_i32(fp2);
7387 b6d96bed ths
        }
7388 5a5012ec ths
        opn = "madd.s";
7389 5a5012ec ths
        break;
7390 5a5012ec ths
    case OPC_MADD_D:
7391 b8aa4598 ths
        check_cop1x(ctx);
7392 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
7393 b6d96bed ths
        {
7394 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7395 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7396 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7397 b6d96bed ths
7398 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7399 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7400 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7401 a7812ae4 pbrook
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7402 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7403 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7404 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7405 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7406 b6d96bed ths
        }
7407 5a5012ec ths
        opn = "madd.d";
7408 5a5012ec ths
        break;
7409 5a5012ec ths
    case OPC_MADD_PS:
7410 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7411 b6d96bed ths
        {
7412 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7413 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7414 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7415 b6d96bed ths
7416 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7417 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7418 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7419 a7812ae4 pbrook
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7420 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7421 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7422 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7423 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7424 b6d96bed ths
        }
7425 5a5012ec ths
        opn = "madd.ps";
7426 5a5012ec ths
        break;
7427 5a5012ec ths
    case OPC_MSUB_S:
7428 b8aa4598 ths
        check_cop1x(ctx);
7429 b6d96bed ths
        {
7430 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7431 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7432 a7812ae4 pbrook
            TCGv_i32 fp2 = tcg_temp_new_i32();
7433 b6d96bed ths
7434 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7435 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7436 b6d96bed ths
            gen_load_fpr32(fp2, fr);
7437 a7812ae4 pbrook
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7438 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7439 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7440 b6d96bed ths
            gen_store_fpr32(fp2, fd);
7441 a7812ae4 pbrook
            tcg_temp_free_i32(fp2);
7442 b6d96bed ths
        }
7443 5a5012ec ths
        opn = "msub.s";
7444 5a5012ec ths
        break;
7445 5a5012ec ths
    case OPC_MSUB_D:
7446 b8aa4598 ths
        check_cop1x(ctx);
7447 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
7448 b6d96bed ths
        {
7449 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7450 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7451 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7452 b6d96bed ths
7453 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7454 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7455 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7456 a7812ae4 pbrook
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7457 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7458 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7459 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7460 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7461 b6d96bed ths
        }
7462 5a5012ec ths
        opn = "msub.d";
7463 5a5012ec ths
        break;
7464 5a5012ec ths
    case OPC_MSUB_PS:
7465 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7466 b6d96bed ths
        {
7467 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7468 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7469 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7470 b6d96bed ths
7471 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7472 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7473 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7474 a7812ae4 pbrook
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7475 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7476 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7477 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7478 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7479 b6d96bed ths
        }
7480 5a5012ec ths
        opn = "msub.ps";
7481 5a5012ec ths
        break;
7482 5a5012ec ths
    case OPC_NMADD_S:
7483 b8aa4598 ths
        check_cop1x(ctx);
7484 b6d96bed ths
        {
7485 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7486 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7487 a7812ae4 pbrook
            TCGv_i32 fp2 = tcg_temp_new_i32();
7488 b6d96bed ths
7489 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7490 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7491 b6d96bed ths
            gen_load_fpr32(fp2, fr);
7492 a7812ae4 pbrook
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7493 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7494 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7495 b6d96bed ths
            gen_store_fpr32(fp2, fd);
7496 a7812ae4 pbrook
            tcg_temp_free_i32(fp2);
7497 b6d96bed ths
        }
7498 5a5012ec ths
        opn = "nmadd.s";
7499 5a5012ec ths
        break;
7500 5a5012ec ths
    case OPC_NMADD_D:
7501 b8aa4598 ths
        check_cop1x(ctx);
7502 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
7503 b6d96bed ths
        {
7504 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7505 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7506 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7507 b6d96bed ths
7508 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7509 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7510 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7511 a7812ae4 pbrook
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7512 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7513 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7514 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7515 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7516 b6d96bed ths
        }
7517 5a5012ec ths
        opn = "nmadd.d";
7518 5a5012ec ths
        break;
7519 5a5012ec ths
    case OPC_NMADD_PS:
7520 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7521 b6d96bed ths
        {
7522 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7523 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7524 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7525 b6d96bed ths
7526 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7527 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7528 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7529 a7812ae4 pbrook
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7530 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7531 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7532 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7533 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7534 b6d96bed ths
        }
7535 5a5012ec ths
        opn = "nmadd.ps";
7536 5a5012ec ths
        break;
7537 5a5012ec ths
    case OPC_NMSUB_S:
7538 b8aa4598 ths
        check_cop1x(ctx);
7539 b6d96bed ths
        {
7540 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7541 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7542 a7812ae4 pbrook
            TCGv_i32 fp2 = tcg_temp_new_i32();
7543 b6d96bed ths
7544 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7545 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7546 b6d96bed ths
            gen_load_fpr32(fp2, fr);
7547 a7812ae4 pbrook
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7548 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7549 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7550 b6d96bed ths
            gen_store_fpr32(fp2, fd);
7551 a7812ae4 pbrook
            tcg_temp_free_i32(fp2);
7552 b6d96bed ths
        }
7553 5a5012ec ths
        opn = "nmsub.s";
7554 5a5012ec ths
        break;
7555 5a5012ec ths
    case OPC_NMSUB_D:
7556 b8aa4598 ths
        check_cop1x(ctx);
7557 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
7558 b6d96bed ths
        {
7559 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7560 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7561 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7562 b6d96bed ths
7563 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7564 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7565 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7566 a7812ae4 pbrook
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7567 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7568 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7569 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7570 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7571 b6d96bed ths
        }
7572 5a5012ec ths
        opn = "nmsub.d";
7573 5a5012ec ths
        break;
7574 5a5012ec ths
    case OPC_NMSUB_PS:
7575 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7576 b6d96bed ths
        {
7577 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7578 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7579 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7580 b6d96bed ths
7581 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7582 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7583 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7584 a7812ae4 pbrook
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7585 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7586 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7587 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7588 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7589 b6d96bed ths
        }
7590 5a5012ec ths
        opn = "nmsub.ps";
7591 5a5012ec ths
        break;
7592 923617a3 ths
    default:
7593 923617a3 ths
        MIPS_INVAL(opn);
7594 5a5012ec ths
        generate_exception (ctx, EXCP_RI);
7595 5a5012ec ths
        return;
7596 5a5012ec ths
    }
7597 5a5012ec ths
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7598 5a5012ec ths
               fregnames[fs], fregnames[ft]);
7599 7a387fff ths
}
7600 7a387fff ths
7601 7a387fff ths
/* ISA extensions (ASEs) */
7602 6af0bf9c bellard
/* MIPS16 extension to MIPS32 */
7603 6af0bf9c bellard
/* SmartMIPS extension to MIPS32 */
7604 6af0bf9c bellard
7605 d26bc211 ths
#if defined(TARGET_MIPS64)
7606 6af0bf9c bellard
7607 6af0bf9c bellard
/* MDMX extension to MIPS64 */
7608 6af0bf9c bellard
7609 6af0bf9c bellard
#endif
7610 6af0bf9c bellard
7611 36d23958 ths
static void decode_opc (CPUState *env, DisasContext *ctx)
7612 6af0bf9c bellard
{
7613 6af0bf9c bellard
    int32_t offset;
7614 6af0bf9c bellard
    int rs, rt, rd, sa;
7615 7a387fff ths
    uint32_t op, op1, op2;
7616 6af0bf9c bellard
    int16_t imm;
7617 6af0bf9c bellard
7618 d796321b bellard
    /* make sure instructions are on a word boundary */
7619 d796321b bellard
    if (ctx->pc & 0x3) {
7620 cbeb0857 ths
        env->CP0_BadVAddr = ctx->pc;
7621 d796321b bellard
        generate_exception(ctx, EXCP_AdEL);
7622 d796321b bellard
        return;
7623 d796321b bellard
    }
7624 d796321b bellard
7625 8e9ade68 ths
    /* Handle blikely not taken case */
7626 4ad40f36 bellard
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7627 8e9ade68 ths
        int l1 = gen_new_label();
7628 8e9ade68 ths
7629 3594c774 ths
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7630 1ba74fb8 aurel32
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7631 41db4607 aurel32
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7632 5a5012ec ths
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7633 5a5012ec ths
        gen_set_label(l1);
7634 6af0bf9c bellard
    }
7635 7a387fff ths
    op = MASK_OP_MAJOR(ctx->opcode);
7636 7a387fff ths
    rs = (ctx->opcode >> 21) & 0x1f;
7637 7a387fff ths
    rt = (ctx->opcode >> 16) & 0x1f;
7638 7a387fff ths
    rd = (ctx->opcode >> 11) & 0x1f;
7639 7a387fff ths
    sa = (ctx->opcode >> 6) & 0x1f;
7640 6af0bf9c bellard
    imm = (int16_t)ctx->opcode;
7641 6af0bf9c bellard
    switch (op) {
7642 7a387fff ths
    case OPC_SPECIAL:
7643 7a387fff ths
        op1 = MASK_SPECIAL(ctx->opcode);
7644 6af0bf9c bellard
        switch (op1) {
7645 324d9e32 aurel32
        case OPC_SLL:          /* Shift with immediate */
7646 324d9e32 aurel32
        case OPC_SRA:
7647 324d9e32 aurel32
        case OPC_SRL:
7648 324d9e32 aurel32
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7649 7a387fff ths
            break;
7650 460f00c4 aurel32
        case OPC_MOVN:         /* Conditional move */
7651 460f00c4 aurel32
        case OPC_MOVZ:
7652 e189e748 ths
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7653 460f00c4 aurel32
            gen_cond_move(env, op1, rd, rs, rt);
7654 460f00c4 aurel32
            break;
7655 460f00c4 aurel32
        case OPC_ADD ... OPC_SUBU:
7656 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
7657 7a387fff ths
            break;
7658 460f00c4 aurel32
        case OPC_SLLV:         /* Shifts */
7659 460f00c4 aurel32
        case OPC_SRLV:
7660 460f00c4 aurel32
        case OPC_SRAV:
7661 460f00c4 aurel32
            gen_shift(env, ctx, op1, rd, rs, rt);
7662 460f00c4 aurel32
            break;
7663 460f00c4 aurel32
        case OPC_SLT:          /* Set on less than */
7664 460f00c4 aurel32
        case OPC_SLTU:
7665 460f00c4 aurel32
            gen_slt(env, op1, rd, rs, rt);
7666 460f00c4 aurel32
            break;
7667 460f00c4 aurel32
        case OPC_AND:          /* Logic*/
7668 460f00c4 aurel32
        case OPC_OR:
7669 460f00c4 aurel32
        case OPC_NOR:
7670 460f00c4 aurel32
        case OPC_XOR:
7671 460f00c4 aurel32
            gen_logic(env, op1, rd, rs, rt);
7672 460f00c4 aurel32
            break;
7673 7a387fff ths
        case OPC_MULT ... OPC_DIVU:
7674 e9c71dd1 ths
            if (sa) {
7675 e9c71dd1 ths
                check_insn(env, ctx, INSN_VR54XX);
7676 e9c71dd1 ths
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7677 e9c71dd1 ths
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7678 e9c71dd1 ths
            } else
7679 e9c71dd1 ths
                gen_muldiv(ctx, op1, rs, rt);
7680 7a387fff ths
            break;
7681 7a387fff ths
        case OPC_JR ... OPC_JALR:
7682 7a387fff ths
            gen_compute_branch(ctx, op1, rs, rd, sa);
7683 6af0bf9c bellard
            return;
7684 7a387fff ths
        case OPC_TGE ... OPC_TEQ: /* Traps */
7685 7a387fff ths
        case OPC_TNE:
7686 7a387fff ths
            gen_trap(ctx, op1, rs, rt, -1);
7687 6af0bf9c bellard
            break;
7688 7a387fff ths
        case OPC_MFHI:          /* Move from HI/LO */
7689 7a387fff ths
        case OPC_MFLO:
7690 7a387fff ths
            gen_HILO(ctx, op1, rd);
7691 6af0bf9c bellard
            break;
7692 7a387fff ths
        case OPC_MTHI:
7693 7a387fff ths
        case OPC_MTLO:          /* Move to HI/LO */
7694 7a387fff ths
            gen_HILO(ctx, op1, rs);
7695 6af0bf9c bellard
            break;
7696 b48cfdff ths
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7697 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
7698 b48cfdff ths
            MIPS_INVAL("PMON / selsl");
7699 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
7700 b48cfdff ths
#else
7701 a7812ae4 pbrook
            gen_helper_0i(pmon, sa);
7702 b48cfdff ths
#endif
7703 7a387fff ths
            break;
7704 7a387fff ths
        case OPC_SYSCALL:
7705 6af0bf9c bellard
            generate_exception(ctx, EXCP_SYSCALL);
7706 8e0f950d pbrook
            ctx->bstate = BS_STOP;
7707 6af0bf9c bellard
            break;
7708 7a387fff ths
        case OPC_BREAK:
7709 6af0bf9c bellard
            generate_exception(ctx, EXCP_BREAK);
7710 6af0bf9c bellard
            break;
7711 b48cfdff ths
        case OPC_SPIM:
7712 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
7713 b48cfdff ths
            MIPS_INVAL("SPIM");
7714 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
7715 b48cfdff ths
#else
7716 7a387fff ths
           /* Implemented as RI exception for now. */
7717 7a387fff ths
            MIPS_INVAL("spim (unofficial)");
7718 7a387fff ths
            generate_exception(ctx, EXCP_RI);
7719 b48cfdff ths
#endif
7720 6af0bf9c bellard
            break;
7721 7a387fff ths
        case OPC_SYNC:
7722 ead9360e ths
            /* Treat as NOP. */
7723 6af0bf9c bellard
            break;
7724 4ad40f36 bellard
7725 7a387fff ths
        case OPC_MOVCI:
7726 e189e748 ths
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7727 36d23958 ths
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7728 5e755519 ths
                check_cp1_enabled(ctx);
7729 36d23958 ths
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7730 36d23958 ths
                          (ctx->opcode >> 16) & 1);
7731 36d23958 ths
            } else {
7732 e397ee33 ths
                generate_exception_err(ctx, EXCP_CpU, 1);
7733 36d23958 ths
            }
7734 4ad40f36 bellard
            break;
7735 4ad40f36 bellard
7736 d26bc211 ths
#if defined(TARGET_MIPS64)
7737 7a387fff ths
       /* MIPS64 specific opcodes */
7738 7a387fff ths
        case OPC_DSLL:
7739 324d9e32 aurel32
        case OPC_DSRA:
7740 324d9e32 aurel32
        case OPC_DSRL:
7741 7a387fff ths
        case OPC_DSLL32:
7742 324d9e32 aurel32
        case OPC_DSRA32:
7743 324d9e32 aurel32
        case OPC_DSRL32:
7744 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
7745 e189e748 ths
            check_mips_64(ctx);
7746 324d9e32 aurel32
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7747 7a387fff ths
            break;
7748 7a387fff ths
        case OPC_DADD ... OPC_DSUBU:
7749 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
7750 e189e748 ths
            check_mips_64(ctx);
7751 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
7752 7a387fff ths
            break;
7753 460f00c4 aurel32
        case OPC_DSLLV:
7754 460f00c4 aurel32
        case OPC_DSRAV:
7755 460f00c4 aurel32
        case OPC_DSRLV:
7756 460f00c4 aurel32
            check_insn(env, ctx, ISA_MIPS3);
7757 460f00c4 aurel32
            check_mips_64(ctx);
7758 460f00c4 aurel32
            gen_shift(env, ctx, op1, rd, rs, rt);
7759 460f00c4 aurel32
            break;
7760 7a387fff ths
        case OPC_DMULT ... OPC_DDIVU:
7761 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
7762 e189e748 ths
            check_mips_64(ctx);
7763 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
7764 7a387fff ths
            break;
7765 6af0bf9c bellard
#endif
7766 6af0bf9c bellard
        default:            /* Invalid */
7767 6af0bf9c bellard
            MIPS_INVAL("special");
7768 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
7769 6af0bf9c bellard
            break;
7770 6af0bf9c bellard
        }
7771 6af0bf9c bellard
        break;
7772 7a387fff ths
    case OPC_SPECIAL2:
7773 7a387fff ths
        op1 = MASK_SPECIAL2(ctx->opcode);
7774 6af0bf9c bellard
        switch (op1) {
7775 7a387fff ths
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7776 7a387fff ths
        case OPC_MSUB ... OPC_MSUBU:
7777 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
7778 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
7779 6af0bf9c bellard
            break;
7780 7a387fff ths
        case OPC_MUL:
7781 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
7782 6af0bf9c bellard
            break;
7783 20e1fb52 aurel32
        case OPC_CLO:
7784 20e1fb52 aurel32
        case OPC_CLZ:
7785 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
7786 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
7787 6af0bf9c bellard
            break;
7788 7a387fff ths
        case OPC_SDBBP:
7789 6af0bf9c bellard
            /* XXX: not clear which exception should be raised
7790 6af0bf9c bellard
             *      when in debug mode...
7791 6af0bf9c bellard
             */
7792 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
7793 6af0bf9c bellard
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7794 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
7795 6af0bf9c bellard
            } else {
7796 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
7797 6af0bf9c bellard
            }
7798 ead9360e ths
            /* Treat as NOP. */
7799 6af0bf9c bellard
            break;
7800 d26bc211 ths
#if defined(TARGET_MIPS64)
7801 20e1fb52 aurel32
        case OPC_DCLO:
7802 20e1fb52 aurel32
        case OPC_DCLZ:
7803 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64);
7804 e189e748 ths
            check_mips_64(ctx);
7805 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
7806 7a387fff ths
            break;
7807 7a387fff ths
#endif
7808 6af0bf9c bellard
        default:            /* Invalid */
7809 6af0bf9c bellard
            MIPS_INVAL("special2");
7810 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
7811 6af0bf9c bellard
            break;
7812 6af0bf9c bellard
        }
7813 6af0bf9c bellard
        break;
7814 7a387fff ths
    case OPC_SPECIAL3:
7815 2b0233ab ths
        op1 = MASK_SPECIAL3(ctx->opcode);
7816 2b0233ab ths
        switch (op1) {
7817 2b0233ab ths
        case OPC_EXT:
7818 2b0233ab ths
        case OPC_INS:
7819 2b0233ab ths
            check_insn(env, ctx, ISA_MIPS32R2);
7820 2b0233ab ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7821 2b0233ab ths
            break;
7822 2b0233ab ths
        case OPC_BSHFL:
7823 2b0233ab ths
            check_insn(env, ctx, ISA_MIPS32R2);
7824 2b0233ab ths
            op2 = MASK_BSHFL(ctx->opcode);
7825 49bcf33c aurel32
            gen_bshfl(ctx, op2, rt, rd);
7826 7a387fff ths
            break;
7827 1579a72e ths
        case OPC_RDHWR:
7828 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
7829 6c5c1e20 ths
            {
7830 35fbce2c aurel32
                TCGv t0 = tcg_temp_new();
7831 6c5c1e20 ths
7832 6c5c1e20 ths
                switch (rd) {
7833 6c5c1e20 ths
                case 0:
7834 6c5c1e20 ths
                    save_cpu_state(ctx, 1);
7835 a7812ae4 pbrook
                    gen_helper_rdhwr_cpunum(t0);
7836 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7837 6c5c1e20 ths
                    break;
7838 6c5c1e20 ths
                case 1:
7839 6c5c1e20 ths
                    save_cpu_state(ctx, 1);
7840 a7812ae4 pbrook
                    gen_helper_rdhwr_synci_step(t0);
7841 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7842 6c5c1e20 ths
                    break;
7843 6c5c1e20 ths
                case 2:
7844 6c5c1e20 ths
                    save_cpu_state(ctx, 1);
7845 a7812ae4 pbrook
                    gen_helper_rdhwr_cc(t0);
7846 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7847 6c5c1e20 ths
                    break;
7848 6c5c1e20 ths
                case 3:
7849 6c5c1e20 ths
                    save_cpu_state(ctx, 1);
7850 a7812ae4 pbrook
                    gen_helper_rdhwr_ccres(t0);
7851 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7852 6c5c1e20 ths
                    break;
7853 6c5c1e20 ths
                case 29:
7854 932e71cd aurel32
#if defined(CONFIG_USER_ONLY)
7855 932e71cd aurel32
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7856 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7857 932e71cd aurel32
                    break;
7858 932e71cd aurel32
#else
7859 932e71cd aurel32
                    /* XXX: Some CPUs implement this in hardware.
7860 932e71cd aurel32
                       Not supported yet. */
7861 932e71cd aurel32
#endif
7862 6c5c1e20 ths
                default:            /* Invalid */
7863 6c5c1e20 ths
                    MIPS_INVAL("rdhwr");
7864 6c5c1e20 ths
                    generate_exception(ctx, EXCP_RI);
7865 6c5c1e20 ths
                    break;
7866 6c5c1e20 ths
                }
7867 6c5c1e20 ths
                tcg_temp_free(t0);
7868 1579a72e ths
            }
7869 1579a72e ths
            break;
7870 ead9360e ths
        case OPC_FORK:
7871 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
7872 6c5c1e20 ths
            {
7873 35fbce2c aurel32
                TCGv t0 = tcg_temp_new();
7874 35fbce2c aurel32
                TCGv t1 = tcg_temp_new();
7875 6c5c1e20 ths
7876 6c5c1e20 ths
                gen_load_gpr(t0, rt);
7877 6c5c1e20 ths
                gen_load_gpr(t1, rs);
7878 a7812ae4 pbrook
                gen_helper_fork(t0, t1);
7879 6c5c1e20 ths
                tcg_temp_free(t0);
7880 6c5c1e20 ths
                tcg_temp_free(t1);
7881 6c5c1e20 ths
            }
7882 ead9360e ths
            break;
7883 ead9360e ths
        case OPC_YIELD:
7884 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
7885 6c5c1e20 ths
            {
7886 35fbce2c aurel32
                TCGv t0 = tcg_temp_new();
7887 6c5c1e20 ths
7888 35fbce2c aurel32
                save_cpu_state(ctx, 1);
7889 6c5c1e20 ths
                gen_load_gpr(t0, rs);
7890 a7812ae4 pbrook
                gen_helper_yield(t0, t0);
7891 6c5c1e20 ths
                gen_store_gpr(t0, rd);
7892 6c5c1e20 ths
                tcg_temp_free(t0);
7893 6c5c1e20 ths
            }
7894 ead9360e ths
            break;
7895 d26bc211 ths
#if defined(TARGET_MIPS64)
7896 1579a72e ths
        case OPC_DEXTM ... OPC_DEXT:
7897 1579a72e ths
        case OPC_DINSM ... OPC_DINS:
7898 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64R2);
7899 e189e748 ths
            check_mips_64(ctx);
7900 1579a72e ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7901 7a387fff ths
            break;
7902 1579a72e ths
        case OPC_DBSHFL:
7903 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64R2);
7904 e189e748 ths
            check_mips_64(ctx);
7905 1579a72e ths
            op2 = MASK_DBSHFL(ctx->opcode);
7906 49bcf33c aurel32
            gen_bshfl(ctx, op2, rt, rd);
7907 c6d6dd7c ths
            break;
7908 7a387fff ths
#endif
7909 7a387fff ths
        default:            /* Invalid */
7910 7a387fff ths
            MIPS_INVAL("special3");
7911 7a387fff ths
            generate_exception(ctx, EXCP_RI);
7912 7a387fff ths
            break;
7913 7a387fff ths
        }
7914 7a387fff ths
        break;
7915 7a387fff ths
    case OPC_REGIMM:
7916 7a387fff ths
        op1 = MASK_REGIMM(ctx->opcode);
7917 7a387fff ths
        switch (op1) {
7918 7a387fff ths
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7919 7a387fff ths
        case OPC_BLTZAL ... OPC_BGEZALL:
7920 7a387fff ths
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7921 6af0bf9c bellard
            return;
7922 7a387fff ths
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7923 7a387fff ths
        case OPC_TNEI:
7924 7a387fff ths
            gen_trap(ctx, op1, rs, -1, imm);
7925 7a387fff ths
            break;
7926 7a387fff ths
        case OPC_SYNCI:
7927 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
7928 ead9360e ths
            /* Treat as NOP. */
7929 6af0bf9c bellard
            break;
7930 6af0bf9c bellard
        default:            /* Invalid */
7931 923617a3 ths
            MIPS_INVAL("regimm");
7932 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
7933 6af0bf9c bellard
            break;
7934 6af0bf9c bellard
        }
7935 6af0bf9c bellard
        break;
7936 7a387fff ths
    case OPC_CP0:
7937 387a8fe5 ths
        check_cp0_enabled(ctx);
7938 7a387fff ths
        op1 = MASK_CP0(ctx->opcode);
7939 6af0bf9c bellard
        switch (op1) {
7940 7a387fff ths
        case OPC_MFC0:
7941 7a387fff ths
        case OPC_MTC0:
7942 ead9360e ths
        case OPC_MFTR:
7943 ead9360e ths
        case OPC_MTTR:
7944 d26bc211 ths
#if defined(TARGET_MIPS64)
7945 7a387fff ths
        case OPC_DMFC0:
7946 7a387fff ths
        case OPC_DMTC0:
7947 7a387fff ths
#endif
7948 f1aa6320 ths
#ifndef CONFIG_USER_ONLY
7949 932e71cd aurel32
            gen_cp0(env, ctx, op1, rt, rd);
7950 0eaef5aa ths
#endif /* !CONFIG_USER_ONLY */
7951 7a387fff ths
            break;
7952 7a387fff ths
        case OPC_C0_FIRST ... OPC_C0_LAST:
7953 f1aa6320 ths
#ifndef CONFIG_USER_ONLY
7954 932e71cd aurel32
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7955 0eaef5aa ths
#endif /* !CONFIG_USER_ONLY */
7956 7a387fff ths
            break;
7957 7a387fff ths
        case OPC_MFMC0:
7958 8706c382 ths
#ifndef CONFIG_USER_ONLY
7959 932e71cd aurel32
            {
7960 35fbce2c aurel32
                TCGv t0 = tcg_temp_new();
7961 6c5c1e20 ths
7962 0eaef5aa ths
                op2 = MASK_MFMC0(ctx->opcode);
7963 6c5c1e20 ths
                switch (op2) {
7964 6c5c1e20 ths
                case OPC_DMT:
7965 6c5c1e20 ths
                    check_insn(env, ctx, ASE_MT);
7966 a7812ae4 pbrook
                    gen_helper_dmt(t0, t0);
7967 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7968 6c5c1e20 ths
                    break;
7969 6c5c1e20 ths
                case OPC_EMT:
7970 6c5c1e20 ths
                    check_insn(env, ctx, ASE_MT);
7971 a7812ae4 pbrook
                    gen_helper_emt(t0, t0);
7972 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7973 da80682b aurel32
                    break;
7974 6c5c1e20 ths
                case OPC_DVPE:
7975 6c5c1e20 ths
                    check_insn(env, ctx, ASE_MT);
7976 a7812ae4 pbrook
                    gen_helper_dvpe(t0, t0);
7977 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7978 6c5c1e20 ths
                    break;
7979 6c5c1e20 ths
                case OPC_EVPE:
7980 6c5c1e20 ths
                    check_insn(env, ctx, ASE_MT);
7981 a7812ae4 pbrook
                    gen_helper_evpe(t0, t0);
7982 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7983 6c5c1e20 ths
                    break;
7984 6c5c1e20 ths
                case OPC_DI:
7985 6c5c1e20 ths
                    check_insn(env, ctx, ISA_MIPS32R2);
7986 867abc7e aurel32
                    save_cpu_state(ctx, 1);
7987 a7812ae4 pbrook
                    gen_helper_di(t0);
7988 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7989 6c5c1e20 ths
                    /* Stop translation as we may have switched the execution mode */
7990 6c5c1e20 ths
                    ctx->bstate = BS_STOP;
7991 6c5c1e20 ths
                    break;
7992 6c5c1e20 ths
                case OPC_EI:
7993 6c5c1e20 ths
                    check_insn(env, ctx, ISA_MIPS32R2);
7994 867abc7e aurel32
                    save_cpu_state(ctx, 1);
7995 a7812ae4 pbrook
                    gen_helper_ei(t0);
7996 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
7997 6c5c1e20 ths
                    /* Stop translation as we may have switched the execution mode */
7998 6c5c1e20 ths
                    ctx->bstate = BS_STOP;
7999 6c5c1e20 ths
                    break;
8000 6c5c1e20 ths
                default:            /* Invalid */
8001 6c5c1e20 ths
                    MIPS_INVAL("mfmc0");
8002 6c5c1e20 ths
                    generate_exception(ctx, EXCP_RI);
8003 6c5c1e20 ths
                    break;
8004 6c5c1e20 ths
                }
8005 6c5c1e20 ths
                tcg_temp_free(t0);
8006 7a387fff ths
            }
8007 0eaef5aa ths
#endif /* !CONFIG_USER_ONLY */
8008 6af0bf9c bellard
            break;
8009 7a387fff ths
        case OPC_RDPGPR:
8010 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
8011 be24bb4f ths
            gen_load_srsgpr(rt, rd);
8012 ead9360e ths
            break;
8013 7a387fff ths
        case OPC_WRPGPR:
8014 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
8015 be24bb4f ths
            gen_store_srsgpr(rt, rd);
8016 38121543 ths
            break;
8017 6af0bf9c bellard
        default:
8018 923617a3 ths
            MIPS_INVAL("cp0");
8019 7a387fff ths
            generate_exception(ctx, EXCP_RI);
8020 6af0bf9c bellard
            break;
8021 6af0bf9c bellard
        }
8022 6af0bf9c bellard
        break;
8023 324d9e32 aurel32
    case OPC_ADDI: /* Arithmetic with immediate opcode */
8024 324d9e32 aurel32
    case OPC_ADDIU:
8025 e189e748 ths
         gen_arith_imm(env, ctx, op, rt, rs, imm);
8026 7a387fff ths
         break;
8027 324d9e32 aurel32
    case OPC_SLTI: /* Set on less than with immediate opcode */
8028 324d9e32 aurel32
    case OPC_SLTIU:
8029 324d9e32 aurel32
         gen_slt_imm(env, op, rt, rs, imm);
8030 324d9e32 aurel32
         break;
8031 324d9e32 aurel32
    case OPC_ANDI: /* Arithmetic with immediate opcode */
8032 324d9e32 aurel32
    case OPC_LUI:
8033 324d9e32 aurel32
    case OPC_ORI:
8034 324d9e32 aurel32
    case OPC_XORI:
8035 324d9e32 aurel32
         gen_logic_imm(env, op, rt, rs, imm);
8036 324d9e32 aurel32
         break;
8037 7a387fff ths
    case OPC_J ... OPC_JAL: /* Jump */
8038 7a387fff ths
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8039 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, offset);
8040 7a387fff ths
         return;
8041 7a387fff ths
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
8042 7a387fff ths
    case OPC_BEQL ... OPC_BGTZL:
8043 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
8044 7a387fff ths
         return;
8045 7a387fff ths
    case OPC_LB ... OPC_LWR: /* Load and stores */
8046 7a387fff ths
    case OPC_SB ... OPC_SW:
8047 7a387fff ths
    case OPC_SWR:
8048 7a387fff ths
    case OPC_LL:
8049 7a387fff ths
         gen_ldst(ctx, op, rt, rs, imm);
8050 7a387fff ths
         break;
8051 d66c7132 aurel32
    case OPC_SC:
8052 d66c7132 aurel32
         gen_st_cond(ctx, op, rt, rs, imm);
8053 d66c7132 aurel32
         break;
8054 7a387fff ths
    case OPC_CACHE:
8055 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8056 ead9360e ths
        /* Treat as NOP. */
8057 34ae7b51 ths
        break;
8058 7a387fff ths
    case OPC_PREF:
8059 e189e748 ths
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8060 ead9360e ths
        /* Treat as NOP. */
8061 6af0bf9c bellard
        break;
8062 4ad40f36 bellard
8063 923617a3 ths
    /* Floating point (COP1). */
8064 7a387fff ths
    case OPC_LWC1:
8065 7a387fff ths
    case OPC_LDC1:
8066 7a387fff ths
    case OPC_SWC1:
8067 7a387fff ths
    case OPC_SDC1:
8068 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8069 5e755519 ths
            check_cp1_enabled(ctx);
8070 36d23958 ths
            gen_flt_ldst(ctx, op, rt, rs, imm);
8071 36d23958 ths
        } else {
8072 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
8073 36d23958 ths
        }
8074 6ea83fed bellard
        break;
8075 6ea83fed bellard
8076 7a387fff ths
    case OPC_CP1:
8077 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8078 5e755519 ths
            check_cp1_enabled(ctx);
8079 36d23958 ths
            op1 = MASK_CP1(ctx->opcode);
8080 36d23958 ths
            switch (op1) {
8081 3a95e3a7 ths
            case OPC_MFHC1:
8082 3a95e3a7 ths
            case OPC_MTHC1:
8083 e189e748 ths
                check_insn(env, ctx, ISA_MIPS32R2);
8084 36d23958 ths
            case OPC_MFC1:
8085 36d23958 ths
            case OPC_CFC1:
8086 36d23958 ths
            case OPC_MTC1:
8087 36d23958 ths
            case OPC_CTC1:
8088 e189e748 ths
                gen_cp1(ctx, op1, rt, rd);
8089 e189e748 ths
                break;
8090 d26bc211 ths
#if defined(TARGET_MIPS64)
8091 36d23958 ths
            case OPC_DMFC1:
8092 36d23958 ths
            case OPC_DMTC1:
8093 e189e748 ths
                check_insn(env, ctx, ISA_MIPS3);
8094 36d23958 ths
                gen_cp1(ctx, op1, rt, rd);
8095 36d23958 ths
                break;
8096 e189e748 ths
#endif
8097 fbcc6828 ths
            case OPC_BC1ANY2:
8098 fbcc6828 ths
            case OPC_BC1ANY4:
8099 b8aa4598 ths
                check_cop1x(ctx);
8100 7385ac0b ths
                check_insn(env, ctx, ASE_MIPS3D);
8101 d8a5950a ths
                /* fall through */
8102 d8a5950a ths
            case OPC_BC1:
8103 e189e748 ths
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8104 5a5012ec ths
                                    (rt >> 2) & 0x7, imm << 2);
8105 36d23958 ths
                return;
8106 36d23958 ths
            case OPC_S_FMT:
8107 36d23958 ths
            case OPC_D_FMT:
8108 36d23958 ths
            case OPC_W_FMT:
8109 36d23958 ths
            case OPC_L_FMT:
8110 5a5012ec ths
            case OPC_PS_FMT:
8111 5a5012ec ths
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8112 5a5012ec ths
                           (imm >> 8) & 0x7);
8113 36d23958 ths
                break;
8114 36d23958 ths
            default:
8115 923617a3 ths
                MIPS_INVAL("cp1");
8116 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
8117 36d23958 ths
                break;
8118 36d23958 ths
            }
8119 36d23958 ths
        } else {
8120 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
8121 6ea83fed bellard
        }
8122 4ad40f36 bellard
        break;
8123 4ad40f36 bellard
8124 4ad40f36 bellard
    /* COP2.  */
8125 7a387fff ths
    case OPC_LWC2:
8126 7a387fff ths
    case OPC_LDC2:
8127 7a387fff ths
    case OPC_SWC2:
8128 7a387fff ths
    case OPC_SDC2:
8129 7a387fff ths
    case OPC_CP2:
8130 7a387fff ths
        /* COP2: Not implemented. */
8131 4ad40f36 bellard
        generate_exception_err(ctx, EXCP_CpU, 2);
8132 4ad40f36 bellard
        break;
8133 4ad40f36 bellard
8134 7a387fff ths
    case OPC_CP3:
8135 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8136 5e755519 ths
            check_cp1_enabled(ctx);
8137 36d23958 ths
            op1 = MASK_CP3(ctx->opcode);
8138 36d23958 ths
            switch (op1) {
8139 5a5012ec ths
            case OPC_LWXC1:
8140 5a5012ec ths
            case OPC_LDXC1:
8141 5a5012ec ths
            case OPC_LUXC1:
8142 5a5012ec ths
            case OPC_SWXC1:
8143 5a5012ec ths
            case OPC_SDXC1:
8144 5a5012ec ths
            case OPC_SUXC1:
8145 93b12ccc ths
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8146 5a5012ec ths
                break;
8147 e0c84da7 ths
            case OPC_PREFX:
8148 ead9360e ths
                /* Treat as NOP. */
8149 e0c84da7 ths
                break;
8150 5a5012ec ths
            case OPC_ALNV_PS:
8151 5a5012ec ths
            case OPC_MADD_S:
8152 5a5012ec ths
            case OPC_MADD_D:
8153 5a5012ec ths
            case OPC_MADD_PS:
8154 5a5012ec ths
            case OPC_MSUB_S:
8155 5a5012ec ths
            case OPC_MSUB_D:
8156 5a5012ec ths
            case OPC_MSUB_PS:
8157 5a5012ec ths
            case OPC_NMADD_S:
8158 5a5012ec ths
            case OPC_NMADD_D:
8159 5a5012ec ths
            case OPC_NMADD_PS:
8160 5a5012ec ths
            case OPC_NMSUB_S:
8161 5a5012ec ths
            case OPC_NMSUB_D:
8162 5a5012ec ths
            case OPC_NMSUB_PS:
8163 5a5012ec ths
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8164 5a5012ec ths
                break;
8165 36d23958 ths
            default:
8166 923617a3 ths
                MIPS_INVAL("cp3");
8167 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
8168 36d23958 ths
                break;
8169 36d23958 ths
            }
8170 36d23958 ths
        } else {
8171 e397ee33 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
8172 7a387fff ths
        }
8173 4ad40f36 bellard
        break;
8174 4ad40f36 bellard
8175 d26bc211 ths
#if defined(TARGET_MIPS64)
8176 7a387fff ths
    /* MIPS64 opcodes */
8177 7a387fff ths
    case OPC_LWU:
8178 7a387fff ths
    case OPC_LDL ... OPC_LDR:
8179 7a387fff ths
    case OPC_SDL ... OPC_SDR:
8180 7a387fff ths
    case OPC_LLD:
8181 7a387fff ths
    case OPC_LD:
8182 7a387fff ths
    case OPC_SD:
8183 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
8184 e189e748 ths
        check_mips_64(ctx);
8185 7a387fff ths
        gen_ldst(ctx, op, rt, rs, imm);
8186 7a387fff ths
        break;
8187 d66c7132 aurel32
    case OPC_SCD:
8188 d66c7132 aurel32
        check_insn(env, ctx, ISA_MIPS3);
8189 d66c7132 aurel32
        check_mips_64(ctx);
8190 d66c7132 aurel32
        gen_st_cond(ctx, op, rt, rs, imm);
8191 d66c7132 aurel32
        break;
8192 324d9e32 aurel32
    case OPC_DADDI:
8193 324d9e32 aurel32
    case OPC_DADDIU:
8194 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
8195 e189e748 ths
        check_mips_64(ctx);
8196 e189e748 ths
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8197 7a387fff ths
        break;
8198 6af0bf9c bellard
#endif
8199 7a387fff ths
    case OPC_JALX:
8200 e189e748 ths
        check_insn(env, ctx, ASE_MIPS16);
8201 7a387fff ths
        /* MIPS16: Not implemented. */
8202 7a387fff ths
    case OPC_MDMX:
8203 e189e748 ths
        check_insn(env, ctx, ASE_MDMX);
8204 7a387fff ths
        /* MDMX: Not implemented. */
8205 6af0bf9c bellard
    default:            /* Invalid */
8206 923617a3 ths
        MIPS_INVAL("major opcode");
8207 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
8208 6af0bf9c bellard
        break;
8209 6af0bf9c bellard
    }
8210 4ad40f36 bellard
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8211 c53f4a62 ths
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8212 6af0bf9c bellard
        /* Branches completion */
8213 4ad40f36 bellard
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8214 6af0bf9c bellard
        ctx->bstate = BS_BRANCH;
8215 6af0bf9c bellard
        save_cpu_state(ctx, 0);
8216 2e70f6ef pbrook
        /* FIXME: Need to clear can_do_io.  */
8217 5a5012ec ths
        switch (hflags) {
8218 6af0bf9c bellard
        case MIPS_HFLAG_B:
8219 6af0bf9c bellard
            /* unconditional branch */
8220 6af0bf9c bellard
            MIPS_DEBUG("unconditional branch");
8221 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
8222 6af0bf9c bellard
            break;
8223 6af0bf9c bellard
        case MIPS_HFLAG_BL:
8224 6af0bf9c bellard
            /* blikely taken case */
8225 6af0bf9c bellard
            MIPS_DEBUG("blikely branch taken");
8226 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
8227 6af0bf9c bellard
            break;
8228 6af0bf9c bellard
        case MIPS_HFLAG_BC:
8229 6af0bf9c bellard
            /* Conditional branch */
8230 6af0bf9c bellard
            MIPS_DEBUG("conditional branch");
8231 c53be334 bellard
            {
8232 8e9ade68 ths
                int l1 = gen_new_label();
8233 8e9ade68 ths
8234 1ba74fb8 aurel32
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8235 8e9ade68 ths
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8236 8e9ade68 ths
                gen_set_label(l1);
8237 8e9ade68 ths
                gen_goto_tb(ctx, 0, ctx->btarget);
8238 c53be334 bellard
            }
8239 6af0bf9c bellard
            break;
8240 6af0bf9c bellard
        case MIPS_HFLAG_BR:
8241 6af0bf9c bellard
            /* unconditional branch to register */
8242 6af0bf9c bellard
            MIPS_DEBUG("branch to register");
8243 4b2eb8d2 ths
            tcg_gen_mov_tl(cpu_PC, btarget);
8244 57fec1fe bellard
            tcg_gen_exit_tb(0);
8245 6af0bf9c bellard
            break;
8246 6af0bf9c bellard
        default:
8247 6af0bf9c bellard
            MIPS_DEBUG("unknown branch");
8248 6af0bf9c bellard
            break;
8249 6af0bf9c bellard
        }
8250 6af0bf9c bellard
    }
8251 6af0bf9c bellard
}
8252 6af0bf9c bellard
8253 2cfc5f17 ths
static inline void
8254 820e00f2 ths
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8255 820e00f2 ths
                                int search_pc)
8256 6af0bf9c bellard
{
8257 278d0702 ths
    DisasContext ctx;
8258 6af0bf9c bellard
    target_ulong pc_start;
8259 6af0bf9c bellard
    uint16_t *gen_opc_end;
8260 a1d1bb31 aliguori
    CPUBreakpoint *bp;
8261 6af0bf9c bellard
    int j, lj = -1;
8262 2e70f6ef pbrook
    int num_insns;
8263 2e70f6ef pbrook
    int max_insns;
8264 6af0bf9c bellard
8265 93fcfe39 aliguori
    if (search_pc)
8266 93fcfe39 aliguori
        qemu_log("search pc %d\n", search_pc);
8267 4ad40f36 bellard
8268 6af0bf9c bellard
    pc_start = tb->pc;
8269 faf7aaa9 ths
    /* Leave some spare opc slots for branch handling. */
8270 faf7aaa9 ths
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8271 6af0bf9c bellard
    ctx.pc = pc_start;
8272 4ad40f36 bellard
    ctx.saved_pc = -1;
8273 6af0bf9c bellard
    ctx.tb = tb;
8274 6af0bf9c bellard
    ctx.bstate = BS_NONE;
8275 4ad40f36 bellard
    /* Restore delay slot state from the tb context.  */
8276 c068688b j_mayer
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8277 fd4a04eb ths
    restore_cpu_state(env, &ctx);
8278 932e71cd aurel32
#ifdef CONFIG_USER_ONLY
8279 0eaef5aa ths
        ctx.mem_idx = MIPS_HFLAG_UM;
8280 932e71cd aurel32
#else
8281 0eaef5aa ths
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8282 932e71cd aurel32
#endif
8283 2e70f6ef pbrook
    num_insns = 0;
8284 2e70f6ef pbrook
    max_insns = tb->cflags & CF_COUNT_MASK;
8285 2e70f6ef pbrook
    if (max_insns == 0)
8286 2e70f6ef pbrook
        max_insns = CF_COUNT_MASK;
8287 6af0bf9c bellard
#ifdef DEBUG_DISAS
8288 93fcfe39 aliguori
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8289 93fcfe39 aliguori
    /* FIXME: This may print out stale hflags from env... */
8290 93fcfe39 aliguori
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8291 6af0bf9c bellard
#endif
8292 d12d51d5 aliguori
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8293 2e70f6ef pbrook
    gen_icount_start();
8294 faf7aaa9 ths
    while (ctx.bstate == BS_NONE) {
8295 c0ce998e aliguori
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8296 c0ce998e aliguori
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8297 a1d1bb31 aliguori
                if (bp->pc == ctx.pc) {
8298 278d0702 ths
                    save_cpu_state(&ctx, 1);
8299 4ad40f36 bellard
                    ctx.bstate = BS_BRANCH;
8300 a7812ae4 pbrook
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8301 ce62e5ba ths
                    /* Include the breakpoint location or the tb won't
8302 ce62e5ba ths
                     * be flushed when it must be.  */
8303 ce62e5ba ths
                    ctx.pc += 4;
8304 4ad40f36 bellard
                    goto done_generating;
8305 4ad40f36 bellard
                }
8306 4ad40f36 bellard
            }
8307 4ad40f36 bellard
        }
8308 4ad40f36 bellard
8309 6af0bf9c bellard
        if (search_pc) {
8310 6af0bf9c bellard
            j = gen_opc_ptr - gen_opc_buf;
8311 6af0bf9c bellard
            if (lj < j) {
8312 6af0bf9c bellard
                lj++;
8313 6af0bf9c bellard
                while (lj < j)
8314 6af0bf9c bellard
                    gen_opc_instr_start[lj++] = 0;
8315 6af0bf9c bellard
            }
8316 4ad40f36 bellard
            gen_opc_pc[lj] = ctx.pc;
8317 4ad40f36 bellard
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8318 4ad40f36 bellard
            gen_opc_instr_start[lj] = 1;
8319 2e70f6ef pbrook
            gen_opc_icount[lj] = num_insns;
8320 6af0bf9c bellard
        }
8321 2e70f6ef pbrook
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8322 2e70f6ef pbrook
            gen_io_start();
8323 6af0bf9c bellard
        ctx.opcode = ldl_code(ctx.pc);
8324 36d23958 ths
        decode_opc(env, &ctx);
8325 6af0bf9c bellard
        ctx.pc += 4;
8326 2e70f6ef pbrook
        num_insns++;
8327 4ad40f36 bellard
8328 4ad40f36 bellard
        if (env->singlestep_enabled)
8329 4ad40f36 bellard
            break;
8330 4ad40f36 bellard
8331 6af0bf9c bellard
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8332 6af0bf9c bellard
            break;
8333 4ad40f36 bellard
8334 faf7aaa9 ths
        if (gen_opc_ptr >= gen_opc_end)
8335 faf7aaa9 ths
            break;
8336 faf7aaa9 ths
8337 2e70f6ef pbrook
        if (num_insns >= max_insns)
8338 2e70f6ef pbrook
            break;
8339 1b530a6d aurel32
8340 1b530a6d aurel32
        if (singlestep)
8341 1b530a6d aurel32
            break;
8342 6af0bf9c bellard
    }
8343 2e70f6ef pbrook
    if (tb->cflags & CF_LAST_IO)
8344 2e70f6ef pbrook
        gen_io_end();
8345 4ad40f36 bellard
    if (env->singlestep_enabled) {
8346 278d0702 ths
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8347 a7812ae4 pbrook
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8348 16c00cb2 ths
    } else {
8349 6958549d aurel32
        switch (ctx.bstate) {
8350 16c00cb2 ths
        case BS_STOP:
8351 a7812ae4 pbrook
            gen_helper_interrupt_restart();
8352 df1561e2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
8353 df1561e2 ths
            break;
8354 16c00cb2 ths
        case BS_NONE:
8355 278d0702 ths
            save_cpu_state(&ctx, 0);
8356 16c00cb2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
8357 16c00cb2 ths
            break;
8358 5a5012ec ths
        case BS_EXCP:
8359 a7812ae4 pbrook
            gen_helper_interrupt_restart();
8360 57fec1fe bellard
            tcg_gen_exit_tb(0);
8361 16c00cb2 ths
            break;
8362 5a5012ec ths
        case BS_BRANCH:
8363 5a5012ec ths
        default:
8364 5a5012ec ths
            break;
8365 6958549d aurel32
        }
8366 6af0bf9c bellard
    }
8367 4ad40f36 bellard
done_generating:
8368 2e70f6ef pbrook
    gen_icount_end(tb, num_insns);
8369 6af0bf9c bellard
    *gen_opc_ptr = INDEX_op_end;
8370 6af0bf9c bellard
    if (search_pc) {
8371 6af0bf9c bellard
        j = gen_opc_ptr - gen_opc_buf;
8372 6af0bf9c bellard
        lj++;
8373 6af0bf9c bellard
        while (lj <= j)
8374 6af0bf9c bellard
            gen_opc_instr_start[lj++] = 0;
8375 6af0bf9c bellard
    } else {
8376 6af0bf9c bellard
        tb->size = ctx.pc - pc_start;
8377 2e70f6ef pbrook
        tb->icount = num_insns;
8378 6af0bf9c bellard
    }
8379 6af0bf9c bellard
#ifdef DEBUG_DISAS
8380 d12d51d5 aliguori
    LOG_DISAS("\n");
8381 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8382 93fcfe39 aliguori
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8383 93fcfe39 aliguori
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8384 93fcfe39 aliguori
        qemu_log("\n");
8385 6af0bf9c bellard
    }
8386 93fcfe39 aliguori
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8387 6af0bf9c bellard
#endif
8388 6af0bf9c bellard
}
8389 6af0bf9c bellard
8390 2cfc5f17 ths
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8391 6af0bf9c bellard
{
8392 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 0);
8393 6af0bf9c bellard
}
8394 6af0bf9c bellard
8395 2cfc5f17 ths
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8396 6af0bf9c bellard
{
8397 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 1);
8398 6af0bf9c bellard
}
8399 6af0bf9c bellard
8400 8706c382 ths
static void fpu_dump_state(CPUState *env, FILE *f,
8401 8706c382 ths
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8402 8706c382 ths
                           int flags)
8403 6ea83fed bellard
{
8404 6ea83fed bellard
    int i;
8405 5e755519 ths
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8406 5a5012ec ths
8407 5a5012ec ths
#define printfpr(fp)                                                        \
8408 5a5012ec ths
    do {                                                                    \
8409 5a5012ec ths
        if (is_fpu64)                                                       \
8410 5a5012ec ths
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8411 5a5012ec ths
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8412 5a5012ec ths
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8413 5a5012ec ths
        else {                                                              \
8414 5a5012ec ths
            fpr_t tmp;                                                      \
8415 5a5012ec ths
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8416 5a5012ec ths
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8417 5a5012ec ths
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8418 5a5012ec ths
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8419 5a5012ec ths
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8420 5a5012ec ths
        }                                                                   \
8421 6ea83fed bellard
    } while(0)
8422 6ea83fed bellard
8423 5a5012ec ths
8424 5a5012ec ths
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8425 f01be154 ths
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8426 f01be154 ths
                get_float_exception_flags(&env->active_fpu.fp_status));
8427 5a5012ec ths
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8428 5a5012ec ths
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8429 f01be154 ths
        printfpr(&env->active_fpu.fpr[i]);
8430 6ea83fed bellard
    }
8431 6ea83fed bellard
8432 6ea83fed bellard
#undef printfpr
8433 6ea83fed bellard
}
8434 6ea83fed bellard
8435 d26bc211 ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8436 c570fd16 ths
/* Debug help: The architecture requires 32bit code to maintain proper
8437 c7e8a937 ths
   sign-extended values on 64bit machines.  */
8438 c570fd16 ths
8439 c570fd16 ths
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8440 c570fd16 ths
8441 8706c382 ths
static void
8442 8706c382 ths
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8443 8706c382 ths
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8444 8706c382 ths
                                int flags)
8445 c570fd16 ths
{
8446 c570fd16 ths
    int i;
8447 c570fd16 ths
8448 b5dc7732 ths
    if (!SIGN_EXT_P(env->active_tc.PC))
8449 b5dc7732 ths
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8450 b5dc7732 ths
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8451 b5dc7732 ths
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8452 b5dc7732 ths
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8453 b5dc7732 ths
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8454 c570fd16 ths
    if (!SIGN_EXT_P(env->btarget))
8455 3594c774 ths
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8456 c570fd16 ths
8457 c570fd16 ths
    for (i = 0; i < 32; i++) {
8458 b5dc7732 ths
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8459 b5dc7732 ths
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8460 c570fd16 ths
    }
8461 c570fd16 ths
8462 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_EPC))
8463 3594c774 ths
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8464 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8465 3594c774 ths
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8466 c570fd16 ths
}
8467 c570fd16 ths
#endif
8468 c570fd16 ths
8469 5fafdf24 ths
void cpu_dump_state (CPUState *env, FILE *f,
8470 6af0bf9c bellard
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8471 6af0bf9c bellard
                     int flags)
8472 6af0bf9c bellard
{
8473 6af0bf9c bellard
    int i;
8474 3b46e624 ths
8475 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",
8476 3d5be870 ths
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8477 3d5be870 ths
                env->hflags, env->btarget, env->bcond);
8478 6af0bf9c bellard
    for (i = 0; i < 32; i++) {
8479 6af0bf9c bellard
        if ((i & 3) == 0)
8480 6af0bf9c bellard
            cpu_fprintf(f, "GPR%02d:", i);
8481 b5dc7732 ths
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8482 6af0bf9c bellard
        if ((i & 3) == 3)
8483 6af0bf9c bellard
            cpu_fprintf(f, "\n");
8484 6af0bf9c bellard
    }
8485 568b600d bellard
8486 3594c774 ths
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8487 5e755519 ths
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8488 3594c774 ths
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8489 6af0bf9c bellard
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8490 5e755519 ths
    if (env->hflags & MIPS_HFLAG_FPU)
8491 7a387fff ths
        fpu_dump_state(env, f, cpu_fprintf, flags);
8492 d26bc211 ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8493 c570fd16 ths
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8494 c570fd16 ths
#endif
8495 6af0bf9c bellard
}
8496 6af0bf9c bellard
8497 39454628 ths
static void mips_tcg_init(void)
8498 39454628 ths
{
8499 f01be154 ths
    int i;
8500 39454628 ths
    static int inited;
8501 39454628 ths
8502 39454628 ths
    /* Initialize various static tables. */
8503 39454628 ths
    if (inited)
8504 6958549d aurel32
        return;
8505 39454628 ths
8506 a7812ae4 pbrook
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8507 f2c94b92 aurel32
    TCGV_UNUSED(cpu_gpr[0]);
8508 bb928dbe aurel32
    for (i = 1; i < 32; i++)
8509 a7812ae4 pbrook
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8510 4b2eb8d2 ths
                                        offsetof(CPUState, active_tc.gpr[i]),
8511 4b2eb8d2 ths
                                        regnames[i]);
8512 a7812ae4 pbrook
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8513 4b2eb8d2 ths
                                offsetof(CPUState, active_tc.PC), "PC");
8514 4b2eb8d2 ths
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8515 a7812ae4 pbrook
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8516 4b2eb8d2 ths
                                       offsetof(CPUState, active_tc.HI[i]),
8517 4b2eb8d2 ths
                                       regnames_HI[i]);
8518 a7812ae4 pbrook
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8519 4b2eb8d2 ths
                                       offsetof(CPUState, active_tc.LO[i]),
8520 4b2eb8d2 ths
                                       regnames_LO[i]);
8521 a7812ae4 pbrook
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8522 4b2eb8d2 ths
                                        offsetof(CPUState, active_tc.ACX[i]),
8523 4b2eb8d2 ths
                                        regnames_ACX[i]);
8524 4b2eb8d2 ths
    }
8525 a7812ae4 pbrook
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8526 4b2eb8d2 ths
                                     offsetof(CPUState, active_tc.DSPControl),
8527 4b2eb8d2 ths
                                     "DSPControl");
8528 1ba74fb8 aurel32
    bcond = tcg_global_mem_new(TCG_AREG0,
8529 1ba74fb8 aurel32
                               offsetof(CPUState, bcond), "bcond");
8530 a7812ae4 pbrook
    btarget = tcg_global_mem_new(TCG_AREG0,
8531 d077b6f7 ths
                                 offsetof(CPUState, btarget), "btarget");
8532 41db4607 aurel32
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8533 41db4607 aurel32
                                    offsetof(CPUState, hflags), "hflags");
8534 41db4607 aurel32
8535 a7812ae4 pbrook
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8536 a7812ae4 pbrook
                                      offsetof(CPUState, active_fpu.fcr0),
8537 a7812ae4 pbrook
                                      "fcr0");
8538 a7812ae4 pbrook
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8539 a7812ae4 pbrook
                                       offsetof(CPUState, active_fpu.fcr31),
8540 a7812ae4 pbrook
                                       "fcr31");
8541 39454628 ths
8542 7dd9e556 ths
    /* register helpers */
8543 a7812ae4 pbrook
#define GEN_HELPER 2
8544 7dd9e556 ths
#include "helper.h"
8545 7dd9e556 ths
8546 39454628 ths
    inited = 1;
8547 39454628 ths
}
8548 39454628 ths
8549 aaed909a bellard
#include "translate_init.c"
8550 aaed909a bellard
8551 aaed909a bellard
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8552 6af0bf9c bellard
{
8553 6af0bf9c bellard
    CPUMIPSState *env;
8554 aaed909a bellard
    const mips_def_t *def;
8555 6af0bf9c bellard
8556 aaed909a bellard
    def = cpu_mips_find_by_name(cpu_model);
8557 aaed909a bellard
    if (!def)
8558 aaed909a bellard
        return NULL;
8559 6af0bf9c bellard
    env = qemu_mallocz(sizeof(CPUMIPSState));
8560 aaed909a bellard
    env->cpu_model = def;
8561 aaed909a bellard
8562 173d6cfe bellard
    cpu_exec_init(env);
8563 01ba9816 ths
    env->cpu_model_str = cpu_model;
8564 39454628 ths
    mips_tcg_init();
8565 6ae81775 ths
    cpu_reset(env);
8566 6ae81775 ths
    return env;
8567 6ae81775 ths
}
8568 6ae81775 ths
8569 6ae81775 ths
void cpu_reset (CPUMIPSState *env)
8570 6ae81775 ths
{
8571 eca1bdf4 aliguori
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8572 eca1bdf4 aliguori
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8573 eca1bdf4 aliguori
        log_cpu_state(env, 0);
8574 eca1bdf4 aliguori
    }
8575 eca1bdf4 aliguori
8576 6ae81775 ths
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8577 6ae81775 ths
8578 6af0bf9c bellard
    tlb_flush(env, 1);
8579 6ae81775 ths
8580 6af0bf9c bellard
    /* Minimal init */
8581 0eaef5aa ths
#if defined(CONFIG_USER_ONLY)
8582 932e71cd aurel32
    env->hflags = MIPS_HFLAG_UM;
8583 932e71cd aurel32
#else
8584 932e71cd aurel32
    if (env->hflags & MIPS_HFLAG_BMASK) {
8585 932e71cd aurel32
        /* If the exception was raised from a delay slot,
8586 932e71cd aurel32
           come back to the jump.  */
8587 932e71cd aurel32
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8588 aa328add ths
    } else {
8589 932e71cd aurel32
        env->CP0_ErrorEPC = env->active_tc.PC;
8590 932e71cd aurel32
    }
8591 932e71cd aurel32
    env->active_tc.PC = (int32_t)0xBFC00000;
8592 932e71cd aurel32
    env->CP0_Wired = 0;
8593 932e71cd aurel32
    /* SMP not implemented */
8594 932e71cd aurel32
    env->CP0_EBase = 0x80000000;
8595 932e71cd aurel32
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8596 932e71cd aurel32
    /* vectored interrupts not implemented, timer on int 7,
8597 932e71cd aurel32
       no performance counters. */
8598 932e71cd aurel32
    env->CP0_IntCtl = 0xe0000000;
8599 932e71cd aurel32
    {
8600 932e71cd aurel32
        int i;
8601 932e71cd aurel32
8602 932e71cd aurel32
        for (i = 0; i < 7; i++) {
8603 932e71cd aurel32
            env->CP0_WatchLo[i] = 0;
8604 932e71cd aurel32
            env->CP0_WatchHi[i] = 0x80000000;
8605 fd88b6ab ths
        }
8606 932e71cd aurel32
        env->CP0_WatchLo[7] = 0;
8607 932e71cd aurel32
        env->CP0_WatchHi[7] = 0;
8608 fd88b6ab ths
    }
8609 932e71cd aurel32
    /* Count register increments in debug mode, EJTAG version 1 */
8610 932e71cd aurel32
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8611 932e71cd aurel32
    env->hflags = MIPS_HFLAG_CP0;
8612 932e71cd aurel32
#endif
8613 6af0bf9c bellard
    env->exception_index = EXCP_NONE;
8614 aaed909a bellard
    cpu_mips_register(env, env->cpu_model);
8615 6af0bf9c bellard
}
8616 d2856f1a aurel32
8617 d2856f1a aurel32
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8618 d2856f1a aurel32
                unsigned long searched_pc, int pc_pos, void *puc)
8619 d2856f1a aurel32
{
8620 b5dc7732 ths
    env->active_tc.PC = gen_opc_pc[pc_pos];
8621 d2856f1a aurel32
    env->hflags &= ~MIPS_HFLAG_BMASK;
8622 d2856f1a aurel32
    env->hflags |= gen_opc_hflags[pc_pos];
8623 d2856f1a aurel32
}