Statistics
| Branch: | Revision:

root / target-mips / translate.c @ d26968ec

History | View | Annotate | Download (244.4 kB)

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