Statistics
| Branch: | Revision:

root / target-mips / translate.c @ f8ed7070

History | View | Annotate | Download (219.8 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 48d38ca5 ths
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
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 48d38ca5 ths
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
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 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1904 48d38ca5 ths
            {
1905 90cb786c ths
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1906 90cb786c ths
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1907 a4a99d71 ths
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1908 a4a99d71 ths
1909 a4a99d71 ths
                tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
1910 a4a99d71 ths
                tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
1911 a4a99d71 ths
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1912 a4a99d71 ths
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1913 a4a99d71 ths
                tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp3);
1914 a4a99d71 ths
                tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp2);
1915 a4a99d71 ths
                gen_store_LO(cpu_T[0], 0);
1916 a4a99d71 ths
                gen_store_HI(cpu_T[1], 0);
1917 48d38ca5 ths
            }
1918 48d38ca5 ths
            gen_set_label(l1);
1919 48d38ca5 ths
        }
1920 6af0bf9c bellard
        opn = "div";
1921 6af0bf9c bellard
        break;
1922 6af0bf9c bellard
    case OPC_DIVU:
1923 48d38ca5 ths
        {
1924 48d38ca5 ths
            int l1 = gen_new_label();
1925 48d38ca5 ths
1926 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1927 48d38ca5 ths
            {
1928 48d38ca5 ths
                TCGv r_tmp1 = new_tmp();
1929 48d38ca5 ths
                TCGv r_tmp2 = new_tmp();
1930 48d38ca5 ths
                TCGv r_tmp3 = new_tmp();
1931 48d38ca5 ths
1932 9b686843 ths
                tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1933 9b686843 ths
                tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1934 48d38ca5 ths
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1935 48d38ca5 ths
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1936 9b686843 ths
                tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3);
1937 9b686843 ths
                tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1);
1938 893f9865 ths
                gen_store_LO(cpu_T[0], 0);
1939 893f9865 ths
                gen_store_HI(cpu_T[1], 0);
1940 48d38ca5 ths
                dead_tmp(r_tmp1);
1941 48d38ca5 ths
                dead_tmp(r_tmp2);
1942 48d38ca5 ths
                dead_tmp(r_tmp3);
1943 48d38ca5 ths
            }
1944 48d38ca5 ths
            gen_set_label(l1);
1945 48d38ca5 ths
        }
1946 6af0bf9c bellard
        opn = "divu";
1947 6af0bf9c bellard
        break;
1948 6af0bf9c bellard
    case OPC_MULT:
1949 6af0bf9c bellard
        gen_op_mult();
1950 6af0bf9c bellard
        opn = "mult";
1951 6af0bf9c bellard
        break;
1952 6af0bf9c bellard
    case OPC_MULTU:
1953 6af0bf9c bellard
        gen_op_multu();
1954 6af0bf9c bellard
        opn = "multu";
1955 6af0bf9c bellard
        break;
1956 d26bc211 ths
#if defined(TARGET_MIPS64)
1957 7a387fff ths
    case OPC_DDIV:
1958 48d38ca5 ths
        {
1959 48d38ca5 ths
            int l1 = gen_new_label();
1960 48d38ca5 ths
1961 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1962 48d38ca5 ths
            {
1963 48d38ca5 ths
                int l2 = gen_new_label();
1964 48d38ca5 ths
1965 cb63669a pbrook
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 1ULL << 63, l2);
1966 cb63669a pbrook
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1ULL, l2);
1967 84774e8e ths
                {
1968 84774e8e ths
                    tcg_gen_movi_tl(cpu_T[1], 0);
1969 84774e8e ths
                    gen_store_LO(cpu_T[0], 0);
1970 84774e8e ths
                    gen_store_HI(cpu_T[1], 0);
1971 84774e8e ths
                    tcg_gen_br(l1);
1972 84774e8e ths
                }
1973 48d38ca5 ths
                gen_set_label(l2);
1974 84774e8e ths
                {
1975 84774e8e ths
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1976 84774e8e ths
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1977 48d38ca5 ths
1978 84774e8e ths
                    tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1979 84774e8e ths
                    tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1980 84774e8e ths
                    gen_store_LO(r_tmp1, 0);
1981 84774e8e ths
                    gen_store_HI(r_tmp2, 0);
1982 84774e8e ths
                }
1983 48d38ca5 ths
            }
1984 48d38ca5 ths
            gen_set_label(l1);
1985 48d38ca5 ths
        }
1986 7a387fff ths
        opn = "ddiv";
1987 7a387fff ths
        break;
1988 7a387fff ths
    case OPC_DDIVU:
1989 48d38ca5 ths
        {
1990 48d38ca5 ths
            int l1 = gen_new_label();
1991 48d38ca5 ths
1992 cb63669a pbrook
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1993 48d38ca5 ths
            {
1994 48d38ca5 ths
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1995 48d38ca5 ths
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1996 48d38ca5 ths
1997 48d38ca5 ths
                tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1998 48d38ca5 ths
                tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1999 893f9865 ths
                gen_store_LO(r_tmp1, 0);
2000 893f9865 ths
                gen_store_HI(r_tmp2, 0);
2001 48d38ca5 ths
            }
2002 48d38ca5 ths
            gen_set_label(l1);
2003 48d38ca5 ths
        }
2004 7a387fff ths
        opn = "ddivu";
2005 7a387fff ths
        break;
2006 7a387fff ths
    case OPC_DMULT:
2007 7a387fff ths
        gen_op_dmult();
2008 7a387fff ths
        opn = "dmult";
2009 7a387fff ths
        break;
2010 7a387fff ths
    case OPC_DMULTU:
2011 7a387fff ths
        gen_op_dmultu();
2012 7a387fff ths
        opn = "dmultu";
2013 7a387fff ths
        break;
2014 7a387fff ths
#endif
2015 6af0bf9c bellard
    case OPC_MADD:
2016 6af0bf9c bellard
        gen_op_madd();
2017 6af0bf9c bellard
        opn = "madd";
2018 6af0bf9c bellard
        break;
2019 6af0bf9c bellard
    case OPC_MADDU:
2020 6af0bf9c bellard
        gen_op_maddu();
2021 6af0bf9c bellard
        opn = "maddu";
2022 6af0bf9c bellard
        break;
2023 6af0bf9c bellard
    case OPC_MSUB:
2024 6af0bf9c bellard
        gen_op_msub();
2025 6af0bf9c bellard
        opn = "msub";
2026 6af0bf9c bellard
        break;
2027 6af0bf9c bellard
    case OPC_MSUBU:
2028 6af0bf9c bellard
        gen_op_msubu();
2029 6af0bf9c bellard
        opn = "msubu";
2030 6af0bf9c bellard
        break;
2031 6af0bf9c bellard
    default:
2032 923617a3 ths
        MIPS_INVAL(opn);
2033 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
2034 6af0bf9c bellard
        return;
2035 6af0bf9c bellard
    }
2036 6af0bf9c bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2037 6af0bf9c bellard
}
2038 6af0bf9c bellard
2039 e9c71dd1 ths
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2040 e9c71dd1 ths
                            int rd, int rs, int rt)
2041 e9c71dd1 ths
{
2042 e9c71dd1 ths
    const char *opn = "mul vr54xx";
2043 e9c71dd1 ths
2044 8e9ade68 ths
    gen_load_gpr(cpu_T[0], rs);
2045 8e9ade68 ths
    gen_load_gpr(cpu_T[1], rt);
2046 e9c71dd1 ths
2047 e9c71dd1 ths
    switch (opc) {
2048 e9c71dd1 ths
    case OPC_VR54XX_MULS:
2049 e9c71dd1 ths
        gen_op_muls();
2050 e9c71dd1 ths
        opn = "muls";
2051 e9c71dd1 ths
        break;
2052 e9c71dd1 ths
    case OPC_VR54XX_MULSU:
2053 e9c71dd1 ths
        gen_op_mulsu();
2054 e9c71dd1 ths
        opn = "mulsu";
2055 e9c71dd1 ths
        break;
2056 e9c71dd1 ths
    case OPC_VR54XX_MACC:
2057 e9c71dd1 ths
        gen_op_macc();
2058 e9c71dd1 ths
        opn = "macc";
2059 e9c71dd1 ths
        break;
2060 e9c71dd1 ths
    case OPC_VR54XX_MACCU:
2061 e9c71dd1 ths
        gen_op_maccu();
2062 e9c71dd1 ths
        opn = "maccu";
2063 e9c71dd1 ths
        break;
2064 e9c71dd1 ths
    case OPC_VR54XX_MSAC:
2065 e9c71dd1 ths
        gen_op_msac();
2066 e9c71dd1 ths
        opn = "msac";
2067 e9c71dd1 ths
        break;
2068 e9c71dd1 ths
    case OPC_VR54XX_MSACU:
2069 e9c71dd1 ths
        gen_op_msacu();
2070 e9c71dd1 ths
        opn = "msacu";
2071 e9c71dd1 ths
        break;
2072 e9c71dd1 ths
    case OPC_VR54XX_MULHI:
2073 e9c71dd1 ths
        gen_op_mulhi();
2074 e9c71dd1 ths
        opn = "mulhi";
2075 e9c71dd1 ths
        break;
2076 e9c71dd1 ths
    case OPC_VR54XX_MULHIU:
2077 e9c71dd1 ths
        gen_op_mulhiu();
2078 e9c71dd1 ths
        opn = "mulhiu";
2079 e9c71dd1 ths
        break;
2080 e9c71dd1 ths
    case OPC_VR54XX_MULSHI:
2081 e9c71dd1 ths
        gen_op_mulshi();
2082 e9c71dd1 ths
        opn = "mulshi";
2083 e9c71dd1 ths
        break;
2084 e9c71dd1 ths
    case OPC_VR54XX_MULSHIU:
2085 e9c71dd1 ths
        gen_op_mulshiu();
2086 e9c71dd1 ths
        opn = "mulshiu";
2087 e9c71dd1 ths
        break;
2088 e9c71dd1 ths
    case OPC_VR54XX_MACCHI:
2089 e9c71dd1 ths
        gen_op_macchi();
2090 e9c71dd1 ths
        opn = "macchi";
2091 e9c71dd1 ths
        break;
2092 e9c71dd1 ths
    case OPC_VR54XX_MACCHIU:
2093 e9c71dd1 ths
        gen_op_macchiu();
2094 e9c71dd1 ths
        opn = "macchiu";
2095 e9c71dd1 ths
        break;
2096 e9c71dd1 ths
    case OPC_VR54XX_MSACHI:
2097 e9c71dd1 ths
        gen_op_msachi();
2098 e9c71dd1 ths
        opn = "msachi";
2099 e9c71dd1 ths
        break;
2100 e9c71dd1 ths
    case OPC_VR54XX_MSACHIU:
2101 e9c71dd1 ths
        gen_op_msachiu();
2102 e9c71dd1 ths
        opn = "msachiu";
2103 e9c71dd1 ths
        break;
2104 e9c71dd1 ths
    default:
2105 e9c71dd1 ths
        MIPS_INVAL("mul vr54xx");
2106 e9c71dd1 ths
        generate_exception(ctx, EXCP_RI);
2107 e9c71dd1 ths
        return;
2108 e9c71dd1 ths
    }
2109 8e9ade68 ths
    gen_store_gpr(cpu_T[0], rd);
2110 e9c71dd1 ths
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2111 e9c71dd1 ths
}
2112 e9c71dd1 ths
2113 7a387fff ths
static void gen_cl (DisasContext *ctx, uint32_t opc,
2114 6af0bf9c bellard
                    int rd, int rs)
2115 6af0bf9c bellard
{
2116 923617a3 ths
    const char *opn = "CLx";
2117 6af0bf9c bellard
    if (rd == 0) {
2118 ead9360e ths
        /* Treat as NOP. */
2119 6af0bf9c bellard
        MIPS_DEBUG("NOP");
2120 6af0bf9c bellard
        return;
2121 6af0bf9c bellard
    }
2122 8e9ade68 ths
    gen_load_gpr(cpu_T[0], rs);
2123 6af0bf9c bellard
    switch (opc) {
2124 6af0bf9c bellard
    case OPC_CLO:
2125 30898801 ths
        tcg_gen_helper_0_0(do_clo);
2126 6af0bf9c bellard
        opn = "clo";
2127 6af0bf9c bellard
        break;
2128 6af0bf9c bellard
    case OPC_CLZ:
2129 30898801 ths
        tcg_gen_helper_0_0(do_clz);
2130 6af0bf9c bellard
        opn = "clz";
2131 6af0bf9c bellard
        break;
2132 d26bc211 ths
#if defined(TARGET_MIPS64)
2133 7a387fff ths
    case OPC_DCLO:
2134 30898801 ths
        tcg_gen_helper_0_0(do_dclo);
2135 7a387fff ths
        opn = "dclo";
2136 7a387fff ths
        break;
2137 7a387fff ths
    case OPC_DCLZ:
2138 30898801 ths
        tcg_gen_helper_0_0(do_dclz);
2139 7a387fff ths
        opn = "dclz";
2140 7a387fff ths
        break;
2141 7a387fff ths
#endif
2142 6af0bf9c bellard
    default:
2143 923617a3 ths
        MIPS_INVAL(opn);
2144 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
2145 6af0bf9c bellard
        return;
2146 6af0bf9c bellard
    }
2147 8e9ade68 ths
    gen_store_gpr(cpu_T[0], rd);
2148 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2149 6af0bf9c bellard
}
2150 6af0bf9c bellard
2151 6af0bf9c bellard
/* Traps */
2152 7a387fff ths
static void gen_trap (DisasContext *ctx, uint32_t opc,
2153 6af0bf9c bellard
                      int rs, int rt, int16_t imm)
2154 6af0bf9c bellard
{
2155 6af0bf9c bellard
    int cond;
2156 6af0bf9c bellard
2157 6af0bf9c bellard
    cond = 0;
2158 6af0bf9c bellard
    /* Load needed operands */
2159 6af0bf9c bellard
    switch (opc) {
2160 6af0bf9c bellard
    case OPC_TEQ:
2161 6af0bf9c bellard
    case OPC_TGE:
2162 6af0bf9c bellard
    case OPC_TGEU:
2163 6af0bf9c bellard
    case OPC_TLT:
2164 6af0bf9c bellard
    case OPC_TLTU:
2165 6af0bf9c bellard
    case OPC_TNE:
2166 6af0bf9c bellard
        /* Compare two registers */
2167 6af0bf9c bellard
        if (rs != rt) {
2168 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rs);
2169 8e9ade68 ths
            gen_load_gpr(cpu_T[1], rt);
2170 6af0bf9c bellard
            cond = 1;
2171 6af0bf9c bellard
        }
2172 179e32bb ths
        break;
2173 6af0bf9c bellard
    case OPC_TEQI:
2174 6af0bf9c bellard
    case OPC_TGEI:
2175 6af0bf9c bellard
    case OPC_TGEIU:
2176 6af0bf9c bellard
    case OPC_TLTI:
2177 6af0bf9c bellard
    case OPC_TLTIU:
2178 6af0bf9c bellard
    case OPC_TNEI:
2179 6af0bf9c bellard
        /* Compare register to immediate */
2180 6af0bf9c bellard
        if (rs != 0 || imm != 0) {
2181 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rs);
2182 8e9ade68 ths
            tcg_gen_movi_tl(cpu_T[1], (int32_t)imm);
2183 6af0bf9c bellard
            cond = 1;
2184 6af0bf9c bellard
        }
2185 6af0bf9c bellard
        break;
2186 6af0bf9c bellard
    }
2187 6af0bf9c bellard
    if (cond == 0) {
2188 6af0bf9c bellard
        switch (opc) {
2189 6af0bf9c bellard
        case OPC_TEQ:   /* rs == rs */
2190 6af0bf9c bellard
        case OPC_TEQI:  /* r0 == 0  */
2191 6af0bf9c bellard
        case OPC_TGE:   /* rs >= rs */
2192 6af0bf9c bellard
        case OPC_TGEI:  /* r0 >= 0  */
2193 6af0bf9c bellard
        case OPC_TGEU:  /* rs >= rs unsigned */
2194 6af0bf9c bellard
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2195 6af0bf9c bellard
            /* Always trap */
2196 8e9ade68 ths
            tcg_gen_movi_tl(cpu_T[0], 1);
2197 6af0bf9c bellard
            break;
2198 6af0bf9c bellard
        case OPC_TLT:   /* rs < rs           */
2199 6af0bf9c bellard
        case OPC_TLTI:  /* r0 < 0            */
2200 6af0bf9c bellard
        case OPC_TLTU:  /* rs < rs unsigned  */
2201 6af0bf9c bellard
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2202 6af0bf9c bellard
        case OPC_TNE:   /* rs != rs          */
2203 6af0bf9c bellard
        case OPC_TNEI:  /* r0 != 0           */
2204 ead9360e ths
            /* Never trap: treat as NOP. */
2205 6af0bf9c bellard
            return;
2206 6af0bf9c bellard
        default:
2207 923617a3 ths
            MIPS_INVAL("trap");
2208 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
2209 6af0bf9c bellard
            return;
2210 6af0bf9c bellard
        }
2211 6af0bf9c bellard
    } else {
2212 6af0bf9c bellard
        switch (opc) {
2213 6af0bf9c bellard
        case OPC_TEQ:
2214 6af0bf9c bellard
        case OPC_TEQI:
2215 6af0bf9c bellard
            gen_op_eq();
2216 6af0bf9c bellard
            break;
2217 6af0bf9c bellard
        case OPC_TGE:
2218 6af0bf9c bellard
        case OPC_TGEI:
2219 6af0bf9c bellard
            gen_op_ge();
2220 6af0bf9c bellard
            break;
2221 6af0bf9c bellard
        case OPC_TGEU:
2222 6af0bf9c bellard
        case OPC_TGEIU:
2223 6af0bf9c bellard
            gen_op_geu();
2224 6af0bf9c bellard
            break;
2225 6af0bf9c bellard
        case OPC_TLT:
2226 6af0bf9c bellard
        case OPC_TLTI:
2227 6af0bf9c bellard
            gen_op_lt();
2228 6af0bf9c bellard
            break;
2229 6af0bf9c bellard
        case OPC_TLTU:
2230 6af0bf9c bellard
        case OPC_TLTIU:
2231 6af0bf9c bellard
            gen_op_ltu();
2232 6af0bf9c bellard
            break;
2233 6af0bf9c bellard
        case OPC_TNE:
2234 6af0bf9c bellard
        case OPC_TNEI:
2235 6af0bf9c bellard
            gen_op_ne();
2236 6af0bf9c bellard
            break;
2237 6af0bf9c bellard
        default:
2238 923617a3 ths
            MIPS_INVAL("trap");
2239 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
2240 6af0bf9c bellard
            return;
2241 6af0bf9c bellard
        }
2242 6af0bf9c bellard
    }
2243 6af0bf9c bellard
    save_cpu_state(ctx, 1);
2244 6af0bf9c bellard
    gen_op_trap();
2245 6af0bf9c bellard
    ctx->bstate = BS_STOP;
2246 6af0bf9c bellard
}
2247 6af0bf9c bellard
2248 aa343735 ths
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2249 c53be334 bellard
{
2250 6e256c93 bellard
    TranslationBlock *tb;
2251 6e256c93 bellard
    tb = ctx->tb;
2252 6e256c93 bellard
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2253 57fec1fe bellard
        tcg_gen_goto_tb(n);
2254 9b9e4393 ths
        gen_save_pc(dest);
2255 57fec1fe bellard
        tcg_gen_exit_tb((long)tb + n);
2256 6e256c93 bellard
    } else {
2257 9b9e4393 ths
        gen_save_pc(dest);
2258 57fec1fe bellard
        tcg_gen_exit_tb(0);
2259 6e256c93 bellard
    }
2260 c53be334 bellard
}
2261 c53be334 bellard
2262 6af0bf9c bellard
/* Branches (before delay slot) */
2263 7a387fff ths
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2264 6af0bf9c bellard
                                int rs, int rt, int32_t offset)
2265 6af0bf9c bellard
{
2266 3ad4bb2d ths
    target_ulong btarget = -1;
2267 3ad4bb2d ths
    int blink = 0;
2268 3ad4bb2d ths
    int bcond = 0;
2269 3ad4bb2d ths
2270 3ad4bb2d ths
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2271 923617a3 ths
#ifdef MIPS_DEBUG_DISAS
2272 3ad4bb2d ths
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2273 3ad4bb2d ths
            fprintf(logfile,
2274 5a5012ec ths
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2275 38121543 ths
                    ctx->pc);
2276 3ad4bb2d ths
        }
2277 923617a3 ths
#endif
2278 3ad4bb2d ths
        generate_exception(ctx, EXCP_RI);
2279 3ad4bb2d ths
        return;
2280 3ad4bb2d ths
    }
2281 6af0bf9c bellard
2282 6af0bf9c bellard
    /* Load needed operands */
2283 6af0bf9c bellard
    switch (opc) {
2284 6af0bf9c bellard
    case OPC_BEQ:
2285 6af0bf9c bellard
    case OPC_BEQL:
2286 6af0bf9c bellard
    case OPC_BNE:
2287 6af0bf9c bellard
    case OPC_BNEL:
2288 6af0bf9c bellard
        /* Compare two registers */
2289 6af0bf9c bellard
        if (rs != rt) {
2290 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rs);
2291 8e9ade68 ths
            gen_load_gpr(cpu_T[1], rt);
2292 6af0bf9c bellard
            bcond = 1;
2293 6af0bf9c bellard
        }
2294 6af0bf9c bellard
        btarget = ctx->pc + 4 + offset;
2295 6af0bf9c bellard
        break;
2296 6af0bf9c bellard
    case OPC_BGEZ:
2297 6af0bf9c bellard
    case OPC_BGEZAL:
2298 6af0bf9c bellard
    case OPC_BGEZALL:
2299 6af0bf9c bellard
    case OPC_BGEZL:
2300 6af0bf9c bellard
    case OPC_BGTZ:
2301 6af0bf9c bellard
    case OPC_BGTZL:
2302 6af0bf9c bellard
    case OPC_BLEZ:
2303 6af0bf9c bellard
    case OPC_BLEZL:
2304 6af0bf9c bellard
    case OPC_BLTZ:
2305 6af0bf9c bellard
    case OPC_BLTZAL:
2306 6af0bf9c bellard
    case OPC_BLTZALL:
2307 6af0bf9c bellard
    case OPC_BLTZL:
2308 6af0bf9c bellard
        /* Compare to zero */
2309 6af0bf9c bellard
        if (rs != 0) {
2310 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rs);
2311 6af0bf9c bellard
            bcond = 1;
2312 6af0bf9c bellard
        }
2313 6af0bf9c bellard
        btarget = ctx->pc + 4 + offset;
2314 6af0bf9c bellard
        break;
2315 6af0bf9c bellard
    case OPC_J:
2316 6af0bf9c bellard
    case OPC_JAL:
2317 6af0bf9c bellard
        /* Jump to immediate */
2318 9b9e4393 ths
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2319 6af0bf9c bellard
        break;
2320 6af0bf9c bellard
    case OPC_JR:
2321 6af0bf9c bellard
    case OPC_JALR:
2322 6af0bf9c bellard
        /* Jump to register */
2323 7a387fff ths
        if (offset != 0 && offset != 16) {
2324 7a387fff ths
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2325 cbeb0857 ths
               others are reserved. */
2326 923617a3 ths
            MIPS_INVAL("jump hint");
2327 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
2328 6af0bf9c bellard
            return;
2329 6af0bf9c bellard
        }
2330 8e9ade68 ths
        gen_save_breg_target(rs);
2331 6af0bf9c bellard
        break;
2332 6af0bf9c bellard
    default:
2333 6af0bf9c bellard
        MIPS_INVAL("branch/jump");
2334 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
2335 6af0bf9c bellard
        return;
2336 6af0bf9c bellard
    }
2337 6af0bf9c bellard
    if (bcond == 0) {
2338 6af0bf9c bellard
        /* No condition to be computed */
2339 6af0bf9c bellard
        switch (opc) {
2340 6af0bf9c bellard
        case OPC_BEQ:     /* rx == rx        */
2341 6af0bf9c bellard
        case OPC_BEQL:    /* rx == rx likely */
2342 6af0bf9c bellard
        case OPC_BGEZ:    /* 0 >= 0          */
2343 6af0bf9c bellard
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2344 6af0bf9c bellard
        case OPC_BLEZ:    /* 0 <= 0          */
2345 6af0bf9c bellard
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2346 6af0bf9c bellard
            /* Always take */
2347 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
2348 6af0bf9c bellard
            MIPS_DEBUG("balways");
2349 6af0bf9c bellard
            break;
2350 6af0bf9c bellard
        case OPC_BGEZAL:  /* 0 >= 0          */
2351 6af0bf9c bellard
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2352 6af0bf9c bellard
            /* Always take and link */
2353 6af0bf9c bellard
            blink = 31;
2354 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
2355 6af0bf9c bellard
            MIPS_DEBUG("balways and link");
2356 6af0bf9c bellard
            break;
2357 6af0bf9c bellard
        case OPC_BNE:     /* rx != rx        */
2358 6af0bf9c bellard
        case OPC_BGTZ:    /* 0 > 0           */
2359 6af0bf9c bellard
        case OPC_BLTZ:    /* 0 < 0           */
2360 ead9360e ths
            /* Treat as NOP. */
2361 6af0bf9c bellard
            MIPS_DEBUG("bnever (NOP)");
2362 6af0bf9c bellard
            return;
2363 eeef26cd bellard
        case OPC_BLTZAL:  /* 0 < 0           */
2364 8e9ade68 ths
            tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2365 8e9ade68 ths
            gen_store_gpr(cpu_T[0], 31);
2366 9898128f ths
            MIPS_DEBUG("bnever and link");
2367 eeef26cd bellard
            return;
2368 eeef26cd bellard
        case OPC_BLTZALL: /* 0 < 0 likely */
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
            /* Skip the instruction in the delay slot */
2372 9898128f ths
            MIPS_DEBUG("bnever, link and skip");
2373 9898128f ths
            ctx->pc += 4;
2374 eeef26cd bellard
            return;
2375 6af0bf9c bellard
        case OPC_BNEL:    /* rx != rx likely */
2376 6af0bf9c bellard
        case OPC_BGTZL:   /* 0 > 0 likely */
2377 6af0bf9c bellard
        case OPC_BLTZL:   /* 0 < 0 likely */
2378 6af0bf9c bellard
            /* Skip the instruction in the delay slot */
2379 6af0bf9c bellard
            MIPS_DEBUG("bnever and skip");
2380 9898128f ths
            ctx->pc += 4;
2381 6af0bf9c bellard
            return;
2382 6af0bf9c bellard
        case OPC_J:
2383 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
2384 923617a3 ths
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
2385 6af0bf9c bellard
            break;
2386 6af0bf9c bellard
        case OPC_JAL:
2387 6af0bf9c bellard
            blink = 31;
2388 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
2389 923617a3 ths
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
2390 6af0bf9c bellard
            break;
2391 6af0bf9c bellard
        case OPC_JR:
2392 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
2393 6af0bf9c bellard
            MIPS_DEBUG("jr %s", regnames[rs]);
2394 6af0bf9c bellard
            break;
2395 6af0bf9c bellard
        case OPC_JALR:
2396 6af0bf9c bellard
            blink = rt;
2397 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
2398 6af0bf9c bellard
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2399 6af0bf9c bellard
            break;
2400 6af0bf9c bellard
        default:
2401 6af0bf9c bellard
            MIPS_INVAL("branch/jump");
2402 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
2403 6af0bf9c bellard
            return;
2404 6af0bf9c bellard
        }
2405 6af0bf9c bellard
    } else {
2406 6af0bf9c bellard
        switch (opc) {
2407 6af0bf9c bellard
        case OPC_BEQ:
2408 6af0bf9c bellard
            gen_op_eq();
2409 923617a3 ths
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2410 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
2411 6af0bf9c bellard
            goto not_likely;
2412 6af0bf9c bellard
        case OPC_BEQL:
2413 6af0bf9c bellard
            gen_op_eq();
2414 923617a3 ths
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2415 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
2416 6af0bf9c bellard
            goto likely;
2417 6af0bf9c bellard
        case OPC_BNE:
2418 6af0bf9c bellard
            gen_op_ne();
2419 923617a3 ths
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2420 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
2421 6af0bf9c bellard
            goto not_likely;
2422 6af0bf9c bellard
        case OPC_BNEL:
2423 6af0bf9c bellard
            gen_op_ne();
2424 923617a3 ths
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2425 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
2426 6af0bf9c bellard
            goto likely;
2427 6af0bf9c bellard
        case OPC_BGEZ:
2428 6af0bf9c bellard
            gen_op_gez();
2429 923617a3 ths
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2430 6af0bf9c bellard
            goto not_likely;
2431 6af0bf9c bellard
        case OPC_BGEZL:
2432 6af0bf9c bellard
            gen_op_gez();
2433 923617a3 ths
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2434 6af0bf9c bellard
            goto likely;
2435 6af0bf9c bellard
        case OPC_BGEZAL:
2436 6af0bf9c bellard
            gen_op_gez();
2437 923617a3 ths
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2438 6af0bf9c bellard
            blink = 31;
2439 6af0bf9c bellard
            goto not_likely;
2440 6af0bf9c bellard
        case OPC_BGEZALL:
2441 6af0bf9c bellard
            gen_op_gez();
2442 6af0bf9c bellard
            blink = 31;
2443 923617a3 ths
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2444 6af0bf9c bellard
            goto likely;
2445 6af0bf9c bellard
        case OPC_BGTZ:
2446 6af0bf9c bellard
            gen_op_gtz();
2447 923617a3 ths
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2448 6af0bf9c bellard
            goto not_likely;
2449 6af0bf9c bellard
        case OPC_BGTZL:
2450 6af0bf9c bellard
            gen_op_gtz();
2451 923617a3 ths
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2452 6af0bf9c bellard
            goto likely;
2453 6af0bf9c bellard
        case OPC_BLEZ:
2454 6af0bf9c bellard
            gen_op_lez();
2455 923617a3 ths
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2456 6af0bf9c bellard
            goto not_likely;
2457 6af0bf9c bellard
        case OPC_BLEZL:
2458 6af0bf9c bellard
            gen_op_lez();
2459 923617a3 ths
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2460 6af0bf9c bellard
            goto likely;
2461 6af0bf9c bellard
        case OPC_BLTZ:
2462 6af0bf9c bellard
            gen_op_ltz();
2463 923617a3 ths
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2464 6af0bf9c bellard
            goto not_likely;
2465 6af0bf9c bellard
        case OPC_BLTZL:
2466 6af0bf9c bellard
            gen_op_ltz();
2467 923617a3 ths
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2468 6af0bf9c bellard
            goto likely;
2469 6af0bf9c bellard
        case OPC_BLTZAL:
2470 6af0bf9c bellard
            gen_op_ltz();
2471 6af0bf9c bellard
            blink = 31;
2472 923617a3 ths
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2473 6af0bf9c bellard
        not_likely:
2474 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BC;
2475 8e9ade68 ths
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2476 6af0bf9c bellard
            break;
2477 6af0bf9c bellard
        case OPC_BLTZALL:
2478 6af0bf9c bellard
            gen_op_ltz();
2479 6af0bf9c bellard
            blink = 31;
2480 923617a3 ths
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2481 6af0bf9c bellard
        likely:
2482 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BL;
2483 8e9ade68 ths
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2484 6af0bf9c bellard
            break;
2485 c53f4a62 ths
        default:
2486 c53f4a62 ths
            MIPS_INVAL("conditional branch/jump");
2487 c53f4a62 ths
            generate_exception(ctx, EXCP_RI);
2488 c53f4a62 ths
            return;
2489 6af0bf9c bellard
        }
2490 6af0bf9c bellard
    }
2491 923617a3 ths
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2492 6af0bf9c bellard
               blink, ctx->hflags, btarget);
2493 9b9e4393 ths
2494 6af0bf9c bellard
    ctx->btarget = btarget;
2495 6af0bf9c bellard
    if (blink > 0) {
2496 8e9ade68 ths
        tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2497 8e9ade68 ths
        gen_store_gpr(cpu_T[0], blink);
2498 6af0bf9c bellard
    }
2499 6af0bf9c bellard
}
2500 6af0bf9c bellard
2501 7a387fff ths
/* special3 bitfield operations */
2502 7a387fff ths
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2503 7a387fff ths
                       int rs, int lsb, int msb)
