Statistics
| Branch: | Revision:

root / target-mips / translate.c @ f0b3f3ae

History | View | Annotate | Download (221.2 kB)

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