Statistics
| Branch: | Revision:

root / target-mips / translate.c @ ed23fbd9

History | View | Annotate | Download (258.2 kB)

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