2504 7a387fff ths
{
2505 8e9ade68 ths
    gen_load_gpr(cpu_T[1], rs);
2506 7a387fff ths
    switch (opc) {
2507 7a387fff ths
    case OPC_EXT:
2508 7a387fff ths
        if (lsb + msb > 31)
2509 7a387fff ths
            goto fail;
2510 7a387fff ths
        gen_op_ext(lsb, msb + 1);
2511 7a387fff ths
        break;
2512 c6d6dd7c ths
#if defined(TARGET_MIPS64)
2513 7a387fff ths
    case OPC_DEXTM:
2514 7a387fff ths
        if (lsb + msb > 63)
2515 7a387fff ths
            goto fail;
2516 c6d6dd7c ths
        gen_op_dext(lsb, msb + 1 + 32);
2517 7a387fff ths
        break;
2518 7a387fff ths
    case OPC_DEXTU:
2519 7a387fff ths
        if (lsb + msb > 63)
2520 7a387fff ths
            goto fail;
2521 c6d6dd7c ths
        gen_op_dext(lsb + 32, msb + 1);
2522 7a387fff ths
        break;
2523 7a387fff ths
    case OPC_DEXT:
2524 c6d6dd7c ths
        if (lsb + msb > 63)
2525 c6d6dd7c ths
            goto fail;
2526 c6d6dd7c ths
        gen_op_dext(lsb, msb + 1);
2527 7a387fff ths
        break;
2528 c6d6dd7c ths
#endif
2529 7a387fff ths
    case OPC_INS:
2530 7a387fff ths
        if (lsb > msb)
2531 7a387fff ths
            goto fail;
2532 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
2533 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1);
2534 7a387fff ths
        break;
2535 c6d6dd7c ths
#if defined(TARGET_MIPS64)
2536 7a387fff ths
    case OPC_DINSM:
2537 7a387fff ths
        if (lsb > msb)
2538 7a387fff ths
            goto fail;
2539 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
2540 c6d6dd7c ths
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2541 7a387fff ths
        break;
2542 7a387fff ths
    case OPC_DINSU:
2543 7a387fff ths
        if (lsb > msb)
2544 7a387fff ths
            goto fail;
2545 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
2546 c6d6dd7c ths
        gen_op_dins(lsb + 32, msb - lsb + 1);
2547 7a387fff ths
        break;
2548 7a387fff ths
    case OPC_DINS:
2549 7a387fff ths
        if (lsb > msb)
2550 7a387fff ths
            goto fail;
2551 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
2552 c6d6dd7c ths
        gen_op_dins(lsb, msb - lsb + 1);
2553 7a387fff ths
        break;
2554 c6d6dd7c ths
#endif
2555 7a387fff ths
    default:
2556 7a387fff ths
fail:
2557 7a387fff ths
        MIPS_INVAL("bitops");
2558 7a387fff ths
        generate_exception(ctx, EXCP_RI);
2559 7a387fff ths
        return;
2560 7a387fff ths
    }
2561 8e9ade68 ths
    gen_store_gpr(cpu_T[0], rt);
2562 7a387fff ths
}
2563 7a387fff ths
2564 6af0bf9c bellard
/* CP0 (MMU and control) */
2565 3a95e3a7 ths
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2566 873eb012 ths
{
2567 7a387fff ths
    const char *rn = "invalid";
2568 f0b3f3ae ths
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2569 f0b3f3ae ths
    TCGv r_tmp64 = tcg_temp_new(TCG_TYPE_I64);
2570 873eb012 ths
2571 e189e748 ths
    if (sel != 0)
2572 e189e748 ths
        check_insn(env, ctx, ISA_MIPS32);
2573 e189e748 ths
2574 873eb012 ths
    switch (reg) {
2575 873eb012 ths
    case 0:
2576 7a387fff ths
        switch (sel) {
2577 7a387fff ths
        case 0:
2578 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
2579 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2580 7a387fff ths
            rn = "Index";
2581 7a387fff ths
            break;
2582 7a387fff ths
        case 1:
2583 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2584 ead9360e ths
            gen_op_mfc0_mvpcontrol();
2585 7a387fff ths
            rn = "MVPControl";
2586 ead9360e ths
            break;
2587 7a387fff ths
        case 2:
2588 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2589 ead9360e ths
            gen_op_mfc0_mvpconf0();
2590 7a387fff ths
            rn = "MVPConf0";
2591 ead9360e ths
            break;
2592 7a387fff ths
        case 3:
2593 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2594 ead9360e ths
            gen_op_mfc0_mvpconf1();
2595 7a387fff ths
            rn = "MVPConf1";
2596 ead9360e ths
            break;
2597 7a387fff ths
        default:
2598 7a387fff ths
            goto die;
2599 7a387fff ths
        }
2600 873eb012 ths
        break;
2601 873eb012 ths
    case 1:
2602 7a387fff ths
        switch (sel) {
2603 7a387fff ths
        case 0:
2604 7a387fff ths
            gen_op_mfc0_random();
2605 7a387fff ths
            rn = "Random";
2606 2423f660 ths
            break;
2607 7a387fff ths
        case 1:
2608 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2609 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
2610 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2611 7a387fff ths
            rn = "VPEControl";
2612 ead9360e ths
            break;
2613 7a387fff ths
        case 2:
2614 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2615 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
2616 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2617 7a387fff ths
            rn = "VPEConf0";
2618 ead9360e ths
            break;
2619 7a387fff ths
        case 3:
2620 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2621 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
2622 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2623 7a387fff ths
            rn = "VPEConf1";
2624 ead9360e ths
            break;
2625 7a387fff ths
        case 4:
2626 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2627 f0b3f3ae ths
            tcg_gen_ld_i64(r_tmp64, cpu_env, offsetof(CPUState, CP0_YQMask));
2628 f0b3f3ae ths
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2629 7a387fff ths
            rn = "YQMask";
2630 ead9360e ths
            break;
2631 7a387fff ths
        case 5:
2632 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2633 f0b3f3ae ths
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPESchedule));
2634 f0b3f3ae ths
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2635 7a387fff ths
            rn = "VPESchedule";
2636 ead9360e ths
            break;
2637 7a387fff ths
        case 6:
2638 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2639 f0b3f3ae ths
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
2640 f0b3f3ae ths
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2641 7a387fff ths
            rn = "VPEScheFBack";
2642 ead9360e ths
            break;
2643 7a387fff ths
        case 7:
2644 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2645 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
2646 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2647 7a387fff ths
            rn = "VPEOpt";
2648 ead9360e ths
            break;
2649 7a387fff ths
        default:
2650 7a387fff ths
            goto die;
2651 7a387fff ths
        }
2652 873eb012 ths
        break;
2653 873eb012 ths
    case 2:
2654 7a387fff ths
        switch (sel) {
2655 7a387fff ths
        case 0:
2656 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
2657 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2658 2423f660 ths
            rn = "EntryLo0";
2659 2423f660 ths
            break;
2660 7a387fff ths
        case 1:
2661 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2662 ead9360e ths
            gen_op_mfc0_tcstatus();
2663 2423f660 ths
            rn = "TCStatus";
2664 ead9360e ths
            break;
2665 7a387fff ths
        case 2:
2666 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2667 ead9360e ths
            gen_op_mfc0_tcbind();
2668 2423f660 ths
            rn = "TCBind";
2669 ead9360e ths
            break;
2670 7a387fff ths
        case 3:
2671 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2672 ead9360e ths
            gen_op_mfc0_tcrestart();
2673 2423f660 ths
            rn = "TCRestart";
2674 ead9360e ths
            break;
2675 7a387fff ths
        case 4:
2676 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2677 ead9360e ths
            gen_op_mfc0_tchalt();
2678 2423f660 ths
            rn = "TCHalt";
2679 ead9360e ths
            break;
2680 7a387fff ths
        case 5:
2681 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2682 ead9360e ths
            gen_op_mfc0_tccontext();
2683 2423f660 ths
            rn = "TCContext";
2684 ead9360e ths
            break;
2685 7a387fff ths
        case 6:
2686 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2687 ead9360e ths
            gen_op_mfc0_tcschedule();
2688 2423f660 ths
            rn = "TCSchedule";
2689 ead9360e ths
            break;
2690 7a387fff ths
        case 7:
2691 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
2692 ead9360e ths
            gen_op_mfc0_tcschefback();
2693 2423f660 ths
            rn = "TCScheFBack";
2694 ead9360e ths
            break;
2695 7a387fff ths
        default:
2696 7a387fff ths
            goto die;
2697 7a387fff ths
        }
2698 873eb012 ths
        break;
2699 873eb012 ths
    case 3:
2700 7a387fff ths
        switch (sel) {
2701 7a387fff ths
        case 0:
2702 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
2703 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2704 2423f660 ths
            rn = "EntryLo1";
2705 2423f660 ths
            break;
2706 7a387fff ths
        default:
2707 7a387fff ths
            goto die;
2708 1579a72e ths
        }
2709 873eb012 ths
        break;
2710 873eb012 ths
    case 4:
2711 7a387fff ths
        switch (sel) {
2712 7a387fff ths
        case 0:
2713 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
2714 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2715 2423f660 ths
            rn = "Context";
2716 2423f660 ths
            break;
2717 7a387fff ths
        case 1:
2718 2423f660 ths
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2719 2423f660 ths
            rn = "ContextConfig";
2720 2423f660 ths
//            break;
2721 7a387fff ths
        default:
2722 7a387fff ths
            goto die;
2723 1579a72e ths
        }
2724 873eb012 ths
        break;
2725 873eb012 ths
    case 5:
2726 7a387fff ths
        switch (sel) {
2727 7a387fff ths
        case 0:
2728 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
2729 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2730 2423f660 ths
            rn = "PageMask";
2731 2423f660 ths
            break;
2732 7a387fff ths
        case 1:
2733 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2734 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
2735 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2736 2423f660 ths
            rn = "PageGrain";
2737 2423f660 ths
            break;
2738 7a387fff ths
        default:
2739 7a387fff ths
            goto die;
2740 1579a72e ths
        }
2741 873eb012 ths
        break;
2742 873eb012 ths
    case 6:
2743 7a387fff ths
        switch (sel) {
2744 7a387fff ths
        case 0:
2745 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
2746 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2747 2423f660 ths
            rn = "Wired";
2748 2423f660 ths
            break;
2749 7a387fff ths
        case 1:
2750 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2751 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
2752 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2753 2423f660 ths
            rn = "SRSConf0";
2754 ead9360e ths
            break;
2755 7a387fff ths
        case 2:
2756 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2757 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
2758 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2759 2423f660 ths
            rn = "SRSConf1";
2760 ead9360e ths
            break;
2761 7a387fff ths
        case 3:
2762 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2763 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
2764 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2765 2423f660 ths
            rn = "SRSConf2";
2766 ead9360e ths
            break;
2767 7a387fff ths
        case 4:
2768 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2769 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
2770 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2771 2423f660 ths
            rn = "SRSConf3";
2772 ead9360e ths
            break;
2773 7a387fff ths
        case 5:
2774 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2775 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
2776 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2777 2423f660 ths
            rn = "SRSConf4";
2778 ead9360e ths
            break;
2779 7a387fff ths
        default:
2780 7a387fff ths
            goto die;
2781 1579a72e ths
        }
2782 873eb012 ths
        break;
2783 8c0fdd85 ths
    case 7:
2784 7a387fff ths
        switch (sel) {
2785 7a387fff ths
        case 0:
2786 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2787 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
2788 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2789 2423f660 ths
            rn = "HWREna";
2790 2423f660 ths
            break;
2791 7a387fff ths
        default:
2792 7a387fff ths
            goto die;
2793 1579a72e ths
        }
2794 8c0fdd85 ths
        break;
2795 873eb012 ths
    case 8:
2796 7a387fff ths
        switch (sel) {
2797 7a387fff ths
        case 0:
2798 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
2799 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2800 f0b3f3ae ths
            rn = "BadVAddr";
2801 2423f660 ths
            break;
2802 7a387fff ths
        default:
2803 7a387fff ths
            goto die;
2804 7a387fff ths
       }
2805 873eb012 ths
        break;
2806 873eb012 ths
    case 9:
2807 7a387fff ths
        switch (sel) {
2808 7a387fff ths
        case 0:
2809 2423f660 ths
            gen_op_mfc0_count();
2810 2423f660 ths
            rn = "Count";
2811 2423f660 ths
            break;
2812 2423f660 ths
        /* 6,7 are implementation dependent */
2813 7a387fff ths
        default:
2814 7a387fff ths
            goto die;
2815 2423f660 ths
        }
2816 873eb012 ths
        break;
2817 873eb012 ths
    case 10:
2818 7a387fff ths
        switch (sel) {
2819 7a387fff ths
        case 0:
2820 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
2821 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2822 2423f660 ths
            rn = "EntryHi";
2823 2423f660 ths
            break;
2824 7a387fff ths
        default:
2825 7a387fff ths
            goto die;
2826 1579a72e ths
        }
2827 873eb012 ths
        break;
2828 873eb012 ths
    case 11:
2829 7a387fff ths
        switch (sel) {
2830 7a387fff ths
        case 0:
2831 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
2832 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2833 2423f660 ths
            rn = "Compare";
2834 2423f660 ths
            break;
2835 2423f660 ths
        /* 6,7 are implementation dependent */
2836 7a387fff ths
        default:
2837 7a387fff ths
            goto die;
2838 2423f660 ths
        }
2839 873eb012 ths
        break;
2840 873eb012 ths
    case 12:
2841 7a387fff ths
        switch (sel) {
2842 7a387fff ths
        case 0:
2843 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
2844 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2845 2423f660 ths
            rn = "Status";
2846 2423f660 ths
            break;
2847 7a387fff ths
        case 1:
2848 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2849 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
2850 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2851 2423f660 ths
            rn = "IntCtl";
2852 2423f660 ths
            break;
2853 7a387fff ths
        case 2:
2854 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2855 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
2856 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2857 2423f660 ths
            rn = "SRSCtl";
2858 2423f660 ths
            break;
2859 7a387fff ths
        case 3:
2860 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2861 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
2862 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2863 2423f660 ths
            rn = "SRSMap";
2864 fd88b6ab ths
            break;
2865 7a387fff ths
        default:
2866 7a387fff ths
            goto die;
2867 7a387fff ths
       }
2868 873eb012 ths
        break;
2869 873eb012 ths
    case 13:
2870 7a387fff ths
        switch (sel) {
2871 7a387fff ths
        case 0:
2872 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
2873 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2874 2423f660 ths
            rn = "Cause";
2875 2423f660 ths
            break;
2876 7a387fff ths
        default:
2877 7a387fff ths
            goto die;
2878 7a387fff ths
       }
2879 873eb012 ths
        break;
2880 873eb012 ths
    case 14:
2881 7a387fff ths
        switch (sel) {
2882 7a387fff ths
        case 0:
2883 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
2884 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2885 2423f660 ths
            rn = "EPC";
2886 2423f660 ths
            break;
2887 7a387fff ths
        default:
2888 7a387fff ths
            goto die;
2889 1579a72e ths
        }
2890 873eb012 ths
        break;
2891 873eb012 ths
    case 15:
2892 7a387fff ths
        switch (sel) {
2893 7a387fff ths
        case 0:
2894 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
2895 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2896 2423f660 ths
            rn = "PRid";
2897 2423f660 ths
            break;
2898 7a387fff ths
        case 1:
2899 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
2900 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
2901 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2902 2423f660 ths
            rn = "EBase";
2903 2423f660 ths
            break;
2904 7a387fff ths
        default:
2905 7a387fff ths
            goto die;
2906 7a387fff ths
       }
2907 873eb012 ths
        break;
2908 873eb012 ths
    case 16:
2909 873eb012 ths
        switch (sel) {
2910 873eb012 ths
        case 0:
2911 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
2912 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2913 873eb012 ths
            rn = "Config";
2914 873eb012 ths
            break;
2915 873eb012 ths
        case 1:
2916 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
2917 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2918 873eb012 ths
            rn = "Config1";
2919 873eb012 ths
            break;
2920 7a387fff ths
        case 2:
2921 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
2922 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2923 7a387fff ths
            rn = "Config2";
2924 7a387fff ths
            break;
2925 7a387fff ths
        case 3:
2926 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
2927 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2928 7a387fff ths
            rn = "Config3";
2929 7a387fff ths
            break;
2930 e397ee33 ths
        /* 4,5 are reserved */
2931 e397ee33 ths
        /* 6,7 are implementation dependent */
2932 e397ee33 ths
        case 6:
2933 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
2934 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2935 e397ee33 ths
            rn = "Config6";
2936 e397ee33 ths
            break;
2937 e397ee33 ths
        case 7:
2938 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
2939 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2940 e397ee33 ths
            rn = "Config7";
2941 e397ee33 ths
            break;
2942 873eb012 ths
        default:
2943 873eb012 ths
            goto die;
2944 873eb012 ths
        }
2945 873eb012 ths
        break;
2946 873eb012 ths
    case 17:
2947 7a387fff ths
        switch (sel) {
2948 7a387fff ths
        case 0:
2949 2423f660 ths
            gen_op_mfc0_lladdr();
2950 2423f660 ths
            rn = "LLAddr";
2951 2423f660 ths
            break;
2952 7a387fff ths
        default:
2953 7a387fff ths
            goto die;
2954 7a387fff ths
        }
2955 873eb012 ths
        break;
2956 873eb012 ths
    case 18:
2957 7a387fff ths
        switch (sel) {
2958 fd88b6ab ths
        case 0 ... 7:
2959 fd88b6ab ths
            gen_op_mfc0_watchlo(sel);
2960 2423f660 ths
            rn = "WatchLo";
2961 2423f660 ths
            break;
2962 7a387fff ths
        default:
2963 7a387fff ths
            goto die;
2964 7a387fff ths
        }
2965 873eb012 ths
        break;
2966 873eb012 ths
    case 19:
2967 7a387fff ths
        switch (sel) {
2968 fd88b6ab ths
        case 0 ...7:
2969 fd88b6ab ths
            gen_op_mfc0_watchhi(sel);
2970 2423f660 ths
            rn = "WatchHi";
2971 2423f660 ths
            break;
2972 7a387fff ths
        default:
2973 7a387fff ths
            goto die;
2974 7a387fff ths
        }
2975 873eb012 ths
        break;
2976 8c0fdd85 ths
    case 20:
2977 7a387fff ths
        switch (sel) {
2978 7a387fff ths
        case 0:
2979 d26bc211 ths
#if defined(TARGET_MIPS64)
2980 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
2981 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
2982 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2983 2423f660 ths
            rn = "XContext";
2984 2423f660 ths
            break;
2985 703eaf37 ths
#endif
2986 7a387fff ths
        default:
2987 7a387fff ths
            goto die;
2988 7a387fff ths
        }
2989 8c0fdd85 ths
        break;
2990 8c0fdd85 ths
    case 21:
2991 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2992 7a387fff ths
        switch (sel) {
2993 7a387fff ths
        case 0:
2994 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
2995 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2996 2423f660 ths
            rn = "Framemask";
2997 2423f660 ths
            break;
2998 7a387fff ths
        default:
2999 7a387fff ths
            goto die;
3000 7a387fff ths
        }
3001 8c0fdd85 ths
        break;
3002 8c0fdd85 ths
    case 22:
3003 2423f660 ths
        /* ignored */
3004 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
3005 2423f660 ths
        break;
3006 873eb012 ths
    case 23:
3007 7a387fff ths
        switch (sel) {
3008 7a387fff ths
        case 0:
3009 2423f660 ths
            gen_op_mfc0_debug(); /* EJTAG support */
3010 2423f660 ths
            rn = "Debug";
3011 2423f660 ths
            break;
3012 7a387fff ths
        case 1:
3013 2423f660 ths
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
3014 2423f660 ths
            rn = "TraceControl";
3015 2423f660 ths
//            break;
3016 7a387fff ths
        case 2:
3017 2423f660 ths
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
3018 2423f660 ths
            rn = "TraceControl2";
3019 2423f660 ths
//            break;
3020 7a387fff ths
        case 3:
3021 2423f660 ths
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
3022 2423f660 ths
            rn = "UserTraceData";
3023 2423f660 ths
//            break;
3024 7a387fff ths
        case 4:
3025 2423f660 ths
//            gen_op_mfc0_debug(); /* PDtrace support */
3026 2423f660 ths
            rn = "TraceBPC";
3027 2423f660 ths
//            break;
3028 7a387fff ths
        default:
3029 7a387fff ths
            goto die;
3030 7a387fff ths
        }
3031 873eb012 ths
        break;
3032 873eb012 ths
    case 24:
3033 7a387fff ths
        switch (sel) {
3034 7a387fff ths
        case 0:
3035 f0b3f3ae ths
            /* EJTAG support */
3036 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
3037 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3038 2423f660 ths
            rn = "DEPC";
3039 2423f660 ths
            break;
3040 7a387fff ths
        default:
3041 7a387fff ths
            goto die;
3042 7a387fff ths
        }
3043 873eb012 ths
        break;
3044 8c0fdd85 ths
    case 25:
3045 7a387fff ths
        switch (sel) {
3046 7a387fff ths
        case 0:
3047 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
3048 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3049 2423f660 ths
            rn = "Performance0";
3050 7a387fff ths
            break;
3051 7a387fff ths
        case 1:
3052 2423f660 ths
//            gen_op_mfc0_performance1();
3053 2423f660 ths
            rn = "Performance1";
3054 2423f660 ths
//            break;
3055 7a387fff ths
        case 2:
3056 2423f660 ths
//            gen_op_mfc0_performance2();
3057 2423f660 ths
            rn = "Performance2";
3058 2423f660 ths
//            break;
3059 7a387fff ths
        case 3:
3060 2423f660 ths
//            gen_op_mfc0_performance3();
3061 2423f660 ths
            rn = "Performance3";
3062 2423f660 ths
//            break;
3063 7a387fff ths
        case 4:
3064 2423f660 ths
//            gen_op_mfc0_performance4();
3065 2423f660 ths
            rn = "Performance4";
3066 2423f660 ths
//            break;
3067 7a387fff ths
        case 5:
3068 2423f660 ths
//            gen_op_mfc0_performance5();
3069 2423f660 ths
            rn = "Performance5";
3070 2423f660 ths
//            break;
3071 7a387fff ths
        case 6:
3072 2423f660 ths
//            gen_op_mfc0_performance6();
3073 2423f660 ths
            rn = "Performance6";
3074 2423f660 ths
//            break;
3075 7a387fff ths
        case 7:
3076 2423f660 ths
//            gen_op_mfc0_performance7();
3077 2423f660 ths
            rn = "Performance7";
3078 2423f660 ths
//            break;
3079 7a387fff ths
        default:
3080 7a387fff ths
            goto die;
3081 7a387fff ths
        }
3082 8c0fdd85 ths
        break;
3083 8c0fdd85 ths
    case 26:
3084 7a387fff ths
       rn = "ECC";
3085 7a387fff ths
       break;
3086 8c0fdd85 ths
    case 27:
3087 7a387fff ths
        switch (sel) {
3088 7a387fff ths
        /* ignored */
3089 7a387fff ths
        case 0 ... 3:
3090 2423f660 ths
            rn = "CacheErr";
3091 2423f660 ths
            break;
3092 7a387fff ths
        default:
3093 7a387fff ths
            goto die;
3094 7a387fff ths
        }
3095 8c0fdd85 ths
        break;
3096 873eb012 ths
    case 28:
3097 873eb012 ths
        switch (sel) {
3098 873eb012 ths
        case 0:
3099 7a387fff ths
        case 2:
3100 7a387fff ths
        case 4:
3101 7a387fff ths
        case 6:
3102 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
3103 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3104 873eb012 ths
            rn = "TagLo";
3105 873eb012 ths
            break;
3106 873eb012 ths
        case 1:
3107 7a387fff ths
        case 3:
3108 7a387fff ths
        case 5:
3109 7a387fff ths
        case 7:
3110 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
3111 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3112 873eb012 ths
            rn = "DataLo";
3113 873eb012 ths
            break;
3114 873eb012 ths
        default:
3115 873eb012 ths
            goto die;
3116 873eb012 ths
        }
3117 873eb012 ths
        break;
3118 8c0fdd85 ths
    case 29:
3119 7a387fff ths
        switch (sel) {
3120 7a387fff ths
        case 0:
3121 7a387fff ths
        case 2:
3122 7a387fff ths
        case 4:
3123 7a387fff ths
        case 6:
3124 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
3125 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3126 7a387fff ths
            rn = "TagHi";
3127 7a387fff ths
            break;
3128 7a387fff ths
        case 1:
3129 7a387fff ths
        case 3:
3130 7a387fff ths
        case 5:
3131 7a387fff ths
        case 7:
3132 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
3133 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3134 7a387fff ths
            rn = "DataHi";
3135 7a387fff ths
            break;
3136 7a387fff ths
        default:
3137 7a387fff ths
            goto die;
3138 7a387fff ths
        }
3139 8c0fdd85 ths
        break;
3140 873eb012 ths
    case 30:
3141 7a387fff ths
        switch (sel) {
3142 7a387fff ths
        case 0:
3143 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3144 f0b3f3ae ths
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3145 2423f660 ths
            rn = "ErrorEPC";
3146 2423f660 ths
            break;
3147 7a387fff ths
        default:
3148 7a387fff ths
            goto die;
3149 7a387fff ths
        }
3150 873eb012 ths
        break;
3151 873eb012 ths
    case 31:
3152 7a387fff ths
        switch (sel) {
3153 7a387fff ths
        case 0:
3154 f0b3f3ae ths
            /* EJTAG support */
3155 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
3156 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3157 2423f660 ths
            rn = "DESAVE";
3158 2423f660 ths
            break;
3159 7a387fff ths
        default:
3160 7a387fff ths
            goto die;
3161 7a387fff ths
        }
3162 873eb012 ths
        break;
3163 873eb012 ths
    default:
3164 873eb012 ths
       goto die;
3165 873eb012 ths
    }
3166 873eb012 ths
#if defined MIPS_DEBUG_DISAS
3167 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3168 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3169 7a387fff ths
                rn, reg, sel);
3170 873eb012 ths
    }
3171 873eb012 ths
#endif
3172 873eb012 ths
    return;
3173 873eb012 ths
3174 873eb012 ths
die:
3175 873eb012 ths
#if defined MIPS_DEBUG_DISAS
3176 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3177 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3178 7a387fff ths
                rn, reg, sel);
3179 873eb012 ths
    }
3180 873eb012 ths
#endif
3181 873eb012 ths
    generate_exception(ctx, EXCP_RI);
