Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 618b0fe9

History | View | Annotate | Download (251.3 kB)

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