Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 72cf2d4f

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