3182 873eb012 ths
}
3183 873eb012 ths
3184 3a95e3a7 ths
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3185 8c0fdd85 ths
{
3186 7a387fff ths
    const char *rn = "invalid";
3187 7a387fff ths
3188 e189e748 ths
    if (sel != 0)
3189 e189e748 ths
        check_insn(env, ctx, ISA_MIPS32);
3190 e189e748 ths
3191 8c0fdd85 ths
    switch (reg) {
3192 8c0fdd85 ths
    case 0:
3193 7a387fff ths
        switch (sel) {
3194 7a387fff ths
        case 0:
3195 855cea8c ths
            gen_op_mtc0_index();
3196 7a387fff ths
            rn = "Index";
3197 7a387fff ths
            break;
3198 7a387fff ths
        case 1:
3199 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3200 ead9360e ths
            gen_op_mtc0_mvpcontrol();
3201 7a387fff ths
            rn = "MVPControl";
3202 ead9360e ths
            break;
3203 7a387fff ths
        case 2:
3204 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3205 ead9360e ths
            /* ignored */
3206 7a387fff ths
            rn = "MVPConf0";
3207 ead9360e ths
            break;
3208 7a387fff ths
        case 3:
3209 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3210 ead9360e ths
            /* ignored */
3211 7a387fff ths
            rn = "MVPConf1";
3212 ead9360e ths
            break;
3213 7a387fff ths
        default:
3214 7a387fff ths
            goto die;
3215 7a387fff ths
        }
3216 8c0fdd85 ths
        break;
3217 8c0fdd85 ths
    case 1:
3218 7a387fff ths
        switch (sel) {
3219 7a387fff ths
        case 0:
3220 2423f660 ths
            /* ignored */
3221 7a387fff ths
            rn = "Random";
3222 2423f660 ths
            break;
3223 7a387fff ths
        case 1:
3224 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3225 ead9360e ths
            gen_op_mtc0_vpecontrol();
3226 7a387fff ths
            rn = "VPEControl";
3227 ead9360e ths
            break;
3228 7a387fff ths
        case 2:
3229 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3230 ead9360e ths
            gen_op_mtc0_vpeconf0();
3231 7a387fff ths
            rn = "VPEConf0";
3232 ead9360e ths
            break;
3233 7a387fff ths
        case 3:
3234 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3235 ead9360e ths
            gen_op_mtc0_vpeconf1();
3236 7a387fff ths
            rn = "VPEConf1";
3237 ead9360e ths
            break;
3238 7a387fff ths
        case 4:
3239 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3240 ead9360e ths
            gen_op_mtc0_yqmask();
3241 7a387fff ths
            rn = "YQMask";
3242 ead9360e ths
            break;
3243 7a387fff ths
        case 5:
3244 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3245 ead9360e ths
            gen_op_mtc0_vpeschedule();
3246 7a387fff ths
            rn = "VPESchedule";
3247 ead9360e ths
            break;
3248 7a387fff ths
        case 6:
3249 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3250 ead9360e ths
            gen_op_mtc0_vpeschefback();
3251 7a387fff ths
            rn = "VPEScheFBack";
3252 ead9360e ths
            break;
3253 7a387fff ths
        case 7:
3254 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3255 ead9360e ths
            gen_op_mtc0_vpeopt();
3256 7a387fff ths
            rn = "VPEOpt";
3257 ead9360e ths
            break;
3258 7a387fff ths
        default:
3259 7a387fff ths
            goto die;
3260 7a387fff ths
        }
3261 8c0fdd85 ths
        break;
3262 8c0fdd85 ths
    case 2:
3263 7a387fff ths
        switch (sel) {
3264 7a387fff ths
        case 0:
3265 2423f660 ths
            gen_op_mtc0_entrylo0();
3266 2423f660 ths
            rn = "EntryLo0";
3267 2423f660 ths
            break;
3268 7a387fff ths
        case 1:
3269 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3270 ead9360e ths
            gen_op_mtc0_tcstatus();
3271 2423f660 ths
            rn = "TCStatus";
3272 ead9360e ths
            break;
3273 7a387fff ths
        case 2:
3274 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3275 ead9360e ths
            gen_op_mtc0_tcbind();
3276 2423f660 ths
            rn = "TCBind";
3277 ead9360e ths
            break;
3278 7a387fff ths
        case 3:
3279 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3280 ead9360e ths
            gen_op_mtc0_tcrestart();
3281 2423f660 ths
            rn = "TCRestart";
3282 ead9360e ths
            break;
3283 7a387fff ths
        case 4:
3284 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3285 ead9360e ths
            gen_op_mtc0_tchalt();
3286 2423f660 ths
            rn = "TCHalt";
3287 ead9360e ths
            break;
3288 7a387fff ths
        case 5:
3289 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3290 ead9360e ths
            gen_op_mtc0_tccontext();
3291 2423f660 ths
            rn = "TCContext";
3292 ead9360e ths
            break;
3293 7a387fff ths
        case 6:
3294 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3295 ead9360e ths
            gen_op_mtc0_tcschedule();
3296 2423f660 ths
            rn = "TCSchedule";
3297 ead9360e ths
            break;
3298 7a387fff ths
        case 7:
3299 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3300 ead9360e ths
            gen_op_mtc0_tcschefback();
3301 2423f660 ths
            rn = "TCScheFBack";
3302 ead9360e ths
            break;
3303 7a387fff ths
        default:
3304 7a387fff ths
            goto die;
3305 7a387fff ths
        }
3306 8c0fdd85 ths
        break;
3307 8c0fdd85 ths
    case 3:
3308 7a387fff ths
        switch (sel) {
3309 7a387fff ths
        case 0:
3310 2423f660 ths
            gen_op_mtc0_entrylo1();
3311 2423f660 ths
            rn = "EntryLo1";
3312 2423f660 ths
            break;
3313 7a387fff ths
        default:
3314 7a387fff ths
            goto die;
3315 876d4b07 ths
        }
3316 8c0fdd85 ths
        break;
3317 8c0fdd85 ths
    case 4:
3318 7a387fff ths
        switch (sel) {
3319 7a387fff ths
        case 0:
3320 2423f660 ths
            gen_op_mtc0_context();
3321 2423f660 ths
            rn = "Context";
3322 2423f660 ths
            break;
3323 7a387fff ths
        case 1:
3324 2423f660 ths
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3325 2423f660 ths
            rn = "ContextConfig";
3326 2423f660 ths
//            break;
3327 7a387fff ths
        default:
3328 7a387fff ths
            goto die;
3329 876d4b07 ths
        }
3330 8c0fdd85 ths
        break;
3331 8c0fdd85 ths
    case 5:
3332 7a387fff ths
        switch (sel) {
3333 7a387fff ths
        case 0:
3334 2423f660 ths
            gen_op_mtc0_pagemask();
3335 2423f660 ths
            rn = "PageMask";
3336 2423f660 ths
            break;
3337 7a387fff ths
        case 1:
3338 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3339 2423f660 ths
            gen_op_mtc0_pagegrain();
3340 2423f660 ths
            rn = "PageGrain";
3341 2423f660 ths
            break;
3342 7a387fff ths
        default:
3343 7a387fff ths
            goto die;
3344 876d4b07 ths
        }
3345 8c0fdd85 ths
        break;
3346 8c0fdd85 ths
    case 6:
3347 7a387fff ths
        switch (sel) {
3348 7a387fff ths
        case 0:
3349 2423f660 ths
            gen_op_mtc0_wired();
3350 2423f660 ths
            rn = "Wired";
3351 2423f660 ths
            break;
3352 7a387fff ths
        case 1:
3353 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3354 ead9360e ths
            gen_op_mtc0_srsconf0();
3355 2423f660 ths
            rn = "SRSConf0";
3356 ead9360e ths
            break;
3357 7a387fff ths
        case 2:
3358 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3359 ead9360e ths
            gen_op_mtc0_srsconf1();
3360 2423f660 ths
            rn = "SRSConf1";
3361 ead9360e ths
            break;
3362 7a387fff ths
        case 3:
3363 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3364 ead9360e ths
            gen_op_mtc0_srsconf2();
3365 2423f660 ths
            rn = "SRSConf2";
3366 ead9360e ths
            break;
3367 7a387fff ths
        case 4:
3368 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3369 ead9360e ths
            gen_op_mtc0_srsconf3();
3370 2423f660 ths
            rn = "SRSConf3";
3371 ead9360e ths
            break;
3372 7a387fff ths
        case 5:
3373 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3374 ead9360e ths
            gen_op_mtc0_srsconf4();
3375 2423f660 ths
            rn = "SRSConf4";
3376 ead9360e ths
            break;
3377 7a387fff ths
        default:
3378 7a387fff ths
            goto die;
3379 876d4b07 ths
        }
3380 8c0fdd85 ths
        break;
3381 8c0fdd85 ths
    case 7:
3382 7a387fff ths
        switch (sel) {
3383 7a387fff ths
        case 0:
3384 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3385 2423f660 ths
            gen_op_mtc0_hwrena();
3386 2423f660 ths
            rn = "HWREna";
3387 2423f660 ths
            break;
3388 7a387fff ths
        default:
3389 7a387fff ths
            goto die;
3390 876d4b07 ths
        }
3391 8c0fdd85 ths
        break;
3392 8c0fdd85 ths
    case 8:
3393 7a387fff ths
        /* ignored */
3394 f0b3f3ae ths
        rn = "BadVAddr";
3395 8c0fdd85 ths
        break;
3396 8c0fdd85 ths
    case 9:
3397 7a387fff ths
        switch (sel) {
3398 7a387fff ths
        case 0:
3399 2423f660 ths
            gen_op_mtc0_count();
3400 2423f660 ths
            rn = "Count";
3401 2423f660 ths
            break;
3402 876d4b07 ths
        /* 6,7 are implementation dependent */
3403 7a387fff ths
        default:
3404 7a387fff ths
            goto die;
3405 876d4b07 ths
        }
3406 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3407 876d4b07 ths
        ctx->bstate = BS_STOP;
3408 8c0fdd85 ths
        break;
3409 8c0fdd85 ths
    case 10:
3410 7a387fff ths
        switch (sel) {
3411 7a387fff ths
        case 0:
3412 2423f660 ths
            gen_op_mtc0_entryhi();
3413 2423f660 ths
            rn = "EntryHi";
3414 2423f660 ths
            break;
3415 7a387fff ths
        default:
3416 7a387fff ths
            goto die;
3417 876d4b07 ths
        }
3418 8c0fdd85 ths
        break;
3419 8c0fdd85 ths
    case 11:
3420 7a387fff ths
        switch (sel) {
3421 7a387fff ths
        case 0:
3422 2423f660 ths
            gen_op_mtc0_compare();
3423 2423f660 ths
            rn = "Compare";
3424 2423f660 ths
            break;
3425 2423f660 ths
        /* 6,7 are implementation dependent */
3426 7a387fff ths
        default:
3427 7a387fff ths
            goto die;
3428 876d4b07 ths
        }
3429 4586f9e9 aurel32
        /* Stop translation as we may have switched the execution mode */
3430 4586f9e9 aurel32
        ctx->bstate = BS_STOP;
3431 8c0fdd85 ths
        break;
3432 8c0fdd85 ths
    case 12:
3433 7a387fff ths
        switch (sel) {
3434 7a387fff ths
        case 0:
3435 2423f660 ths
            gen_op_mtc0_status();
3436 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
3437 8487327a ths
            gen_save_pc(ctx->pc + 4);
3438 8487327a ths
            ctx->bstate = BS_EXCP;
3439 2423f660 ths
            rn = "Status";
3440 2423f660 ths
            break;
3441 7a387fff ths
        case 1:
3442 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3443 2423f660 ths
            gen_op_mtc0_intctl();
3444 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3445 8487327a ths
            ctx->bstate = BS_STOP;
3446 2423f660 ths
            rn = "IntCtl";
3447 2423f660 ths
            break;
3448 7a387fff ths
        case 2:
3449 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3450 2423f660 ths
            gen_op_mtc0_srsctl();
3451 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3452 8487327a ths
            ctx->bstate = BS_STOP;
3453 2423f660 ths
            rn = "SRSCtl";
3454 2423f660 ths
            break;
3455 7a387fff ths
        case 3:
3456 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3457 fd88b6ab ths
            gen_op_mtc0_srsmap();
3458 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3459 8487327a ths
            ctx->bstate = BS_STOP;
3460 2423f660 ths
            rn = "SRSMap";
3461 fd88b6ab ths
            break;
3462 7a387fff ths
        default:
3463 7a387fff ths
            goto die;
3464 876d4b07 ths
        }
3465 8c0fdd85 ths
        break;
3466 8c0fdd85 ths
    case 13:
3467 7a387fff ths
        switch (sel) {
3468 7a387fff ths
        case 0:
3469 2423f660 ths
            gen_op_mtc0_cause();
3470 2423f660 ths
            rn = "Cause";
3471 2423f660 ths
            break;
3472 7a387fff ths
        default:
3473 7a387fff ths
            goto die;
3474 876d4b07 ths
        }
3475 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
3476 876d4b07 ths
        ctx->bstate = BS_STOP;
3477 8c0fdd85 ths
        break;
3478 8c0fdd85 ths
    case 14:
3479 7a387fff ths
        switch (sel) {
3480 7a387fff ths
        case 0:
3481 2423f660 ths
            gen_op_mtc0_epc();
3482 2423f660 ths
            rn = "EPC";
3483 2423f660 ths
            break;
3484 7a387fff ths
        default:
3485 7a387fff ths
            goto die;
3486 876d4b07 ths
        }
3487 8c0fdd85 ths
        break;
3488 8c0fdd85 ths
    case 15:
3489 7a387fff ths
        switch (sel) {
3490 7a387fff ths
        case 0:
3491 2423f660 ths
            /* ignored */
3492 2423f660 ths
            rn = "PRid";
3493 2423f660 ths
            break;
3494 7a387fff ths
        case 1:
3495 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3496 2423f660 ths
            gen_op_mtc0_ebase();
3497 2423f660 ths
            rn = "EBase";
3498 2423f660 ths
            break;
3499 7a387fff ths
        default:
3500 7a387fff ths
            goto die;
3501 1579a72e ths
        }
3502 8c0fdd85 ths
        break;
3503 8c0fdd85 ths
    case 16:
3504 8c0fdd85 ths
        switch (sel) {
3505 8c0fdd85 ths
        case 0:
3506 e397ee33 ths
            gen_op_mtc0_config0();
3507 7a387fff ths
            rn = "Config";
3508 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3509 2423f660 ths
            ctx->bstate = BS_STOP;
3510 7a387fff ths
            break;
3511 7a387fff ths
        case 1:
3512 e397ee33 ths
            /* ignored, read only */
3513 7a387fff ths
            rn = "Config1";
3514 7a387fff ths
            break;
3515 7a387fff ths
        case 2:
3516 e397ee33 ths
            gen_op_mtc0_config2();
3517 7a387fff ths
            rn = "Config2";
3518 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
3519 2423f660 ths
            ctx->bstate = BS_STOP;
3520 8c0fdd85 ths
            break;
3521 7a387fff ths
        case 3:
3522 e397ee33 ths
            /* ignored, read only */
3523 7a387fff ths
            rn = "Config3";
3524 7a387fff ths
            break;
3525 e397ee33 ths
        /* 4,5 are reserved */
3526 e397ee33 ths
        /* 6,7 are implementation dependent */
3527 e397ee33 ths
        case 6:
3528 e397ee33 ths
            /* ignored */
3529 e397ee33 ths
            rn = "Config6";
3530 e397ee33 ths
            break;
3531 e397ee33 ths
        case 7:
3532 e397ee33 ths
            /* ignored */
3533 e397ee33 ths
            rn = "Config7";
3534 e397ee33 ths
            break;
3535 8c0fdd85 ths
        default:
3536 8c0fdd85 ths
            rn = "Invalid config selector";
3537 8c0fdd85 ths
            goto die;
3538 8c0fdd85 ths
        }
3539 8c0fdd85 ths
        break;
3540 8c0fdd85 ths
    case 17:
3541 7a387fff ths
        switch (sel) {
3542 7a387fff ths
        case 0:
3543 2423f660 ths
            /* ignored */
3544 2423f660 ths
            rn = "LLAddr";
3545 2423f660 ths
            break;
3546 7a387fff ths
        default:
3547 7a387fff ths
            goto die;
3548 7a387fff ths
        }
3549 8c0fdd85 ths
        break;
3550 8c0fdd85 ths
    case 18:
3551 7a387fff ths
        switch (sel) {
3552 fd88b6ab ths
        case 0 ... 7:
3553 fd88b6ab ths
            gen_op_mtc0_watchlo(sel);
3554 2423f660 ths
            rn = "WatchLo";
3555 2423f660 ths
            break;
3556 7a387fff ths
        default:
3557 7a387fff ths
            goto die;
3558 7a387fff ths
        }
3559 8c0fdd85 ths
        break;
3560 8c0fdd85 ths
    case 19:
3561 7a387fff ths
        switch (sel) {
3562 fd88b6ab ths
        case 0 ... 7:
3563 fd88b6ab ths
            gen_op_mtc0_watchhi(sel);
3564 2423f660 ths
            rn = "WatchHi";
3565 2423f660 ths
            break;
3566 7a387fff ths
        default:
3567 7a387fff ths
            goto die;
3568 7a387fff ths
        }
3569 8c0fdd85 ths
        break;
3570 8c0fdd85 ths
    case 20:
3571 7a387fff ths
        switch (sel) {
3572 7a387fff ths
        case 0:
3573 d26bc211 ths
#if defined(TARGET_MIPS64)
3574 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
3575 f1b0aa5d ths
            gen_op_mtc0_xcontext();
3576 2423f660 ths
            rn = "XContext";
3577 2423f660 ths
            break;
3578 703eaf37 ths
#endif
3579 7a387fff ths
        default:
3580 7a387fff ths
            goto die;
3581 7a387fff ths
        }
3582 8c0fdd85 ths
        break;
3583 8c0fdd85 ths
    case 21:
3584 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3585 7a387fff ths
        switch (sel) {
3586 7a387fff ths
        case 0:
3587 2423f660 ths
            gen_op_mtc0_framemask();
3588 2423f660 ths
            rn = "Framemask";
3589 2423f660 ths
            break;
3590 7a387fff ths
        default:
3591 7a387fff ths
            goto die;
3592 7a387fff ths
        }
3593 7a387fff ths
        break;
3594 8c0fdd85 ths
    case 22:
3595 7a387fff ths
        /* ignored */
3596 7a387fff ths
        rn = "Diagnostic"; /* implementation dependent */
3597 2423f660 ths
        break;
3598 8c0fdd85 ths
    case 23:
3599 7a387fff ths
        switch (sel) {
3600 7a387fff ths
        case 0:
3601 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
3602 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
3603 8487327a ths
            gen_save_pc(ctx->pc + 4);
3604 8487327a ths
            ctx->bstate = BS_EXCP;
3605 2423f660 ths
            rn = "Debug";
3606 2423f660 ths
            break;
3607 7a387fff ths
        case 1:
3608 2423f660 ths
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3609 2423f660 ths
            rn = "TraceControl";
3610 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3611 8487327a ths
            ctx->bstate = BS_STOP;
3612 2423f660 ths
//            break;
3613 7a387fff ths
        case 2:
3614 2423f660 ths
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3615 2423f660 ths
            rn = "TraceControl2";
3616 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3617 8487327a ths
            ctx->bstate = BS_STOP;
3618 2423f660 ths
//            break;
3619 7a387fff ths
        case 3:
3620 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3621 8487327a ths
            ctx->bstate = BS_STOP;
3622 2423f660 ths
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3623 2423f660 ths
            rn = "UserTraceData";
3624 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3625 8487327a ths
            ctx->bstate = BS_STOP;
3626 2423f660 ths
//            break;
3627 7a387fff ths
        case 4:
3628 2423f660 ths
//            gen_op_mtc0_debug(); /* PDtrace support */
3629 8487327a ths
            /* Stop translation as we may have switched the execution mode */
3630 8487327a ths
            ctx->bstate = BS_STOP;
3631 2423f660 ths
            rn = "TraceBPC";
3632 2423f660 ths
//            break;
3633 7a387fff ths
        default:
3634 7a387fff ths
            goto die;
3635 7a387fff ths
        }
3636 8c0fdd85 ths
        break;
3637 8c0fdd85 ths
    case 24:
3638 7a387fff ths
        switch (sel) {
3639 7a387fff ths
        case 0:
3640 2423f660 ths
            gen_op_mtc0_depc(); /* EJTAG support */
3641 2423f660 ths
            rn = "DEPC";
3642 2423f660 ths
            break;
3643 7a387fff ths
        default:
3644 7a387fff ths
            goto die;
3645 7a387fff ths
        }
3646 8c0fdd85 ths
        break;
3647 8c0fdd85 ths
    case 25:
3648 7a387fff ths
        switch (sel) {
3649 7a387fff ths
        case 0:
3650 2423f660 ths
            gen_op_mtc0_performance0();
3651 2423f660 ths
            rn = "Performance0";
3652 2423f660 ths
            break;
3653 7a387fff ths
        case 1:
3654 2423f660 ths
//            gen_op_mtc0_performance1();
3655 2423f660 ths
            rn = "Performance1";
3656 2423f660 ths
//            break;
3657 7a387fff ths
        case 2:
3658 2423f660 ths
//            gen_op_mtc0_performance2();
3659 2423f660 ths
            rn = "Performance2";
3660 2423f660 ths
//            break;
3661 7a387fff ths
        case 3:
3662 2423f660 ths
//            gen_op_mtc0_performance3();
3663 2423f660 ths
            rn = "Performance3";
3664 2423f660 ths
//            break;
3665 7a387fff ths
        case 4:
3666 2423f660 ths
//            gen_op_mtc0_performance4();
3667 2423f660 ths
            rn = "Performance4";
3668 2423f660 ths
//            break;
3669 7a387fff ths
        case 5:
3670 2423f660 ths
//            gen_op_mtc0_performance5();
3671 2423f660 ths
            rn = "Performance5";
3672 2423f660 ths
//            break;
3673 7a387fff ths
        case 6:
3674 2423f660 ths
//            gen_op_mtc0_performance6();
3675 2423f660 ths
            rn = "Performance6";
3676 2423f660 ths
//            break;
3677 7a387fff ths
        case 7:
3678 2423f660 ths
//            gen_op_mtc0_performance7();
3679 2423f660 ths
            rn = "Performance7";
3680 2423f660 ths
//            break;
3681 7a387fff ths
        default:
3682 7a387fff ths
            goto die;
3683 7a387fff ths
        }
3684 8c0fdd85 ths
       break;
3685 8c0fdd85 ths
    case 26:
3686 2423f660 ths
        /* ignored */
3687 8c0fdd85 ths
        rn = "ECC";
3688 2423f660 ths
        break;
3689 8c0fdd85 ths
    case 27:
3690 7a387fff ths
        switch (sel) {
3691 7a387fff ths
        case 0 ... 3:
3692 2423f660 ths
            /* ignored */
3693 2423f660 ths
            rn = "CacheErr";
3694 2423f660 ths
            break;
3695 7a387fff ths
        default:
3696 7a387fff ths
            goto die;
3697 7a387fff ths
        }
3698 8c0fdd85 ths
       break;
3699 8c0fdd85 ths
    case 28:
3700 8c0fdd85 ths
        switch (sel) {
3701 8c0fdd85 ths
        case 0:
3702 7a387fff ths
        case 2:
3703 7a387fff ths
        case 4:
3704 7a387fff ths
        case 6:
3705 8c0fdd85 ths
            gen_op_mtc0_taglo();
3706 8c0fdd85 ths
            rn = "TagLo";
3707 8c0fdd85 ths
            break;
3708 7a387fff ths
        case 1:
3709 7a387fff ths
        case 3:
3710 7a387fff ths
        case 5:
3711 7a387fff ths
        case 7:
3712 2423f660 ths
            gen_op_mtc0_datalo();
3713 7a387fff ths
            rn = "DataLo";
3714 7a387fff ths
            break;
3715 8c0fdd85 ths
        default:
3716 8c0fdd85 ths
            goto die;
3717 8c0fdd85 ths
        }
3718 8c0fdd85 ths
        break;
3719 8c0fdd85 ths
    case 29:
3720 7a387fff ths
        switch (sel) {
3721 7a387fff ths
        case 0:
3722 7a387fff ths
        case 2:
3723 7a387fff ths
        case 4:
3724 7a387fff ths
        case 6:
3725 7a387fff ths
            gen_op_mtc0_taghi();
3726 7a387fff ths
            rn = "TagHi";
3727 7a387fff ths
            break;
3728 7a387fff ths
        case 1:
3729 7a387fff ths
        case 3:
3730 7a387fff ths
        case 5:
3731 7a387fff ths
        case 7:
3732 2423f660 ths
            gen_op_mtc0_datahi();
3733 7a387fff ths
            rn = "DataHi";
3734 7a387fff ths
            break;
3735 7a387fff ths
        default:
3736 7a387fff ths
            rn = "invalid sel";
3737 7a387fff ths
            goto die;
3738 7a387fff ths
        }
3739 8c0fdd85 ths
       break;
3740 8c0fdd85 ths
    case 30:
3741 7a387fff ths
        switch (sel) {
3742 7a387fff ths
        case 0:
3743 2423f660 ths
            gen_op_mtc0_errorepc();
3744 2423f660 ths
            rn = "ErrorEPC";
3745 2423f660 ths
            break;
3746 7a387fff ths
        default:
3747 7a387fff ths
            goto die;
3748 7a387fff ths
        }
3749 8c0fdd85 ths
        break;
3750 8c0fdd85 ths
    case 31:
3751 7a387fff ths
        switch (sel) {
3752 7a387fff ths
        case 0:
3753 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
3754 2423f660 ths
            rn = "DESAVE";
3755 2423f660 ths
            break;
3756 7a387fff ths
        default:
3757 7a387fff ths
            goto die;
3758 7a387fff ths
        }
3759 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
3760 2423f660 ths
        ctx->bstate = BS_STOP;
3761 8c0fdd85 ths
        break;
3762 8c0fdd85 ths
    default:
3763 8c0fdd85 ths
       goto die;
3764 8c0fdd85 ths
    }
3765 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
3766 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3767 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3768 7a387fff ths
                rn, reg, sel);
3769 8c0fdd85 ths
    }
3770 8c0fdd85 ths
#endif
3771 8c0fdd85 ths
    return;
3772 8c0fdd85 ths
3773 8c0fdd85 ths
die:
3774 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
3775 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3776 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3777 7a387fff ths
                rn, reg, sel);
3778 8c0fdd85 ths
    }
3779 8c0fdd85 ths
#endif
3780 8c0fdd85 ths
    generate_exception(ctx, EXCP_RI);
3781 8c0fdd85 ths
}
3782 8c0fdd85 ths
3783 d26bc211 ths
#if defined(TARGET_MIPS64)
3784 3a95e3a7 ths
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3785 9c2149c8 ths
{
3786 9c2149c8 ths
    const char *rn = "invalid";
3787 f0b3f3ae ths
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
3788 9c2149c8 ths
3789 e189e748 ths
    if (sel != 0)
3790 e189e748 ths
        check_insn(env, ctx, ISA_MIPS64);
3791 e189e748 ths
3792 9c2149c8 ths
    switch (reg) {
3793 9c2149c8 ths
    case 0:
3794 9c2149c8 ths
        switch (sel) {
3795 9c2149c8 ths
        case 0:
3796 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
3797 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3798 9c2149c8 ths
            rn = "Index";
3799 9c2149c8 ths
            break;
3800 9c2149c8 ths
        case 1:
3801 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3802 ead9360e ths
            gen_op_mfc0_mvpcontrol();
3803 9c2149c8 ths
            rn = "MVPControl";
3804 ead9360e ths
            break;
3805 9c2149c8 ths
        case 2:
3806 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3807 ead9360e ths
            gen_op_mfc0_mvpconf0();
3808 9c2149c8 ths
            rn = "MVPConf0";
3809 ead9360e ths
            break;
3810 9c2149c8 ths
        case 3:
3811 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3812 ead9360e ths
            gen_op_mfc0_mvpconf1();
3813 9c2149c8 ths
            rn = "MVPConf1";
3814 ead9360e ths
            break;
3815 9c2149c8 ths
        default:
3816 9c2149c8 ths
            goto die;
3817 9c2149c8 ths
        }
3818 9c2149c8 ths
        break;
3819 9c2149c8 ths
    case 1:
3820 9c2149c8 ths
        switch (sel) {
3821 9c2149c8 ths
        case 0:
3822 9c2149c8 ths
            gen_op_mfc0_random();
3823 9c2149c8 ths
            rn = "Random";
3824 2423f660 ths
            break;
3825 9c2149c8 ths
        case 1:
3826 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3827 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
3828 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3829 9c2149c8 ths
            rn = "VPEControl";
3830 ead9360e ths
            break;
3831 9c2149c8 ths
        case 2:
3832 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3833 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
3834 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3835 9c2149c8 ths
            rn = "VPEConf0";
3836 ead9360e ths
            break;
3837 9c2149c8 ths
        case 3:
3838 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3839 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
3840 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3841 9c2149c8 ths
            rn = "VPEConf1";
3842 ead9360e ths
            break;
3843 9c2149c8 ths
        case 4:
3844 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3845 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask));
3846 9c2149c8 ths
            rn = "YQMask";
3847 ead9360e ths
            break;
3848 9c2149c8 ths
        case 5:
3849 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3850 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
3851 9c2149c8 ths
            rn = "VPESchedule";
3852 ead9360e ths
            break;
3853 9c2149c8 ths
        case 6:
3854 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3855 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3856 9c2149c8 ths
            rn = "VPEScheFBack";
3857 ead9360e ths
            break;
3858 9c2149c8 ths
        case 7:
3859 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3860 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
3861 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3862 9c2149c8 ths
            rn = "VPEOpt";
3863 ead9360e ths
            break;
3864 9c2149c8 ths
        default:
3865 9c2149c8 ths
            goto die;
3866 9c2149c8 ths
        }
3867 9c2149c8 ths
        break;
3868 9c2149c8 ths
    case 2:
3869 9c2149c8 ths
        switch (sel) {
3870 9c2149c8 ths
        case 0:
3871 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
3872 2423f660 ths
            rn = "EntryLo0";
3873 2423f660 ths
            break;
3874 9c2149c8 ths
        case 1:
3875 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3876 ead9360e ths
            gen_op_mfc0_tcstatus();
3877 2423f660 ths
            rn = "TCStatus";
3878 ead9360e ths
            break;
3879 9c2149c8 ths
        case 2:
3880 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3881 ead9360e ths
            gen_op_mfc0_tcbind();
3882 2423f660 ths
            rn = "TCBind";
3883 ead9360e ths
            break;
3884 9c2149c8 ths
        case 3:
3885 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3886 ead9360e ths
            gen_op_dmfc0_tcrestart();
3887 2423f660 ths
            rn = "TCRestart";
3888 ead9360e ths
            break;
3889 9c2149c8 ths
        case 4:
3890 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3891 ead9360e ths
            gen_op_dmfc0_tchalt();
3892 2423f660 ths
            rn = "TCHalt";
3893 ead9360e ths
            break;
3894 9c2149c8 ths
        case 5:
3895 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3896 ead9360e ths
            gen_op_dmfc0_tccontext();
3897 2423f660 ths
            rn = "TCContext";
3898 ead9360e ths
            break;
3899 9c2149c8 ths
        case 6:
3900 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3901 ead9360e ths
            gen_op_dmfc0_tcschedule();
3902 2423f660 ths
            rn = "TCSchedule";
3903 ead9360e ths
            break;
3904 9c2149c8 ths
        case 7:
3905 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3906 ead9360e ths
            gen_op_dmfc0_tcschefback();
3907 2423f660 ths
            rn = "TCScheFBack";
3908 ead9360e ths
            break;
3909 9c2149c8 ths
        default:
3910 9c2149c8 ths
            goto die;
3911 9c2149c8 ths
        }
3912 9c2149c8 ths
        break;
3913 9c2149c8 ths
    case 3:
3914 9c2149c8 ths
        switch (sel) {
3915 9c2149c8 ths
        case 0:
3916 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
3917 2423f660 ths
            rn = "EntryLo1";
3918 2423f660 ths
            break;
3919 9c2149c8 ths
        default:
3920 9c2149c8 ths
            goto die;
3921 1579a72e ths
        }
3922 9c2149c8 ths
        break;
3923 9c2149c8 ths
    case 4:
3924 9c2149c8 ths
        switch (sel) {
3925 9c2149c8 ths
        case 0:
3926 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
3927 2423f660 ths
            rn = "Context";
3928 2423f660 ths
            break;
3929 9c2149c8 ths
        case 1:
3930 2423f660 ths
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3931 2423f660 ths
            rn = "ContextConfig";
3932 2423f660 ths
//            break;
3933 9c2149c8 ths
        default:
3934 9c2149c8 ths
            goto die;
3935 876d4b07 ths
        }
3936 9c2149c8 ths
        break;
3937 9c2149c8 ths
    case 5:
3938 9c2149c8 ths
        switch (sel) {
3939 9c2149c8 ths
        case 0:
3940 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
3941 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3942 2423f660 ths
            rn = "PageMask";
3943 2423f660 ths
            break;
3944 9c2149c8 ths
        case 1:
3945 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3946 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
3947 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3948 2423f660 ths
            rn = "PageGrain";
3949 2423f660 ths
            break;
3950 9c2149c8 ths
        default:
3951 9c2149c8 ths
            goto die;
3952 876d4b07 ths
        }
3953 9c2149c8 ths
        break;
3954 9c2149c8 ths
    case 6:
3955 9c2149c8 ths
        switch (sel) {
3956 9c2149c8 ths
        case 0:
3957 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
3958 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3959 2423f660 ths
            rn = "Wired";
3960 2423f660 ths
            break;
3961 9c2149c8 ths
        case 1:
3962 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3963 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
3964 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3965 2423f660 ths
            rn = "SRSConf0";
3966 ead9360e ths
            break;
3967 9c2149c8 ths
        case 2:
3968 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3969 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
3970 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3971 2423f660 ths
            rn = "SRSConf1";
3972 ead9360e ths
            break;
3973 9c2149c8 ths
        case 3:
3974 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3975 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
3976 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3977 2423f660 ths
            rn = "SRSConf2";
3978 ead9360e ths
            break;
3979 9c2149c8 ths
        case 4:
3980 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3981 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
3982 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3983 2423f660 ths
            rn = "SRSConf3";
3984 ead9360e ths
            break;
3985 9c2149c8 ths
        case 5:
3986 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3987 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
3988 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3989 2423f660 ths
            rn = "SRSConf4";
3990 ead9360e ths
            break;
3991 9c2149c8 ths
        default:
3992 9c2149c8 ths
            goto die;
3993 876d4b07 ths
        }
3994 9c2149c8 ths
        break;
3995 9c2149c8 ths
    case 7:
3996 9c2149c8 ths
        switch (sel) {
3997 9c2149c8 ths
        case 0:
3998 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3999 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
4000 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4001 2423f660 ths
            rn = "HWREna";
4002 2423f660 ths
            break;
4003 9c2149c8 ths
        default:
4004 9c2149c8 ths
            goto die;
4005 876d4b07 ths
        }
4006 9c2149c8 ths
        break;
4007 9c2149c8 ths
    case 8:
4008 9c2149c8 ths
        switch (sel) {
4009 9c2149c8 ths
        case 0:
4010 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
4011 f0b3f3ae ths
            rn = "BadVAddr";
4012 2423f660 ths
            break;
4013 9c2149c8 ths
        default:
4014 9c2149c8 ths
            goto die;
4015 876d4b07 ths
        }
4016 9c2149c8 ths
        break;
4017 9c2149c8 ths
    case 9:
4018 9c2149c8 ths
        switch (sel) {
4019 9c2149c8 ths
        case 0:
4020 2423f660 ths
            gen_op_mfc0_count();
4021 2423f660 ths
            rn = "Count";
4022 2423f660 ths
            break;
4023 2423f660 ths
        /* 6,7 are implementation dependent */
4024 9c2149c8 ths
        default:
4025 9c2149c8 ths
            goto die;
4026 876d4b07 ths
        }
4027 9c2149c8 ths
        break;
4028 9c2149c8 ths
    case 10:
4029 9c2149c8 ths
        switch (sel) {
4030 9c2149c8 ths
        case 0:
4031 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
4032 2423f660 ths
            rn = "EntryHi";
4033 2423f660 ths
            break;
4034 9c2149c8 ths
        default:
4035 9c2149c8 ths
            goto die;
4036 876d4b07 ths
        }
4037 9c2149c8 ths
        break;
4038 9c2149c8 ths
    case 11:
4039 9c2149c8 ths
        switch (sel) {
4040 9c2149c8 ths
        case 0:
4041 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
4042 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4043 2423f660 ths
            rn = "Compare";
4044 2423f660 ths
            break;
4045 876d4b07 ths
        /* 6,7 are implementation dependent */
4046 9c2149c8 ths
        default:
4047 9c2149c8 ths
            goto die;
4048 876d4b07 ths
        }
4049 9c2149c8 ths
        break;
4050 9c2149c8 ths
    case 12:
4051 9c2149c8 ths
        switch (sel) {
4052 9c2149c8 ths
        case 0:
4053 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
4054 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4055 2423f660 ths
            rn = "Status";
4056 2423f660 ths
            break;
4057 9c2149c8 ths
        case 1:
4058 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4059 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
4060 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4061 2423f660 ths
            rn = "IntCtl";
4062 2423f660 ths
            break;
4063 9c2149c8 ths
        case 2:
4064 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4065 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
4066 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4067 2423f660 ths
            rn = "SRSCtl";
4068 2423f660 ths
            break;
4069 9c2149c8 ths
        case 3:
4070 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4071 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
4072 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4073 2423f660 ths
            rn = "SRSMap";
4074 2423f660 ths
            break;
4075 9c2149c8 ths
        default:
4076 9c2149c8 ths
            goto die;
4077 876d4b07 ths
        }
4078 9c2149c8 ths
        break;
4079 9c2149c8 ths
    case 13:
4080 9c2149c8 ths
        switch (sel) {
4081 9c2149c8 ths
        case 0:
4082 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
4083 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4084 2423f660 ths
            rn = "Cause";
4085 2423f660 ths
            break;
4086 9c2149c8 ths
        default:
4087 9c2149c8 ths
            goto die;
4088 876d4b07 ths
        }
4089 9c2149c8 ths
        break;
4090 9c2149c8 ths
    case 14:
4091 9c2149c8 ths
        switch (sel) {
4092 9c2149c8 ths
        case 0:
4093 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4094 2423f660 ths
            rn = "EPC";
4095 2423f660 ths
            break;
4096 9c2149c8 ths
        default:
4097 9c2149c8 ths
            goto die;
4098 876d4b07 ths
        }
4099 9c2149c8 ths
        break;
4100 9c2149c8 ths
    case 15:
