Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a569557f

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