4101 9c2149c8 ths
        switch (sel) {
4102 9c2149c8 ths
        case 0:
4103 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
4104 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4105 2423f660 ths
            rn = "PRid";
4106 2423f660 ths
            break;
4107 9c2149c8 ths
        case 1:
4108 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4109 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
4110 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4111 2423f660 ths
            rn = "EBase";
4112 2423f660 ths
            break;
4113 9c2149c8 ths
        default:
4114 9c2149c8 ths
            goto die;
4115 876d4b07 ths
        }
4116 9c2149c8 ths
        break;
4117 9c2149c8 ths
    case 16:
4118 9c2149c8 ths
        switch (sel) {
4119 9c2149c8 ths
        case 0:
4120 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
4121 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4122 9c2149c8 ths
            rn = "Config";
4123 9c2149c8 ths
            break;
4124 9c2149c8 ths
        case 1:
4125 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
4126 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4127 9c2149c8 ths
            rn = "Config1";
4128 9c2149c8 ths
            break;
4129 9c2149c8 ths
        case 2:
4130 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
4131 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4132 9c2149c8 ths
            rn = "Config2";
4133 9c2149c8 ths
            break;
4134 9c2149c8 ths
        case 3:
4135 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
4136 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4137 9c2149c8 ths
            rn = "Config3";
4138 9c2149c8 ths
            break;
4139 9c2149c8 ths
       /* 6,7 are implementation dependent */
4140 f0b3f3ae ths
        case 6:
4141 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
4142 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4143 f0b3f3ae ths
            rn = "Config6";
4144 f0b3f3ae ths
            break;
4145 f0b3f3ae ths
        case 7:
4146 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
4147 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4148 f0b3f3ae ths
            rn = "Config7";
4149 f0b3f3ae ths
            break;
4150 9c2149c8 ths
        default:
4151 9c2149c8 ths
            goto die;
4152 9c2149c8 ths
        }
4153 9c2149c8 ths
        break;
4154 9c2149c8 ths
    case 17:
4155 9c2149c8 ths
        switch (sel) {
4156 9c2149c8 ths
        case 0:
4157 2423f660 ths
            gen_op_dmfc0_lladdr();
4158 2423f660 ths
            rn = "LLAddr";
4159 2423f660 ths
            break;
4160 9c2149c8 ths
        default:
4161 9c2149c8 ths
            goto die;
4162 9c2149c8 ths
        }
4163 9c2149c8 ths
        break;
4164 9c2149c8 ths
    case 18:
4165 9c2149c8 ths
        switch (sel) {
4166 fd88b6ab ths
        case 0 ... 7:
4167 fd88b6ab ths
            gen_op_dmfc0_watchlo(sel);
4168 2423f660 ths
            rn = "WatchLo";
4169 2423f660 ths
            break;
4170 9c2149c8 ths
        default:
4171 9c2149c8 ths
            goto die;
4172 9c2149c8 ths
        }
4173 9c2149c8 ths
        break;
4174 9c2149c8 ths
    case 19:
4175 9c2149c8 ths
        switch (sel) {
4176 fd88b6ab ths
        case 0 ... 7:
4177 fd88b6ab ths
            gen_op_mfc0_watchhi(sel);
4178 2423f660 ths
            rn = "WatchHi";
4179 2423f660 ths
            break;
4180 9c2149c8 ths
        default:
4181 9c2149c8 ths
            goto die;
4182 9c2149c8 ths
        }
4183 9c2149c8 ths
        break;
4184 9c2149c8 ths
    case 20:
4185 9c2149c8 ths
        switch (sel) {
4186 9c2149c8 ths
        case 0:
4187 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
4188 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
4189 2423f660 ths
            rn = "XContext";
4190 2423f660 ths
            break;
4191 9c2149c8 ths
        default:
4192 9c2149c8 ths
            goto die;
4193 9c2149c8 ths
        }
4194 9c2149c8 ths
        break;
4195 9c2149c8 ths
    case 21:
4196 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4197 9c2149c8 ths
        switch (sel) {
4198 9c2149c8 ths
        case 0:
4199 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
4200 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4201 2423f660 ths
            rn = "Framemask";
4202 2423f660 ths
            break;
4203 9c2149c8 ths
        default:
4204 9c2149c8 ths
            goto die;
4205 9c2149c8 ths
        }
4206 9c2149c8 ths
        break;
4207 9c2149c8 ths
    case 22:
4208 2423f660 ths
        /* ignored */
4209 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
4210 2423f660 ths
        break;
4211 9c2149c8 ths
    case 23:
4212 9c2149c8 ths
        switch (sel) {
4213 9c2149c8 ths
        case 0:
4214 2423f660 ths
            gen_op_mfc0_debug(); /* EJTAG support */
4215 2423f660 ths
            rn = "Debug";
4216 2423f660 ths
            break;
4217 9c2149c8 ths
        case 1:
4218 2423f660 ths
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
4219 2423f660 ths
            rn = "TraceControl";
4220 2423f660 ths
//            break;
4221 9c2149c8 ths
        case 2:
4222 2423f660 ths
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
4223 2423f660 ths
            rn = "TraceControl2";
4224 2423f660 ths
//            break;
4225 9c2149c8 ths
        case 3:
4226 2423f660 ths
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
4227 2423f660 ths
            rn = "UserTraceData";
4228 2423f660 ths
//            break;
4229 9c2149c8 ths
        case 4:
4230 2423f660 ths
//            gen_op_dmfc0_debug(); /* PDtrace support */
4231 2423f660 ths
            rn = "TraceBPC";
4232 2423f660 ths
//            break;
4233 9c2149c8 ths
        default:
4234 9c2149c8 ths
            goto die;
4235 9c2149c8 ths
        }
4236 9c2149c8 ths
        break;
4237 9c2149c8 ths
    case 24:
4238 9c2149c8 ths
        switch (sel) {
4239 9c2149c8 ths
        case 0:
4240 f0b3f3ae ths
            /* EJTAG support */
4241 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4242 2423f660 ths
            rn = "DEPC";
4243 2423f660 ths
            break;
4244 9c2149c8 ths
        default:
4245 9c2149c8 ths
            goto die;
4246 9c2149c8 ths
        }
4247 9c2149c8 ths
        break;
4248 9c2149c8 ths
    case 25:
4249 9c2149c8 ths
        switch (sel) {
4250 9c2149c8 ths
        case 0:
4251 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
4252 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4253 2423f660 ths
            rn = "Performance0";
4254 9c2149c8 ths
            break;
4255 9c2149c8 ths
        case 1:
4256 2423f660 ths
//            gen_op_dmfc0_performance1();
4257 2423f660 ths
            rn = "Performance1";
4258 2423f660 ths
//            break;
4259 9c2149c8 ths
        case 2:
4260 2423f660 ths
//            gen_op_dmfc0_performance2();
4261 2423f660 ths
            rn = "Performance2";
4262 2423f660 ths
//            break;
4263 9c2149c8 ths
        case 3:
4264 2423f660 ths
//            gen_op_dmfc0_performance3();
4265 2423f660 ths
            rn = "Performance3";
4266 2423f660 ths
//            break;
4267 9c2149c8 ths
        case 4:
4268 2423f660 ths
//            gen_op_dmfc0_performance4();
4269 2423f660 ths
            rn = "Performance4";
4270 2423f660 ths
//            break;
4271 9c2149c8 ths
        case 5:
4272 2423f660 ths
//            gen_op_dmfc0_performance5();
4273 2423f660 ths
            rn = "Performance5";
4274 2423f660 ths
//            break;
4275 9c2149c8 ths
        case 6:
4276 2423f660 ths
//            gen_op_dmfc0_performance6();
4277 2423f660 ths
            rn = "Performance6";
4278 2423f660 ths
//            break;
4279 9c2149c8 ths
        case 7:
4280 2423f660 ths
//            gen_op_dmfc0_performance7();
4281 2423f660 ths
            rn = "Performance7";
4282 2423f660 ths
//            break;
4283 9c2149c8 ths
        default:
4284 9c2149c8 ths
            goto die;
4285 9c2149c8 ths
        }
4286 9c2149c8 ths
        break;
4287 9c2149c8 ths
    case 26:
4288 9c2149c8 ths
       rn = "ECC";
4289 9c2149c8 ths
       break;
4290 9c2149c8 ths
    case 27:
4291 9c2149c8 ths
        switch (sel) {
4292 9c2149c8 ths
        /* ignored */
4293 9c2149c8 ths
        case 0 ... 3:
4294 2423f660 ths
            rn = "CacheErr";
4295 2423f660 ths
            break;
4296 9c2149c8 ths
        default:
4297 9c2149c8 ths
            goto die;
4298 9c2149c8 ths
        }
4299 9c2149c8 ths
        break;
4300 9c2149c8 ths
    case 28:
4301 9c2149c8 ths
        switch (sel) {
4302 9c2149c8 ths
        case 0:
4303 9c2149c8 ths
        case 2:
4304 9c2149c8 ths
        case 4:
4305 9c2149c8 ths
        case 6:
4306 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
4307 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4308 9c2149c8 ths
            rn = "TagLo";
4309 9c2149c8 ths
            break;
4310 9c2149c8 ths
        case 1:
4311 9c2149c8 ths
        case 3:
4312 9c2149c8 ths
        case 5:
4313 9c2149c8 ths
        case 7:
4314 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
4315 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4316 9c2149c8 ths
            rn = "DataLo";
4317 9c2149c8 ths
            break;
4318 9c2149c8 ths
        default:
4319 9c2149c8 ths
            goto die;
4320 9c2149c8 ths
        }
4321 9c2149c8 ths
        break;
4322 9c2149c8 ths
    case 29:
4323 9c2149c8 ths
        switch (sel) {
4324 9c2149c8 ths
        case 0:
4325 9c2149c8 ths
        case 2:
4326 9c2149c8 ths
        case 4:
4327 9c2149c8 ths
        case 6:
4328 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
4329 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4330 9c2149c8 ths
            rn = "TagHi";
4331 9c2149c8 ths
            break;
4332 9c2149c8 ths
        case 1:
4333 9c2149c8 ths
        case 3:
4334 9c2149c8 ths
        case 5:
4335 9c2149c8 ths
        case 7:
4336 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
4337 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4338 9c2149c8 ths
            rn = "DataHi";
4339 9c2149c8 ths
            break;
4340 9c2149c8 ths
        default:
4341 9c2149c8 ths
            goto die;
4342 9c2149c8 ths
        }
4343 9c2149c8 ths
        break;
4344 9c2149c8 ths
    case 30:
4345 9c2149c8 ths
        switch (sel) {
4346 9c2149c8 ths
        case 0:
4347 f0b3f3ae ths
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4348 2423f660 ths
            rn = "ErrorEPC";
4349 2423f660 ths
            break;
4350 9c2149c8 ths
        default:
4351 9c2149c8 ths
            goto die;
4352 9c2149c8 ths
        }
4353 9c2149c8 ths
        break;
4354 9c2149c8 ths
    case 31:
4355 9c2149c8 ths
        switch (sel) {
4356 9c2149c8 ths
        case 0:
4357 f0b3f3ae ths
            /* EJTAG support */
4358 f0b3f3ae ths
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
4359 f0b3f3ae ths
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4360 2423f660 ths
            rn = "DESAVE";
4361 2423f660 ths
            break;
4362 9c2149c8 ths
        default:
4363 9c2149c8 ths
            goto die;
4364 9c2149c8 ths
        }
4365 9c2149c8 ths
        break;
4366 9c2149c8 ths
    default:
4367 876d4b07 ths
        goto die;
4368 9c2149c8 ths
    }
4369 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4370 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4371 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4372 9c2149c8 ths
                rn, reg, sel);
4373 9c2149c8 ths
    }
4374 9c2149c8 ths
#endif
4375 9c2149c8 ths
    return;
4376 9c2149c8 ths
4377 9c2149c8 ths
die:
4378 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4379 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4380 9c2149c8 ths
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4381 9c2149c8 ths
                rn, reg, sel);
4382 9c2149c8 ths
    }
4383 9c2149c8 ths
#endif
4384 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
4385 9c2149c8 ths
}
4386 9c2149c8 ths
4387 3a95e3a7 ths
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4388 9c2149c8 ths
{
4389 9c2149c8 ths
    const char *rn = "invalid";
4390 9c2149c8 ths
4391 e189e748 ths
    if (sel != 0)
4392 e189e748 ths
        check_insn(env, ctx, ISA_MIPS64);
4393 e189e748 ths
4394 9c2149c8 ths
    switch (reg) {
4395 9c2149c8 ths
    case 0:
4396 9c2149c8 ths
        switch (sel) {
4397 9c2149c8 ths
        case 0:
4398 9c2149c8 ths
            gen_op_mtc0_index();
4399 9c2149c8 ths
            rn = "Index";
4400 9c2149c8 ths
            break;
4401 9c2149c8 ths
        case 1:
4402 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4403 ead9360e ths
            gen_op_mtc0_mvpcontrol();
4404 9c2149c8 ths
            rn = "MVPControl";
4405 ead9360e ths
            break;
4406 9c2149c8 ths
        case 2:
4407 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4408 ead9360e ths
            /* ignored */
4409 9c2149c8 ths
            rn = "MVPConf0";
4410 ead9360e ths
            break;
4411 9c2149c8 ths
        case 3:
4412 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4413 ead9360e ths
            /* ignored */
4414 9c2149c8 ths
            rn = "MVPConf1";
4415 ead9360e ths
            break;
4416 9c2149c8 ths
        default:
4417 9c2149c8 ths
            goto die;
4418 9c2149c8 ths
        }
4419 9c2149c8 ths
        break;
4420 9c2149c8 ths
    case 1:
4421 9c2149c8 ths
        switch (sel) {
4422 9c2149c8 ths
        case 0:
4423 2423f660 ths
            /* ignored */
4424 9c2149c8 ths
            rn = "Random";
4425 2423f660 ths
            break;
4426 9c2149c8 ths
        case 1:
4427 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4428 ead9360e ths
            gen_op_mtc0_vpecontrol();
4429 9c2149c8 ths
            rn = "VPEControl";
4430 ead9360e ths
            break;
4431 9c2149c8 ths
        case 2:
4432 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4433 ead9360e ths
            gen_op_mtc0_vpeconf0();
4434 9c2149c8 ths
            rn = "VPEConf0";
4435 ead9360e ths
            break;
4436 9c2149c8 ths
        case 3:
4437 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4438 ead9360e ths
            gen_op_mtc0_vpeconf1();
4439 9c2149c8 ths
            rn = "VPEConf1";
4440 ead9360e ths
            break;
4441 9c2149c8 ths
        case 4:
4442 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4443 ead9360e ths
            gen_op_mtc0_yqmask();
4444 9c2149c8 ths
            rn = "YQMask";
4445 ead9360e ths
            break;
4446 9c2149c8 ths
        case 5:
4447 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4448 ead9360e ths
            gen_op_mtc0_vpeschedule();
4449 9c2149c8 ths
            rn = "VPESchedule";
4450 ead9360e ths
            break;
4451 9c2149c8 ths
        case 6:
4452 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4453 ead9360e ths
            gen_op_mtc0_vpeschefback();
4454 9c2149c8 ths
            rn = "VPEScheFBack";
4455 ead9360e ths
            break;
4456 9c2149c8 ths
        case 7:
4457 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4458 ead9360e ths
            gen_op_mtc0_vpeopt();
4459 9c2149c8 ths
            rn = "VPEOpt";
4460 ead9360e ths
            break;
4461 9c2149c8 ths
        default:
4462 9c2149c8 ths
            goto die;
4463 9c2149c8 ths
        }
4464 9c2149c8 ths
        break;
4465 9c2149c8 ths
    case 2:
4466 9c2149c8 ths
        switch (sel) {
4467 9c2149c8 ths
        case 0:
4468 f1b0aa5d ths
            gen_op_mtc0_entrylo0();
4469 2423f660 ths
            rn = "EntryLo0";
4470 2423f660 ths
            break;
4471 9c2149c8 ths
        case 1:
4472 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4473 ead9360e ths
            gen_op_mtc0_tcstatus();
4474 2423f660 ths
            rn = "TCStatus";
4475 ead9360e ths
            break;
4476 9c2149c8 ths
        case 2:
4477 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4478 ead9360e ths
            gen_op_mtc0_tcbind();
4479 2423f660 ths
            rn = "TCBind";
4480 ead9360e ths
            break;
4481 9c2149c8 ths
        case 3:
4482 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4483 ead9360e ths
            gen_op_mtc0_tcrestart();
4484 2423f660 ths
            rn = "TCRestart";
4485 ead9360e ths
            break;
4486 9c2149c8 ths
        case 4:
4487 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4488 ead9360e ths
            gen_op_mtc0_tchalt();
4489 2423f660 ths
            rn = "TCHalt";
4490 ead9360e ths
            break;
4491 9c2149c8 ths
        case 5:
4492 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4493 ead9360e ths
            gen_op_mtc0_tccontext();
4494 2423f660 ths
            rn = "TCContext";
4495 ead9360e ths
            break;
4496 9c2149c8 ths
        case 6:
4497 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4498 ead9360e ths
            gen_op_mtc0_tcschedule();
4499 2423f660 ths
            rn = "TCSchedule";
4500 ead9360e ths
            break;
4501 9c2149c8 ths
        case 7:
4502 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4503 ead9360e ths
            gen_op_mtc0_tcschefback();
4504 2423f660 ths
            rn = "TCScheFBack";
4505 ead9360e ths
            break;
4506 9c2149c8 ths
        default:
4507 9c2149c8 ths
            goto die;
4508 9c2149c8 ths
        }
4509 9c2149c8 ths
        break;
4510 9c2149c8 ths
    case 3:
4511 9c2149c8 ths
        switch (sel) {
4512 9c2149c8 ths
        case 0:
4513 f1b0aa5d ths
            gen_op_mtc0_entrylo1();
4514 2423f660 ths
            rn = "EntryLo1";
4515 2423f660 ths
            break;
4516 9c2149c8 ths
        default:
4517 9c2149c8 ths
            goto die;
4518 876d4b07 ths
        }
4519 9c2149c8 ths
        break;
4520 9c2149c8 ths
    case 4:
4521 9c2149c8 ths
        switch (sel) {
4522 9c2149c8 ths
        case 0:
4523 f1b0aa5d ths
            gen_op_mtc0_context();
4524 2423f660 ths
            rn = "Context";
4525 2423f660 ths
            break;
4526 9c2149c8 ths
        case 1:
4527 f1b0aa5d ths
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
4528 2423f660 ths
            rn = "ContextConfig";
4529 2423f660 ths
//           break;
4530 9c2149c8 ths
        default:
4531 9c2149c8 ths
            goto die;
4532 876d4b07 ths
        }
4533 9c2149c8 ths
        break;
4534 9c2149c8 ths
    case 5:
4535 9c2149c8 ths
        switch (sel) {
4536 9c2149c8 ths
        case 0:
4537 2423f660 ths
            gen_op_mtc0_pagemask();
4538 2423f660 ths
            rn = "PageMask";
4539 2423f660 ths
            break;
4540 9c2149c8 ths
        case 1:
4541 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4542 2423f660 ths
            gen_op_mtc0_pagegrain();
4543 2423f660 ths
            rn = "PageGrain";
4544 2423f660 ths
            break;
4545 9c2149c8 ths
        default:
4546 9c2149c8 ths
            goto die;
4547 876d4b07 ths
        }
4548 9c2149c8 ths
        break;
4549 9c2149c8 ths
    case 6:
4550 9c2149c8 ths
        switch (sel) {
4551 9c2149c8 ths
        case 0:
4552 2423f660 ths
            gen_op_mtc0_wired();
4553 2423f660 ths
            rn = "Wired";
4554 2423f660 ths
            break;
4555 9c2149c8 ths
        case 1:
4556 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4557 ead9360e ths
            gen_op_mtc0_srsconf0();
4558 2423f660 ths
            rn = "SRSConf0";
4559 ead9360e ths
            break;
4560 9c2149c8 ths
        case 2:
4561 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4562 ead9360e ths
            gen_op_mtc0_srsconf1();
4563 2423f660 ths
            rn = "SRSConf1";
4564 ead9360e ths
            break;
4565 9c2149c8 ths
        case 3:
4566 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4567 ead9360e ths
            gen_op_mtc0_srsconf2();
4568 2423f660 ths
            rn = "SRSConf2";
4569 ead9360e ths
            break;
4570 9c2149c8 ths
        case 4:
4571 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4572 ead9360e ths
            gen_op_mtc0_srsconf3();
4573 2423f660 ths
            rn = "SRSConf3";
4574 ead9360e ths
            break;
4575 9c2149c8 ths
        case 5:
4576 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4577 ead9360e ths
            gen_op_mtc0_srsconf4();
4578 2423f660 ths
            rn = "SRSConf4";
4579 ead9360e ths
            break;
4580 9c2149c8 ths
        default:
4581 9c2149c8 ths
            goto die;
4582 876d4b07 ths
        }
4583 9c2149c8 ths
        break;
4584 9c2149c8 ths
    case 7:
4585 9c2149c8 ths
        switch (sel) {
4586 9c2149c8 ths
        case 0:
4587 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4588 2423f660 ths
            gen_op_mtc0_hwrena();
4589 2423f660 ths
            rn = "HWREna";
4590 2423f660 ths
            break;
4591 9c2149c8 ths
        default:
4592 9c2149c8 ths
            goto die;
4593 876d4b07 ths
        }
4594 9c2149c8 ths
        break;
4595 9c2149c8 ths
    case 8:
4596 9c2149c8 ths
        /* ignored */
4597 f0b3f3ae ths
        rn = "BadVAddr";
4598 9c2149c8 ths
        break;
4599 9c2149c8 ths
    case 9:
4600 9c2149c8 ths
        switch (sel) {
4601 9c2149c8 ths
        case 0:
4602 2423f660 ths
            gen_op_mtc0_count();
4603 2423f660 ths
            rn = "Count";
4604 2423f660 ths
            break;
4605 876d4b07 ths
        /* 6,7 are implementation dependent */
4606 9c2149c8 ths
        default:
4607 9c2149c8 ths
            goto die;
4608 876d4b07 ths
        }
4609 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
4610 876d4b07 ths
        ctx->bstate = BS_STOP;
4611 9c2149c8 ths
        break;
4612 9c2149c8 ths
    case 10:
4613 9c2149c8 ths
        switch (sel) {
4614 9c2149c8 ths
        case 0:
4615 2423f660 ths
            gen_op_mtc0_entryhi();
4616 2423f660 ths
            rn = "EntryHi";
4617 2423f660 ths
            break;
4618 9c2149c8 ths
        default:
4619 9c2149c8 ths
            goto die;
4620 876d4b07 ths
        }
4621 9c2149c8 ths
        break;
4622 9c2149c8 ths
    case 11:
4623 9c2149c8 ths
        switch (sel) {
4624 9c2149c8 ths
        case 0:
4625 2423f660 ths
            gen_op_mtc0_compare();
4626 2423f660 ths
            rn = "Compare";
4627 2423f660 ths
            break;
4628 876d4b07 ths
        /* 6,7 are implementation dependent */
4629 9c2149c8 ths
        default:
4630 9c2149c8 ths
            goto die;
4631 876d4b07 ths
        }
4632 4586f9e9 aurel32
        /* Stop translation as we may have switched the execution mode */
4633 4586f9e9 aurel32
        ctx->bstate = BS_STOP;
4634 9c2149c8 ths
        break;
4635 9c2149c8 ths
    case 12:
4636 9c2149c8 ths
        switch (sel) {
4637 9c2149c8 ths
        case 0:
4638 2423f660 ths
            gen_op_mtc0_status();
4639 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
4640 8487327a ths
            gen_save_pc(ctx->pc + 4);
4641 8487327a ths
            ctx->bstate = BS_EXCP;
4642 2423f660 ths
            rn = "Status";
4643 2423f660 ths
            break;
4644 9c2149c8 ths
        case 1:
4645 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4646 2423f660 ths
            gen_op_mtc0_intctl();
4647 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4648 8487327a ths
            ctx->bstate = BS_STOP;
4649 2423f660 ths
            rn = "IntCtl";
4650 2423f660 ths
            break;
4651 9c2149c8 ths
        case 2:
4652 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4653 2423f660 ths
            gen_op_mtc0_srsctl();
4654 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4655 8487327a ths
            ctx->bstate = BS_STOP;
4656 2423f660 ths
            rn = "SRSCtl";
4657 2423f660 ths
            break;
4658 9c2149c8 ths
        case 3:
4659 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4660 fd88b6ab ths
            gen_op_mtc0_srsmap();
4661 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4662 8487327a ths
            ctx->bstate = BS_STOP;
4663 2423f660 ths
            rn = "SRSMap";
4664 2423f660 ths
            break;
4665 2423f660 ths
        default:
4666 9c2149c8 ths
            goto die;
4667 876d4b07 ths
        }
4668 9c2149c8 ths
        break;
4669 9c2149c8 ths
    case 13:
4670 9c2149c8 ths
        switch (sel) {
4671 9c2149c8 ths
        case 0:
4672 2423f660 ths
            gen_op_mtc0_cause();
4673 2423f660 ths
            rn = "Cause";
4674 2423f660 ths
            break;
4675 9c2149c8 ths
        default:
4676 9c2149c8 ths
            goto die;
4677 876d4b07 ths
        }
4678 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
4679 876d4b07 ths
        ctx->bstate = BS_STOP;
4680 9c2149c8 ths
        break;
4681 9c2149c8 ths
    case 14:
4682 9c2149c8 ths
        switch (sel) {
4683 9c2149c8 ths
        case 0:
4684 f1b0aa5d ths
            gen_op_mtc0_epc();
4685 2423f660 ths
            rn = "EPC";
4686 2423f660 ths
            break;
4687 9c2149c8 ths
        default:
4688 9c2149c8 ths
            goto die;
4689 876d4b07 ths
        }
4690 9c2149c8 ths
        break;
4691 9c2149c8 ths
    case 15:
4692 9c2149c8 ths
        switch (sel) {
4693 9c2149c8 ths
        case 0:
4694 2423f660 ths
            /* ignored */
4695 2423f660 ths
            rn = "PRid";
4696 2423f660 ths
            break;
4697 9c2149c8 ths
        case 1:
4698 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4699 2423f660 ths
            gen_op_mtc0_ebase();
4700 2423f660 ths
            rn = "EBase";
4701 2423f660 ths
            break;
4702 9c2149c8 ths
        default:
4703 9c2149c8 ths
            goto die;
4704 876d4b07 ths
        }
4705 9c2149c8 ths
        break;
4706 9c2149c8 ths
    case 16:
4707 9c2149c8 ths
        switch (sel) {
4708 9c2149c8 ths
        case 0:
4709 9c2149c8 ths
            gen_op_mtc0_config0();
4710 9c2149c8 ths
            rn = "Config";
4711 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
4712 2423f660 ths
            ctx->bstate = BS_STOP;
4713 9c2149c8 ths
            break;
4714 9c2149c8 ths
        case 1:
4715 2423f660 ths
            /* ignored */
4716 9c2149c8 ths
            rn = "Config1";
4717 9c2149c8 ths
            break;
4718 9c2149c8 ths
        case 2:
4719 9c2149c8 ths
            gen_op_mtc0_config2();
4720 9c2149c8 ths
            rn = "Config2";
4721 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
4722 2423f660 ths
            ctx->bstate = BS_STOP;
4723 9c2149c8 ths
            break;
4724 9c2149c8 ths
        case 3:
4725 2423f660 ths
            /* ignored */
4726 9c2149c8 ths
            rn = "Config3";
4727 9c2149c8 ths
            break;
4728 9c2149c8 ths
        /* 6,7 are implementation dependent */
4729 9c2149c8 ths
        default:
4730 9c2149c8 ths
            rn = "Invalid config selector";
4731 9c2149c8 ths
            goto die;
4732 9c2149c8 ths
        }
4733 9c2149c8 ths
        break;
4734 9c2149c8 ths
    case 17:
4735 9c2149c8 ths
        switch (sel) {
4736 9c2149c8 ths
        case 0:
4737 2423f660 ths
            /* ignored */
4738 2423f660 ths
            rn = "LLAddr";
4739 2423f660 ths
            break;
4740 9c2149c8 ths
        default:
4741 9c2149c8 ths
            goto die;
4742 9c2149c8 ths
        }
4743 9c2149c8 ths
        break;
4744 9c2149c8 ths
    case 18:
4745 9c2149c8 ths
        switch (sel) {
4746 fd88b6ab ths
        case 0 ... 7:
4747 fd88b6ab ths
            gen_op_mtc0_watchlo(sel);
4748 2423f660 ths
            rn = "WatchLo";
4749 2423f660 ths
            break;
4750 9c2149c8 ths
        default:
4751 9c2149c8 ths
            goto die;
4752 9c2149c8 ths
        }
4753 9c2149c8 ths
        break;
4754 9c2149c8 ths
    case 19:
4755 9c2149c8 ths
        switch (sel) {
4756 fd88b6ab ths
        case 0 ... 7:
4757 fd88b6ab ths
            gen_op_mtc0_watchhi(sel);
4758 2423f660 ths
            rn = "WatchHi";
4759 2423f660 ths
            break;
4760 9c2149c8 ths
        default:
4761 9c2149c8 ths
            goto die;
4762 9c2149c8 ths
        }
4763 9c2149c8 ths
        break;
4764 9c2149c8 ths
    case 20:
4765 9c2149c8 ths
        switch (sel) {
4766 9c2149c8 ths
        case 0:
4767 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
4768 f1b0aa5d ths
            gen_op_mtc0_xcontext();
4769 2423f660 ths
            rn = "XContext";
4770 2423f660 ths
            break;
4771 9c2149c8 ths
        default:
4772 9c2149c8 ths
            goto die;
4773 9c2149c8 ths
        }
4774 9c2149c8 ths
        break;
4775 9c2149c8 ths
    case 21:
4776 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4777 9c2149c8 ths
        switch (sel) {
4778 9c2149c8 ths
        case 0:
4779 2423f660 ths
            gen_op_mtc0_framemask();
4780 2423f660 ths
            rn = "Framemask";
4781 2423f660 ths
            break;
4782 9c2149c8 ths
        default:
4783 9c2149c8 ths
            goto die;
4784 9c2149c8 ths
        }
4785 9c2149c8 ths
        break;
4786 9c2149c8 ths
    case 22:
4787 9c2149c8 ths
        /* ignored */
4788 9c2149c8 ths
        rn = "Diagnostic"; /* implementation dependent */
4789 876d4b07 ths
        break;
4790 9c2149c8 ths
    case 23:
4791 9c2149c8 ths
        switch (sel) {
4792 9c2149c8 ths
        case 0:
4793 2423f660 ths
            gen_op_mtc0_debug(); /* EJTAG support */
4794 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
4795 8487327a ths
            gen_save_pc(ctx->pc + 4);
4796 8487327a ths
            ctx->bstate = BS_EXCP;
4797 2423f660 ths
            rn = "Debug";
4798 2423f660 ths
            break;
4799 9c2149c8 ths
        case 1:
4800 f1b0aa5d ths
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4801 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4802 8487327a ths
            ctx->bstate = BS_STOP;
4803 2423f660 ths
            rn = "TraceControl";
4804 2423f660 ths
//            break;
4805 9c2149c8 ths
        case 2:
4806 f1b0aa5d ths
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4807 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4808 8487327a ths
            ctx->bstate = BS_STOP;
4809 2423f660 ths
            rn = "TraceControl2";
4810 2423f660 ths
//            break;
4811 9c2149c8 ths
        case 3:
4812 f1b0aa5d ths
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4813 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4814 8487327a ths
            ctx->bstate = BS_STOP;
4815 2423f660 ths
            rn = "UserTraceData";
4816 2423f660 ths
//            break;
4817 9c2149c8 ths
        case 4:
4818 f1b0aa5d ths
//            gen_op_mtc0_debug(); /* PDtrace support */
4819 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4820 8487327a ths
            ctx->bstate = BS_STOP;
4821 2423f660 ths
            rn = "TraceBPC";
4822 2423f660 ths
//            break;
4823 9c2149c8 ths
        default:
4824 9c2149c8 ths
            goto die;
4825 9c2149c8 ths
        }
4826 9c2149c8 ths
        break;
4827 9c2149c8 ths
    case 24:
4828 9c2149c8 ths
        switch (sel) {
4829 9c2149c8 ths
        case 0:
4830 f1b0aa5d ths
            gen_op_mtc0_depc(); /* EJTAG support */
4831 2423f660 ths
            rn = "DEPC";
4832 2423f660 ths
            break;
4833 9c2149c8 ths
        default:
4834 9c2149c8 ths
            goto die;
4835 9c2149c8 ths
        }
4836 9c2149c8 ths
        break;
4837 9c2149c8 ths
    case 25:
4838 9c2149c8 ths
        switch (sel) {
4839 9c2149c8 ths
        case 0:
4840 2423f660 ths
            gen_op_mtc0_performance0();
4841 2423f660 ths
            rn = "Performance0";
4842 2423f660 ths
            break;
4843 9c2149c8 ths
        case 1:
4844 f1b0aa5d ths
//            gen_op_mtc0_performance1();
4845 2423f660 ths
            rn = "Performance1";
4846 2423f660 ths
//            break;
4847 9c2149c8 ths
        case 2:
4848 f1b0aa5d ths
//            gen_op_mtc0_performance2();
4849 2423f660 ths
            rn = "Performance2";
4850 2423f660 ths
//            break;
4851 9c2149c8 ths
        case 3:
4852 f1b0aa5d ths
//            gen_op_mtc0_performance3();
4853 2423f660 ths
            rn = "Performance3";
4854 2423f660 ths
//            break;
4855 9c2149c8 ths
        case 4:
4856 f1b0aa5d ths
//            gen_op_mtc0_performance4();
4857 2423f660 ths
            rn = "Performance4";
4858 2423f660 ths
//            break;
4859 9c2149c8 ths
        case 5:
4860 f1b0aa5d ths
//            gen_op_mtc0_performance5();
4861 2423f660 ths
            rn = "Performance5";
4862 2423f660 ths
//            break;
4863 9c2149c8 ths
        case 6:
4864 f1b0aa5d ths
//            gen_op_mtc0_performance6();
4865 2423f660 ths
            rn = "Performance6";
4866 2423f660 ths
//            break;
4867 9c2149c8 ths
        case 7:
4868 f1b0aa5d ths
//            gen_op_mtc0_performance7();
4869 2423f660 ths
            rn = "Performance7";
4870 2423f660 ths
//            break;
4871 9c2149c8 ths
        default:
4872 9c2149c8 ths
            goto die;
4873 9c2149c8 ths
        }
4874 876d4b07 ths
        break;
4875 9c2149c8 ths
    case 26:
4876 876d4b07 ths
        /* ignored */
4877 9c2149c8 ths
        rn = "ECC";
4878 876d4b07 ths
        break;
4879 9c2149c8 ths
    case 27:
4880 9c2149c8 ths
        switch (sel) {
4881 9c2149c8 ths
        case 0 ... 3:
4882 2423f660 ths
            /* ignored */
4883 2423f660 ths
            rn = "CacheErr";
4884 2423f660 ths
            break;
4885 9c2149c8 ths
        default:
4886 9c2149c8 ths
            goto die;
4887 9c2149c8 ths
        }
4888 876d4b07 ths
        break;
4889 9c2149c8 ths
    case 28:
4890 9c2149c8 ths
        switch (sel) {
4891 9c2149c8 ths
        case 0:
4892 9c2149c8 ths
        case 2:
4893 9c2149c8 ths
        case 4:
4894 9c2149c8 ths
        case 6:
4895 9c2149c8 ths
            gen_op_mtc0_taglo();
4896 9c2149c8 ths
            rn = "TagLo";
4897 9c2149c8 ths
            break;
4898 9c2149c8 ths
        case 1:
4899 9c2149c8 ths
        case 3:
4900 9c2149c8 ths
        case 5:
4901 9c2149c8 ths
        case 7:
4902 2423f660 ths
            gen_op_mtc0_datalo();
4903 9c2149c8 ths
            rn = "DataLo";
4904 9c2149c8 ths
            break;
4905 9c2149c8 ths
        default:
4906 9c2149c8 ths
            goto die;
4907 9c2149c8 ths
        }
4908 9c2149c8 ths
        break;
4909 9c2149c8 ths
    case 29:
4910 9c2149c8 ths
        switch (sel) {
4911 9c2149c8 ths
        case 0:
4912 9c2149c8 ths
        case 2:
4913 9c2149c8 ths
        case 4:
4914 9c2149c8 ths
        case 6:
4915 9c2149c8 ths
            gen_op_mtc0_taghi();
4916 9c2149c8 ths
            rn = "TagHi";
4917 9c2149c8 ths
            break;
4918 9c2149c8 ths
        case 1:
4919 9c2149c8 ths
        case 3:
4920 9c2149c8 ths
        case 5:
4921 9c2149c8 ths
        case 7:
4922 2423f660 ths
            gen_op_mtc0_datahi();
4923 9c2149c8 ths
            rn = "DataHi";
4924 9c2149c8 ths
            break;
4925 9c2149c8 ths
        default:
4926 9c2149c8 ths
            rn = "invalid sel";
4927 9c2149c8 ths
            goto die;
4928 9c2149c8 ths
        }
4929 876d4b07 ths
        break;
4930 9c2149c8 ths
    case 30:
4931 9c2149c8 ths
        switch (sel) {
4932 9c2149c8 ths
        case 0:
4933 f1b0aa5d ths
            gen_op_mtc0_errorepc();
4934 2423f660 ths
            rn = "ErrorEPC";
4935 2423f660 ths
            break;
4936 9c2149c8 ths
        default:
4937 9c2149c8 ths
            goto die;
4938 9c2149c8 ths
        }
4939 9c2149c8 ths
        break;
4940 9c2149c8 ths
    case 31:
4941 9c2149c8 ths
        switch (sel) {
4942 9c2149c8 ths
        case 0:
4943 2423f660 ths
            gen_op_mtc0_desave(); /* EJTAG support */
4944 2423f660 ths
            rn = "DESAVE";
4945 2423f660 ths
            break;
4946 9c2149c8 ths
        default:
4947 9c2149c8 ths
            goto die;
4948 9c2149c8 ths
        }
4949 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
4950 876d4b07 ths
        ctx->bstate = BS_STOP;
4951 9c2149c8 ths
        break;
4952 9c2149c8 ths
    default:
4953 876d4b07 ths
        goto die;
4954 9c2149c8 ths
    }
4955 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4956 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4957 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4958 9c2149c8 ths
                rn, reg, sel);
4959 9c2149c8 ths
    }
4960 9c2149c8 ths
#endif
4961 9c2149c8 ths
    return;
4962 9c2149c8 ths
4963 9c2149c8 ths
die:
4964 9c2149c8 ths
#if defined MIPS_DEBUG_DISAS
4965 9c2149c8 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4966 9c2149c8 ths
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4967 9c2149c8 ths
                rn, reg, sel);
4968 9c2149c8 ths
    }
4969 9c2149c8 ths
#endif
4970 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
4971 9c2149c8 ths
}
4972 d26bc211 ths
#endif /* TARGET_MIPS64 */
4973 9c2149c8 ths
4974 ead9360e ths
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4975 ead9360e ths
                     int u, int sel, int h)
4976 ead9360e ths
{
4977 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4978 ead9360e ths
4979 ead9360e ths
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4980 ead9360e ths
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4981 ead9360e ths
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4982 8e9ade68 ths
        tcg_gen_movi_tl(cpu_T[0], -1);
4983 ead9360e ths
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4984 ead9360e ths
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4985 8e9ade68 ths
        tcg_gen_movi_tl(cpu_T[0], -1);
4986 ead9360e ths
    else if (u == 0) {
4987 ead9360e ths
        switch (rt) {
4988 ead9360e ths
        case 2:
4989 ead9360e ths
            switch (sel) {
4990 ead9360e ths
            case 1:
4991 ead9360e ths
                gen_op_mftc0_tcstatus();
4992 ead9360e ths
                break;
4993 ead9360e ths
            case 2:
4994 ead9360e ths
                gen_op_mftc0_tcbind();
4995 ead9360e ths
                break;
4996 ead9360e ths
            case 3:
4997 ead9360e ths
                gen_op_mftc0_tcrestart();
4998 ead9360e ths
                break;
4999 ead9360e ths
            case 4:
5000 ead9360e ths
                gen_op_mftc0_tchalt();
5001 ead9360e ths
                break;
5002 ead9360e ths
            case 5:
5003 ead9360e ths
                gen_op_mftc0_tccontext();
5004 ead9360e ths
                break;
5005 ead9360e ths
            case 6:
5006 ead9360e ths
                gen_op_mftc0_tcschedule();
5007 ead9360e ths
                break;
5008 ead9360e ths
            case 7:
5009 ead9360e ths
                gen_op_mftc0_tcschefback();
5010 ead9360e ths
                break;
5011 ead9360e ths
            default:
5012 ead9360e ths
                gen_mfc0(env, ctx, rt, sel);
5013 ead9360e ths
                break;
5014 ead9360e ths
            }
5015 ead9360e ths
            break;
5016 ead9360e ths
        case 10:
5017 ead9360e ths
            switch (sel) {
5018 ead9360e ths
            case 0:
5019 ead9360e ths
                gen_op_mftc0_entryhi();
5020 ead9360e ths
                break;
5021 ead9360e ths
            default:
5022 ead9360e ths
                gen_mfc0(env, ctx, rt, sel);
5023 ead9360e ths
                break;
5024 ead9360e ths
            }
5025 ead9360e ths
        case 12:
5026 ead9360e ths
            switch (sel) {
5027 ead9360e ths
            case 0:
5028 ead9360e ths
                gen_op_mftc0_status();
5029 ead9360e ths
                break;
5030 ead9360e ths
            default:
5031 ead9360e ths
                gen_mfc0(env, ctx, rt, sel);
5032 ead9360e ths
                break;
5033 ead9360e ths
            }
5034 ead9360e ths
        case 23:
5035 ead9360e ths
            switch (sel) {
5036 ead9360e ths
            case 0:
5037 ead9360e ths
                gen_op_mftc0_debug();
5038 ead9360e ths
                break;
5039 ead9360e ths
            default:
5040 ead9360e ths
                gen_mfc0(env, ctx, rt, sel);
5041 ead9360e ths
                break;
5042 ead9360e ths
            }
5043 ead9360e ths
            break;
5044 ead9360e ths
        default:
5045 ead9360e ths
            gen_mfc0(env, ctx, rt, sel);
5046 ead9360e ths
        }
5047 ead9360e ths
    } else switch (sel) {
5048 ead9360e ths
    /* GPR registers. */
5049 ead9360e ths
    case 0:
5050 ead9360e ths
        gen_op_mftgpr(rt);
5051 ead9360e ths
        break;
5052 ead9360e ths
    /* Auxiliary CPU registers */
5053 ead9360e ths
    case 1:
5054 ead9360e ths
        switch (rt) {
5055 ead9360e ths
        case 0:
5056 ead9360e ths
            gen_op_mftlo(0);
5057 ead9360e ths
            break;
5058 ead9360e ths
        case 1:
5059 ead9360e ths
            gen_op_mfthi(0);
5060 ead9360e ths
            break;
5061 ead9360e ths
        case 2:
5062 ead9360e ths
            gen_op_mftacx(0);
5063 ead9360e ths
            break;
5064 ead9360e ths
        case 4:
5065 ead9360e ths
            gen_op_mftlo(1);
5066 ead9360e ths
            break;
5067 ead9360e ths
        case 5:
5068 ead9360e ths
            gen_op_mfthi(1);
5069 ead9360e ths
            break;
5070 ead9360e ths
        case 6:
5071 ead9360e ths
            gen_op_mftacx(1);
5072 ead9360e ths
            break;
5073 ead9360e ths
        case 8:
5074 ead9360e ths
            gen_op_mftlo(2);
5075 ead9360e ths
            break;
5076 ead9360e ths
        case 9:
5077 ead9360e ths
            gen_op_mfthi(2);
5078 ead9360e ths
            break;
5079 ead9360e ths
        case 10:
5080 ead9360e ths
            gen_op_mftacx(2);
5081 ead9360e ths
            break;
5082 ead9360e ths
        case 12:
5083 ead9360e ths
            gen_op_mftlo(3);
5084 ead9360e ths
            break;
5085 ead9360e ths
        case 13:
5086 ead9360e ths
            gen_op_mfthi(3);
5087 ead9360e ths
            break;
5088 ead9360e ths
        case 14:
5089 ead9360e ths
            gen_op_mftacx(3);
5090 ead9360e ths
            break;
5091 ead9360e ths
        case 16:
5092 ead9360e ths
            gen_op_mftdsp();
5093 ead9360e ths
            break;
5094 ead9360e ths
        default:
5095 ead9360e ths
            goto die;
5096 ead9360e ths
        }
5097 ead9360e ths
        break;
5098 ead9360e ths
    /* Floating point (COP1). */
5099 ead9360e ths
    case 2:
5100 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5101 ead9360e ths
        if (h == 0) {
5102 ead9360e ths
            GEN_LOAD_FREG_FTN(WT0, rt);
5103 ead9360e ths
            gen_op_mfc1();
5104 ead9360e ths
        } else {
5105 ead9360e ths
            GEN_LOAD_FREG_FTN(WTH0, rt);
5106 ead9360e ths
            gen_op_mfhc1();
5107 ead9360e ths
        }
5108 ead9360e ths
        break;
5109 ead9360e ths
    case 3:
5110 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5111 ead9360e ths
        gen_op_cfc1(rt);
5112 ead9360e ths
        break;
5113 ead9360e ths
    /* COP2: Not implemented. */
5114 ead9360e ths
    case 4:
5115 ead9360e ths
    case 5:
5116 ead9360e ths
        /* fall through */
5117 ead9360e ths
    default:
5118 ead9360e ths
        goto die;
5119 ead9360e ths
    }
5120 ead9360e ths
#if defined MIPS_DEBUG_DISAS
5121 ead9360e ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5122 ead9360e ths
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5123 ead9360e ths
                rt, u, sel, h);
5124 ead9360e ths
    }
5125 ead9360e ths
#endif
5126 ead9360e ths
    return;
5127 ead9360e ths
5128 ead9360e ths
die:
5129 ead9360e ths
#if defined MIPS_DEBUG_DISAS
5130 ead9360e ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5131 ead9360e ths
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5132 ead9360e ths
                rt, u, sel, h);
5133 ead9360e ths
    }
5134 ead9360e ths
#endif
5135 ead9360e ths
    generate_exception(ctx, EXCP_RI);
5136 ead9360e ths
}
5137 ead9360e ths
5138 ead9360e ths
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5139 ead9360e ths
                     int u, int sel, int h)
5140 ead9360e ths
{
5141 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5142 ead9360e ths
5143 ead9360e ths
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5144 ead9360e ths
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
5145 ead9360e ths
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
5146 ead9360e ths
        /* NOP */ ;
5147 ead9360e ths
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5148 ead9360e ths
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5149 ead9360e ths
        /* NOP */ ;
5150 ead9360e ths
    else if (u == 0) {
5151 ead9360e ths
        switch (rd) {
5152 ead9360e ths
        case 2:
5153 ead9360e ths
            switch (sel) {
5154 ead9360e ths
            case 1:
5155 ead9360e ths
                gen_op_mttc0_tcstatus();
5156 ead9360e ths
                break;
5157 ead9360e ths
            case 2:
5158 ead9360e ths
                gen_op_mttc0_tcbind();
5159 ead9360e ths
                break;
5160 ead9360e ths
            case 3:
5161 ead9360e ths
                gen_op_mttc0_tcrestart();
5162 ead9360e ths
                break;
5163 ead9360e ths
            case 4:
5164 ead9360e ths
                gen_op_mttc0_tchalt();
5165 ead9360e ths
                break;
5166 ead9360e ths
            case 5:
5167 ead9360e ths
                gen_op_mttc0_tccontext();
5168 ead9360e ths
                break;
5169 ead9360e ths
            case 6:
5170 ead9360e ths
                gen_op_mttc0_tcschedule();
5171 ead9360e ths
                break;
5172 ead9360e ths
            case 7:
5173 ead9360e ths
                gen_op_mttc0_tcschefback();
5174 ead9360e ths
                break;
5175 ead9360e ths
            default:
5176 ead9360e ths
                gen_mtc0(env, ctx, rd, sel);
5177 ead9360e ths
                break;
5178 ead9360e ths
            }
5179 ead9360e ths
            break;
5180 ead9360e ths
        case 10:
5181 ead9360e ths
            switch (sel) {
5182 ead9360e ths
            case 0:
5183 ead9360e ths
                gen_op_mttc0_entryhi();
5184 ead9360e ths
                break;
5185 ead9360e ths
            default:
5186 ead9360e ths
                gen_mtc0(env, ctx, rd, sel);
5187 ead9360e ths
                break;
5188 ead9360e ths
            }
5189 ead9360e ths
        case 12:
5190 ead9360e ths
            switch (sel) {
5191 ead9360e ths
            case 0:
5192 ead9360e ths
                gen_op_mttc0_status();
5193 ead9360e ths
                break;
5194 ead9360e ths
            default:
5195 ead9360e ths
                gen_mtc0(env, ctx, rd, sel);
5196 ead9360e ths
                break;
5197 ead9360e ths
            }
5198 ead9360e ths
        case 23:
5199 ead9360e ths
            switch (sel) {
5200 ead9360e ths
            case 0:
5201 ead9360e ths
                gen_op_mttc0_debug();
5202 ead9360e ths
                break;
5203 ead9360e ths
            default:
5204 ead9360e ths
                gen_mtc0(env, ctx, rd, sel);
5205 ead9360e ths
                break;
5206 ead9360e ths
            }
5207 ead9360e ths
            break;
5208 ead9360e ths
        default:
5209 ead9360e ths
            gen_mtc0(env, ctx, rd, sel);
5210 ead9360e ths
        }
5211 ead9360e ths
    } else switch (sel) {
5212 ead9360e ths
    /* GPR registers. */
5213 ead9360e ths
    case 0:
5214 ead9360e ths
        gen_op_mttgpr(rd);
5215 ead9360e ths
        break;
5216 ead9360e ths
    /* Auxiliary CPU registers */
5217 ead9360e ths
    case 1:
5218 ead9360e ths
        switch (rd) {
5219 ead9360e ths
        case 0:
5220 ead9360e ths
            gen_op_mttlo(0);
5221 ead9360e ths
            break;
5222 ead9360e ths
        case 1:
5223 ead9360e ths
            gen_op_mtthi(0);
5224 ead9360e ths
            break;
5225 ead9360e ths
        case 2:
5226 ead9360e ths
            gen_op_mttacx(0);
5227 ead9360e ths
            break;
5228 ead9360e ths
        case 4:
5229 ead9360e ths
            gen_op_mttlo(1);
5230 ead9360e ths
            break;
5231 ead9360e ths
        case 5:
5232 ead9360e ths
            gen_op_mtthi(1);
5233 ead9360e ths
            break;
5234 ead9360e ths
        case 6:
5235 ead9360e ths
            gen_op_mttacx(1);
5236 ead9360e ths
            break;
5237 ead9360e ths
        case 8:
5238 ead9360e ths
            gen_op_mttlo(2);
5239 ead9360e ths
            break;
5240 ead9360e ths
        case 9:
5241 ead9360e ths
            gen_op_mtthi(2);
5242 ead9360e ths
            break;
5243 ead9360e ths
        case 10:
5244 ead9360e ths
            gen_op_mttacx(2);
5245 ead9360e ths
            break;
5246 ead9360e ths
        case 12:
5247 ead9360e ths
            gen_op_mttlo(3);
5248 ead9360e ths
            break;
5249 ead9360e ths
        case 13:
5250 ead9360e ths
            gen_op_mtthi(3);
5251 ead9360e ths
            break;
5252 ead9360e ths
        case 14:
5253 ead9360e ths
            gen_op_mttacx(3);
5254 ead9360e ths
            break;
5255 ead9360e ths
        case 16:
5256 ead9360e ths
            gen_op_mttdsp();
5257 ead9360e ths
            break;
5258 ead9360e ths
        default:
5259 ead9360e ths
            goto die;
5260 ead9360e ths
        }
5261 ead9360e ths
        break;
5262 ead9360e ths
    /* Floating point (COP1). */
5263 ead9360e ths
    case 2:
5264 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5265 ead9360e ths
        if (h == 0) {
5266 ead9360e ths
            gen_op_mtc1();
5267 ead9360e ths
            GEN_STORE_FTN_FREG(rd, WT0);
5268 ead9360e ths
        } else {
5269 ead9360e ths
            gen_op_mthc1();
5270 ead9360e ths
            GEN_STORE_FTN_FREG(rd, WTH0);
5271 ead9360e ths
        }
5272 ead9360e ths
        break;
5273 ead9360e ths
    case 3:
5274 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5275 ead9360e ths
        gen_op_ctc1(rd);
5276 ead9360e ths
        break;
5277 ead9360e ths
    /* COP2: Not implemented. */
5278 ead9360e ths
    case 4:
5279 ead9360e ths
    case 5:
5280 ead9360e ths
        /* fall through */
5281 ead9360e ths
    default:
5282 ead9360e ths
        goto die;
5283 ead9360e ths
    }
5284 ead9360e ths
#if defined MIPS_DEBUG_DISAS
5285 ead9360e ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5286 ead9360e ths
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5287 ead9360e ths
                rd, u, sel, h);
5288 ead9360e ths
    }
5289 ead9360e ths
#endif
5290 ead9360e ths
    return;
5291 ead9360e ths
5292 ead9360e ths
die:
5293 ead9360e ths
#if defined MIPS_DEBUG_DISAS
5294 ead9360e ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5295 ead9360e ths
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5296 ead9360e ths
                rd, u, sel, h);
5297 ead9360e ths
    }
5298 ead9360e ths
#endif
5299 ead9360e ths
    generate_exception(ctx, EXCP_RI);
5300 ead9360e ths
}
5301 ead9360e ths
5302 29929e34 ths
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5303 6af0bf9c bellard
{
5304 287c4b84 ths
    const char *opn = "ldst";
5305 6af0bf9c bellard
5306 6af0bf9c bellard
    switch (opc) {
5307 6af0bf9c bellard
    case OPC_MFC0:
5308 6af0bf9c bellard
        if (rt == 0) {
5309 ead9360e ths
            /* Treat as NOP. */
5310 6af0bf9c bellard
            return;
5311 6af0bf9c bellard
        }
5312 3a95e3a7 ths
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
5313 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5314 6af0bf9c bellard
        opn = "mfc0";
5315 6af0bf9c bellard
        break;
5316 6af0bf9c bellard
    case OPC_MTC0:
5317 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5318 387a8fe5 ths
        save_cpu_state(ctx, 1);
5319 3a95e3a7 ths
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
5320 6af0bf9c bellard
        opn = "mtc0";
5321 6af0bf9c bellard
        break;
5322 d26bc211 ths
#if defined(TARGET_MIPS64)
5323 9c2149c8 ths
    case OPC_DMFC0:
5324 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
5325 9c2149c8 ths
        if (rt == 0) {
5326 ead9360e ths
            /* Treat as NOP. */
5327 9c2149c8 ths
            return;
5328 9c2149c8 ths
        }
5329 3a95e3a7 ths
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
5330 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5331 9c2149c8 ths
        opn = "dmfc0";
5332 9c2149c8 ths
        break;
5333 9c2149c8 ths
    case OPC_DMTC0:
5334 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
5335 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5336 387a8fe5 ths
        save_cpu_state(ctx, 1);
5337 ead9360e ths
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
5338 9c2149c8 ths
        opn = "dmtc0";
5339 9c2149c8 ths
        break;
5340 534ce69f ths
#endif
5341 ead9360e ths
    case OPC_MFTR:
5342 7385ac0b ths
        check_insn(env, ctx, ASE_MT);
5343 ead9360e ths
        if (rd == 0) {
5344 ead9360e ths
            /* Treat as NOP. */
5345 ead9360e ths
            return;
5346 ead9360e ths
        }
5347 ead9360e ths
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
5348 ead9360e ths
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5349 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rd);
5350 ead9360e ths
        opn = "mftr";
5351 ead9360e ths
        break;
5352 ead9360e ths
    case OPC_MTTR:
5353 7385ac0b ths
        check_insn(env, ctx, ASE_MT);
5354 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5355 ead9360e ths
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
5356 ead9360e ths
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5357 ead9360e ths
        opn = "mttr";
5358 ead9360e ths
        break;
5359 6af0bf9c bellard
    case OPC_TLBWI:
5360 6af0bf9c bellard
        opn = "tlbwi";
5361 ead9360e ths
        if (!env->tlb->do_tlbwi)
5362 29929e34 ths
            goto die;
5363 29929e34 ths
        gen_op_tlbwi();
5364 6af0bf9c bellard
        break;
5365 6af0bf9c bellard
    case OPC_TLBWR:
5366 6af0bf9c bellard
        opn = "tlbwr";
5367 ead9360e ths
        if (!env->tlb->do_tlbwr)
5368 29929e34 ths
            goto die;
5369 29929e34 ths
        gen_op_tlbwr();
5370 6af0bf9c bellard
        break;
5371 6af0bf9c bellard
    case OPC_TLBP:
5372 6af0bf9c bellard
        opn = "tlbp";
5373 ead9360e ths
        if (!env->tlb->do_tlbp)
5374 29929e34 ths
            goto die;
5375 29929e34 ths
        gen_op_tlbp();
5376 6af0bf9c bellard
        break;
5377 6af0bf9c bellard
    case OPC_TLBR:
5378 6af0bf9c bellard
        opn = "tlbr";
5379 ead9360e ths
        if (!env->tlb->do_tlbr)
5380 29929e34 ths
            goto die;
5381 29929e34 ths
        gen_op_tlbr();
5382 6af0bf9c bellard
        break;
5383 6af0bf9c bellard
    case OPC_ERET:
5384 6af0bf9c bellard
        opn = "eret";
5385 e189e748 ths
        check_insn(env, ctx, ISA_MIPS2);
5386 387a8fe5 ths
        save_cpu_state(ctx, 1);
5387 6af0bf9c bellard
        gen_op_eret();
5388 6af0bf9c bellard
        ctx->bstate = BS_EXCP;
5389 6af0bf9c bellard
        break;
5390 6af0bf9c bellard
    case OPC_DERET:
5391 6af0bf9c bellard
        opn = "deret";
5392 e189e748 ths
        check_insn(env, ctx, ISA_MIPS32);
5393 6af0bf9c bellard
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5394 923617a3 ths
            MIPS_INVAL(opn);
5395 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
5396 6af0bf9c bellard
        } else {
5397 387a8fe5 ths
            save_cpu_state(ctx, 1);
5398 6af0bf9c bellard
            gen_op_deret();
5399 6af0bf9c bellard
            ctx->bstate = BS_EXCP;
5400 6af0bf9c bellard
        }
5401 6af0bf9c bellard
        break;
5402 4ad40f36 bellard
    case OPC_WAIT:
5403 4ad40f36 bellard
        opn = "wait";
5404 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5405 4ad40f36 bellard
        /* If we get an exception, we want to restart at next instruction */
5406 4ad40f36 bellard
        ctx->pc += 4;
5407 4ad40f36 bellard
        save_cpu_state(ctx, 1);
5408 4ad40f36 bellard
        ctx->pc -= 4;
5409 4ad40f36 bellard
        gen_op_wait();
5410 4ad40f36 bellard
        ctx->bstate = BS_EXCP;
5411 4ad40f36 bellard
        break;
5412 6af0bf9c bellard
    default:
5413 29929e34 ths
 die:
5414 923617a3 ths
        MIPS_INVAL(opn);
5415 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
5416 6af0bf9c bellard
        return;
5417 6af0bf9c bellard
    }
5418 6af0bf9c bellard
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5419 6af0bf9c bellard
}
5420 6af0bf9c bellard
5421 6ea83fed bellard
/* CP1 Branches (before delay slot) */
5422 e189e748 ths
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5423 5a5012ec ths
                                 int32_t cc, int32_t offset)
5424 6ea83fed bellard
{
5425 6ea83fed bellard
    target_ulong btarget;
5426 923617a3 ths
    const char *opn = "cp1 cond branch";
5427 6ea83fed bellard
5428 e189e748 ths
    if (cc != 0)
5429 e189e748 ths
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5430 e189e748 ths
5431 6ea83fed bellard
    btarget = ctx->pc + 4 + offset;
5432 6ea83fed bellard
5433 7a387fff ths
    switch (op) {
5434 7a387fff ths
    case OPC_BC1F:
5435 5a5012ec ths
        gen_op_bc1f(cc);
5436 923617a3 ths
        opn = "bc1f";
5437 6ea83fed bellard
        goto not_likely;
5438 7a387fff ths
    case OPC_BC1FL:
5439 5a5012ec ths
        gen_op_bc1f(cc);
5440 923617a3 ths
        opn = "bc1fl";
5441 6ea83fed bellard
        goto likely;
5442 7a387fff ths
    case OPC_BC1T:
5443 5a5012ec ths
        gen_op_bc1t(cc);
5444 923617a3 ths
        opn = "bc1t";
5445 5a5012ec ths
        goto not_likely;
5446 7a387fff ths
    case OPC_BC1TL:
5447 5a5012ec ths
        gen_op_bc1t(cc);
5448 923617a3 ths
        opn = "bc1tl";
5449 6ea83fed bellard
    likely:
5450 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BL;
5451 8e9ade68 ths
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5452 6ea83fed bellard
        break;
5453 5a5012ec ths
    case OPC_BC1FANY2:
5454 fd4a04eb ths
        gen_op_bc1any2f(cc);
5455 fd4a04eb ths
        opn = "bc1any2f";
5456 5a5012ec ths
        goto not_likely;
5457 5a5012ec ths
    case OPC_BC1TANY2:
5458 fd4a04eb ths
        gen_op_bc1any2t(cc);
5459 fd4a04eb ths
        opn = "bc1any2t";
5460 5a5012ec ths
        goto not_likely;
5461 5a5012ec ths
    case OPC_BC1FANY4:
5462 fd4a04eb ths
        gen_op_bc1any4f(cc);
5463 fd4a04eb ths
        opn = "bc1any4f";
5464 5a5012ec ths
        goto not_likely;
5465 5a5012ec ths
    case OPC_BC1TANY4:
5466 fd4a04eb ths
        gen_op_bc1any4t(cc);
5467 fd4a04eb ths
        opn = "bc1any4t";
5468 5a5012ec ths
    not_likely:
5469 5a5012ec ths
        ctx->hflags |= MIPS_HFLAG_BC;
5470 8e9ade68 ths
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5471 5a5012ec ths
        break;
5472 5a5012ec ths
    default:
5473 923617a3 ths
        MIPS_INVAL(opn);
5474 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
5475 6ea83fed bellard
        return;
5476 6ea83fed bellard
    }
5477 923617a3 ths
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5478 6ea83fed bellard
               ctx->hflags, btarget);
5479 6ea83fed bellard
    ctx->btarget = btarget;
5480 6ea83fed bellard
}
5481 6ea83fed bellard
5482 6af0bf9c bellard
/* Coprocessor 1 (FPU) */
5483 5a5012ec ths
5484 5a5012ec ths
#define FOP(func, fmt) (((fmt) << 21) | (func))
5485 5a5012ec ths
5486 7a387fff ths
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5487 6ea83fed bellard
{
5488 923617a3 ths
    const char *opn = "cp1 move";
5489 6ea83fed bellard
5490 6ea83fed bellard
    switch (opc) {
5491 6ea83fed bellard
    case OPC_MFC1:
5492 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
5493 6ea83fed bellard
        gen_op_mfc1();
5494 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5495 6ea83fed bellard
        opn = "mfc1";
5496 6ea83fed bellard
        break;
5497 6ea83fed bellard
    case OPC_MTC1:
5498 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5499 6ea83fed bellard
        gen_op_mtc1();
5500 6ea83fed bellard
        GEN_STORE_FTN_FREG(fs, WT0);
5501 6ea83fed bellard
        opn = "mtc1";
5502 6ea83fed bellard
        break;
5503 6ea83fed bellard
    case OPC_CFC1:
5504 ead9360e ths
        gen_op_cfc1(fs);
5505 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5506 6ea83fed bellard
        opn = "cfc1";
5507 6ea83fed bellard
        break;
5508 6ea83fed bellard
    case OPC_CTC1:
5509 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5510 ead9360e ths
        gen_op_ctc1(fs);
5511 6ea83fed bellard
        opn = "ctc1";
5512 6ea83fed bellard
        break;
5513 9c2149c8 ths
    case OPC_DMFC1:
5514 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5515 5a5012ec ths
        gen_op_dmfc1();
5516 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5517 5a5012ec ths
        opn = "dmfc1";
5518 5a5012ec ths
        break;
5519 9c2149c8 ths
    case OPC_DMTC1:
5520 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5521 5a5012ec ths
        gen_op_dmtc1();
5522 5a5012ec ths
        GEN_STORE_FTN_FREG(fs, DT0);
5523 5a5012ec ths
        opn = "dmtc1";
5524 5a5012ec ths
        break;
5525 5a5012ec ths
    case OPC_MFHC1:
5526 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
5527 5a5012ec ths
        gen_op_mfhc1();
5528 8e9ade68 ths
        gen_store_gpr(cpu_T[0], rt);
5529 5a5012ec ths
        opn = "mfhc1";
5530 5a5012ec ths
        break;
5531 5a5012ec ths
    case OPC_MTHC1:
5532 8e9ade68 ths
        gen_load_gpr(cpu_T[0], rt);
5533 5a5012ec ths
        gen_op_mthc1();
5534 5a5012ec ths
        GEN_STORE_FTN_FREG(fs, WTH0);
5535 5a5012ec ths
        opn = "mthc1";
5536 5a5012ec ths
        break;
5537 6ea83fed bellard
    default:
5538 923617a3 ths
        MIPS_INVAL(opn);
5539 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
5540 6ea83fed bellard
        return;
5541 6ea83fed bellard
    }
5542 6ea83fed bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5543 6ea83fed bellard
}
5544 6ea83fed bellard
5545 5a5012ec ths
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5546 5a5012ec ths
{
5547 e214b9bb ths
    int l1 = gen_new_label();
5548 5a5012ec ths
    uint32_t ccbit;
5549 e214b9bb ths
    TCGCond cond;
5550 6ea83fed bellard
5551 e214b9bb ths
    if (cc)
5552 5a5012ec ths
        ccbit = 1 << (24 + cc);
5553 e214b9bb ths
    else
5554 5a5012ec ths
        ccbit = 1 << 23;
5555 e214b9bb ths
    if (tf)
5556 e214b9bb ths
        cond = TCG_COND_EQ;
5557 27848470 ths
    else
5558 27848470 ths
        cond = TCG_COND_NE;
5559 27848470 ths
5560 27848470 ths
    gen_load_gpr(cpu_T[0], rd);
5561 27848470 ths
    gen_load_gpr(cpu_T[1], rs);
5562 27848470 ths
    {
5563 27848470 ths
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5564 27848470 ths
        TCGv r_tmp = new_tmp();
5565 27848470 ths
5566 27848470 ths
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5567 27848470 ths
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5568 27848470 ths
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5569 27848470 ths
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5570 27848470 ths
        dead_tmp(r_tmp);
5571 27848470 ths
    }
5572 27848470 ths
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
5573 e214b9bb ths
5574 e214b9bb ths
    gen_set_label(l1);
5575 27848470 ths
    gen_store_gpr(cpu_T[0], rd);
5576 5a5012ec ths
}
5577 5a5012ec ths
5578 5a5012ec ths
#define GEN_MOVCF(fmt)                                                \
5579 5a5012ec ths
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5580 5a5012ec ths
{                                                                     \
5581 5a5012ec ths
    uint32_t ccbit;                                                   \
5582 5a5012ec ths
                                                                      \
5583 57fa1fb3 ths
    if (cc) {                                                         \
5584 5a5012ec ths
        ccbit = 1 << (24 + cc);                                       \
5585 57fa1fb3 ths
    } else                                                            \
5586 5a5012ec ths
        ccbit = 1 << 23;                                              \
5587 5a5012ec ths
    if (!tf)                                                          \
5588 5a5012ec ths
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5589 5a5012ec ths
    else                                                              \
5590 5a5012ec ths
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5591 5a5012ec ths
}
5592 5a5012ec ths
GEN_MOVCF(d);
5593 5a5012ec ths
GEN_MOVCF(s);
5594 5a5012ec ths
#undef GEN_MOVCF
5595 6ea83fed bellard
5596 5e755519 ths
static void gen_farith (DisasContext *ctx, uint32_t op1,
5597 5e755519 ths
                        int ft, int fs, int fd, int cc)
5598 6ea83fed bellard
{
5599 923617a3 ths
    const char *opn = "farith";
5600 6ea83fed bellard
    const char *condnames[] = {
5601 6ea83fed bellard
            "c.f",
5602 6ea83fed bellard
            "c.un",
5603 6ea83fed bellard
            "c.eq",
5604 6ea83fed bellard
            "c.ueq",
5605 6ea83fed bellard
            "c.olt",
5606 6ea83fed bellard
            "c.ult",
5607 6ea83fed bellard
            "c.ole",
5608 6ea83fed bellard
            "c.ule",
5609 6ea83fed bellard
            "c.sf",
5610 6ea83fed bellard
            "c.ngle",
5611 6ea83fed bellard
            "c.seq",
5612 6ea83fed bellard
            "c.ngl",
5613 6ea83fed bellard
            "c.lt",
5614 6ea83fed bellard
            "c.nge",
5615 6ea83fed bellard
            "c.le",
5616 6ea83fed bellard
            "c.ngt",
5617 6ea83fed bellard
    };
5618 5a1e8ffb ths
    const char *condnames_abs[] = {
5619 5a1e8ffb ths
            "cabs.f",
5620 5a1e8ffb ths
            "cabs.un",
5621 5a1e8ffb ths
            "cabs.eq",
5622 5a1e8ffb ths
            "cabs.ueq",
5623 5a1e8ffb ths
            "cabs.olt",
5624 5a1e8ffb ths
            "cabs.ult",
5625 5a1e8ffb ths
            "cabs.ole",
5626 5a1e8ffb ths
            "cabs.ule",
5627 5a1e8ffb ths
            "cabs.sf",
5628 5a1e8ffb ths
            "cabs.ngle",
5629 5a1e8ffb ths
            "cabs.seq",
5630 5a1e8ffb ths
            "cabs.ngl",
5631 5a1e8ffb ths
            "cabs.lt",
5632 5a1e8ffb ths
            "cabs.nge",
5633 5a1e8ffb ths
            "cabs.le",
5634 5a1e8ffb ths
            "cabs.ngt",
5635 5a1e8ffb ths
    };
5636 5a1e8ffb ths
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5637 7a387fff ths
    uint32_t func = ctx->opcode & 0x3f;
5638 7a387fff ths
5639 6ea83fed bellard
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5640 5a5012ec ths
    case FOP(0, 16):
5641 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5642 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5643 5a5012ec ths
        gen_op_float_add_s();
5644 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5645 5a5012ec ths
        opn = "add.s";
5646 5a1e8ffb ths
        optype = BINOP;
5647 5a5012ec ths
        break;
5648 5a5012ec ths
    case FOP(1, 16):
5649 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5650 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5651 5a5012ec ths
        gen_op_float_sub_s();
5652 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5653 5a5012ec ths
        opn = "sub.s";
5654 5a1e8ffb ths
        optype = BINOP;
5655 5a5012ec ths
        break;
5656 5a5012ec ths
    case FOP(2, 16):
5657 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5658 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5659 5a5012ec ths
        gen_op_float_mul_s();
5660 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5661 5a5012ec ths
        opn = "mul.s";
5662 5a1e8ffb ths
        optype = BINOP;
5663 5a5012ec ths
        break;
5664 5a5012ec ths
    case FOP(3, 16):
5665 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5666 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5667 5a5012ec ths
        gen_op_float_div_s();
5668 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5669 5a5012ec ths
        opn = "div.s";
5670 5a1e8ffb ths
        optype = BINOP;
5671 5a5012ec ths
        break;
5672 5a5012ec ths
    case FOP(4, 16):
5673 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5674 5a5012ec ths
        gen_op_float_sqrt_s();
5675 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5676 5a5012ec ths
        opn = "sqrt.s";
5677 5a5012ec ths
        break;
5678 5a5012ec ths
    case FOP(5, 16):
5679 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5680 5a5012ec ths
        gen_op_float_abs_s();
5681 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5682 5a5012ec ths
        opn = "abs.s";
5683 5a5012ec ths
        break;
5684 5a5012ec ths
    case FOP(6, 16):
5685 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5686 5a5012ec ths
        gen_op_float_mov_s();
5687 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5688 5a5012ec ths
        opn = "mov.s";
5689 5a5012ec ths
        break;
5690 5a5012ec ths
    case FOP(7, 16):
5691 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5692 5a5012ec ths
        gen_op_float_chs_s();
5693 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5694 5a5012ec ths
        opn = "neg.s";
5695 5a5012ec ths
        break;
5696 5a5012ec ths
    case FOP(8, 16):
5697 5e755519 ths
        check_cp1_64bitmode(ctx);
5698 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5699 5a5012ec ths
        gen_op_float_roundl_s();
5700 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5701 5a5012ec ths
        opn = "round.l.s";
5702 5a5012ec ths
        break;
5703 5a5012ec ths
    case FOP(9, 16):
5704 5e755519 ths
        check_cp1_64bitmode(ctx);
5705 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5706 5a5012ec ths
        gen_op_float_truncl_s();
5707 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5708 5a5012ec ths
        opn = "trunc.l.s";
5709 5a5012ec ths
        break;
5710 5a5012ec ths
    case FOP(10, 16):
5711 5e755519 ths
        check_cp1_64bitmode(ctx);
5712 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5713 5a5012ec ths
        gen_op_float_ceill_s();
5714 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5715 5a5012ec ths
        opn = "ceil.l.s";
5716 5a5012ec ths
        break;
5717 5a5012ec ths
    case FOP(11, 16):
5718 5e755519 ths
        check_cp1_64bitmode(ctx);
5719 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5720 5a5012ec ths
        gen_op_float_floorl_s();
5721 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5722 5a5012ec ths
        opn = "floor.l.s";
5723 5a5012ec ths
        break;
5724 5a5012ec ths
    case FOP(12, 16):
5725 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5726 5a5012ec ths
        gen_op_float_roundw_s();
5727 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5728 5a5012ec ths
        opn = "round.w.s";
5729 5a5012ec ths
        break;
5730 5a5012ec ths
    case FOP(13, 16):
5731 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5732 5a5012ec ths
        gen_op_float_truncw_s();
5733 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5734 5a5012ec ths
        opn = "trunc.w.s";
5735 5a5012ec ths
        break;
5736 5a5012ec ths
    case FOP(14, 16):
5737 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5738 5a5012ec ths
        gen_op_float_ceilw_s();
5739 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5740 5a5012ec ths
        opn = "ceil.w.s";
5741 5a5012ec ths
        break;
5742 5a5012ec ths
    case FOP(15, 16):
5743 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5744 5a5012ec ths
        gen_op_float_floorw_s();
5745 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5746 5a5012ec ths
        opn = "floor.w.s";
5747 5a5012ec ths
        break;
5748 5a5012ec ths
    case FOP(17, 16):
5749 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
5750 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5751 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
5752 5a5012ec ths
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5753 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5754 5a5012ec ths
        opn = "movcf.s";
5755 5a5012ec ths
        break;
5756 5a5012ec ths
    case FOP(18, 16):
5757 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
5758 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5759 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
5760 5a5012ec ths
        gen_op_float_movz_s();
5761 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5762 5a5012ec ths
        opn = "movz.s";
5763 5a5012ec ths
        break;
5764 5a5012ec ths
    case FOP(19, 16):
5765 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
5766 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5767 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
5768 5a5012ec ths
        gen_op_float_movn_s();
5769 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5770 5a5012ec ths
        opn = "movn.s";
5771 5a5012ec ths
        break;
5772 57fa1fb3 ths
    case FOP(21, 16):
5773 b8aa4598 ths
        check_cop1x(ctx);
5774 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5775 57fa1fb3 ths
        gen_op_float_recip_s();
5776 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5777 57fa1fb3 ths
        opn = "recip.s";
5778 57fa1fb3 ths
        break;
5779 57fa1fb3 ths
    case FOP(22, 16):
5780 b8aa4598 ths
        check_cop1x(ctx);
5781 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5782 57fa1fb3 ths
        gen_op_float_rsqrt_s();
5783 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5784 57fa1fb3 ths
        opn = "rsqrt.s";
5785 57fa1fb3 ths
        break;
5786 57fa1fb3 ths
    case FOP(28, 16):
5787 5e755519 ths
        check_cp1_64bitmode(ctx);
5788 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5789 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT2, fd);
5790 57fa1fb3 ths
        gen_op_float_recip2_s();
5791 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5792 57fa1fb3 ths
        opn = "recip2.s";
5793 57fa1fb3 ths
        break;
5794 57fa1fb3 ths
    case FOP(29, 16):
5795 5e755519 ths
        check_cp1_64bitmode(ctx);
5796 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5797 57fa1fb3 ths
        gen_op_float_recip1_s();
5798 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5799 57fa1fb3 ths
        opn = "recip1.s";
5800 57fa1fb3 ths
        break;
5801 57fa1fb3 ths
    case FOP(30, 16):
5802 5e755519 ths
        check_cp1_64bitmode(ctx);
5803 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5804 57fa1fb3 ths
        gen_op_float_rsqrt1_s();
5805 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5806 57fa1fb3 ths
        opn = "rsqrt1.s";
5807 57fa1fb3 ths
        break;
5808 57fa1fb3 ths
    case FOP(31, 16):
5809 5e755519 ths
        check_cp1_64bitmode(ctx);
5810 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5811 8dfdb87c ths
        GEN_LOAD_FREG_FTN(WT2, ft);
5812 57fa1fb3 ths
        gen_op_float_rsqrt2_s();
5813 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
5814 57fa1fb3 ths
        opn = "rsqrt2.s";
5815 57fa1fb3 ths
        break;
5816 5a5012ec ths
    case FOP(33, 16):
5817 5e755519 ths
        check_cp1_registers(ctx, fd);
5818 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5819 5a5012ec ths
        gen_op_float_cvtd_s();
5820 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5821 5a5012ec ths
        opn = "cvt.d.s";
5822 5a5012ec ths
        break;
5823 5a5012ec ths
    case FOP(36, 16):
5824 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5825 5a5012ec ths
        gen_op_float_cvtw_s();
5826 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
5827 5a5012ec ths
        opn = "cvt.w.s";
5828 5a5012ec ths
        break;
5829 5a5012ec ths
    case FOP(37, 16):
5830 5e755519 ths
        check_cp1_64bitmode(ctx);
5831 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5832 5a5012ec ths
        gen_op_float_cvtl_s();
5833 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5834 5a5012ec ths
        opn = "cvt.l.s";
5835 5a5012ec ths
        break;
5836 5a5012ec ths
    case FOP(38, 16):
5837 5e755519 ths
        check_cp1_64bitmode(ctx);
5838 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, fs);
5839 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, ft);
5840 5a5012ec ths
        gen_op_float_cvtps_s();
5841 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5842 5a5012ec ths
        opn = "cvt.ps.s";
5843 5a5012ec ths
        break;
5844 5a5012ec ths
    case FOP(48, 16):
5845 5a5012ec ths
    case FOP(49, 16):
5846 5a5012ec ths
    case FOP(50, 16):
5847 5a5012ec ths
    case FOP(51, 16):
5848 5a5012ec ths
    case FOP(52, 16):
5849 5a5012ec ths
    case FOP(53, 16):
5850 5a5012ec ths
    case FOP(54, 16):
5851 5a5012ec ths
    case FOP(55, 16):
5852 5a5012ec ths
    case FOP(56, 16):
5853 5a5012ec ths
    case FOP(57, 16):
5854 5a5012ec ths
    case FOP(58, 16):
5855 5a5012ec ths
    case FOP(59, 16):
5856 5a5012ec ths
    case FOP(60, 16):
5857 5a5012ec ths
    case FOP(61, 16):
5858 5a5012ec ths
    case FOP(62, 16):
5859 5a5012ec ths
    case FOP(63, 16):
5860 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
5861 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
5862 5a1e8ffb ths
        if (ctx->opcode & (1 << 6)) {
5863 b8aa4598 ths
            check_cop1x(ctx);
5864 5a1e8ffb ths
            gen_cmpabs_s(func-48, cc);
5865 5a1e8ffb ths
            opn = condnames_abs[func-48];
5866 5a1e8ffb ths
        } else {
5867 5a1e8ffb ths
            gen_cmp_s(func-48, cc);
5868 5a1e8ffb ths
            opn = condnames[func-48];
5869 5a1e8ffb ths
        }
5870 5a5012ec ths
        break;
5871 6ea83fed bellard
    case FOP(0, 17):
5872 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
5873 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5874 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
5875 6ea83fed bellard
        gen_op_float_add_d();
5876 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5877 6ea83fed bellard
        opn = "add.d";
5878 5a1e8ffb ths
        optype = BINOP;
5879 6ea83fed bellard
        break;
5880 6ea83fed bellard
    case FOP(1, 17):
5881 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
5882 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5883 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
5884 6ea83fed bellard
        gen_op_float_sub_d();
5885 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5886 6ea83fed bellard
        opn = "sub.d";
5887 5a1e8ffb ths
        optype = BINOP;
5888 6ea83fed bellard
        break;
5889 6ea83fed bellard
    case FOP(2, 17):
5890 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
5891 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5892 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
5893 6ea83fed bellard
        gen_op_float_mul_d();
5894 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5895 6ea83fed bellard
        opn = "mul.d";
5896 5a1e8ffb ths
        optype = BINOP;
5897 6ea83fed bellard
        break;
5898 6ea83fed bellard
    case FOP(3, 17):
5899 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
5900 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5901 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
5902 6ea83fed bellard
        gen_op_float_div_d();
5903 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5904 6ea83fed bellard
        opn = "div.d";
5905 5a1e8ffb ths
        optype = BINOP;
5906 6ea83fed bellard
        break;
5907 6ea83fed bellard
    case FOP(4, 17):
5908 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
5909 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5910 6ea83fed bellard
        gen_op_float_sqrt_d();
5911 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5912 6ea83fed bellard
        opn = "sqrt.d";
5913 6ea83fed bellard
        break;
5914 6ea83fed bellard
    case FOP(5, 17):
5915 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
5916 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5917 6ea83fed bellard
        gen_op_float_abs_d();
5918 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5919 6ea83fed bellard
        opn = "abs.d";
5920 6ea83fed bellard
        break;
5921 6ea83fed bellard
    case FOP(6, 17):
5922 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
5923 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5924 6ea83fed bellard
        gen_op_float_mov_d();
5925 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5926 6ea83fed bellard
        opn = "mov.d";
5927 6ea83fed bellard
        break;
5928 6ea83fed bellard
    case FOP(7, 17):
5929 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
5930 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5931 6ea83fed bellard
        gen_op_float_chs_d();
5932 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5933 6ea83fed bellard
        opn = "neg.d";
5934 6ea83fed bellard
        break;
5935 5a5012ec ths
    case FOP(8, 17):
5936 5e755519 ths
        check_cp1_64bitmode(ctx);
5937 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5938 5a5012ec ths
        gen_op_float_roundl_d();
5939 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5940 5a5012ec ths
        opn = "round.l.d";
5941 5a5012ec ths
        break;
5942 5a5012ec ths
    case FOP(9, 17):
5943 5e755519 ths
        check_cp1_64bitmode(ctx);
5944 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5945 5a5012ec ths
        gen_op_float_truncl_d();
5946 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5947 5a5012ec ths
        opn = "trunc.l.d";
5948 5a5012ec ths
        break;
5949 5a5012ec ths
    case FOP(10, 17):
5950 5e755519 ths
        check_cp1_64bitmode(ctx);
5951 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5952 5a5012ec ths
        gen_op_float_ceill_d();
5953 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5954 5a5012ec ths
        opn = "ceil.l.d";
5955 5a5012ec ths
        break;
5956 5a5012ec ths
    case FOP(11, 17):
5957 5e755519 ths
        check_cp1_64bitmode(ctx);
5958 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5959 5a5012ec ths
        gen_op_float_floorl_d();
5960 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
5961 5a5012ec ths
        opn = "floor.l.d";
5962 5a5012ec ths
        break;
5963 6ea83fed bellard
    case FOP(12, 17):
5964 5e755519 ths
        check_cp1_registers(ctx, fs);
5965 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5966 6ea83fed bellard
        gen_op_float_roundw_d();
5967 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5968 6ea83fed bellard
        opn = "round.w.d";
5969 6ea83fed bellard
        break;
5970 6ea83fed bellard
    case FOP(13, 17):
5971 5e755519 ths
        check_cp1_registers(ctx, fs);
5972 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5973 6ea83fed bellard
        gen_op_float_truncw_d();
5974 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5975 6ea83fed bellard
        opn = "trunc.w.d";
5976 6ea83fed bellard
        break;
5977 6ea83fed bellard
    case FOP(14, 17):
5978 5e755519 ths
        check_cp1_registers(ctx, fs);
5979 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5980 6ea83fed bellard
        gen_op_float_ceilw_d();
5981 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5982 6ea83fed bellard
        opn = "ceil.w.d";
5983 6ea83fed bellard
        break;
5984 6ea83fed bellard
    case FOP(15, 17):
5985 5e755519 ths
        check_cp1_registers(ctx, fs);
5986 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
5987 6ea83fed bellard
        gen_op_float_floorw_d();
5988 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
5989 7a387fff ths
        opn = "floor.w.d";
5990 6ea83fed bellard
        break;
5991 5a5012ec ths
    case FOP(17, 17):
5992 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
5993 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
5994 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT2, fd);
5995 5a5012ec ths
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5996 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, DT2);
5997 5a5012ec ths
        opn = "movcf.d";
5998 dd016883 bellard
        break;
5999 5a5012ec ths
    case FOP(18, 17):
6000 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6001 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6002 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT2, fd);
6003 5a5012ec ths
        gen_op_float_movz_d();
6004 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
6005 5a5012ec ths
        opn = "movz.d";
6006 5a5012ec ths
        break;
6007 5a5012ec ths
    case FOP(19, 17):
6008 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6009 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6010 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT2, fd);
6011 5a5012ec ths
        gen_op_float_movn_d();
6012 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6013 5a5012ec ths
        opn = "movn.d";
6014 6ea83fed bellard
        break;
6015 57fa1fb3 ths
    case FOP(21, 17):
6016 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6017 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6018 57fa1fb3 ths
        gen_op_float_recip_d();
6019 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6020 57fa1fb3 ths
        opn = "recip.d";
6021 57fa1fb3 ths
        break;
6022 57fa1fb3 ths
    case FOP(22, 17):
6023 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6024 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6025 57fa1fb3 ths
        gen_op_float_rsqrt_d();
6026 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6027 57fa1fb3 ths
        opn = "rsqrt.d";
6028 57fa1fb3 ths
        break;
6029 57fa1fb3 ths
    case FOP(28, 17):
6030 5e755519 ths
        check_cp1_64bitmode(ctx);
6031 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6032 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT2, ft);
6033 57fa1fb3 ths
        gen_op_float_recip2_d();
6034 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6035 57fa1fb3 ths
        opn = "recip2.d";
6036 57fa1fb3 ths
        break;
6037 57fa1fb3 ths
    case FOP(29, 17):
6038 5e755519 ths
        check_cp1_64bitmode(ctx);
6039 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6040 57fa1fb3 ths
        gen_op_float_recip1_d();
6041 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6042 57fa1fb3 ths
        opn = "recip1.d";
6043 57fa1fb3 ths
        break;
6044 57fa1fb3 ths
    case FOP(30, 17):
6045 5e755519 ths
        check_cp1_64bitmode(ctx);
6046 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6047 57fa1fb3 ths
        gen_op_float_rsqrt1_d();
6048 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6049 57fa1fb3 ths
        opn = "rsqrt1.d";
6050 57fa1fb3 ths
        break;
6051 57fa1fb3 ths
    case FOP(31, 17):
6052 5e755519 ths
        check_cp1_64bitmode(ctx);
6053 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6054 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(DT2, ft);
6055 57fa1fb3 ths
        gen_op_float_rsqrt2_d();
6056 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6057 57fa1fb3 ths
        opn = "rsqrt2.d";
6058 57fa1fb3 ths
        break;
6059 6ea83fed bellard
    case FOP(48, 17):
6060 6ea83fed bellard
    case FOP(49, 17):
6061 6ea83fed bellard
    case FOP(50, 17):
6062 6ea83fed bellard
    case FOP(51, 17):
6063 6ea83fed bellard
    case FOP(52, 17):
6064 6ea83fed bellard
    case FOP(53, 17):
6065 6ea83fed bellard
    case FOP(54, 17):
6066 6ea83fed bellard
    case FOP(55, 17):
6067 6ea83fed bellard
    case FOP(56, 17):
6068 6ea83fed bellard
    case FOP(57, 17):
6069 6ea83fed bellard
    case FOP(58, 17):
6070 6ea83fed bellard
    case FOP(59, 17):
6071 6ea83fed bellard
    case FOP(60, 17):
6072 6ea83fed bellard
    case FOP(61, 17):
6073 6ea83fed bellard
    case FOP(62, 17):
6074 6ea83fed bellard
    case FOP(63, 17):
6075 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
6076 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
6077 5a1e8ffb ths
        if (ctx->opcode & (1 << 6)) {
6078 b8aa4598 ths
            check_cop1x(ctx);
6079 b8aa4598 ths
            check_cp1_registers(ctx, fs | ft);
6080 5a1e8ffb ths
            gen_cmpabs_d(func-48, cc);
6081 5a1e8ffb ths
            opn = condnames_abs[func-48];
6082 5a1e8ffb ths
        } else {
6083 5e755519 ths
            check_cp1_registers(ctx, fs | ft);
6084 5a1e8ffb ths
            gen_cmp_d(func-48, cc);
6085 5a1e8ffb ths
            opn = condnames[func-48];
6086 5a1e8ffb ths
        }
6087 6ea83fed bellard
        break;
6088 5a5012ec ths
    case FOP(32, 17):
6089 5e755519 ths
        check_cp1_registers(ctx, fs);
6090 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6091 5a5012ec ths
        gen_op_float_cvts_d();
6092 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6093 5a5012ec ths
        opn = "cvt.s.d";
6094 5a5012ec ths
        break;
6095 5a5012ec ths
    case FOP(36, 17):
6096 5e755519 ths
        check_cp1_registers(ctx, fs);
6097 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6098 5a5012ec ths
        gen_op_float_cvtw_d();
6099 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6100 5a5012ec ths
        opn = "cvt.w.d";
6101 5a5012ec ths
        break;
6102 5a5012ec ths
    case FOP(37, 17):
6103 5e755519 ths
        check_cp1_64bitmode(ctx);
6104 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6105 5a5012ec ths
        gen_op_float_cvtl_d();
6106 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6107 5a5012ec ths
        opn = "cvt.l.d";
6108 5a5012ec ths
        break;
6109 5a5012ec ths
    case FOP(32, 20):
6110 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6111 5a5012ec ths
        gen_op_float_cvts_w();
6112 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6113 5a5012ec ths
        opn = "cvt.s.w";
6114 6ea83fed bellard
        break;
6115 5a5012ec ths
    case FOP(33, 20):
6116 5e755519 ths
        check_cp1_registers(ctx, fd);
6117 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6118 5a5012ec ths
        gen_op_float_cvtd_w();
6119 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6120 5a5012ec ths
        opn = "cvt.d.w";
6121 5a5012ec ths
        break;
6122 5a5012ec ths
    case FOP(32, 21):
6123 5e755519 ths
        check_cp1_64bitmode(ctx);
6124 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6125 5a5012ec ths
        gen_op_float_cvts_l();
6126 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6127 5a5012ec ths
        opn = "cvt.s.l";
6128 5a5012ec ths
        break;
6129 5a5012ec ths
    case FOP(33, 21):
6130 5e755519 ths
        check_cp1_64bitmode(ctx);
6131 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6132 5a5012ec ths
        gen_op_float_cvtd_l();
6133 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6134 5a5012ec ths
        opn = "cvt.d.l";
6135 5a5012ec ths
        break;
6136 5a5012ec ths
    case FOP(38, 20):
6137 5e755519 ths
        check_cp1_64bitmode(ctx);
6138 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6139 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6140 5a5012ec ths
        gen_op_float_cvtps_pw();
6141 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6142 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6143 5a5012ec ths
        opn = "cvt.ps.pw";
6144 5a5012ec ths
        break;
6145 5a5012ec ths
    case FOP(0, 22):
6146 5e755519 ths
        check_cp1_64bitmode(ctx);
6147 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6148 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6149 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
6150 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6151 5a5012ec ths
        gen_op_float_add_ps();
6152 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6153 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6154 5a5012ec ths
        opn = "add.ps";
6155 6ea83fed bellard
        break;
6156 5a5012ec ths
    case FOP(1, 22):
6157 5e755519 ths
        check_cp1_64bitmode(ctx);
6158 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6159 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6160 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
6161 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6162 5a5012ec ths
        gen_op_float_sub_ps();
6163 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6164 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6165 5a5012ec ths
        opn = "sub.ps";
6166 6ea83fed bellard
        break;
6167 5a5012ec ths
    case FOP(2, 22):
6168 5e755519 ths
        check_cp1_64bitmode(ctx);
6169 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6170 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6171 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
6172 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6173 5a5012ec ths
        gen_op_float_mul_ps();
6174 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6175 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6176 5a5012ec ths
        opn = "mul.ps";
6177 6ea83fed bellard
        break;
6178 5a5012ec ths
    case FOP(5, 22):
6179 5e755519 ths
        check_cp1_64bitmode(ctx);
6180 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6181 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6182 5a5012ec ths
        gen_op_float_abs_ps();
6183 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6184 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6185 5a5012ec ths
        opn = "abs.ps";
6186 6ea83fed bellard
        break;
6187 5a5012ec ths
    case FOP(6, 22):
6188 5e755519 ths
        check_cp1_64bitmode(ctx);
6189 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6190 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6191 5a5012ec ths
        gen_op_float_mov_ps();
6192 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6193 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6194 5a5012ec ths
        opn = "mov.ps";
6195 6ea83fed bellard
        break;
6196 5a5012ec ths
    case FOP(7, 22):
6197 5e755519 ths
        check_cp1_64bitmode(ctx);
6198 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6199 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6200 5a5012ec ths
        gen_op_float_chs_ps();
6201 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6202 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6203 5a5012ec ths
        opn = "neg.ps";
6204 6ea83fed bellard
        break;
6205 5a5012ec ths
    case FOP(17, 22):
6206 5e755519 ths
        check_cp1_64bitmode(ctx);
6207 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6208 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6209 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6210 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
6211 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
6212 e6bb7d7e ths
        if (ft & 0x1)
6213 e6bb7d7e ths
            gen_op_float_movt_ps ((ft >> 2) & 0x7);
6214 e6bb7d7e ths
        else
6215 e6bb7d7e ths
            gen_op_float_movf_ps ((ft >> 2) & 0x7);
6216 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6217 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6218 5a5012ec ths
        opn = "movcf.ps";
6219 6ea83fed bellard
        break;
6220 5a5012ec ths
    case FOP(18, 22):
6221 5e755519 ths
        check_cp1_64bitmode(ctx);
6222 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6223 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6224 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6225 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
6226 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
6227 5a5012ec ths
        gen_op_float_movz_ps();
6228 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6229 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6230 5a5012ec ths
        opn = "movz.ps";
6231 6ea83fed bellard
        break;
6232 5a5012ec ths
    case FOP(19, 22):
6233 5e755519 ths
        check_cp1_64bitmode(ctx);
6234 8e9ade68 ths
        gen_load_gpr(cpu_T[0], ft);
6235 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6236 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6237 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fd);
6238 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
6239 5a5012ec ths
        gen_op_float_movn_ps();
6240 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6241 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6242 5a5012ec ths
        opn = "movn.ps";
6243 6ea83fed bellard
        break;
6244 fbcc6828 ths
    case FOP(24, 22):
6245 5e755519 ths
        check_cp1_64bitmode(ctx);
6246 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT0, ft);
6247 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH0, ft);
6248 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT1, fs);
6249 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH1, fs);
6250 fbcc6828 ths
        gen_op_float_addr_ps();
6251 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6252 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6253 fbcc6828 ths
        opn = "addr.ps";
6254 fbcc6828 ths
        break;
6255 57fa1fb3 ths
    case FOP(26, 22):
6256 5e755519 ths
        check_cp1_64bitmode(ctx);
6257 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT0, ft);
6258 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH0, ft);
6259 3a5b360d ths
        GEN_LOAD_FREG_FTN(WT1, fs);
6260 3a5b360d ths
        GEN_LOAD_FREG_FTN(WTH1, fs);
6261 57fa1fb3 ths
        gen_op_float_mulr_ps();
6262 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6263 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6264 57fa1fb3 ths
        opn = "mulr.ps";
6265 57fa1fb3 ths
        break;
6266 57fa1fb3 ths
    case FOP(28, 22):
6267 5e755519 ths
        check_cp1_64bitmode(ctx);
6268 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6269 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6270 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT2, fd);
6271 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH2, fd);
6272 57fa1fb3 ths
        gen_op_float_recip2_ps();
6273 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6274 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6275 57fa1fb3 ths
        opn = "recip2.ps";
6276 57fa1fb3 ths
        break;
6277 57fa1fb3 ths
    case FOP(29, 22):
6278 5e755519 ths
        check_cp1_64bitmode(ctx);
6279 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6280 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6281 57fa1fb3 ths
        gen_op_float_recip1_ps();
6282 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6283 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6284 57fa1fb3 ths
        opn = "recip1.ps";
6285 57fa1fb3 ths
        break;
6286 57fa1fb3 ths
    case FOP(30, 22):
6287 5e755519 ths
        check_cp1_64bitmode(ctx);
6288 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6289 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6290 57fa1fb3 ths
        gen_op_float_rsqrt1_ps();
6291 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6292 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6293 57fa1fb3 ths
        opn = "rsqrt1.ps";
6294 57fa1fb3 ths
        break;
6295 57fa1fb3 ths
    case FOP(31, 22):
6296 5e755519 ths
        check_cp1_64bitmode(ctx);
6297 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6298 57fa1fb3 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6299 8dfdb87c ths
        GEN_LOAD_FREG_FTN(WT2, ft);
6300 8dfdb87c ths
        GEN_LOAD_FREG_FTN(WTH2, ft);
6301 57fa1fb3 ths
        gen_op_float_rsqrt2_ps();
6302 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6303 57fa1fb3 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6304 57fa1fb3 ths
        opn = "rsqrt2.ps";
6305 57fa1fb3 ths
        break;
6306 5a5012ec ths
    case FOP(32, 22):
6307 5e755519 ths
        check_cp1_64bitmode(ctx);
6308 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6309 5a5012ec ths
        gen_op_float_cvts_pu();
6310 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6311 5a5012ec ths
        opn = "cvt.s.pu";
6312 dd016883 bellard
        break;
6313 5a5012ec ths
    case FOP(36, 22):
6314 5e755519 ths
        check_cp1_64bitmode(ctx);
6315 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6316 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6317 5a5012ec ths
        gen_op_float_cvtpw_ps();
6318 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6319 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6320 5a5012ec ths
        opn = "cvt.pw.ps";
6321 6ea83fed bellard
        break;
6322 5a5012ec ths
    case FOP(40, 22):
6323 5e755519 ths
        check_cp1_64bitmode(ctx);
6324 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6325 5a5012ec ths
        gen_op_float_cvts_pl();
6326 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
6327 5a5012ec ths
        opn = "cvt.s.pl";
6328 6ea83fed bellard
        break;
6329 5a5012ec ths
    case FOP(44, 22):
6330 5e755519 ths
        check_cp1_64bitmode(ctx);
6331 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6332 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6333 5a5012ec ths
        gen_op_float_pll_ps();
6334 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6335 5a5012ec ths
        opn = "pll.ps";
6336 6ea83fed bellard
        break;
6337 5a5012ec ths
    case FOP(45, 22):
6338 5e755519 ths
        check_cp1_64bitmode(ctx);
6339 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
6340 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6341 5a5012ec ths
        gen_op_float_plu_ps();
6342 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6343 5a5012ec ths
        opn = "plu.ps";
6344 5a5012ec ths
        break;
6345 5a5012ec ths
    case FOP(46, 22):
6346 5e755519 ths
        check_cp1_64bitmode(ctx);
6347 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6348 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
6349 5a5012ec ths
        gen_op_float_pul_ps();
6350 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6351 5a5012ec ths
        opn = "pul.ps";
6352 5a5012ec ths
        break;
6353 5a5012ec ths
    case FOP(47, 22):
6354 5e755519 ths
        check_cp1_64bitmode(ctx);
6355 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6356 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6357 5a5012ec ths
        gen_op_float_puu_ps();
6358 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6359 5a5012ec ths
        opn = "puu.ps";
6360 5a5012ec ths
        break;
6361 5a5012ec ths
    case FOP(48, 22):
6362 5a5012ec ths
    case FOP(49, 22):
6363 5a5012ec ths
    case FOP(50, 22):
6364 5a5012ec ths
    case FOP(51, 22):
6365 5a5012ec ths
    case FOP(52, 22):
6366 5a5012ec ths
    case FOP(53, 22):
6367 5a5012ec ths
    case FOP(54, 22):
6368 5a5012ec ths
    case FOP(55, 22):
6369 5a5012ec ths
    case FOP(56, 22):
6370 5a5012ec ths
    case FOP(57, 22):
6371 5a5012ec ths
    case FOP(58, 22):
6372 5a5012ec ths
    case FOP(59, 22):
6373 5a5012ec ths
    case FOP(60, 22):
6374 5a5012ec ths
    case FOP(61, 22):
6375 5a5012ec ths
    case FOP(62, 22):
6376 5a5012ec ths
    case FOP(63, 22):
6377 5e755519 ths
        check_cp1_64bitmode(ctx);
6378 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6379 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6380 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6381 5a5012ec ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6382 5a1e8ffb ths
        if (ctx->opcode & (1 << 6)) {
6383 5a1e8ffb ths
            gen_cmpabs_ps(func-48, cc);
6384 5a1e8ffb ths
            opn = condnames_abs[func-48];
6385 5a1e8ffb ths
        } else {
6386 5a1e8ffb ths
            gen_cmp_ps(func-48, cc);
6387 5a1e8ffb ths
            opn = condnames[func-48];
6388 5a1e8ffb ths
        }
6389 6ea83fed bellard
        break;
6390 5a5012ec ths
    default:
6391 923617a3 ths
        MIPS_INVAL(opn);
6392 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
6393 6ea83fed bellard
        return;
6394 6ea83fed bellard
    }
6395 5a1e8ffb ths
    switch (optype) {
6396 5a1e8ffb ths
    case BINOP:
6397 6ea83fed bellard
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
6398 5a1e8ffb ths
        break;
6399 5a1e8ffb ths
    case CMPOP:
6400 5a1e8ffb ths
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
6401 5a1e8ffb ths
        break;
6402 5a1e8ffb ths
    default:
6403 6ea83fed bellard
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
6404 5a1e8ffb ths
        break;
6405 5a1e8ffb ths
    }
6406 6ea83fed bellard
}
6407 6af0bf9c bellard
6408 5a5012ec ths
/* Coprocessor 3 (FPU) */
6409 5e755519 ths
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6410 5e755519 ths
                           int fd, int fs, int base, int index)
6411 7a387fff ths
{
6412 923617a3 ths
    const char *opn = "extended float load/store";
6413 93b12ccc ths
    int store = 0;
6414 7a387fff ths
6415 93b12ccc ths
    if (base == 0) {
6416 8e9ade68 ths
        gen_load_gpr(cpu_T[0], index);
6417 93b12ccc ths
    } else if (index == 0) {
6418 8e9ade68 ths
        gen_load_gpr(cpu_T[0], base);
6419 93b12ccc ths
    } else {
6420 8e9ade68 ths
        gen_load_gpr(cpu_T[0], base);
6421 8e9ade68 ths
        gen_load_gpr(cpu_T[1], index);
6422 93b12ccc ths
        gen_op_addr_add();
6423 93b12ccc ths
    }
6424 5a5012ec ths
    /* Don't do NOP if destination is zero: we must perform the actual
6425 ead9360e ths
       memory access. */
6426 5a5012ec ths
    switch (opc) {
6427 5a5012ec ths
    case OPC_LWXC1:
6428 b8aa4598 ths
        check_cop1x(ctx);
6429 aaa9128a ths
        op_ldst_lwc1(ctx);
6430 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT0);
6431 5a5012ec ths
        opn = "lwxc1";
6432 5a5012ec ths
        break;
6433 5a5012ec ths
    case OPC_LDXC1:
6434 b8aa4598 ths
        check_cop1x(ctx);
6435 b8aa4598 ths
        check_cp1_registers(ctx, fd);
6436 aaa9128a ths
        op_ldst_ldc1(ctx);
6437 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT0);
6438 5a5012ec ths
        opn = "ldxc1";
6439 5a5012ec ths
        break;
6440 5a5012ec ths
    case OPC_LUXC1:
6441 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6442 5a5012ec ths
        op_ldst(luxc1);
6443 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT0);
6444 5a5012ec ths
        opn = "luxc1";
6445 5a5012ec ths
        break;
6446 5a5012ec ths
    case OPC_SWXC1:
6447 b8aa4598 ths
        check_cop1x(ctx);
6448 93b12ccc ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6449 aaa9128a ths
        op_ldst_swc1(ctx);
6450 5a5012ec ths
        opn = "swxc1";
6451 93b12ccc ths
        store = 1;
6452 5a5012ec ths
        break;
6453 5a5012ec ths
    case OPC_SDXC1:
6454 b8aa4598 ths
        check_cop1x(ctx);
6455 b8aa4598 ths
        check_cp1_registers(ctx, fs);
6456 93b12ccc ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6457 aaa9128a ths
        op_ldst_sdc1(ctx);
6458 5a5012ec ths
        opn = "sdxc1";
6459 93b12ccc ths
        store = 1;
6460 5a5012ec ths
        break;
6461 5a5012ec ths
    case OPC_SUXC1:
6462 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6463 93b12ccc ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6464 5a5012ec ths
        op_ldst(suxc1);
6465 5a5012ec ths
        opn = "suxc1";
6466 93b12ccc ths
        store = 1;
6467 5a5012ec ths
        break;
6468 5a5012ec ths
    default:
6469 923617a3 ths
        MIPS_INVAL(opn);
6470 5a5012ec ths
        generate_exception(ctx, EXCP_RI);
6471 5a5012ec ths
        return;
6472 5a5012ec ths
    }
6473 93b12ccc ths
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6474 93b12ccc ths
               regnames[index], regnames[base]);
6475 5a5012ec ths
}
6476 5a5012ec ths
6477 5e755519 ths
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6478 5e755519 ths
                            int fd, int fr, int fs, int ft)
6479 5a5012ec ths
{
6480 923617a3 ths
    const char *opn = "flt3_arith";
6481 5a5012ec ths
6482 5a5012ec ths
    switch (opc) {
6483 5a5012ec ths
    case OPC_ALNV_PS:
6484 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6485 8e9ade68 ths
        gen_load_gpr(cpu_T[0], fr);
6486 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6487 5a5012ec ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6488 5a5012ec ths
        gen_op_float_alnv_ps();
6489 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, DT2);
6490 5a5012ec ths
        opn = "alnv.ps";
6491 5a5012ec ths
        break;
6492 5a5012ec ths
    case OPC_MADD_S:
6493 b8aa4598 ths
        check_cop1x(ctx);
6494 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6495 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6496 5a5012ec ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6497 5a5012ec ths
        gen_op_float_muladd_s();
6498 5a5012ec ths
        GEN_STORE_FTN_FREG(fd, WT2);
6499 5a5012ec ths
        opn = "madd.s";
6500 5a5012ec ths
        break;
6501 5a5012ec ths
    case OPC_MADD_D:
6502 b8aa4598 ths
        check_cop1x(ctx);
6503 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
6504 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6505 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6506 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
6507 fbcc6828 ths
        gen_op_float_muladd_d();
6508 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6509 5a5012ec ths
        opn = "madd.d";
6510 5a5012ec ths
        break;
6511 5a5012ec ths
    case OPC_MADD_PS:
6512 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6513 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6514 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6515 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6516 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6517 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6518 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
6519 fbcc6828 ths
        gen_op_float_muladd_ps();
6520 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6521 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6522 5a5012ec ths
        opn = "madd.ps";
6523 5a5012ec ths
        break;
6524 5a5012ec ths
    case OPC_MSUB_S:
6525 b8aa4598 ths
        check_cop1x(ctx);
6526 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6527 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6528 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6529 fbcc6828 ths
        gen_op_float_mulsub_s();
6530 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6531 5a5012ec ths
        opn = "msub.s";
6532 5a5012ec ths
        break;
6533 5a5012ec ths
    case OPC_MSUB_D:
6534 b8aa4598 ths
        check_cop1x(ctx);
6535 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
6536 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6537 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6538 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
6539 fbcc6828 ths
        gen_op_float_mulsub_d();
6540 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6541 5a5012ec ths
        opn = "msub.d";
6542 5a5012ec ths
        break;
6543 5a5012ec ths
    case OPC_MSUB_PS:
6544 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6545 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6546 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6547 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6548 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6549 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6550 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
6551 fbcc6828 ths
        gen_op_float_mulsub_ps();
6552 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6553 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6554 5a5012ec ths
        opn = "msub.ps";
6555 5a5012ec ths
        break;
6556 5a5012ec ths
    case OPC_NMADD_S:
6557 b8aa4598 ths
        check_cop1x(ctx);
6558 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6559 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6560 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6561 fbcc6828 ths
        gen_op_float_nmuladd_s();
6562 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6563 5a5012ec ths
        opn = "nmadd.s";
6564 5a5012ec ths
        break;
6565 5a5012ec ths
    case OPC_NMADD_D:
6566 b8aa4598 ths
        check_cop1x(ctx);
6567 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
6568 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6569 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6570 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
6571 fbcc6828 ths
        gen_op_float_nmuladd_d();
6572 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6573 5a5012ec ths
        opn = "nmadd.d";
6574 5a5012ec ths
        break;
6575 5a5012ec ths
    case OPC_NMADD_PS:
6576 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6577 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6578 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6579 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6580 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6581 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6582 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
6583 fbcc6828 ths
        gen_op_float_nmuladd_ps();
6584 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6585 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6586 5a5012ec ths
        opn = "nmadd.ps";
6587 5a5012ec ths
        break;
6588 5a5012ec ths
    case OPC_NMSUB_S:
6589 b8aa4598 ths
        check_cop1x(ctx);
6590 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6591 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6592 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6593 fbcc6828 ths
        gen_op_float_nmulsub_s();
6594 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6595 5a5012ec ths
        opn = "nmsub.s";
6596 5a5012ec ths
        break;
6597 5a5012ec ths
    case OPC_NMSUB_D:
6598 b8aa4598 ths
        check_cop1x(ctx);
6599 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
6600 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT0, fs);
6601 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT1, ft);
6602 fbcc6828 ths
        GEN_LOAD_FREG_FTN(DT2, fr);
6603 fbcc6828 ths
        gen_op_float_nmulsub_d();
6604 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, DT2);
6605 5a5012ec ths
        opn = "nmsub.d";
6606 5a5012ec ths
        break;
6607 5a5012ec ths
    case OPC_NMSUB_PS:
6608 b8aa4598 ths
        check_cp1_64bitmode(ctx);
6609 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT0, fs);
6610 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH0, fs);
6611 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT1, ft);
6612 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH1, ft);
6613 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WT2, fr);
6614 fbcc6828 ths
        GEN_LOAD_FREG_FTN(WTH2, fr);
6615 fbcc6828 ths
        gen_op_float_nmulsub_ps();
6616 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WT2);
6617 fbcc6828 ths
        GEN_STORE_FTN_FREG(fd, WTH2);
6618 5a5012ec ths
        opn = "nmsub.ps";
6619 5a5012ec ths
        break;
6620 923617a3 ths
    default:
6621 923617a3 ths
        MIPS_INVAL(opn);
6622 5a5012ec ths
        generate_exception (ctx, EXCP_RI);
6623 5a5012ec ths
        return;
6624 5a5012ec ths
    }
6625 5a5012ec ths
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6626 5a5012ec ths
               fregnames[fs], fregnames[ft]);
6627 7a387fff ths
}
6628 7a387fff ths
6629 7a387fff ths
/* ISA extensions (ASEs) */
6630 6af0bf9c bellard
/* MIPS16 extension to MIPS32 */
6631 6af0bf9c bellard
/* SmartMIPS extension to MIPS32 */
6632 6af0bf9c bellard
6633 d26bc211 ths
#if defined(TARGET_MIPS64)
6634 6af0bf9c bellard
6635 6af0bf9c bellard
/* MDMX extension to MIPS64 */
6636 6af0bf9c bellard
6637 6af0bf9c bellard
#endif
6638 6af0bf9c bellard
6639 36d23958 ths
static void decode_opc (CPUState *env, DisasContext *ctx)
6640 6af0bf9c bellard
{
6641 6af0bf9c bellard
    int32_t offset;
6642 6af0bf9c bellard
    int rs, rt, rd, sa;
6643 7a387fff ths
    uint32_t op, op1, op2;
6644 6af0bf9c bellard
    int16_t imm;
6645 6af0bf9c bellard
6646 d796321b bellard
    /* make sure instructions are on a word boundary */
6647 d796321b bellard
    if (ctx->pc & 0x3) {
6648 cbeb0857 ths
        env->CP0_BadVAddr = ctx->pc;
6649 d796321b bellard
        generate_exception(ctx, EXCP_AdEL);
6650 d796321b bellard
        return;
6651 d796321b bellard
    }
6652 d796321b bellard
6653 8e9ade68 ths
    /* Handle blikely not taken case */
6654 4ad40f36 bellard
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6655 8e9ade68 ths
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
6656 8e9ade68 ths
        int l1 = gen_new_label();
6657 8e9ade68 ths
6658 3594c774 ths
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6659 8e9ade68 ths
        tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
6660 cb63669a pbrook
        tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
6661 5a5012ec ths
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6662 5a5012ec ths
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6663 5a5012ec ths
        gen_set_label(l1);
6664 6af0bf9c bellard
    }
6665 7a387fff ths
    op = MASK_OP_MAJOR(ctx->opcode);
6666 7a387fff ths
    rs = (ctx->opcode >> 21) & 0x1f;
6667 7a387fff ths
    rt = (ctx->opcode >> 16) & 0x1f;
6668 7a387fff ths
    rd = (ctx->opcode >> 11) & 0x1f;
6669 7a387fff ths
    sa = (ctx->opcode >> 6) & 0x1f;
6670 6af0bf9c bellard
    imm = (int16_t)ctx->opcode;
6671 6af0bf9c bellard
    switch (op) {
6672 7a387fff ths
    case OPC_SPECIAL:
6673 7a387fff ths
        op1 = MASK_SPECIAL(ctx->opcode);
6674 6af0bf9c bellard
        switch (op1) {
6675 7a387fff ths
        case OPC_SLL:          /* Arithmetic with immediate */
6676 7a387fff ths
        case OPC_SRL ... OPC_SRA:
6677 e189e748 ths
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6678 7a387fff ths
            break;
6679 e189e748 ths
        case OPC_MOVZ ... OPC_MOVN:
6680 e189e748 ths
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6681 7a387fff ths
        case OPC_SLLV:         /* Arithmetic */
6682 7a387fff ths
        case OPC_SRLV ... OPC_SRAV:
6683 7a387fff ths
        case OPC_ADD ... OPC_NOR:
6684 7a387fff ths
        case OPC_SLT ... OPC_SLTU:
6685 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
6686 7a387fff ths
            break;
6687 7a387fff ths
        case OPC_MULT ... OPC_DIVU:
6688 e9c71dd1 ths
            if (sa) {
6689 e9c71dd1 ths
                check_insn(env, ctx, INSN_VR54XX);
6690 e9c71dd1 ths
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6691 e9c71dd1 ths
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6692 e9c71dd1 ths
            } else
6693 e9c71dd1 ths
                gen_muldiv(ctx, op1, rs, rt);
6694 7a387fff ths
            break;
6695 7a387fff ths
        case OPC_JR ... OPC_JALR:
6696 7a387fff ths
            gen_compute_branch(ctx, op1, rs, rd, sa);
6697 6af0bf9c bellard
            return;
6698 7a387fff ths
        case OPC_TGE ... OPC_TEQ: /* Traps */
6699 7a387fff ths
        case OPC_TNE:
6700 7a387fff ths
            gen_trap(ctx, op1, rs, rt, -1);
6701 6af0bf9c bellard
            break;
6702 7a387fff ths
        case OPC_MFHI:          /* Move from HI/LO */
6703 7a387fff ths
        case OPC_MFLO:
6704 7a387fff ths
            gen_HILO(ctx, op1, rd);
6705 6af0bf9c bellard
            break;
6706 7a387fff ths
        case OPC_MTHI:
6707 7a387fff ths
        case OPC_MTLO:          /* Move to HI/LO */
6708 7a387fff ths
            gen_HILO(ctx, op1, rs);
6709 6af0bf9c bellard
            break;
6710 b48cfdff ths
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6711 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
6712 b48cfdff ths
            MIPS_INVAL("PMON / selsl");
6713 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
6714 b48cfdff ths
#else
6715 7a387fff ths
            gen_op_pmon(sa);
6716 b48cfdff ths
#endif
6717 7a387fff ths
            break;
6718 7a387fff ths
        case OPC_SYSCALL:
6719 6af0bf9c bellard
            generate_exception(ctx, EXCP_SYSCALL);
6720 6af0bf9c bellard
            break;
6721 7a387fff ths
        case OPC_BREAK:
6722 6af0bf9c bellard
            generate_exception(ctx, EXCP_BREAK);
6723 6af0bf9c bellard
            break;
6724 b48cfdff ths
        case OPC_SPIM:
6725 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
6726 b48cfdff ths
            MIPS_INVAL("SPIM");
6727 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
6728 b48cfdff ths
#else
6729 7a387fff ths
           /* Implemented as RI exception for now. */
6730 7a387fff ths
            MIPS_INVAL("spim (unofficial)");
6731 7a387fff ths
            generate_exception(ctx, EXCP_RI);
6732 b48cfdff ths
#endif
6733 6af0bf9c bellard
            break;
6734 7a387fff ths
        case OPC_SYNC:
6735 ead9360e ths
            /* Treat as NOP. */
6736 6af0bf9c bellard
            break;
6737 4ad40f36 bellard
6738 7a387fff ths
        case OPC_MOVCI:
6739 e189e748 ths
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6740 36d23958 ths
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6741 e397ee33 ths
                save_cpu_state(ctx, 1);
6742 5e755519 ths
                check_cp1_enabled(ctx);
6743 36d23958 ths
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6744 36d23958 ths
                          (ctx->opcode >> 16) & 1);
6745 36d23958 ths
            } else {
6746 e397ee33 ths
                generate_exception_err(ctx, EXCP_CpU, 1);
6747 36d23958 ths
            }
6748 4ad40f36 bellard
            break;
6749 4ad40f36 bellard
6750 d26bc211 ths
#if defined(TARGET_MIPS64)
6751 7a387fff ths
       /* MIPS64 specific opcodes */
6752 7a387fff ths
        case OPC_DSLL:
6753 7a387fff ths
        case OPC_DSRL ... OPC_DSRA:
6754 7a387fff ths
        case OPC_DSLL32:
6755 7a387fff ths
        case OPC_DSRL32 ... OPC_DSRA32:
6756 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
6757 e189e748 ths
            check_mips_64(ctx);
6758 e189e748 ths
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6759 7a387fff ths
            break;
6760 7a387fff ths
        case OPC_DSLLV:
6761 7a387fff ths
        case OPC_DSRLV ... OPC_DSRAV:
6762 7a387fff ths
        case OPC_DADD ... OPC_DSUBU:
6763 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
6764 e189e748 ths
            check_mips_64(ctx);
6765 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
6766 7a387fff ths
            break;
6767 7a387fff ths
        case OPC_DMULT ... OPC_DDIVU:
6768 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
6769 e189e748 ths
            check_mips_64(ctx);
6770 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
6771 7a387fff ths
            break;
6772 6af0bf9c bellard
#endif
6773 6af0bf9c bellard
        default:            /* Invalid */
6774 6af0bf9c bellard
            MIPS_INVAL("special");
6775 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
6776 6af0bf9c bellard
            break;
6777 6af0bf9c bellard
        }
6778 6af0bf9c bellard
        break;
6779 7a387fff ths
    case OPC_SPECIAL2:
6780 7a387fff ths
        op1 = MASK_SPECIAL2(ctx->opcode);
6781 6af0bf9c bellard
        switch (op1) {
6782 7a387fff ths
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6783 7a387fff ths
        case OPC_MSUB ... OPC_MSUBU:
6784 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
6785 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
6786 6af0bf9c bellard
            break;
6787 7a387fff ths
        case OPC_MUL:
6788 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
6789 6af0bf9c bellard
            break;
6790 7a387fff ths
        case OPC_CLZ ... OPC_CLO:
6791 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
6792 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
6793 6af0bf9c bellard
            break;
6794 7a387fff ths
        case OPC_SDBBP:
6795 6af0bf9c bellard
            /* XXX: not clear which exception should be raised
6796 6af0bf9c bellard
             *      when in debug mode...
6797 6af0bf9c bellard
             */
6798 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
6799 6af0bf9c bellard
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6800 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
6801 6af0bf9c bellard
            } else {
6802 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
6803 6af0bf9c bellard
            }
6804 ead9360e ths
            /* Treat as NOP. */
6805 6af0bf9c bellard
            break;
6806 d26bc211 ths
#if defined(TARGET_MIPS64)
6807 7a387fff ths
        case OPC_DCLZ ... OPC_DCLO:
6808 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64);
6809 e189e748 ths
            check_mips_64(ctx);
6810 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
6811 7a387fff ths
            break;
6812 7a387fff ths
#endif
6813 6af0bf9c bellard
        default:            /* Invalid */
6814 6af0bf9c bellard
            MIPS_INVAL("special2");
6815 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
6816 6af0bf9c bellard
            break;
6817 6af0bf9c bellard
        }
6818 6af0bf9c bellard
        break;
6819 7a387fff ths
    case OPC_SPECIAL3:
6820 1579a72e ths
         op1 = MASK_SPECIAL3(ctx->opcode);
6821 1579a72e ths
         switch (op1) {
6822 1579a72e ths
         case OPC_EXT:
6823 1579a72e ths
         case OPC_INS:
6824 e189e748 ths
             check_insn(env, ctx, ISA_MIPS32R2);
6825 1579a72e ths
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6826 1579a72e ths
             break;
6827 1579a72e ths
         case OPC_BSHFL:
6828 e189e748 ths
             check_insn(env, ctx, ISA_MIPS32R2);
6829 1579a72e ths
             op2 = MASK_BSHFL(ctx->opcode);
6830 1579a72e ths
             switch (op2) {
6831 1579a72e ths
             case OPC_WSBH:
6832 8e9ade68 ths
                 gen_load_gpr(cpu_T[1], rt);
6833 1579a72e ths
                 gen_op_wsbh();
6834 1579a72e ths
                 break;
6835 1579a72e ths
             case OPC_SEB:
6836 8e9ade68 ths
                 gen_load_gpr(cpu_T[1], rt);
6837 48d38ca5 ths
                 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
6838 1579a72e ths
                 break;
6839 1579a72e ths
             case OPC_SEH:
6840 8e9ade68 ths
                 gen_load_gpr(cpu_T[1], rt);
6841 48d38ca5 ths
                 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
6842 1579a72e ths
                 break;
6843 1579a72e ths
             default:            /* Invalid */
6844 1579a72e ths
                 MIPS_INVAL("bshfl");
6845 1579a72e ths
                 generate_exception(ctx, EXCP_RI);
6846 1579a72e ths
                 break;
6847 1579a72e ths
            }
6848 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rd);
6849 7a387fff ths
            break;
6850 1579a72e ths
        case OPC_RDHWR:
6851 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
6852 1579a72e ths
            switch (rd) {
6853 1579a72e ths
            case 0:
6854 97428a4d ths
                save_cpu_state(ctx, 1);
6855 1579a72e ths
                gen_op_rdhwr_cpunum();
6856 7a387fff ths
                break;
6857 1579a72e ths
            case 1:
6858 97428a4d ths
                save_cpu_state(ctx, 1);
6859 1579a72e ths
                gen_op_rdhwr_synci_step();
6860 7a387fff ths
                break;
6861 1579a72e ths
            case 2:
6862 97428a4d ths
                save_cpu_state(ctx, 1);
6863 1579a72e ths
                gen_op_rdhwr_cc();
6864 7a387fff ths
                break;
6865 1579a72e ths
            case 3:
6866 97428a4d ths
                save_cpu_state(ctx, 1);
6867 1579a72e ths
                gen_op_rdhwr_ccres();
6868 7a387fff ths
                break;
6869 1579a72e ths
            case 29:
6870 6f5b89a0 ths
#if defined (CONFIG_USER_ONLY)
6871 ead9360e ths
                gen_op_tls_value();
6872 1579a72e ths
                break;
6873 97428a4d ths
#endif
6874 1579a72e ths
            default:            /* Invalid */
6875 1579a72e ths
                MIPS_INVAL("rdhwr");
6876 1579a72e ths
                generate_exception(ctx, EXCP_RI);
6877 1579a72e ths
                break;
6878 1579a72e ths
            }
6879 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rt);
6880 1579a72e ths
            break;
6881 ead9360e ths
        case OPC_FORK:
6882 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
6883 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rt);
6884 8e9ade68 ths
            gen_load_gpr(cpu_T[1], rs);
6885 ead9360e ths
            gen_op_fork();
6886 ead9360e ths
            break;
6887 ead9360e ths
        case OPC_YIELD:
6888 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
6889 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rs);
6890 ead9360e ths
            gen_op_yield();
6891 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rd);
6892 ead9360e ths
            break;
6893 d26bc211 ths
#if defined(TARGET_MIPS64)
6894 1579a72e ths
        case OPC_DEXTM ... OPC_DEXT:
6895 1579a72e ths
        case OPC_DINSM ... OPC_DINS:
6896 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64R2);
6897 e189e748 ths
            check_mips_64(ctx);
6898 1579a72e ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6899 7a387fff ths
            break;
6900 1579a72e ths
        case OPC_DBSHFL:
6901 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64R2);
6902 e189e748 ths
            check_mips_64(ctx);
6903 1579a72e ths
            op2 = MASK_DBSHFL(ctx->opcode);
6904 1579a72e ths
            switch (op2) {
6905 1579a72e ths
            case OPC_DSBH:
6906 8e9ade68 ths
                gen_load_gpr(cpu_T[1], rt);
6907 1579a72e ths
                gen_op_dsbh();
6908 1579a72e ths
                break;
6909 1579a72e ths
            case OPC_DSHD:
6910 8e9ade68 ths
                gen_load_gpr(cpu_T[1], rt);
6911 1579a72e ths
                gen_op_dshd();
6912 1579a72e ths
                break;
6913 7a387fff ths
            default:            /* Invalid */
6914 7a387fff ths
                MIPS_INVAL("dbshfl");
6915 7a387fff ths
                generate_exception(ctx, EXCP_RI);
6916 7a387fff ths
                break;
6917 1579a72e ths
            }
6918 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rd);
6919 c6d6dd7c ths
            break;
6920 7a387fff ths
#endif
6921 7a387fff ths
        default:            /* Invalid */
6922 7a387fff ths
            MIPS_INVAL("special3");
6923 7a387fff ths
            generate_exception(ctx, EXCP_RI);
6924 7a387fff ths
            break;
6925 7a387fff ths
        }
6926 7a387fff ths
        break;
6927 7a387fff ths
    case OPC_REGIMM:
6928 7a387fff ths
        op1 = MASK_REGIMM(ctx->opcode);
6929 7a387fff ths
        switch (op1) {
6930 7a387fff ths
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6931 7a387fff ths
        case OPC_BLTZAL ... OPC_BGEZALL:
6932 7a387fff ths
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6933 6af0bf9c bellard
            return;
6934 7a387fff ths
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6935 7a387fff ths
        case OPC_TNEI:
6936 7a387fff ths
            gen_trap(ctx, op1, rs, -1, imm);
6937 7a387fff ths
            break;
6938 7a387fff ths
        case OPC_SYNCI:
6939 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
6940 ead9360e ths
            /* Treat as NOP. */
6941 6af0bf9c bellard
            break;
6942 6af0bf9c bellard
        default:            /* Invalid */
6943 923617a3 ths
            MIPS_INVAL("regimm");
6944 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
6945 6af0bf9c bellard
            break;
6946 6af0bf9c bellard
        }
6947 6af0bf9c bellard
        break;
6948 7a387fff ths
    case OPC_CP0:
6949 387a8fe5 ths
        check_cp0_enabled(ctx);
6950 7a387fff ths
        op1 = MASK_CP0(ctx->opcode);
6951 6af0bf9c bellard
        switch (op1) {
6952 7a387fff ths
        case OPC_MFC0:
6953 7a387fff ths
        case OPC_MTC0:
6954 ead9360e ths
        case OPC_MFTR:
6955 ead9360e ths
        case OPC_MTTR:
6956 d26bc211 ths
#if defined(TARGET_MIPS64)
6957 7a387fff ths
        case OPC_DMFC0:
6958 7a387fff ths
        case OPC_DMTC0:
6959 7a387fff ths
#endif
6960 29929e34 ths
            gen_cp0(env, ctx, op1, rt, rd);
6961 7a387fff ths
            break;
6962 7a387fff ths
        case OPC_C0_FIRST ... OPC_C0_LAST:
6963 29929e34 ths
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6964 7a387fff ths
            break;
6965 7a387fff ths
        case OPC_MFMC0:
6966 7a387fff ths
            op2 = MASK_MFMC0(ctx->opcode);
6967 7a387fff ths
            switch (op2) {
6968 ead9360e ths
            case OPC_DMT:
6969 7385ac0b ths
                check_insn(env, ctx, ASE_MT);
6970 ead9360e ths
                gen_op_dmt();
6971 ead9360e ths
                break;
6972 ead9360e ths
            case OPC_EMT:
6973 7385ac0b ths
                check_insn(env, ctx, ASE_MT);
6974 ead9360e ths
                gen_op_emt();
6975 ead9360e ths
                break;
6976 ead9360e ths
            case OPC_DVPE:
6977 7385ac0b ths
                check_insn(env, ctx, ASE_MT);
6978 ead9360e ths
                gen_op_dvpe();
6979 ead9360e ths
                break;
6980 ead9360e ths
            case OPC_EVPE:
6981 7385ac0b ths
                check_insn(env, ctx, ASE_MT);
6982 ead9360e ths
                gen_op_evpe();
6983 ead9360e ths
                break;
6984 7a387fff ths
            case OPC_DI:
6985 e189e748 ths
                check_insn(env, ctx, ISA_MIPS32R2);
6986 387a8fe5 ths
                save_cpu_state(ctx, 1);
6987 7a387fff ths
                gen_op_di();
6988 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
6989 7a387fff ths
                ctx->bstate = BS_STOP;
6990 7a387fff ths
                break;
6991 7a387fff ths
            case OPC_EI:
6992 e189e748 ths
                check_insn(env, ctx, ISA_MIPS32R2);
6993 387a8fe5 ths
                save_cpu_state(ctx, 1);
6994 7a387fff ths
                gen_op_ei();
6995 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
6996 7a387fff ths
                ctx->bstate = BS_STOP;
6997 7a387fff ths
                break;
6998 7a387fff ths
            default:            /* Invalid */
6999 923617a3 ths
                MIPS_INVAL("mfmc0");
7000 7a387fff ths
                generate_exception(ctx, EXCP_RI);
7001 7a387fff ths
                break;
7002 7a387fff ths
            }
7003 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rt);
7004 6af0bf9c bellard
            break;
7005 7a387fff ths
        case OPC_RDPGPR:
7006 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
7007 8e9ade68 ths
            gen_load_srsgpr(cpu_T[0], rt);
7008 8e9ade68 ths
            gen_store_gpr(cpu_T[0], rd);
7009 ead9360e ths
            break;
7010 7a387fff ths
        case OPC_WRPGPR:
7011 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
7012 8e9ade68 ths
            gen_load_gpr(cpu_T[0], rt);
7013 8e9ade68 ths
            gen_store_srsgpr(cpu_T[0], rd);
7014 38121543 ths
            break;
7015 6af0bf9c bellard
        default:
7016 923617a3 ths
            MIPS_INVAL("cp0");
7017 7a387fff ths
            generate_exception(ctx, EXCP_RI);
7018 6af0bf9c bellard
            break;
7019 6af0bf9c bellard
        }
7020 6af0bf9c bellard
        break;
7021 7a387fff ths
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7022 e189e748 ths
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7023 7a387fff ths
         break;
7024 7a387fff ths
    case OPC_J ... OPC_JAL: /* Jump */
7025 7a387fff ths
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7026 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, offset);
7027 7a387fff ths
         return;
7028 7a387fff ths
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7029 7a387fff ths
    case OPC_BEQL ... OPC_BGTZL:
7030 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7031 7a387fff ths
         return;
7032 7a387fff ths
    case OPC_LB ... OPC_LWR: /* Load and stores */
7033 7a387fff ths
    case OPC_SB ... OPC_SW:
7034 7a387fff ths
    case OPC_SWR:
7035 7a387fff ths
    case OPC_LL:
7036 7a387fff ths
    case OPC_SC:
7037 7a387fff ths
         gen_ldst(ctx, op, rt, rs, imm);
7038 7a387fff ths
         break;
7039 7a387fff ths
    case OPC_CACHE:
7040 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7041 ead9360e ths
        /* Treat as NOP. */
7042 34ae7b51 ths
        break;
7043 7a387fff ths
    case OPC_PREF:
7044 e189e748 ths
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7045 ead9360e ths
        /* Treat as NOP. */
7046 6af0bf9c bellard
        break;
7047 4ad40f36 bellard
7048 923617a3 ths
    /* Floating point (COP1). */
7049 7a387fff ths
    case OPC_LWC1:
7050 7a387fff ths
    case OPC_LDC1:
7051 7a387fff ths
    case OPC_SWC1:
7052 7a387fff ths
    case OPC_SDC1:
7053 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7054 36d23958 ths
            save_cpu_state(ctx, 1);
7055 5e755519 ths
            check_cp1_enabled(ctx);
7056 36d23958 ths
            gen_flt_ldst(ctx, op, rt, rs, imm);
7057 36d23958 ths
        } else {
7058 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
7059 36d23958 ths
        }
7060 6ea83fed bellard
        break;
7061 6ea83fed bellard
7062 7a387fff ths
    case OPC_CP1:
7063 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7064 36d23958 ths
            save_cpu_state(ctx, 1);
7065 5e755519 ths
            check_cp1_enabled(ctx);
7066 36d23958 ths
            op1 = MASK_CP1(ctx->opcode);
7067 36d23958 ths
            switch (op1) {
7068 3a95e3a7 ths
            case OPC_MFHC1:
7069 3a95e3a7 ths
            case OPC_MTHC1:
7070 e189e748 ths
                check_insn(env, ctx, ISA_MIPS32R2);
7071 36d23958 ths
            case OPC_MFC1:
7072 36d23958 ths
            case OPC_CFC1:
7073 36d23958 ths
            case OPC_MTC1:
7074 36d23958 ths
            case OPC_CTC1:
7075 e189e748 ths
                gen_cp1(ctx, op1, rt, rd);
7076 e189e748 ths
                break;
7077 d26bc211 ths
#if defined(TARGET_MIPS64)
7078 36d23958 ths
            case OPC_DMFC1:
7079 36d23958 ths
            case OPC_DMTC1:
7080 e189e748 ths
                check_insn(env, ctx, ISA_MIPS3);
7081 36d23958 ths
                gen_cp1(ctx, op1, rt, rd);
7082 36d23958 ths
                break;
7083 e189e748 ths
#endif
7084 fbcc6828 ths
            case OPC_BC1ANY2:
7085 fbcc6828 ths
            case OPC_BC1ANY4:
7086 b8aa4598 ths
                check_cop1x(ctx);
7087 7385ac0b ths
                check_insn(env, ctx, ASE_MIPS3D);
7088 d8a5950a ths
                /* fall through */
7089 d8a5950a ths
            case OPC_BC1:
7090 e189e748 ths
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7091 5a5012ec ths
                                    (rt >> 2) & 0x7, imm << 2);
7092 36d23958 ths
                return;
7093 36d23958 ths
            case OPC_S_FMT:
7094 36d23958 ths
            case OPC_D_FMT:
7095 36d23958 ths
            case OPC_W_FMT:
7096 36d23958 ths
            case OPC_L_FMT:
7097 5a5012ec ths
            case OPC_PS_FMT:
7098 5a5012ec ths
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7099 5a5012ec ths
                           (imm >> 8) & 0x7);
7100 36d23958 ths
                break;
7101 36d23958 ths
            default:
7102 923617a3 ths
                MIPS_INVAL("cp1");
7103 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
7104 36d23958 ths
                break;
7105 36d23958 ths
            }
7106 36d23958 ths
        } else {
7107 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
7108 6ea83fed bellard
        }
7109 4ad40f36 bellard
        break;
7110 4ad40f36 bellard
7111 4ad40f36 bellard
    /* COP2.  */
7112 7a387fff ths
    case OPC_LWC2:
7113 7a387fff ths
    case OPC_LDC2:
7114 7a387fff ths
    case OPC_SWC2:
7115 7a387fff ths
    case OPC_SDC2:
7116 7a387fff ths
    case OPC_CP2:
7117 7a387fff ths
        /* COP2: Not implemented. */
7118 4ad40f36 bellard
        generate_exception_err(ctx, EXCP_CpU, 2);
7119 4ad40f36 bellard
        break;
7120 4ad40f36 bellard
7121 7a387fff ths
    case OPC_CP3:
7122 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7123 e397ee33 ths
            save_cpu_state(ctx, 1);
7124 5e755519 ths
            check_cp1_enabled(ctx);
7125 36d23958 ths
            op1 = MASK_CP3(ctx->opcode);
7126 36d23958 ths
            switch (op1) {
7127 5a5012ec ths
            case OPC_LWXC1:
7128 5a5012ec ths
            case OPC_LDXC1:
7129 5a5012ec ths
            case OPC_LUXC1:
7130 5a5012ec ths
            case OPC_SWXC1:
7131 5a5012ec ths
            case OPC_SDXC1:
7132 5a5012ec ths
            case OPC_SUXC1:
7133 93b12ccc ths
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7134 5a5012ec ths
                break;
7135 e0c84da7 ths
            case OPC_PREFX:
7136 ead9360e ths
                /* Treat as NOP. */
7137 e0c84da7 ths
                break;
7138 5a5012ec ths
            case OPC_ALNV_PS:
7139 5a5012ec ths
            case OPC_MADD_S:
7140 5a5012ec ths
            case OPC_MADD_D:
7141 5a5012ec ths
            case OPC_MADD_PS:
7142 5a5012ec ths
            case OPC_MSUB_S:
7143 5a5012ec ths
            case OPC_MSUB_D:
7144 5a5012ec ths
            case OPC_MSUB_PS:
7145 5a5012ec ths
            case OPC_NMADD_S:
7146 5a5012ec ths
            case OPC_NMADD_D:
7147 5a5012ec ths
            case OPC_NMADD_PS:
7148 5a5012ec ths
            case OPC_NMSUB_S:
7149 5a5012ec ths
            case OPC_NMSUB_D:
7150 5a5012ec ths
            case OPC_NMSUB_PS:
7151 5a5012ec ths
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7152 5a5012ec ths
                break;
7153 36d23958 ths
            default:
7154 923617a3 ths
                MIPS_INVAL("cp3");
7155 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
7156 36d23958 ths
                break;
7157 36d23958 ths
            }
7158 36d23958 ths
        } else {
7159 e397ee33 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
7160 7a387fff ths
        }
7161 4ad40f36 bellard
        break;
7162 4ad40f36 bellard
7163 d26bc211 ths
#if defined(TARGET_MIPS64)
7164 7a387fff ths
    /* MIPS64 opcodes */
7165 7a387fff ths
    case OPC_LWU:
7166 7a387fff ths
    case OPC_LDL ... OPC_LDR:
7167 7a387fff ths
    case OPC_SDL ... OPC_SDR:
7168 7a387fff ths
    case OPC_LLD:
7169 7a387fff ths
    case OPC_LD:
7170 7a387fff ths
    case OPC_SCD:
7171 7a387fff ths
    case OPC_SD:
7172 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
7173 e189e748 ths
        check_mips_64(ctx);
7174 7a387fff ths
        gen_ldst(ctx, op, rt, rs, imm);
7175 7a387fff ths
        break;
7176 7a387fff ths
    case OPC_DADDI ... OPC_DADDIU:
7177 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
7178 e189e748 ths
        check_mips_64(ctx);
7179 e189e748 ths
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7180 7a387fff ths
        break;
7181 6af0bf9c bellard
#endif
7182 7a387fff ths
    case OPC_JALX:
7183 e189e748 ths
        check_insn(env, ctx, ASE_MIPS16);
7184 7a387fff ths
        /* MIPS16: Not implemented. */
7185 7a387fff ths
    case OPC_MDMX:
7186 e189e748 ths
        check_insn(env, ctx, ASE_MDMX);
7187 7a387fff ths
        /* MDMX: Not implemented. */
7188 6af0bf9c bellard
    default:            /* Invalid */
7189 923617a3 ths
        MIPS_INVAL("major opcode");
7190 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
7191 6af0bf9c bellard
        break;
7192 6af0bf9c bellard
    }
7193 4ad40f36 bellard
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7194 c53f4a62 ths
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7195 6af0bf9c bellard
        /* Branches completion */
7196 4ad40f36 bellard
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7197 6af0bf9c bellard
        ctx->bstate = BS_BRANCH;
7198 6af0bf9c bellard
        save_cpu_state(ctx, 0);
7199 5a5012ec ths
        switch (hflags) {
7200 6af0bf9c bellard
        case MIPS_HFLAG_B:
7201 6af0bf9c bellard
            /* unconditional branch */
7202 6af0bf9c bellard
            MIPS_DEBUG("unconditional branch");
7203 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
7204 6af0bf9c bellard
            break;
7205 6af0bf9c bellard
        case MIPS_HFLAG_BL:
7206 6af0bf9c bellard
            /* blikely taken case */
7207 6af0bf9c bellard
            MIPS_DEBUG("blikely branch taken");
7208 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
7209 6af0bf9c bellard
            break;
7210 6af0bf9c bellard
        case MIPS_HFLAG_BC:
7211 6af0bf9c bellard
            /* Conditional branch */
7212 6af0bf9c bellard
            MIPS_DEBUG("conditional branch");
7213 c53be334 bellard
            {
7214 8e9ade68 ths
                TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
7215 8e9ade68 ths
                int l1 = gen_new_label();
7216 8e9ade68 ths
7217 8e9ade68 ths
                tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7218 cb63669a pbrook
                tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7219 8e9ade68 ths
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7220 8e9ade68 ths
                gen_set_label(l1);
7221 8e9ade68 ths
                gen_goto_tb(ctx, 0, ctx->btarget);
7222 c53be334 bellard
            }
7223 6af0bf9c bellard
            break;
7224 6af0bf9c bellard
        case MIPS_HFLAG_BR:
7225 6af0bf9c bellard
            /* unconditional branch to register */
7226 6af0bf9c bellard
            MIPS_DEBUG("branch to register");
7227 8e9ade68 ths
            gen_breg_pc();
7228 57fec1fe bellard
            tcg_gen_exit_tb(0);
7229 6af0bf9c bellard
            break;
7230 6af0bf9c bellard
        default:
7231 6af0bf9c bellard
            MIPS_DEBUG("unknown branch");
7232 6af0bf9c bellard
            break;
7233 6af0bf9c bellard
        }
7234 6af0bf9c bellard
    }
7235 6af0bf9c bellard
}
7236 6af0bf9c bellard
7237 aa343735 ths
static always_inline int
7238 820e00f2 ths
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7239 820e00f2 ths
                                int search_pc)
7240 6af0bf9c bellard
{
7241 278d0702 ths
    DisasContext ctx;
7242 6af0bf9c bellard
    target_ulong pc_start;
7243 6af0bf9c bellard
    uint16_t *gen_opc_end;
7244 6af0bf9c bellard
    int j, lj = -1;
7245 6af0bf9c bellard
7246 4ad40f36 bellard
    if (search_pc && loglevel)
7247 6ea83fed bellard
        fprintf (logfile, "search pc %d\n", search_pc);
7248 4ad40f36 bellard
7249 8c99506c ths
    num_temps = 0;
7250 8c99506c ths
    memset(temps, 0, sizeof(temps));
7251 8c99506c ths
7252 48d38ca5 ths
    num_temps = 0;
7253 48d38ca5 ths
    memset(temps, 0, sizeof(temps));
7254 48d38ca5 ths
7255 6af0bf9c bellard
    pc_start = tb->pc;
7256 6af0bf9c bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7257 6af0bf9c bellard
    ctx.pc = pc_start;
7258 4ad40f36 bellard
    ctx.saved_pc = -1;
7259 6af0bf9c bellard
    ctx.tb = tb;
7260 6af0bf9c bellard
    ctx.bstate = BS_NONE;
7261 4ad40f36 bellard
    /* Restore delay slot state from the tb context.  */
7262 c068688b j_mayer
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7263 fd4a04eb ths
    restore_cpu_state(env, &ctx);
7264 6af0bf9c bellard
#if defined(CONFIG_USER_ONLY)
7265 623a930e ths
    ctx.mem_idx = MIPS_HFLAG_UM;
7266 6af0bf9c bellard
#else
7267 623a930e ths
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7268 6af0bf9c bellard
#endif
7269 6af0bf9c bellard
#ifdef DEBUG_DISAS
7270 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
7271 6af0bf9c bellard
        fprintf(logfile, "------------------------------------------------\n");
7272 4ad40f36 bellard
        /* FIXME: This may print out stale hflags from env... */
7273 6af0bf9c bellard
        cpu_dump_state(env, logfile, fprintf, 0);
7274 6af0bf9c bellard
    }
7275 6af0bf9c bellard
#endif
7276 923617a3 ths
#ifdef MIPS_DEBUG_DISAS
7277 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
7278 623a930e ths
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7279 4ad40f36 bellard
                tb, ctx.mem_idx, ctx.hflags);
7280 6af0bf9c bellard
#endif
7281 6af0bf9c bellard
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
7282 4ad40f36 bellard
        if (env->nb_breakpoints > 0) {
7283 4ad40f36 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
7284 4ad40f36 bellard
                if (env->breakpoints[j] == ctx.pc) {
7285 278d0702 ths
                    save_cpu_state(&ctx, 1);
7286 4ad40f36 bellard
                    ctx.bstate = BS_BRANCH;
7287 4ad40f36 bellard
                    gen_op_debug();
7288 ce62e5ba ths
                    /* Include the breakpoint location or the tb won't
7289 ce62e5ba ths
                     * be flushed when it must be.  */
7290 ce62e5ba ths
                    ctx.pc += 4;
7291 4ad40f36 bellard
                    goto done_generating;
7292 4ad40f36 bellard
                }
7293 4ad40f36 bellard
            }
7294 4ad40f36 bellard
        }
7295 4ad40f36 bellard
7296 6af0bf9c bellard
        if (search_pc) {
7297 6af0bf9c bellard
            j = gen_opc_ptr - gen_opc_buf;
7298 6af0bf9c bellard
            if (lj < j) {
7299 6af0bf9c bellard
                lj++;
7300 6af0bf9c bellard
                while (lj < j)
7301 6af0bf9c bellard
                    gen_opc_instr_start[lj++] = 0;
7302 6af0bf9c bellard
            }
7303 4ad40f36 bellard
            gen_opc_pc[lj] = ctx.pc;
7304 4ad40f36 bellard
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7305 4ad40f36 bellard
            gen_opc_instr_start[lj] = 1;
7306 6af0bf9c bellard
        }
7307 6af0bf9c bellard
        ctx.opcode = ldl_code(ctx.pc);
7308 36d23958 ths
        decode_opc(env, &ctx);
7309 8c99506c ths
        if (num_temps) {
7310 8c99506c ths
            fprintf(stderr,
7311 8c99506c ths
                    "Internal resource leak before " TARGET_FMT_lx "\n",
7312 8c99506c ths
                    ctx.pc);
7313 8c99506c ths
            num_temps = 0;
7314 8c99506c ths
        }
7315 6af0bf9c bellard
        ctx.pc += 4;
7316 4ad40f36 bellard
7317 4ad40f36 bellard
        if (env->singlestep_enabled)
7318 4ad40f36 bellard
            break;
7319 4ad40f36 bellard
7320 6af0bf9c bellard
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7321 6af0bf9c bellard
            break;
7322 4ad40f36 bellard
7323 6af0bf9c bellard
#if defined (MIPS_SINGLE_STEP)
7324 6af0bf9c bellard
        break;
7325 6af0bf9c bellard
#endif
7326 6af0bf9c bellard
    }
7327 4ad40f36 bellard
    if (env->singlestep_enabled) {
7328 278d0702 ths
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7329 4ad40f36 bellard
        gen_op_debug();
7330 16c00cb2 ths
    } else {
7331 16c00cb2 ths
        switch (ctx.bstate) {
7332 16c00cb2 ths
        case BS_STOP:
7333 48d38ca5 ths
            tcg_gen_helper_0_0(do_interrupt_restart);
7334 df1561e2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
7335 df1561e2 ths
            break;
7336 16c00cb2 ths
        case BS_NONE:
7337 278d0702 ths
            save_cpu_state(&ctx, 0);
7338 16c00cb2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
7339 16c00cb2 ths
            break;
7340 5a5012ec ths
        case BS_EXCP:
7341 48d38ca5 ths
            tcg_gen_helper_0_0(do_interrupt_restart);
7342 57fec1fe bellard
            tcg_gen_exit_tb(0);
7343 16c00cb2 ths
            break;
7344 5a5012ec ths
        case BS_BRANCH:
7345 5a5012ec ths
        default:
7346 5a5012ec ths
            break;
7347 16c00cb2 ths
        }
7348 6af0bf9c bellard
    }
7349 4ad40f36 bellard
done_generating:
7350 6af0bf9c bellard
    *gen_opc_ptr = INDEX_op_end;
7351 6af0bf9c bellard
    if (search_pc) {
7352 6af0bf9c bellard
        j = gen_opc_ptr - gen_opc_buf;
7353 6af0bf9c bellard
        lj++;
7354 6af0bf9c bellard
        while (lj <= j)
7355 6af0bf9c bellard
            gen_opc_instr_start[lj++] = 0;
7356 6af0bf9c bellard
    } else {
7357 6af0bf9c bellard
        tb->size = ctx.pc - pc_start;
7358 6af0bf9c bellard
    }
7359 6af0bf9c bellard
#ifdef DEBUG_DISAS
7360 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
7361 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
7362 6af0bf9c bellard
        fprintf(logfile, "\n");
7363 6af0bf9c bellard
#endif
7364 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7365 6af0bf9c bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7366 9898128f ths
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7367 6af0bf9c bellard
        fprintf(logfile, "\n");
7368 6af0bf9c bellard
    }
7369 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
7370 6af0bf9c bellard
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7371 6af0bf9c bellard
    }
7372 6af0bf9c bellard
#endif
7373 3b46e624 ths
7374 6af0bf9c bellard
    return 0;
7375 6af0bf9c bellard
}
7376 6af0bf9c bellard
7377 6af0bf9c bellard
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7378 6af0bf9c bellard
{
7379 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 0);
7380 6af0bf9c bellard
}
7381 6af0bf9c bellard
7382 6af0bf9c bellard
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7383 6af0bf9c bellard
{
7384 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 1);
7385 6af0bf9c bellard
}
7386 6af0bf9c bellard
7387 5fafdf24 ths
void fpu_dump_state(CPUState *env, FILE *f,
7388 6ea83fed bellard
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7389 6ea83fed bellard
                    int flags)
7390 6ea83fed bellard
{
7391 6ea83fed bellard
    int i;
7392 5e755519 ths
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7393 5a5012ec ths
7394 5a5012ec ths
#define printfpr(fp)                                                        \
7395 5a5012ec ths
    do {                                                                    \
7396 5a5012ec ths
        if (is_fpu64)                                                       \
7397 5a5012ec ths
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
7398 5a5012ec ths
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
7399 5a5012ec ths
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7400 5a5012ec ths
        else {                                                              \
7401 5a5012ec ths
            fpr_t tmp;                                                      \
7402 5a5012ec ths
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
7403 5a5012ec ths
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
7404 5a5012ec ths
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
7405 5a5012ec ths
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
7406 5a5012ec ths
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
7407 5a5012ec ths
        }                                                                   \
7408 6ea83fed bellard
    } while(0)
7409 6ea83fed bellard
7410 5a5012ec ths
7411 5a5012ec ths
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
7412 ead9360e ths
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7413 ead9360e ths
                get_float_exception_flags(&env->fpu->fp_status));
7414 ead9360e ths
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
7415 ead9360e ths
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
7416 ead9360e ths
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
7417 5a5012ec ths
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7418 5a5012ec ths
        fpu_fprintf(f, "%3s: ", fregnames[i]);
7419 ead9360e ths
        printfpr(&env->fpu->fpr[i]);
7420 6ea83fed bellard
    }
7421 6ea83fed bellard
7422 6ea83fed bellard
#undef printfpr
7423 6ea83fed bellard
}
7424 6ea83fed bellard
7425 7a387fff ths
void dump_fpu (CPUState *env)
7426 6ea83fed bellard
{
7427 5fafdf24 ths
    if (loglevel) {
7428 958fb4a9 ths
        fprintf(logfile,
7429 958fb4a9 ths
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7430 958fb4a9 ths
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7431 958fb4a9 ths
                " %04x\n",
7432 958fb4a9 ths
                env->PC[env->current_tc], env->HI[env->current_tc][0],
7433 958fb4a9 ths
                env->LO[env->current_tc][0], env->hflags, env->btarget,
7434 958fb4a9 ths
                env->bcond);
7435 6ea83fed bellard
       fpu_dump_state(env, logfile, fprintf, 0);
7436 6ea83fed bellard
    }
7437 6ea83fed bellard
}
7438 6ea83fed bellard
7439 d26bc211 ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7440 c570fd16 ths
/* Debug help: The architecture requires 32bit code to maintain proper
7441 c570fd16 ths
   sign-extened values on 64bit machines.  */
7442 c570fd16 ths
7443 c570fd16 ths
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7444 c570fd16 ths
7445 c570fd16 ths
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7446 c570fd16 ths
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7447 c570fd16 ths
                     int flags)
7448 c570fd16 ths
{
7449 c570fd16 ths
    int i;
7450 c570fd16 ths
7451 ead9360e ths
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7452 ead9360e ths
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7453 d0dc7dc3 ths
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7454 d0dc7dc3 ths
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7455 d0dc7dc3 ths
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7456 d0dc7dc3 ths
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7457 c570fd16 ths
    if (!SIGN_EXT_P(env->btarget))
7458 3594c774 ths
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7459 c570fd16 ths
7460 c570fd16 ths
    for (i = 0; i < 32; i++) {
7461 d0dc7dc3 ths
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7462 d0dc7dc3 ths
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7463 c570fd16 ths
    }
7464 c570fd16 ths
7465 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_EPC))
7466 3594c774 ths
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7467 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7468 3594c774 ths
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7469 c570fd16 ths
}
7470 c570fd16 ths
#endif
7471 c570fd16 ths
7472 5fafdf24 ths
void cpu_dump_state (CPUState *env, FILE *f,
7473 6af0bf9c bellard
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7474 6af0bf9c bellard
                     int flags)
7475 6af0bf9c bellard
{
7476 6af0bf9c bellard
    int i;
7477 3b46e624 ths
7478 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",
7479 ead9360e ths
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7480 6af0bf9c bellard
    for (i = 0; i < 32; i++) {
7481 6af0bf9c bellard
        if ((i & 3) == 0)
7482 6af0bf9c bellard
            cpu_fprintf(f, "GPR%02d:", i);
7483 d0dc7dc3 ths
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7484 6af0bf9c bellard
        if ((i & 3) == 3)
7485 6af0bf9c bellard
            cpu_fprintf(f, "\n");
7486 6af0bf9c bellard
    }
7487 568b600d bellard
7488 3594c774 ths
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7489 5e755519 ths
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7490 3594c774 ths
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7491 6af0bf9c bellard
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7492 5e755519 ths
    if (env->hflags & MIPS_HFLAG_FPU)
7493 7a387fff ths
        fpu_dump_state(env, f, cpu_fprintf, flags);
7494 d26bc211 ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7495 c570fd16 ths
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7496 c570fd16 ths
#endif
7497 6af0bf9c bellard
}
7498 6af0bf9c bellard
7499 39454628 ths
static void mips_tcg_init(void)
7500 39454628 ths
{
7501 39454628 ths
    static int inited;
7502 39454628 ths
7503 39454628 ths
    /* Initialize various static tables. */
7504 39454628 ths
    if (inited)
7505 39454628 ths
        return;
7506 39454628 ths
7507 39454628 ths
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7508 958fb4a9 ths
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7509 958fb4a9 ths
                                         TCG_AREG0,
7510 958fb4a9 ths
                                         offsetof(CPUState, current_tc_gprs),
7511 958fb4a9 ths
                                         "current_tc_gprs");
7512 893f9865 ths
    current_tc_hi = tcg_global_mem_new(TCG_TYPE_PTR,
7513 893f9865 ths
                                       TCG_AREG0,
7514 893f9865 ths
                                       offsetof(CPUState, current_tc_hi),
7515 893f9865 ths
                                       "current_tc_hi");
7516 39454628 ths
#if TARGET_LONG_BITS > HOST_LONG_BITS
7517 39454628 ths
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7518 39454628 ths
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7519 39454628 ths
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7520 39454628 ths
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7521 39454628 ths
#else
7522 958fb4a9 ths
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7523 958fb4a9 ths
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7524 39454628 ths
#endif
7525 39454628 ths
7526 39454628 ths
    inited = 1;
7527 39454628 ths
}
7528 39454628 ths
7529 aaed909a bellard
#include "translate_init.c"
7530 aaed909a bellard
7531 aaed909a bellard
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7532 6af0bf9c bellard
{
7533 6af0bf9c bellard
    CPUMIPSState *env;
7534 aaed909a bellard
    const mips_def_t *def;
7535 6af0bf9c bellard
7536 aaed909a bellard
    def = cpu_mips_find_by_name(cpu_model);
7537 aaed909a bellard
    if (!def)
7538 aaed909a bellard
        return NULL;
7539 6af0bf9c bellard
    env = qemu_mallocz(sizeof(CPUMIPSState));
7540 6af0bf9c bellard
    if (!env)
7541 6af0bf9c bellard
        return NULL;
7542 aaed909a bellard
    env->cpu_model = def;
7543 aaed909a bellard
7544 173d6cfe bellard
    cpu_exec_init(env);
7545 01ba9816 ths
    env->cpu_model_str = cpu_model;
7546 39454628 ths
    mips_tcg_init();
7547 6ae81775 ths
    cpu_reset(env);
7548 6ae81775 ths
    return env;
7549 6ae81775 ths
}
7550 6ae81775 ths
7551 6ae81775 ths
void cpu_reset (CPUMIPSState *env)
7552 6ae81775 ths
{
7553 6ae81775 ths
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7554 6ae81775 ths
7555 6af0bf9c bellard
    tlb_flush(env, 1);
7556 6ae81775 ths
7557 6af0bf9c bellard
    /* Minimal init */
7558 ca7c2b1b ths
#if !defined(CONFIG_USER_ONLY)
7559 aa328add ths
    if (env->hflags & MIPS_HFLAG_BMASK) {
7560 aa328add ths
        /* If the exception was raised from a delay slot,
7561 aa328add ths
         * come back to the jump.  */
7562 ead9360e ths
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7563 aa328add ths
    } else {
7564 ead9360e ths
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7565 aa328add ths
    }
7566 ead9360e ths
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7567 6af0bf9c bellard
    env->CP0_Wired = 0;
7568 7a387fff ths
    /* SMP not implemented */
7569 b29a0341 ths
    env->CP0_EBase = 0x80000000;
7570 aa328add ths
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7571 c090a8f4 ths
    /* vectored interrupts not implemented, timer on int 7,
7572 c090a8f4 ths
       no performance counters. */
7573 c090a8f4 ths
    env->CP0_IntCtl = 0xe0000000;
7574 fd88b6ab ths
    {
7575 fd88b6ab ths
        int i;
7576 fd88b6ab ths
7577 fd88b6ab ths
        for (i = 0; i < 7; i++) {
7578 fd88b6ab ths
            env->CP0_WatchLo[i] = 0;
7579 fd88b6ab ths
            env->CP0_WatchHi[i] = 0x80000000;
7580 fd88b6ab ths
        }
7581 fd88b6ab ths
        env->CP0_WatchLo[7] = 0;
7582 fd88b6ab ths
        env->CP0_WatchHi[7] = 0;
7583 fd88b6ab ths
    }
7584 6af0bf9c bellard
    /* Count register increments in debug mode, EJTAG version 1 */
7585 6af0bf9c bellard
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7586 ca7c2b1b ths
#endif
7587 6af0bf9c bellard
    env->exception_index = EXCP_NONE;
7588 eeef26cd bellard
#if defined(CONFIG_USER_ONLY)
7589 387a8fe5 ths
    env->hflags = MIPS_HFLAG_UM;
7590 ca7c2b1b ths
    env->user_mode_only = 1;
7591 387a8fe5 ths
#else
7592 387a8fe5 ths
    env->hflags = MIPS_HFLAG_CP0;
7593 eeef26cd bellard
#endif
7594 aaed909a bellard
    cpu_mips_register(env, env->cpu_model);
7595 6af0bf9c bellard
}
7596 d2856f1a aurel32
7597 d2856f1a aurel32
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7598 d2856f1a aurel32
                unsigned long searched_pc, int pc_pos, void *puc)
7599 d2856f1a aurel32
{
7600 d2856f1a aurel32
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7601 d2856f1a aurel32
    env->hflags &= ~MIPS_HFLAG_BMASK;
7602 d2856f1a aurel32
    env->hflags |= gen_opc_hflags[pc_pos];
7603 d2856f1a aurel32
}