Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 7a387fff

History | View | Annotate | Download (110 kB)

1 6af0bf9c bellard
/*
2 6af0bf9c bellard
 *  MIPS32 emulation for qemu: main translation routines.
3 6af0bf9c bellard
 * 
4 6af0bf9c bellard
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5 6ea83fed bellard
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6 6af0bf9c bellard
 *
7 6af0bf9c bellard
 * This library is free software; you can redistribute it and/or
8 6af0bf9c bellard
 * modify it under the terms of the GNU Lesser General Public
9 6af0bf9c bellard
 * License as published by the Free Software Foundation; either
10 6af0bf9c bellard
 * version 2 of the License, or (at your option) any later version.
11 6af0bf9c bellard
 *
12 6af0bf9c bellard
 * This library is distributed in the hope that it will be useful,
13 6af0bf9c bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 6af0bf9c bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 6af0bf9c bellard
 * Lesser General Public License for more details.
16 6af0bf9c bellard
 *
17 6af0bf9c bellard
 * You should have received a copy of the GNU Lesser General Public
18 6af0bf9c bellard
 * License along with this library; if not, write to the Free Software
19 6af0bf9c bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 6af0bf9c bellard
 */
21 6af0bf9c bellard
22 6af0bf9c bellard
#include <stdarg.h>
23 6af0bf9c bellard
#include <stdlib.h>
24 6af0bf9c bellard
#include <stdio.h>
25 6af0bf9c bellard
#include <string.h>
26 6af0bf9c bellard
#include <inttypes.h>
27 6af0bf9c bellard
28 6af0bf9c bellard
#include "cpu.h"
29 6af0bf9c bellard
#include "exec-all.h"
30 6af0bf9c bellard
#include "disas.h"
31 6af0bf9c bellard
32 eeef26cd bellard
//#define MIPS_DEBUG_DISAS
33 6af0bf9c bellard
//#define MIPS_SINGLE_STEP
34 6af0bf9c bellard
35 c53be334 bellard
#ifdef USE_DIRECT_JUMP
36 c53be334 bellard
#define TBPARAM(x)
37 c53be334 bellard
#else
38 c53be334 bellard
#define TBPARAM(x) (long)(x)
39 c53be334 bellard
#endif
40 c53be334 bellard
41 6af0bf9c bellard
enum {
42 6af0bf9c bellard
#define DEF(s, n, copy_size) INDEX_op_ ## s,
43 6af0bf9c bellard
#include "opc.h"
44 6af0bf9c bellard
#undef DEF
45 6af0bf9c bellard
    NB_OPS,
46 6af0bf9c bellard
};
47 6af0bf9c bellard
48 6af0bf9c bellard
static uint16_t *gen_opc_ptr;
49 6af0bf9c bellard
static uint32_t *gen_opparam_ptr;
50 6af0bf9c bellard
51 6af0bf9c bellard
#include "gen-op.h"
52 6af0bf9c bellard
53 7a387fff ths
/* MIPS major opcodes */
54 7a387fff ths
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
55 e37e863f bellard
56 e37e863f bellard
enum {
57 e37e863f bellard
    /* indirect opcode tables */
58 7a387fff ths
    OPC_SPECIAL  = (0x00 << 26),
59 7a387fff ths
    OPC_REGIMM   = (0x01 << 26),
60 7a387fff ths
    OPC_CP0      = (0x10 << 26),
61 7a387fff ths
    OPC_CP1      = (0x11 << 26),
62 7a387fff ths
    OPC_CP2      = (0x12 << 26),
63 7a387fff ths
    OPC_CP3      = (0x13 << 26),
64 7a387fff ths
    OPC_SPECIAL2 = (0x1C << 26),
65 7a387fff ths
    OPC_SPECIAL3 = (0x1F << 26),
66 e37e863f bellard
    /* arithmetic with immediate */
67 7a387fff ths
    OPC_ADDI     = (0x08 << 26),
68 7a387fff ths
    OPC_ADDIU    = (0x09 << 26),
69 7a387fff ths
    OPC_SLTI     = (0x0A << 26),
70 7a387fff ths
    OPC_SLTIU    = (0x0B << 26),
71 7a387fff ths
    OPC_ANDI     = (0x0C << 26),
72 7a387fff ths
    OPC_ORI      = (0x0D << 26),
73 7a387fff ths
    OPC_XORI     = (0x0E << 26),
74 7a387fff ths
    OPC_LUI      = (0x0F << 26),
75 7a387fff ths
    OPC_DADDI    = (0x18 << 26),
76 7a387fff ths
    OPC_DADDIU   = (0x19 << 26),
77 e37e863f bellard
    /* Jump and branches */
78 7a387fff ths
    OPC_J        = (0x02 << 26),
79 7a387fff ths
    OPC_JAL      = (0x03 << 26),
80 7a387fff ths
    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
81 7a387fff ths
    OPC_BEQL     = (0x14 << 26),
82 7a387fff ths
    OPC_BNE      = (0x05 << 26),
83 7a387fff ths
    OPC_BNEL     = (0x15 << 26),
84 7a387fff ths
    OPC_BLEZ     = (0x06 << 26),
85 7a387fff ths
    OPC_BLEZL    = (0x16 << 26),
86 7a387fff ths
    OPC_BGTZ     = (0x07 << 26),
87 7a387fff ths
    OPC_BGTZL    = (0x17 << 26),
88 7a387fff ths
    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
89 e37e863f bellard
    /* Load and stores */
90 7a387fff ths
    OPC_LDL      = (0x1A << 26),
91 7a387fff ths
    OPC_LDR      = (0x1B << 26),
92 7a387fff ths
    OPC_LB       = (0x20 << 26),
93 7a387fff ths
    OPC_LH       = (0x21 << 26),
94 7a387fff ths
    OPC_LWL      = (0x22 << 26),
95 7a387fff ths
    OPC_LW       = (0x23 << 26),
96 7a387fff ths
    OPC_LBU      = (0x24 << 26),
97 7a387fff ths
    OPC_LHU      = (0x25 << 26),
98 7a387fff ths
    OPC_LWR      = (0x26 << 26),
99 7a387fff ths
    OPC_LWU      = (0x27 << 26),
100 7a387fff ths
    OPC_SB       = (0x28 << 26),
101 7a387fff ths
    OPC_SH       = (0x29 << 26),
102 7a387fff ths
    OPC_SWL      = (0x2A << 26),
103 7a387fff ths
    OPC_SW       = (0x2B << 26),
104 7a387fff ths
    OPC_SDL      = (0x2C << 26),
105 7a387fff ths
    OPC_SDR      = (0x2D << 26),
106 7a387fff ths
    OPC_SWR      = (0x2E << 26),
107 7a387fff ths
    OPC_LL       = (0x30 << 26),
108 7a387fff ths
    OPC_LLD      = (0x34 << 26),
109 7a387fff ths
    OPC_LD       = (0x37 << 26),
110 7a387fff ths
    OPC_SC       = (0x38 << 26),
111 7a387fff ths
    OPC_SCD      = (0x3C << 26),
112 7a387fff ths
    OPC_SD       = (0x3F << 26),
113 e37e863f bellard
    /* Floating point load/store */
114 7a387fff ths
    OPC_LWC1     = (0x31 << 26),
115 7a387fff ths
    OPC_LWC2     = (0x32 << 26),
116 7a387fff ths
    OPC_LDC1     = (0x35 << 26),
117 7a387fff ths
    OPC_LDC2     = (0x36 << 26),
118 7a387fff ths
    OPC_SWC1     = (0x39 << 26),
119 7a387fff ths
    OPC_SWC2     = (0x3A << 26),
120 7a387fff ths
    OPC_SDC1     = (0x3D << 26),
121 7a387fff ths
    OPC_SDC2     = (0x3E << 26),
122 7a387fff ths
    /* MDMX ASE specific */
123 7a387fff ths
    OPC_MDMX     = (0x1E << 26),
124 e37e863f bellard
    /* Cache and prefetch */
125 7a387fff ths
    OPC_CACHE    = (0x2F << 26),
126 7a387fff ths
    OPC_PREF     = (0x33 << 26),
127 7a387fff ths
    /* Reserved major opcode */
128 7a387fff ths
    OPC_MAJOR3B_RESERVED = (0x3B << 26),
129 e37e863f bellard
};
130 e37e863f bellard
131 e37e863f bellard
/* MIPS special opcodes */
132 7a387fff ths
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
133 7a387fff ths
134 e37e863f bellard
enum {
135 e37e863f bellard
    /* Shifts */
136 7a387fff ths
    OPC_SLL      = 0x00 | OPC_SPECIAL,
137 e37e863f bellard
    /* NOP is SLL r0, r0, 0   */
138 e37e863f bellard
    /* SSNOP is SLL r0, r0, 1 */
139 7a387fff ths
    /* EHB is SLL r0, r0, 3 */
140 7a387fff ths
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
141 7a387fff ths
    OPC_SRA      = 0x03 | OPC_SPECIAL,
142 7a387fff ths
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
143 7a387fff ths
    OPC_SRLV     = 0x06 | OPC_SPECIAL,
144 7a387fff ths
    OPC_SRAV     = 0x07 | OPC_SPECIAL,
145 7a387fff ths
    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
146 7a387fff ths
    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
147 7a387fff ths
    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
148 7a387fff ths
    OPC_DSLL     = 0x38 | OPC_SPECIAL,
149 7a387fff ths
    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
150 7a387fff ths
    OPC_DSRA     = 0x3B | OPC_SPECIAL,
151 7a387fff ths
    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
152 7a387fff ths
    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
153 7a387fff ths
    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
154 e37e863f bellard
    /* Multiplication / division */
155 7a387fff ths
    OPC_MULT     = 0x18 | OPC_SPECIAL,
156 7a387fff ths
    OPC_MULTU    = 0x19 | OPC_SPECIAL,
157 7a387fff ths
    OPC_DIV      = 0x1A | OPC_SPECIAL,
158 7a387fff ths
    OPC_DIVU     = 0x1B | OPC_SPECIAL,
159 7a387fff ths
    OPC_DMULT    = 0x1C | OPC_SPECIAL,
160 7a387fff ths
    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
161 7a387fff ths
    OPC_DDIV     = 0x1E | OPC_SPECIAL,
162 7a387fff ths
    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
163 e37e863f bellard
    /* 2 registers arithmetic / logic */
164 7a387fff ths
    OPC_ADD      = 0x20 | OPC_SPECIAL,
165 7a387fff ths
    OPC_ADDU     = 0x21 | OPC_SPECIAL,
166 7a387fff ths
    OPC_SUB      = 0x22 | OPC_SPECIAL,
167 7a387fff ths
    OPC_SUBU     = 0x23 | OPC_SPECIAL,
168 7a387fff ths
    OPC_AND      = 0x24 | OPC_SPECIAL,
169 7a387fff ths
    OPC_OR       = 0x25 | OPC_SPECIAL,
170 7a387fff ths
    OPC_XOR      = 0x26 | OPC_SPECIAL,
171 7a387fff ths
    OPC_NOR      = 0x27 | OPC_SPECIAL,
172 7a387fff ths
    OPC_SLT      = 0x2A | OPC_SPECIAL,
173 7a387fff ths
    OPC_SLTU     = 0x2B | OPC_SPECIAL,
174 7a387fff ths
    OPC_DADD     = 0x2C | OPC_SPECIAL,
175 7a387fff ths
    OPC_DADDU    = 0x2D | OPC_SPECIAL,
176 7a387fff ths
    OPC_DSUB     = 0x2E | OPC_SPECIAL,
177 7a387fff ths
    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
178 e37e863f bellard
    /* Jumps */
179 7a387fff ths
    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
180 7a387fff ths
    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
181 e37e863f bellard
    /* Traps */
182 7a387fff ths
    OPC_TGE      = 0x30 | OPC_SPECIAL,
183 7a387fff ths
    OPC_TGEU     = 0x31 | OPC_SPECIAL,
184 7a387fff ths
    OPC_TLT      = 0x32 | OPC_SPECIAL,
185 7a387fff ths
    OPC_TLTU     = 0x33 | OPC_SPECIAL,
186 7a387fff ths
    OPC_TEQ      = 0x34 | OPC_SPECIAL,
187 7a387fff ths
    OPC_TNE      = 0x36 | OPC_SPECIAL,
188 e37e863f bellard
    /* HI / LO registers load & stores */
189 7a387fff ths
    OPC_MFHI     = 0x10 | OPC_SPECIAL,
190 7a387fff ths
    OPC_MTHI     = 0x11 | OPC_SPECIAL,
191 7a387fff ths
    OPC_MFLO     = 0x12 | OPC_SPECIAL,
192 7a387fff ths
    OPC_MTLO     = 0x13 | OPC_SPECIAL,
193 e37e863f bellard
    /* Conditional moves */
194 7a387fff ths
    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
195 7a387fff ths
    OPC_MOVN     = 0x0B | OPC_SPECIAL,
196 e37e863f bellard
197 7a387fff ths
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
198 e37e863f bellard
199 e37e863f bellard
    /* Special */
200 7a387fff ths
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
201 7a387fff ths
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
202 7a387fff ths
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
203 7a387fff ths
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
204 7a387fff ths
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
205 7a387fff ths
206 7a387fff ths
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
207 7a387fff ths
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
208 7a387fff ths
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
209 7a387fff ths
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
210 7a387fff ths
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
211 7a387fff ths
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
212 7a387fff ths
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
213 7a387fff ths
};
214 7a387fff ths
215 7a387fff ths
/* REGIMM (rt field) opcodes */
216 7a387fff ths
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
217 7a387fff ths
218 7a387fff ths
enum {
219 7a387fff ths
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
220 7a387fff ths
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
221 7a387fff ths
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
222 7a387fff ths
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
223 7a387fff ths
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
224 7a387fff ths
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
225 7a387fff ths
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
226 7a387fff ths
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
227 7a387fff ths
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
228 7a387fff ths
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
229 7a387fff ths
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
230 7a387fff ths
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
231 7a387fff ths
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
232 7a387fff ths
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
233 7a387fff ths
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
234 e37e863f bellard
};
235 e37e863f bellard
236 7a387fff ths
/* Special2 opcodes */
237 7a387fff ths
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
238 7a387fff ths
239 e37e863f bellard
enum {
240 7a387fff ths
    /* Multiply & xxx operations */
241 7a387fff ths
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
242 7a387fff ths
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
243 7a387fff ths
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
244 7a387fff ths
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
245 7a387fff ths
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
246 e37e863f bellard
    /* Misc */
247 7a387fff ths
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
248 7a387fff ths
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
249 7a387fff ths
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
250 7a387fff ths
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
251 e37e863f bellard
    /* Special */
252 7a387fff ths
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
253 7a387fff ths
};
254 7a387fff ths
255 7a387fff ths
/* Special3 opcodes */
256 7a387fff ths
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
257 7a387fff ths
258 7a387fff ths
enum {
259 7a387fff ths
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
260 7a387fff ths
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
261 7a387fff ths
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
262 7a387fff ths
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
263 7a387fff ths
    OPC_INS      = 0x04 | OPC_SPECIAL3,
264 7a387fff ths
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
265 7a387fff ths
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
266 7a387fff ths
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
267 7a387fff ths
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
268 7a387fff ths
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
269 7a387fff ths
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
270 e37e863f bellard
};
271 e37e863f bellard
272 7a387fff ths
/* BSHFL opcodes */
273 7a387fff ths
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
274 7a387fff ths
275 e37e863f bellard
enum {
276 7a387fff ths
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
277 7a387fff ths
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
278 7a387fff ths
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
279 e37e863f bellard
};
280 e37e863f bellard
281 7a387fff ths
/* DBSHFL opcodes */
282 7a387fff ths
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
283 7a387fff ths
284 e37e863f bellard
enum {
285 7a387fff ths
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
286 7a387fff ths
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
287 e37e863f bellard
};
288 e37e863f bellard
289 7a387fff ths
/* Coprocessor 0 (rs field) */
290 7a387fff ths
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
291 7a387fff ths
292 6ea83fed bellard
enum {
293 7a387fff ths
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
294 7a387fff ths
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
295 7a387fff ths
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
296 7a387fff ths
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
297 7a387fff ths
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
298 7a387fff ths
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
299 7a387fff ths
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
300 7a387fff ths
    OPC_C0       = (0x10 << 21) | OPC_CP0,
301 7a387fff ths
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
302 7a387fff ths
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
303 6ea83fed bellard
};
304 7a387fff ths
305 7a387fff ths
/* MFMC0 opcodes */
306 7a387fff ths
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & ((0x0C << 11) | (1 << 5)))
307 7a387fff ths
308 7a387fff ths
enum {
309 7a387fff ths
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
310 7a387fff ths
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
311 7a387fff ths
};
312 7a387fff ths
313 7a387fff ths
/* Coprocessor 0 (with rs == C0) */
314 7a387fff ths
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
315 7a387fff ths
316 7a387fff ths
enum {
317 7a387fff ths
    OPC_TLBR     = 0x01 | OPC_C0,
318 7a387fff ths
    OPC_TLBWI    = 0x02 | OPC_C0,
319 7a387fff ths
    OPC_TLBWR    = 0x06 | OPC_C0,
320 7a387fff ths
    OPC_TLBP     = 0x08 | OPC_C0,
321 7a387fff ths
    OPC_RFE      = 0x10 | OPC_C0,
322 7a387fff ths
    OPC_ERET     = 0x18 | OPC_C0,
323 7a387fff ths
    OPC_DERET    = 0x1F | OPC_C0,
324 7a387fff ths
    OPC_WAIT     = 0x20 | OPC_C0,
325 7a387fff ths
};
326 7a387fff ths
327 7a387fff ths
/* Coprocessor 1 (rs field) */
328 7a387fff ths
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
329 7a387fff ths
330 7a387fff ths
enum {
331 7a387fff ths
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
332 7a387fff ths
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
333 7a387fff ths
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
334 7a387fff ths
    OPC_MFHCI    = (0x03 << 21) | OPC_CP1,
335 7a387fff ths
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
336 7a387fff ths
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
337 7a387fff ths
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
338 7a387fff ths
    OPC_MTHCI    = (0x07 << 21) | OPC_CP1,
339 7a387fff ths
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
340 7a387fff ths
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
341 7a387fff ths
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
342 7a387fff ths
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
343 7a387fff ths
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
344 7a387fff ths
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
345 7a387fff ths
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
346 7a387fff ths
};
347 7a387fff ths
348 7a387fff ths
enum {
349 7a387fff ths
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
350 7a387fff ths
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
351 7a387fff ths
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
352 7a387fff ths
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
353 7a387fff ths
};
354 7a387fff ths
355 7a387fff ths
#define MASK_CP1_BCOND(op)      MASK_CP1(op) | (op & ((0x1F << 21) | (0x3 << 16)))
356 7a387fff ths
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & ((0x1F << 21) | 0x3F))
357 7a387fff ths
358 7a387fff ths
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
359 7a387fff ths
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
360 6ea83fed bellard
361 6af0bf9c bellard
const unsigned char *regnames[] =
362 6af0bf9c bellard
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
363 6af0bf9c bellard
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
364 6af0bf9c bellard
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
365 6af0bf9c bellard
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
366 6af0bf9c bellard
367 6af0bf9c bellard
/* Warning: no function for r0 register (hard wired to zero) */
368 6af0bf9c bellard
#define GEN32(func, NAME) \
369 6af0bf9c bellard
static GenOpFunc *NAME ## _table [32] = {                                     \
370 6af0bf9c bellard
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,                                  \
371 6af0bf9c bellard
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,                                  \
372 6af0bf9c bellard
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,                                \
373 6af0bf9c bellard
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
374 6af0bf9c bellard
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
375 6af0bf9c bellard
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
376 6af0bf9c bellard
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
377 6af0bf9c bellard
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
378 6af0bf9c bellard
};                                                                            \
379 6af0bf9c bellard
static inline void func(int n)                                                \
380 6af0bf9c bellard
{                                                                             \
381 6af0bf9c bellard
    NAME ## _table[n]();                                                      \
382 6af0bf9c bellard
}
383 6af0bf9c bellard
384 6af0bf9c bellard
/* General purpose registers moves */
385 6af0bf9c bellard
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
386 6af0bf9c bellard
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
387 6af0bf9c bellard
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
388 6af0bf9c bellard
389 6af0bf9c bellard
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
390 6af0bf9c bellard
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
391 6af0bf9c bellard
392 7a387fff ths
static const char *fregnames[] =
393 6ea83fed bellard
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
394 6ea83fed bellard
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
395 6ea83fed bellard
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
396 6ea83fed bellard
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
397 6ea83fed bellard
398 6ea83fed bellard
# define SFGEN32(func, NAME) \
399 6ea83fed bellard
static GenOpFunc *NAME ## _table [32] = {                                     \
400 6ea83fed bellard
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,                                \
401 6ea83fed bellard
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,                                \
402 6ea83fed bellard
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,                               \
403 6ea83fed bellard
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
404 6ea83fed bellard
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
405 6ea83fed bellard
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
406 6ea83fed bellard
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
407 6ea83fed bellard
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
408 6ea83fed bellard
};                                                                            \
409 6ea83fed bellard
static inline void func(int n)                                                \
410 6ea83fed bellard
{                                                                             \
411 6ea83fed bellard
    NAME ## _table[n]();                                                      \
412 6ea83fed bellard
}
413 6ea83fed bellard
414 6ea83fed bellard
# define DFGEN32(func, NAME) \
415 6ea83fed bellard
static GenOpFunc *NAME ## _table [32] = {                                     \
416 6ea83fed bellard
NAME ## 0,  0, NAME ## 2,  0,                                                 \
417 6ea83fed bellard
NAME ## 4,  0, NAME ## 6,  0,                                                 \
418 6ea83fed bellard
NAME ## 8,  0, NAME ## 10, 0,                                                 \
419 6ea83fed bellard
NAME ## 12, 0, NAME ## 14, 0,                                                 \
420 6ea83fed bellard
NAME ## 16, 0, NAME ## 18, 0,                                                 \
421 6ea83fed bellard
NAME ## 20, 0, NAME ## 22, 0,                                                 \
422 6ea83fed bellard
NAME ## 24, 0, NAME ## 26, 0,                                                 \
423 6ea83fed bellard
NAME ## 28, 0, NAME ## 30, 0,                                                 \
424 6ea83fed bellard
};                                                                            \
425 6ea83fed bellard
static inline void func(int n)                                                \
426 6ea83fed bellard
{                                                                             \
427 6ea83fed bellard
    NAME ## _table[n]();                                                      \
428 6ea83fed bellard
}
429 6ea83fed bellard
430 6ea83fed bellard
SFGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
431 6ea83fed bellard
SFGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
432 6ea83fed bellard
433 6ea83fed bellard
SFGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
434 6ea83fed bellard
SFGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
435 6ea83fed bellard
436 6ea83fed bellard
SFGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
437 6ea83fed bellard
SFGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
438 6ea83fed bellard
439 6ea83fed bellard
DFGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
440 6ea83fed bellard
DFGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
441 6ea83fed bellard
442 6ea83fed bellard
DFGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
443 6ea83fed bellard
DFGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
444 6ea83fed bellard
445 6ea83fed bellard
DFGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
446 6ea83fed bellard
DFGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
447 6ea83fed bellard
448 6ea83fed bellard
#define FOP_CONDS(fmt) \
449 6ea83fed bellard
static GenOpFunc * cond_ ## fmt ## _table[16] = {                       \
450 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _f,                                           \
451 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _un,                                          \
452 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _eq,                                          \
453 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ueq,                                         \
454 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _olt,                                         \
455 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ult,                                         \
456 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ole,                                         \
457 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ule,                                         \
458 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _sf,                                          \
459 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ngle,                                        \
460 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _seq,                                         \
461 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ngl,                                         \
462 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _lt,                                          \
463 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _nge,                                         \
464 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _le,                                          \
465 6ea83fed bellard
    gen_op_cmp_ ## fmt ## _ngt,                                         \
466 6ea83fed bellard
};                                                                      \
467 6ea83fed bellard
static inline void gen_cmp_ ## fmt(int n)                               \
468 6ea83fed bellard
{                                                                       \
469 6ea83fed bellard
    cond_ ## fmt ## _table[n]();                                        \
470 6ea83fed bellard
}
471 6ea83fed bellard
472 6ea83fed bellard
FOP_CONDS(d)
473 6ea83fed bellard
FOP_CONDS(s)
474 6ea83fed bellard
475 6af0bf9c bellard
typedef struct DisasContext {
476 6af0bf9c bellard
    struct TranslationBlock *tb;
477 6af0bf9c bellard
    target_ulong pc, saved_pc;
478 6af0bf9c bellard
    uint32_t opcode;
479 6af0bf9c bellard
    /* Routine used to access memory */
480 6af0bf9c bellard
    int mem_idx;
481 6af0bf9c bellard
    uint32_t hflags, saved_hflags;
482 6af0bf9c bellard
    uint32_t CP0_Status;
483 6af0bf9c bellard
    int bstate;
484 6af0bf9c bellard
    target_ulong btarget;
485 6af0bf9c bellard
} DisasContext;
486 6af0bf9c bellard
487 6af0bf9c bellard
enum {
488 6af0bf9c bellard
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
489 6af0bf9c bellard
                      * exception condition
490 6af0bf9c bellard
                      */
491 6af0bf9c bellard
    BS_STOP     = 1, /* We want to stop translation for any reason */
492 6af0bf9c bellard
    BS_BRANCH   = 2, /* We reached a branch condition     */
493 6af0bf9c bellard
    BS_EXCP     = 3, /* We reached an exception condition */
494 6af0bf9c bellard
};
495 6af0bf9c bellard
496 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
497 6af0bf9c bellard
#define MIPS_DEBUG(fmt, args...)                                              \
498 6af0bf9c bellard
do {                                                                          \
499 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
500 6af0bf9c bellard
        fprintf(logfile, "%08x: %08x " fmt "\n",                              \
501 6af0bf9c bellard
                ctx->pc, ctx->opcode , ##args);                               \
502 6af0bf9c bellard
    }                                                                         \
503 6af0bf9c bellard
} while (0)
504 6af0bf9c bellard
#else
505 6af0bf9c bellard
#define MIPS_DEBUG(fmt, args...) do { } while(0)
506 6af0bf9c bellard
#endif
507 6af0bf9c bellard
508 6af0bf9c bellard
#define MIPS_INVAL(op)                                                        \
509 6af0bf9c bellard
do {                                                                          \
510 6af0bf9c bellard
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
511 6af0bf9c bellard
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
512 6af0bf9c bellard
} while (0)
513 6af0bf9c bellard
514 6af0bf9c bellard
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
515 6af0bf9c bellard
do {                                                                          \
516 6af0bf9c bellard
    if (Rn == 0) {                                                            \
517 6af0bf9c bellard
        glue(gen_op_reset_, Tn)();                                            \
518 6af0bf9c bellard
    } else {                                                                  \
519 6af0bf9c bellard
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
520 6af0bf9c bellard
    }                                                                         \
521 6af0bf9c bellard
} while (0)
522 6af0bf9c bellard
523 6af0bf9c bellard
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
524 6af0bf9c bellard
do {                                                                          \
525 6af0bf9c bellard
    if (Imm == 0) {                                                           \
526 6af0bf9c bellard
        glue(gen_op_reset_, Tn)();                                            \
527 6af0bf9c bellard
    } else {                                                                  \
528 6af0bf9c bellard
        glue(gen_op_set_, Tn)(Imm);                                           \
529 6af0bf9c bellard
    }                                                                         \
530 6af0bf9c bellard
} while (0)
531 6af0bf9c bellard
532 6af0bf9c bellard
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
533 6af0bf9c bellard
do {                                                                          \
534 6af0bf9c bellard
    if (Rn != 0) {                                                            \
535 6af0bf9c bellard
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
536 6af0bf9c bellard
    }                                                                         \
537 6af0bf9c bellard
} while (0)
538 6af0bf9c bellard
539 7a387fff ths
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
540 6ea83fed bellard
do {                                                                          \
541 6ea83fed bellard
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
542 6ea83fed bellard
} while (0)
543 6ea83fed bellard
544 6ea83fed bellard
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
545 6ea83fed bellard
do {                                                                          \
546 6ea83fed bellard
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
547 6ea83fed bellard
} while (0)
548 6ea83fed bellard
549 6af0bf9c bellard
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
550 6af0bf9c bellard
{
551 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
552 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
553 6af0bf9c bellard
            fprintf(logfile, "hflags %08x saved %08x\n",
554 6af0bf9c bellard
                    ctx->hflags, ctx->saved_hflags);
555 6af0bf9c bellard
    }
556 6af0bf9c bellard
#endif
557 6af0bf9c bellard
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
558 6af0bf9c bellard
        gen_op_save_pc(ctx->pc);
559 6af0bf9c bellard
        ctx->saved_pc = ctx->pc;
560 6af0bf9c bellard
    }
561 6af0bf9c bellard
    if (ctx->hflags != ctx->saved_hflags) {
562 6af0bf9c bellard
        gen_op_save_state(ctx->hflags);
563 6af0bf9c bellard
        ctx->saved_hflags = ctx->hflags;
564 6af0bf9c bellard
        if (ctx->hflags & MIPS_HFLAG_BR) {
565 6af0bf9c bellard
            gen_op_save_breg_target();
566 6af0bf9c bellard
        } else if (ctx->hflags & MIPS_HFLAG_B) {
567 6af0bf9c bellard
            gen_op_save_btarget(ctx->btarget);
568 6af0bf9c bellard
        } else if (ctx->hflags & MIPS_HFLAG_BMASK) {
569 6af0bf9c bellard
            gen_op_save_bcond();
570 6af0bf9c bellard
            gen_op_save_btarget(ctx->btarget);
571 6af0bf9c bellard
        }
572 6af0bf9c bellard
    }
573 6af0bf9c bellard
}
574 6af0bf9c bellard
575 4ad40f36 bellard
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
576 6af0bf9c bellard
{
577 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
578 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
579 6af0bf9c bellard
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
580 6af0bf9c bellard
#endif
581 6af0bf9c bellard
    save_cpu_state(ctx, 1);
582 4ad40f36 bellard
    if (err == 0)
583 4ad40f36 bellard
        gen_op_raise_exception(excp);
584 4ad40f36 bellard
    else
585 4ad40f36 bellard
        gen_op_raise_exception_err(excp, err);
586 6af0bf9c bellard
    ctx->bstate = BS_EXCP;
587 6af0bf9c bellard
}
588 6af0bf9c bellard
589 4ad40f36 bellard
static inline void generate_exception (DisasContext *ctx, int excp)
590 4ad40f36 bellard
{
591 4ad40f36 bellard
    generate_exception_err (ctx, excp, 0);
592 4ad40f36 bellard
}
593 4ad40f36 bellard
594 6af0bf9c bellard
#if defined(CONFIG_USER_ONLY)
595 6af0bf9c bellard
#define op_ldst(name)        gen_op_##name##_raw()
596 6af0bf9c bellard
#define OP_LD_TABLE(width)
597 6af0bf9c bellard
#define OP_ST_TABLE(width)
598 6af0bf9c bellard
#else
599 6af0bf9c bellard
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
600 6af0bf9c bellard
#define OP_LD_TABLE(width)                                                    \
601 6af0bf9c bellard
static GenOpFunc *gen_op_l##width[] = {                                       \
602 6af0bf9c bellard
    &gen_op_l##width##_user,                                                  \
603 6af0bf9c bellard
    &gen_op_l##width##_kernel,                                                \
604 6af0bf9c bellard
}
605 6af0bf9c bellard
#define OP_ST_TABLE(width)                                                    \
606 6af0bf9c bellard
static GenOpFunc *gen_op_s##width[] = {                                       \
607 6af0bf9c bellard
    &gen_op_s##width##_user,                                                  \
608 6af0bf9c bellard
    &gen_op_s##width##_kernel,                                                \
609 6af0bf9c bellard
}
610 6af0bf9c bellard
#endif
611 6af0bf9c bellard
612 7a387fff ths
#ifdef MIPS_HAS_MIPS64
613 6af0bf9c bellard
OP_LD_TABLE(d);
614 6af0bf9c bellard
OP_LD_TABLE(dl);
615 6af0bf9c bellard
OP_LD_TABLE(dr);
616 6af0bf9c bellard
OP_ST_TABLE(d);
617 6af0bf9c bellard
OP_ST_TABLE(dl);
618 6af0bf9c bellard
OP_ST_TABLE(dr);
619 6af0bf9c bellard
#endif
620 6af0bf9c bellard
OP_LD_TABLE(w);
621 d796321b bellard
OP_LD_TABLE(wu);
622 6af0bf9c bellard
OP_LD_TABLE(wl);
623 6af0bf9c bellard
OP_LD_TABLE(wr);
624 6af0bf9c bellard
OP_ST_TABLE(w);
625 6af0bf9c bellard
OP_ST_TABLE(wl);
626 6af0bf9c bellard
OP_ST_TABLE(wr);
627 6af0bf9c bellard
OP_LD_TABLE(h);
628 6af0bf9c bellard
OP_LD_TABLE(hu);
629 6af0bf9c bellard
OP_ST_TABLE(h);
630 6af0bf9c bellard
OP_LD_TABLE(b);
631 6af0bf9c bellard
OP_LD_TABLE(bu);
632 6af0bf9c bellard
OP_ST_TABLE(b);
633 6af0bf9c bellard
OP_LD_TABLE(l);
634 6af0bf9c bellard
OP_ST_TABLE(c);
635 6ea83fed bellard
OP_LD_TABLE(wc1);
636 6ea83fed bellard
OP_ST_TABLE(wc1);
637 6ea83fed bellard
OP_LD_TABLE(dc1);
638 6ea83fed bellard
OP_ST_TABLE(dc1);
639 6af0bf9c bellard
640 6af0bf9c bellard
/* Load and store */
641 7a387fff ths
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
642 6af0bf9c bellard
                      int base, int16_t offset)
643 6af0bf9c bellard
{
644 7a387fff ths
    const char *opn = "unk";
645 6af0bf9c bellard
646 6af0bf9c bellard
    if (base == 0) {
647 6af0bf9c bellard
        GEN_LOAD_IMM_TN(T0, offset);
648 6af0bf9c bellard
    } else if (offset == 0) {
649 6af0bf9c bellard
        gen_op_load_gpr_T0(base);
650 6af0bf9c bellard
    } else {
651 6af0bf9c bellard
        gen_op_load_gpr_T0(base);
652 6af0bf9c bellard
        gen_op_set_T1(offset);
653 6af0bf9c bellard
        gen_op_add();
654 6af0bf9c bellard
    }
655 6af0bf9c bellard
    /* Don't do NOP if destination is zero: we must perform the actual
656 6af0bf9c bellard
     * memory access
657 6af0bf9c bellard
     */
658 6af0bf9c bellard
    switch (opc) {
659 7a387fff ths
#ifdef MIPS_HAS_MIPS64
660 6af0bf9c bellard
    case OPC_LD:
661 6af0bf9c bellard
        op_ldst(ld);
662 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
663 6af0bf9c bellard
        opn = "ld";
664 6af0bf9c bellard
        break;
665 7a387fff ths
    case OPC_LLD:
666 7a387fff ths
        op_ldst(lld);
667 7a387fff ths
        GEN_STORE_TN_REG(rt, T0);
668 7a387fff ths
        opn = "lld";
669 7a387fff ths
        break;
670 6af0bf9c bellard
    case OPC_SD:
671 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
672 6af0bf9c bellard
        op_ldst(sd);
673 6af0bf9c bellard
        opn = "sd";
674 6af0bf9c bellard
        break;
675 7a387fff ths
    case OPC_SCD:
676 7a387fff ths
        GEN_LOAD_REG_TN(T1, rt);
677 7a387fff ths
        op_ldst(scd);
678 7a387fff ths
        opn = "scd";
679 7a387fff ths
        break;
680 6af0bf9c bellard
    case OPC_LDL:
681 6af0bf9c bellard
        op_ldst(ldl);
682 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
683 6af0bf9c bellard
        opn = "ldl";
684 6af0bf9c bellard
        break;
685 6af0bf9c bellard
    case OPC_SDL:
686 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
687 6af0bf9c bellard
        op_ldst(sdl);
688 6af0bf9c bellard
        opn = "sdl";
689 6af0bf9c bellard
        break;
690 6af0bf9c bellard
    case OPC_LDR:
691 6af0bf9c bellard
        op_ldst(ldr);
692 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
693 6af0bf9c bellard
        opn = "ldr";
694 6af0bf9c bellard
        break;
695 6af0bf9c bellard
    case OPC_SDR:
696 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
697 6af0bf9c bellard
        op_ldst(sdr);
698 6af0bf9c bellard
        opn = "sdr";
699 6af0bf9c bellard
        break;
700 6af0bf9c bellard
#endif
701 6af0bf9c bellard
    case OPC_LW:
702 6af0bf9c bellard
        op_ldst(lw);
703 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
704 6af0bf9c bellard
        opn = "lw";
705 6af0bf9c bellard
        break;
706 d796321b bellard
    case OPC_LWU:
707 d796321b bellard
        op_ldst(lwu);
708 d796321b bellard
        GEN_STORE_TN_REG(rt, T0);
709 d796321b bellard
        opn = "lwu";
710 d796321b bellard
        break;
711 6af0bf9c bellard
    case OPC_SW:
712 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
713 6af0bf9c bellard
        op_ldst(sw);
714 6af0bf9c bellard
        opn = "sw";
715 6af0bf9c bellard
        break;
716 6af0bf9c bellard
    case OPC_LH:
717 6af0bf9c bellard
        op_ldst(lh);
718 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
719 6af0bf9c bellard
        opn = "lh";
720 6af0bf9c bellard
        break;
721 6af0bf9c bellard
    case OPC_SH:
722 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
723 6af0bf9c bellard
        op_ldst(sh);
724 6af0bf9c bellard
        opn = "sh";
725 6af0bf9c bellard
        break;
726 6af0bf9c bellard
    case OPC_LHU:
727 6af0bf9c bellard
        op_ldst(lhu);
728 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
729 6af0bf9c bellard
        opn = "lhu";
730 6af0bf9c bellard
        break;
731 6af0bf9c bellard
    case OPC_LB:
732 6af0bf9c bellard
        op_ldst(lb);
733 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
734 6af0bf9c bellard
        opn = "lb";
735 6af0bf9c bellard
        break;
736 6af0bf9c bellard
    case OPC_SB:
737 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
738 6af0bf9c bellard
        op_ldst(sb);
739 6af0bf9c bellard
        opn = "sb";
740 6af0bf9c bellard
        break;
741 6af0bf9c bellard
    case OPC_LBU:
742 6af0bf9c bellard
        op_ldst(lbu);
743 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
744 6af0bf9c bellard
        opn = "lbu";
745 6af0bf9c bellard
        break;
746 6af0bf9c bellard
    case OPC_LWL:
747 9d1d106a bellard
        GEN_LOAD_REG_TN(T1, rt);
748 6af0bf9c bellard
        op_ldst(lwl);
749 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
750 6af0bf9c bellard
        opn = "lwl";
751 6af0bf9c bellard
        break;
752 6af0bf9c bellard
    case OPC_SWL:
753 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
754 6af0bf9c bellard
        op_ldst(swl);
755 6af0bf9c bellard
        opn = "swr";
756 6af0bf9c bellard
        break;
757 6af0bf9c bellard
    case OPC_LWR:
758 9d1d106a bellard
        GEN_LOAD_REG_TN(T1, rt);
759 6af0bf9c bellard
        op_ldst(lwr);
760 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
761 6af0bf9c bellard
        opn = "lwr";
762 6af0bf9c bellard
        break;
763 6af0bf9c bellard
    case OPC_SWR:
764 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
765 6af0bf9c bellard
        op_ldst(swr);
766 6af0bf9c bellard
        opn = "swr";
767 6af0bf9c bellard
        break;
768 6af0bf9c bellard
    case OPC_LL:
769 6af0bf9c bellard
        op_ldst(ll);
770 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
771 6af0bf9c bellard
        opn = "ll";
772 6af0bf9c bellard
        break;
773 6af0bf9c bellard
    case OPC_SC:
774 6af0bf9c bellard
        GEN_LOAD_REG_TN(T1, rt);
775 6af0bf9c bellard
        op_ldst(sc);
776 6af0bf9c bellard
        GEN_STORE_TN_REG(rt, T0);
777 6af0bf9c bellard
        opn = "sc";
778 6af0bf9c bellard
        break;
779 6af0bf9c bellard
    default:
780 6af0bf9c bellard
        MIPS_INVAL("load/store");
781 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
782 6af0bf9c bellard
        return;
783 6af0bf9c bellard
    }
784 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
785 6af0bf9c bellard
}
786 6af0bf9c bellard
787 6ea83fed bellard
/* Load and store */
788 7a387fff ths
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
789 6ea83fed bellard
                      int base, int16_t offset)
790 6ea83fed bellard
{
791 7a387fff ths
    const char *opn = "unk";
792 6ea83fed bellard
793 6ea83fed bellard
    if (base == 0) {
794 6ea83fed bellard
        GEN_LOAD_IMM_TN(T0, offset);
795 6ea83fed bellard
    } else if (offset == 0) {
796 6ea83fed bellard
        gen_op_load_gpr_T0(base);
797 6ea83fed bellard
    } else {
798 6ea83fed bellard
        gen_op_load_gpr_T0(base);
799 6ea83fed bellard
        gen_op_set_T1(offset);
800 6ea83fed bellard
        gen_op_add();
801 6ea83fed bellard
    }
802 6ea83fed bellard
    /* Don't do NOP if destination is zero: we must perform the actual
803 6ea83fed bellard
     * memory access
804 6ea83fed bellard
     */
805 6ea83fed bellard
    switch (opc) {
806 6ea83fed bellard
    case OPC_LWC1:
807 6ea83fed bellard
        op_ldst(lwc1);
808 6ea83fed bellard
        GEN_STORE_FTN_FREG(ft, WT0);
809 6ea83fed bellard
        opn = "lwc1";
810 6ea83fed bellard
        break;
811 6ea83fed bellard
    case OPC_SWC1:
812 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, ft);
813 6ea83fed bellard
        op_ldst(swc1);
814 6ea83fed bellard
        opn = "swc1";
815 6ea83fed bellard
        break;
816 6ea83fed bellard
    case OPC_LDC1:
817 6ea83fed bellard
        op_ldst(ldc1);
818 6ea83fed bellard
        GEN_STORE_FTN_FREG(ft, DT0);
819 6ea83fed bellard
        opn = "ldc1";
820 6ea83fed bellard
        break;
821 6ea83fed bellard
    case OPC_SDC1:
822 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, ft);
823 6ea83fed bellard
        op_ldst(sdc1);
824 6ea83fed bellard
        opn = "sdc1";
825 6ea83fed bellard
        break;
826 6ea83fed bellard
    default:
827 6ea83fed bellard
        MIPS_INVAL("float load/store");
828 7a387fff ths
        generate_exception_err(ctx, EXCP_CpU, 1);
829 6ea83fed bellard
        return;
830 6ea83fed bellard
    }
831 6ea83fed bellard
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
832 6ea83fed bellard
}
833 6ea83fed bellard
834 6af0bf9c bellard
/* Arithmetic with immediate operand */
835 7a387fff ths
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
836 6af0bf9c bellard
                           int rs, int16_t imm)
837 6af0bf9c bellard
{
838 6af0bf9c bellard
    uint32_t uimm;
839 7a387fff ths
    const char *opn = "unk";
840 6af0bf9c bellard
841 7a387fff ths
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
842 6af0bf9c bellard
        /* if no destination, treat it as a NOP 
843 6af0bf9c bellard
         * For addi, we must generate the overflow exception when needed.
844 6af0bf9c bellard
         */
845 6af0bf9c bellard
        MIPS_DEBUG("NOP");
846 6af0bf9c bellard
        return;
847 6af0bf9c bellard
    }
848 6af0bf9c bellard
    if (opc == OPC_ADDI || opc == OPC_ADDIU ||
849 7a387fff ths
        opc == OPC_DADDI || opc == OPC_DADDIU ||
850 6af0bf9c bellard
        opc == OPC_SLTI || opc == OPC_SLTIU)
851 7a387fff ths
        uimm = (int32_t)imm; /* Sign extend to 32 bits */
852 6af0bf9c bellard
    else
853 6af0bf9c bellard
        uimm = (uint16_t)imm;
854 6af0bf9c bellard
    if (opc != OPC_LUI) {
855 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, rs);
856 6af0bf9c bellard
        GEN_LOAD_IMM_TN(T1, uimm);
857 6af0bf9c bellard
    } else {
858 6af0bf9c bellard
        uimm = uimm << 16;
859 6af0bf9c bellard
        GEN_LOAD_IMM_TN(T0, uimm);
860 6af0bf9c bellard
    }
861 6af0bf9c bellard
    switch (opc) {
862 6af0bf9c bellard
    case OPC_ADDI:
863 6af0bf9c bellard
        save_cpu_state(ctx, 1);
864 6af0bf9c bellard
        gen_op_addo();
865 6af0bf9c bellard
        opn = "addi";
866 6af0bf9c bellard
        break;
867 6af0bf9c bellard
    case OPC_ADDIU:
868 6af0bf9c bellard
        gen_op_add();
869 6af0bf9c bellard
        opn = "addiu";
870 6af0bf9c bellard
        break;
871 7a387fff ths
#ifdef MIPS_HAS_MIPS64
872 7a387fff ths
    case OPC_DADDI:
873 7a387fff ths
        save_cpu_state(ctx, 1);
874 7a387fff ths
        gen_op_daddo();
875 7a387fff ths
        opn = "daddi";
876 7a387fff ths
        break;
877 7a387fff ths
    case OPC_DADDIU:
878 7a387fff ths
        gen_op_dadd();
879 7a387fff ths
        opn = "daddiu";
880 7a387fff ths
        break;
881 7a387fff ths
#endif
882 6af0bf9c bellard
    case OPC_SLTI:
883 6af0bf9c bellard
        gen_op_lt();
884 6af0bf9c bellard
        opn = "slti";
885 6af0bf9c bellard
        break;
886 6af0bf9c bellard
    case OPC_SLTIU:
887 6af0bf9c bellard
        gen_op_ltu();
888 6af0bf9c bellard
        opn = "sltiu";
889 6af0bf9c bellard
        break;
890 6af0bf9c bellard
    case OPC_ANDI:
891 6af0bf9c bellard
        gen_op_and();
892 6af0bf9c bellard
        opn = "andi";
893 6af0bf9c bellard
        break;
894 6af0bf9c bellard
    case OPC_ORI:
895 6af0bf9c bellard
        gen_op_or();
896 6af0bf9c bellard
        opn = "ori";
897 6af0bf9c bellard
        break;
898 6af0bf9c bellard
    case OPC_XORI:
899 6af0bf9c bellard
        gen_op_xor();
900 6af0bf9c bellard
        opn = "xori";
901 6af0bf9c bellard
        break;
902 6af0bf9c bellard
    case OPC_LUI:
903 6af0bf9c bellard
        opn = "lui";
904 6af0bf9c bellard
        break;
905 6af0bf9c bellard
    case OPC_SLL:
906 6af0bf9c bellard
        gen_op_sll();
907 6af0bf9c bellard
        opn = "sll";
908 6af0bf9c bellard
        break;
909 6af0bf9c bellard
    case OPC_SRA:
910 6af0bf9c bellard
        gen_op_sra();
911 6af0bf9c bellard
        opn = "sra";
912 6af0bf9c bellard
        break;
913 6af0bf9c bellard
    case OPC_SRL:
914 7a387fff ths
       if ((ctx->opcode >> 21) & 1) {
915 7a387fff ths
            gen_op_rotr();
916 7a387fff ths
            opn = "rotr";
917 7a387fff ths
       } else {
918 7a387fff ths
            gen_op_srl();
919 7a387fff ths
            opn = "srl";
920 7a387fff ths
       }
921 7a387fff ths
        break;
922 7a387fff ths
#ifdef MIPS_HAS_MIPS64
923 7a387fff ths
    case OPC_DSLL:
924 7a387fff ths
        gen_op_dsll();
925 7a387fff ths
        opn = "dsll";
926 7a387fff ths
        break;
927 7a387fff ths
    case OPC_DSRA:
928 7a387fff ths
        gen_op_dsra();
929 7a387fff ths
        opn = "dsra";
930 7a387fff ths
        break;
931 7a387fff ths
    case OPC_DSRL:
932 7a387fff ths
       if ((ctx->opcode >> 21) & 1) {
933 7a387fff ths
            gen_op_drotr();
934 7a387fff ths
            opn = "drotr";
935 7a387fff ths
       } else {
936 7a387fff ths
            gen_op_dsrl();
937 7a387fff ths
            opn = "dsrl";
938 7a387fff ths
       }
939 7a387fff ths
        break;
940 7a387fff ths
    case OPC_DSLL32:
941 7a387fff ths
        gen_op_dsll32();
942 7a387fff ths
        opn = "dsll32";
943 7a387fff ths
        break;
944 7a387fff ths
    case OPC_DSRA32:
945 7a387fff ths
        gen_op_dsra32();
946 7a387fff ths
        opn = "dsra32";
947 7a387fff ths
        break;
948 7a387fff ths
    case OPC_DSRL32:
949 7a387fff ths
       if ((ctx->opcode >> 21) & 1) {
950 7a387fff ths
            gen_op_drotr32();
951 7a387fff ths
            opn = "drotr32";
952 7a387fff ths
       } else {
953 7a387fff ths
            gen_op_dsrl32();
954 7a387fff ths
            opn = "dsrl32";
955 7a387fff ths
       }
956 6af0bf9c bellard
        break;
957 7a387fff ths
#endif
958 6af0bf9c bellard
    default:
959 6af0bf9c bellard
        MIPS_INVAL("imm arith");
960 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
961 6af0bf9c bellard
        return;
962 6af0bf9c bellard
    }
963 6af0bf9c bellard
    GEN_STORE_TN_REG(rt, T0);
964 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
965 6af0bf9c bellard
}
966 6af0bf9c bellard
967 6af0bf9c bellard
/* Arithmetic */
968 7a387fff ths
static void gen_arith (DisasContext *ctx, uint32_t opc,
969 6af0bf9c bellard
                       int rd, int rs, int rt)
970 6af0bf9c bellard
{
971 7a387fff ths
    const char *opn = "unk";
972 6af0bf9c bellard
973 7a387fff ths
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
974 7a387fff ths
       && opc != OPC_DADD && opc != OPC_DSUB) {
975 6af0bf9c bellard
        /* if no destination, treat it as a NOP 
976 6af0bf9c bellard
         * For add & sub, we must generate the overflow exception when needed.
977 6af0bf9c bellard
         */
978 6af0bf9c bellard
        MIPS_DEBUG("NOP");
979 6af0bf9c bellard
        return;
980 6af0bf9c bellard
    }
981 6af0bf9c bellard
    GEN_LOAD_REG_TN(T0, rs);
982 6af0bf9c bellard
    GEN_LOAD_REG_TN(T1, rt);
983 6af0bf9c bellard
    switch (opc) {
984 6af0bf9c bellard
    case OPC_ADD:
985 6af0bf9c bellard
        save_cpu_state(ctx, 1);
986 6af0bf9c bellard
        gen_op_addo();
987 6af0bf9c bellard
        opn = "add";
988 6af0bf9c bellard
        break;
989 6af0bf9c bellard
    case OPC_ADDU:
990 6af0bf9c bellard
        gen_op_add();
991 6af0bf9c bellard
        opn = "addu";
992 6af0bf9c bellard
        break;
993 6af0bf9c bellard
    case OPC_SUB:
994 6af0bf9c bellard
        save_cpu_state(ctx, 1);
995 6af0bf9c bellard
        gen_op_subo();
996 6af0bf9c bellard
        opn = "sub";
997 6af0bf9c bellard
        break;
998 6af0bf9c bellard
    case OPC_SUBU:
999 6af0bf9c bellard
        gen_op_sub();
1000 6af0bf9c bellard
        opn = "subu";
1001 6af0bf9c bellard
        break;
1002 7a387fff ths
#ifdef MIPS_HAS_MIPS64
1003 7a387fff ths
    case OPC_DADD:
1004 7a387fff ths
        save_cpu_state(ctx, 1);
1005 7a387fff ths
        gen_op_daddo();
1006 7a387fff ths
        opn = "dadd";
1007 7a387fff ths
        break;
1008 7a387fff ths
    case OPC_DADDU:
1009 7a387fff ths
        gen_op_dadd();
1010 7a387fff ths
        opn = "daddu";
1011 7a387fff ths
        break;
1012 7a387fff ths
    case OPC_DSUB:
1013 7a387fff ths
        save_cpu_state(ctx, 1);
1014 7a387fff ths
        gen_op_dsubo();
1015 7a387fff ths
        opn = "dsub";
1016 7a387fff ths
        break;
1017 7a387fff ths
    case OPC_DSUBU:
1018 7a387fff ths
        gen_op_dsub();
1019 7a387fff ths
        opn = "dsubu";
1020 7a387fff ths
        break;
1021 7a387fff ths
#endif
1022 6af0bf9c bellard
    case OPC_SLT:
1023 6af0bf9c bellard
        gen_op_lt();
1024 6af0bf9c bellard
        opn = "slt";
1025 6af0bf9c bellard
        break;
1026 6af0bf9c bellard
    case OPC_SLTU:
1027 6af0bf9c bellard
        gen_op_ltu();
1028 6af0bf9c bellard
        opn = "sltu";
1029 6af0bf9c bellard
        break;
1030 6af0bf9c bellard
    case OPC_AND:
1031 6af0bf9c bellard
        gen_op_and();
1032 6af0bf9c bellard
        opn = "and";
1033 6af0bf9c bellard
        break;
1034 6af0bf9c bellard
    case OPC_NOR:
1035 6af0bf9c bellard
        gen_op_nor();
1036 6af0bf9c bellard
        opn = "nor";
1037 6af0bf9c bellard
        break;
1038 6af0bf9c bellard
    case OPC_OR:
1039 6af0bf9c bellard
        gen_op_or();
1040 6af0bf9c bellard
        opn = "or";
1041 6af0bf9c bellard
        break;
1042 6af0bf9c bellard
    case OPC_XOR:
1043 6af0bf9c bellard
        gen_op_xor();
1044 6af0bf9c bellard
        opn = "xor";
1045 6af0bf9c bellard
        break;
1046 6af0bf9c bellard
    case OPC_MUL:
1047 6af0bf9c bellard
        gen_op_mul();
1048 6af0bf9c bellard
        opn = "mul";
1049 6af0bf9c bellard
        break;
1050 6af0bf9c bellard
    case OPC_MOVN:
1051 6af0bf9c bellard
        gen_op_movn(rd);
1052 6af0bf9c bellard
        opn = "movn";
1053 6af0bf9c bellard
        goto print;
1054 6af0bf9c bellard
    case OPC_MOVZ:
1055 6af0bf9c bellard
        gen_op_movz(rd);
1056 6af0bf9c bellard
        opn = "movz";
1057 6af0bf9c bellard
        goto print;
1058 6af0bf9c bellard
    case OPC_SLLV:
1059 6af0bf9c bellard
        gen_op_sllv();
1060 6af0bf9c bellard
        opn = "sllv";
1061 6af0bf9c bellard
        break;
1062 6af0bf9c bellard
    case OPC_SRAV:
1063 6af0bf9c bellard
        gen_op_srav();
1064 6af0bf9c bellard
        opn = "srav";
1065 6af0bf9c bellard
        break;
1066 6af0bf9c bellard
    case OPC_SRLV:
1067 7a387fff ths
       if ((ctx->opcode >> 6) & 1) {
1068 7a387fff ths
            gen_op_rotrv();
1069 7a387fff ths
            opn = "rotrv";
1070 7a387fff ths
       } else {
1071 7a387fff ths
            gen_op_srlv();
1072 7a387fff ths
            opn = "srlv";
1073 7a387fff ths
       }
1074 7a387fff ths
        break;
1075 7a387fff ths
#ifdef MIPS_HAS_MIPS64
1076 7a387fff ths
    case OPC_DSLLV:
1077 7a387fff ths
        gen_op_dsllv();
1078 7a387fff ths
        opn = "dsllv";
1079 7a387fff ths
        break;
1080 7a387fff ths
    case OPC_DSRAV:
1081 7a387fff ths
        gen_op_dsrav();
1082 7a387fff ths
        opn = "dsrav";
1083 7a387fff ths
        break;
1084 7a387fff ths
    case OPC_DSRLV:
1085 7a387fff ths
       if ((ctx->opcode >> 6) & 1) {
1086 7a387fff ths
            gen_op_drotrv();
1087 7a387fff ths
            opn = "drotrv";
1088 7a387fff ths
       } else {
1089 7a387fff ths
            gen_op_dsrlv();
1090 7a387fff ths
            opn = "dsrlv";
1091 7a387fff ths
       }
1092 6af0bf9c bellard
        break;
1093 7a387fff ths
#endif
1094 6af0bf9c bellard
    default:
1095 6af0bf9c bellard
        MIPS_INVAL("arith");
1096 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1097 6af0bf9c bellard
        return;
1098 6af0bf9c bellard
    }
1099 6af0bf9c bellard
    GEN_STORE_TN_REG(rd, T0);
1100 6af0bf9c bellard
 print:
1101 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1102 6af0bf9c bellard
}
1103 6af0bf9c bellard
1104 6af0bf9c bellard
/* Arithmetic on HI/LO registers */
1105 7a387fff ths
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1106 6af0bf9c bellard
{
1107 7a387fff ths
    const char *opn = "unk";
1108 6af0bf9c bellard
1109 6af0bf9c bellard
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1110 6af0bf9c bellard
        /* Treat as a NOP */
1111 6af0bf9c bellard
        MIPS_DEBUG("NOP");
1112 6af0bf9c bellard
        return;
1113 6af0bf9c bellard
    }
1114 6af0bf9c bellard
    switch (opc) {
1115 6af0bf9c bellard
    case OPC_MFHI:
1116 6af0bf9c bellard
        gen_op_load_HI();
1117 6af0bf9c bellard
        GEN_STORE_TN_REG(reg, T0);
1118 6af0bf9c bellard
        opn = "mfhi";
1119 6af0bf9c bellard
        break;
1120 6af0bf9c bellard
    case OPC_MFLO:
1121 6af0bf9c bellard
        gen_op_load_LO();
1122 6af0bf9c bellard
        GEN_STORE_TN_REG(reg, T0);
1123 6af0bf9c bellard
        opn = "mflo";
1124 6af0bf9c bellard
        break;
1125 6af0bf9c bellard
    case OPC_MTHI:
1126 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, reg);
1127 6af0bf9c bellard
        gen_op_store_HI();
1128 6af0bf9c bellard
        opn = "mthi";
1129 6af0bf9c bellard
        break;
1130 6af0bf9c bellard
    case OPC_MTLO:
1131 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, reg);
1132 6af0bf9c bellard
        gen_op_store_LO();
1133 6af0bf9c bellard
        opn = "mtlo";
1134 6af0bf9c bellard
        break;
1135 6af0bf9c bellard
    default:
1136 6af0bf9c bellard
        MIPS_INVAL("HILO");
1137 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1138 6af0bf9c bellard
        return;
1139 6af0bf9c bellard
    }
1140 6af0bf9c bellard
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1141 6af0bf9c bellard
}
1142 6af0bf9c bellard
1143 7a387fff ths
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1144 6af0bf9c bellard
                        int rs, int rt)
1145 6af0bf9c bellard
{
1146 7a387fff ths
    const char *opn = "unk";
1147 6af0bf9c bellard
1148 6af0bf9c bellard
    GEN_LOAD_REG_TN(T0, rs);
1149 6af0bf9c bellard
    GEN_LOAD_REG_TN(T1, rt);
1150 6af0bf9c bellard
    switch (opc) {
1151 6af0bf9c bellard
    case OPC_DIV:
1152 6af0bf9c bellard
        gen_op_div();
1153 6af0bf9c bellard
        opn = "div";
1154 6af0bf9c bellard
        break;
1155 6af0bf9c bellard
    case OPC_DIVU:
1156 6af0bf9c bellard
        gen_op_divu();
1157 6af0bf9c bellard
        opn = "divu";
1158 6af0bf9c bellard
        break;
1159 6af0bf9c bellard
    case OPC_MULT:
1160 6af0bf9c bellard
        gen_op_mult();
1161 6af0bf9c bellard
        opn = "mult";
1162 6af0bf9c bellard
        break;
1163 6af0bf9c bellard
    case OPC_MULTU:
1164 6af0bf9c bellard
        gen_op_multu();
1165 6af0bf9c bellard
        opn = "multu";
1166 6af0bf9c bellard
        break;
1167 7a387fff ths
#ifdef MIPS_HAS_MIPS64
1168 7a387fff ths
    case OPC_DDIV:
1169 7a387fff ths
        gen_op_ddiv();
1170 7a387fff ths
        opn = "ddiv";
1171 7a387fff ths
        break;
1172 7a387fff ths
    case OPC_DDIVU:
1173 7a387fff ths
        gen_op_ddivu();
1174 7a387fff ths
        opn = "ddivu";
1175 7a387fff ths
        break;
1176 7a387fff ths
    case OPC_DMULT:
1177 7a387fff ths
        gen_op_dmult();
1178 7a387fff ths
        opn = "dmult";
1179 7a387fff ths
        break;
1180 7a387fff ths
    case OPC_DMULTU:
1181 7a387fff ths
        gen_op_dmultu();
1182 7a387fff ths
        opn = "dmultu";
1183 7a387fff ths
        break;
1184 7a387fff ths
#endif
1185 6af0bf9c bellard
    case OPC_MADD:
1186 6af0bf9c bellard
        gen_op_madd();
1187 6af0bf9c bellard
        opn = "madd";
1188 6af0bf9c bellard
        break;
1189 6af0bf9c bellard
    case OPC_MADDU:
1190 6af0bf9c bellard
        gen_op_maddu();
1191 6af0bf9c bellard
        opn = "maddu";
1192 6af0bf9c bellard
        break;
1193 6af0bf9c bellard
    case OPC_MSUB:
1194 6af0bf9c bellard
        gen_op_msub();
1195 6af0bf9c bellard
        opn = "msub";
1196 6af0bf9c bellard
        break;
1197 6af0bf9c bellard
    case OPC_MSUBU:
1198 6af0bf9c bellard
        gen_op_msubu();
1199 6af0bf9c bellard
        opn = "msubu";
1200 6af0bf9c bellard
        break;
1201 6af0bf9c bellard
    default:
1202 6af0bf9c bellard
        MIPS_INVAL("mul/div");
1203 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1204 6af0bf9c bellard
        return;
1205 6af0bf9c bellard
    }
1206 6af0bf9c bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1207 6af0bf9c bellard
}
1208 6af0bf9c bellard
1209 7a387fff ths
static void gen_cl (DisasContext *ctx, uint32_t opc,
1210 6af0bf9c bellard
                    int rd, int rs)
1211 6af0bf9c bellard
{
1212 7a387fff ths
    const char *opn = "unk";
1213 6af0bf9c bellard
    if (rd == 0) {
1214 6af0bf9c bellard
        /* Treat as a NOP */
1215 6af0bf9c bellard
        MIPS_DEBUG("NOP");
1216 6af0bf9c bellard
        return;
1217 6af0bf9c bellard
    }
1218 6af0bf9c bellard
    GEN_LOAD_REG_TN(T0, rs);
1219 6af0bf9c bellard
    switch (opc) {
1220 6af0bf9c bellard
    case OPC_CLO:
1221 6af0bf9c bellard
        gen_op_clo();
1222 6af0bf9c bellard
        opn = "clo";
1223 6af0bf9c bellard
        break;
1224 6af0bf9c bellard
    case OPC_CLZ:
1225 6af0bf9c bellard
        gen_op_clz();
1226 6af0bf9c bellard
        opn = "clz";
1227 6af0bf9c bellard
        break;
1228 7a387fff ths
#ifdef MIPS_HAS_MIPS64
1229 7a387fff ths
    case OPC_DCLO:
1230 7a387fff ths
        gen_op_dclo();
1231 7a387fff ths
        opn = "dclo";
1232 7a387fff ths
        break;
1233 7a387fff ths
    case OPC_DCLZ:
1234 7a387fff ths
        gen_op_dclz();
1235 7a387fff ths
        opn = "dclz";
1236 7a387fff ths
        break;
1237 7a387fff ths
#endif
1238 6af0bf9c bellard
    default:
1239 6af0bf9c bellard
        MIPS_INVAL("CLx");
1240 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1241 6af0bf9c bellard
        return;
1242 6af0bf9c bellard
    }
1243 6af0bf9c bellard
    gen_op_store_T0_gpr(rd);
1244 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1245 6af0bf9c bellard
}
1246 6af0bf9c bellard
1247 6af0bf9c bellard
/* Traps */
1248 7a387fff ths
static void gen_trap (DisasContext *ctx, uint32_t opc,
1249 6af0bf9c bellard
                      int rs, int rt, int16_t imm)
1250 6af0bf9c bellard
{
1251 6af0bf9c bellard
    int cond;
1252 6af0bf9c bellard
1253 6af0bf9c bellard
    cond = 0;
1254 6af0bf9c bellard
    /* Load needed operands */
1255 6af0bf9c bellard
    switch (opc) {
1256 6af0bf9c bellard
    case OPC_TEQ:
1257 6af0bf9c bellard
    case OPC_TGE:
1258 6af0bf9c bellard
    case OPC_TGEU:
1259 6af0bf9c bellard
    case OPC_TLT:
1260 6af0bf9c bellard
    case OPC_TLTU:
1261 6af0bf9c bellard
    case OPC_TNE:
1262 6af0bf9c bellard
        /* Compare two registers */
1263 6af0bf9c bellard
        if (rs != rt) {
1264 6af0bf9c bellard
            GEN_LOAD_REG_TN(T0, rs);
1265 6af0bf9c bellard
            GEN_LOAD_REG_TN(T1, rt);
1266 6af0bf9c bellard
            cond = 1;
1267 6af0bf9c bellard
        }
1268 6af0bf9c bellard
    case OPC_TEQI:
1269 6af0bf9c bellard
    case OPC_TGEI:
1270 6af0bf9c bellard
    case OPC_TGEIU:
1271 6af0bf9c bellard
    case OPC_TLTI:
1272 6af0bf9c bellard
    case OPC_TLTIU:
1273 6af0bf9c bellard
    case OPC_TNEI:
1274 6af0bf9c bellard
        /* Compare register to immediate */
1275 6af0bf9c bellard
        if (rs != 0 || imm != 0) {
1276 6af0bf9c bellard
            GEN_LOAD_REG_TN(T0, rs);
1277 6af0bf9c bellard
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1278 6af0bf9c bellard
            cond = 1;
1279 6af0bf9c bellard
        }
1280 6af0bf9c bellard
        break;
1281 6af0bf9c bellard
    }
1282 6af0bf9c bellard
    if (cond == 0) {
1283 6af0bf9c bellard
        switch (opc) {
1284 6af0bf9c bellard
        case OPC_TEQ:   /* rs == rs */
1285 6af0bf9c bellard
        case OPC_TEQI:  /* r0 == 0  */
1286 6af0bf9c bellard
        case OPC_TGE:   /* rs >= rs */
1287 6af0bf9c bellard
        case OPC_TGEI:  /* r0 >= 0  */
1288 6af0bf9c bellard
        case OPC_TGEU:  /* rs >= rs unsigned */
1289 6af0bf9c bellard
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1290 6af0bf9c bellard
            /* Always trap */
1291 6af0bf9c bellard
            gen_op_set_T0(1);
1292 6af0bf9c bellard
            break;
1293 6af0bf9c bellard
        case OPC_TLT:   /* rs < rs           */
1294 6af0bf9c bellard
        case OPC_TLTI:  /* r0 < 0            */
1295 6af0bf9c bellard
        case OPC_TLTU:  /* rs < rs unsigned  */
1296 6af0bf9c bellard
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1297 6af0bf9c bellard
        case OPC_TNE:   /* rs != rs          */
1298 6af0bf9c bellard
        case OPC_TNEI:  /* r0 != 0           */
1299 6af0bf9c bellard
            /* Never trap: treat as NOP */
1300 6af0bf9c bellard
            return;
1301 6af0bf9c bellard
        default:
1302 6af0bf9c bellard
            MIPS_INVAL("TRAP");
1303 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1304 6af0bf9c bellard
            return;
1305 6af0bf9c bellard
        }
1306 6af0bf9c bellard
    } else {
1307 6af0bf9c bellard
        switch (opc) {
1308 6af0bf9c bellard
        case OPC_TEQ:
1309 6af0bf9c bellard
        case OPC_TEQI:
1310 6af0bf9c bellard
            gen_op_eq();
1311 6af0bf9c bellard
            break;
1312 6af0bf9c bellard
        case OPC_TGE:
1313 6af0bf9c bellard
        case OPC_TGEI:
1314 6af0bf9c bellard
            gen_op_ge();
1315 6af0bf9c bellard
            break;
1316 6af0bf9c bellard
        case OPC_TGEU:
1317 6af0bf9c bellard
        case OPC_TGEIU:
1318 6af0bf9c bellard
            gen_op_geu();
1319 6af0bf9c bellard
            break;
1320 6af0bf9c bellard
        case OPC_TLT:
1321 6af0bf9c bellard
        case OPC_TLTI:
1322 6af0bf9c bellard
            gen_op_lt();
1323 6af0bf9c bellard
            break;
1324 6af0bf9c bellard
        case OPC_TLTU:
1325 6af0bf9c bellard
        case OPC_TLTIU:
1326 6af0bf9c bellard
            gen_op_ltu();
1327 6af0bf9c bellard
            break;
1328 6af0bf9c bellard
        case OPC_TNE:
1329 6af0bf9c bellard
        case OPC_TNEI:
1330 6af0bf9c bellard
            gen_op_ne();
1331 6af0bf9c bellard
            break;
1332 6af0bf9c bellard
        default:
1333 6af0bf9c bellard
            MIPS_INVAL("TRAP");
1334 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1335 6af0bf9c bellard
            return;
1336 6af0bf9c bellard
        }
1337 6af0bf9c bellard
    }
1338 6af0bf9c bellard
    save_cpu_state(ctx, 1);
1339 6af0bf9c bellard
    gen_op_trap();
1340 6af0bf9c bellard
    ctx->bstate = BS_STOP;
1341 6af0bf9c bellard
}
1342 6af0bf9c bellard
1343 6e256c93 bellard
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1344 c53be334 bellard
{
1345 6e256c93 bellard
    TranslationBlock *tb;
1346 6e256c93 bellard
    tb = ctx->tb;
1347 6e256c93 bellard
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1348 6e256c93 bellard
        if (n == 0)
1349 6e256c93 bellard
            gen_op_goto_tb0(TBPARAM(tb));
1350 6e256c93 bellard
        else
1351 6e256c93 bellard
            gen_op_goto_tb1(TBPARAM(tb));
1352 6e256c93 bellard
        gen_op_save_pc(dest);
1353 6e256c93 bellard
        gen_op_set_T0((long)tb + n);
1354 6e256c93 bellard
        gen_op_exit_tb();
1355 6e256c93 bellard
    } else {
1356 6e256c93 bellard
        gen_op_save_pc(dest);
1357 6e256c93 bellard
        gen_op_set_T0(0);
1358 6e256c93 bellard
        gen_op_exit_tb();
1359 6e256c93 bellard
    }
1360 c53be334 bellard
}
1361 c53be334 bellard
1362 6af0bf9c bellard
/* Branches (before delay slot) */
1363 7a387fff ths
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1364 6af0bf9c bellard
                                int rs, int rt, int32_t offset)
1365 6af0bf9c bellard
{
1366 6af0bf9c bellard
    target_ulong btarget;
1367 6af0bf9c bellard
    int blink, bcond;
1368 6af0bf9c bellard
1369 6af0bf9c bellard
    btarget = -1;
1370 6af0bf9c bellard
    blink = 0;
1371 6af0bf9c bellard
    bcond = 0;
1372 6af0bf9c bellard
    /* Load needed operands */
1373 6af0bf9c bellard
    switch (opc) {
1374 6af0bf9c bellard
    case OPC_BEQ:
1375 6af0bf9c bellard
    case OPC_BEQL:
1376 6af0bf9c bellard
    case OPC_BNE:
1377 6af0bf9c bellard
    case OPC_BNEL:
1378 6af0bf9c bellard
        /* Compare two registers */
1379 6af0bf9c bellard
        if (rs != rt) {
1380 6af0bf9c bellard
            GEN_LOAD_REG_TN(T0, rs);
1381 6af0bf9c bellard
            GEN_LOAD_REG_TN(T1, rt);
1382 6af0bf9c bellard
            bcond = 1;
1383 6af0bf9c bellard
        }
1384 6af0bf9c bellard
        btarget = ctx->pc + 4 + offset;
1385 6af0bf9c bellard
        break;
1386 6af0bf9c bellard
    case OPC_BGEZ:
1387 6af0bf9c bellard
    case OPC_BGEZAL:
1388 6af0bf9c bellard
    case OPC_BGEZALL:
1389 6af0bf9c bellard
    case OPC_BGEZL:
1390 6af0bf9c bellard
    case OPC_BGTZ:
1391 6af0bf9c bellard
    case OPC_BGTZL:
1392 6af0bf9c bellard
    case OPC_BLEZ:
1393 6af0bf9c bellard
    case OPC_BLEZL:
1394 6af0bf9c bellard
    case OPC_BLTZ:
1395 6af0bf9c bellard
    case OPC_BLTZAL:
1396 6af0bf9c bellard
    case OPC_BLTZALL:
1397 6af0bf9c bellard
    case OPC_BLTZL:
1398 6af0bf9c bellard
        /* Compare to zero */
1399 6af0bf9c bellard
        if (rs != 0) {
1400 6af0bf9c bellard
            gen_op_load_gpr_T0(rs);
1401 6af0bf9c bellard
            bcond = 1;
1402 6af0bf9c bellard
        }
1403 6af0bf9c bellard
        btarget = ctx->pc + 4 + offset;
1404 6af0bf9c bellard
        break;
1405 6af0bf9c bellard
    case OPC_J:
1406 6af0bf9c bellard
    case OPC_JAL:
1407 6af0bf9c bellard
        /* Jump to immediate */
1408 bc9ed47b bellard
        btarget = ((ctx->pc + 4) & 0xF0000000) | offset;
1409 6af0bf9c bellard
        break;
1410 6af0bf9c bellard
    case OPC_JR:
1411 6af0bf9c bellard
    case OPC_JALR:
1412 6af0bf9c bellard
        /* Jump to register */
1413 7a387fff ths
        if (offset != 0 && offset != 16) {
1414 7a387fff ths
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1415 7a387fff ths
              others are reserved. */
1416 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1417 6af0bf9c bellard
            return;
1418 6af0bf9c bellard
        }
1419 6af0bf9c bellard
        GEN_LOAD_REG_TN(T2, rs);
1420 6af0bf9c bellard
        break;
1421 6af0bf9c bellard
    default:
1422 6af0bf9c bellard
        MIPS_INVAL("branch/jump");
1423 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
1424 6af0bf9c bellard
        return;
1425 6af0bf9c bellard
    }
1426 6af0bf9c bellard
    if (bcond == 0) {
1427 6af0bf9c bellard
        /* No condition to be computed */
1428 6af0bf9c bellard
        switch (opc) {
1429 6af0bf9c bellard
        case OPC_BEQ:     /* rx == rx        */
1430 6af0bf9c bellard
        case OPC_BEQL:    /* rx == rx likely */
1431 6af0bf9c bellard
        case OPC_BGEZ:    /* 0 >= 0          */
1432 6af0bf9c bellard
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1433 6af0bf9c bellard
        case OPC_BLEZ:    /* 0 <= 0          */
1434 6af0bf9c bellard
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1435 6af0bf9c bellard
            /* Always take */
1436 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1437 6af0bf9c bellard
            MIPS_DEBUG("balways");
1438 6af0bf9c bellard
            break;
1439 6af0bf9c bellard
        case OPC_BGEZAL:  /* 0 >= 0          */
1440 6af0bf9c bellard
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1441 6af0bf9c bellard
            /* Always take and link */
1442 6af0bf9c bellard
            blink = 31;
1443 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1444 6af0bf9c bellard
            MIPS_DEBUG("balways and link");
1445 6af0bf9c bellard
            break;
1446 6af0bf9c bellard
        case OPC_BNE:     /* rx != rx        */
1447 6af0bf9c bellard
        case OPC_BGTZ:    /* 0 > 0           */
1448 6af0bf9c bellard
        case OPC_BLTZ:    /* 0 < 0           */
1449 6af0bf9c bellard
            /* Treated as NOP */
1450 6af0bf9c bellard
            MIPS_DEBUG("bnever (NOP)");
1451 6af0bf9c bellard
            return;
1452 eeef26cd bellard
        case OPC_BLTZAL:  /* 0 < 0           */
1453 eeef26cd bellard
            gen_op_set_T0(ctx->pc + 8);
1454 eeef26cd bellard
            gen_op_store_T0_gpr(31);
1455 eeef26cd bellard
            return;
1456 eeef26cd bellard
        case OPC_BLTZALL: /* 0 < 0 likely */
1457 eeef26cd bellard
            gen_op_set_T0(ctx->pc + 8);
1458 eeef26cd bellard
            gen_op_store_T0_gpr(31);
1459 eeef26cd bellard
            gen_goto_tb(ctx, 0, ctx->pc + 4);
1460 eeef26cd bellard
            return;
1461 6af0bf9c bellard
        case OPC_BNEL:    /* rx != rx likely */
1462 6af0bf9c bellard
        case OPC_BGTZL:   /* 0 > 0 likely */
1463 6af0bf9c bellard
        case OPC_BLTZL:   /* 0 < 0 likely */
1464 6af0bf9c bellard
            /* Skip the instruction in the delay slot */
1465 6af0bf9c bellard
            MIPS_DEBUG("bnever and skip");
1466 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->pc + 4);
1467 6af0bf9c bellard
            return;
1468 6af0bf9c bellard
        case OPC_J:
1469 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1470 6af0bf9c bellard
            MIPS_DEBUG("j %08x", btarget);
1471 6af0bf9c bellard
            break;
1472 6af0bf9c bellard
        case OPC_JAL:
1473 6af0bf9c bellard
            blink = 31;
1474 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
1475 6af0bf9c bellard
            MIPS_DEBUG("jal %08x", btarget);
1476 6af0bf9c bellard
            break;
1477 6af0bf9c bellard
        case OPC_JR:
1478 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
1479 6af0bf9c bellard
            MIPS_DEBUG("jr %s", regnames[rs]);
1480 6af0bf9c bellard
            break;
1481 6af0bf9c bellard
        case OPC_JALR:
1482 6af0bf9c bellard
            blink = rt;
1483 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
1484 6af0bf9c bellard
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1485 6af0bf9c bellard
            break;
1486 6af0bf9c bellard
        default:
1487 6af0bf9c bellard
            MIPS_INVAL("branch/jump");
1488 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
1489 6af0bf9c bellard
            return;
1490 6af0bf9c bellard
        }
1491 6af0bf9c bellard
    } else {
1492 6af0bf9c bellard
        switch (opc) {
1493 6af0bf9c bellard
        case OPC_BEQ:
1494 6af0bf9c bellard
            gen_op_eq();
1495 6af0bf9c bellard
            MIPS_DEBUG("beq %s, %s, %08x",
1496 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1497 6af0bf9c bellard
            goto not_likely;
1498 6af0bf9c bellard
        case OPC_BEQL:
1499 6af0bf9c bellard
            gen_op_eq();
1500 6af0bf9c bellard
            MIPS_DEBUG("beql %s, %s, %08x",
1501 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1502 6af0bf9c bellard
            goto likely;
1503 6af0bf9c bellard
        case OPC_BNE:
1504 6af0bf9c bellard
            gen_op_ne();
1505 6af0bf9c bellard
            MIPS_DEBUG("bne %s, %s, %08x",
1506 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1507 6af0bf9c bellard
            goto not_likely;
1508 6af0bf9c bellard
        case OPC_BNEL:
1509 6af0bf9c bellard
            gen_op_ne();
1510 6af0bf9c bellard
            MIPS_DEBUG("bnel %s, %s, %08x",
1511 6af0bf9c bellard
                       regnames[rs], regnames[rt], btarget);
1512 6af0bf9c bellard
            goto likely;
1513 6af0bf9c bellard
        case OPC_BGEZ:
1514 6af0bf9c bellard
            gen_op_gez();
1515 6af0bf9c bellard
            MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget);
1516 6af0bf9c bellard
            goto not_likely;
1517 6af0bf9c bellard
        case OPC_BGEZL:
1518 6af0bf9c bellard
            gen_op_gez();
1519 6af0bf9c bellard
            MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget);
1520 6af0bf9c bellard
            goto likely;
1521 6af0bf9c bellard
        case OPC_BGEZAL:
1522 6af0bf9c bellard
            gen_op_gez();
1523 6af0bf9c bellard
            MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget);
1524 6af0bf9c bellard
            blink = 31;
1525 6af0bf9c bellard
            goto not_likely;
1526 6af0bf9c bellard
        case OPC_BGEZALL:
1527 6af0bf9c bellard
            gen_op_gez();
1528 6af0bf9c bellard
            blink = 31;
1529 6af0bf9c bellard
            MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget);
1530 6af0bf9c bellard
            goto likely;
1531 6af0bf9c bellard
        case OPC_BGTZ:
1532 6af0bf9c bellard
            gen_op_gtz();
1533 6af0bf9c bellard
            MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget);
1534 6af0bf9c bellard
            goto not_likely;
1535 6af0bf9c bellard
        case OPC_BGTZL:
1536 6af0bf9c bellard
            gen_op_gtz();
1537 6af0bf9c bellard
            MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget);
1538 6af0bf9c bellard
            goto likely;
1539 6af0bf9c bellard
        case OPC_BLEZ:
1540 6af0bf9c bellard
            gen_op_lez();
1541 6af0bf9c bellard
            MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget);
1542 6af0bf9c bellard
            goto not_likely;
1543 6af0bf9c bellard
        case OPC_BLEZL:
1544 6af0bf9c bellard
            gen_op_lez();
1545 6af0bf9c bellard
            MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget);
1546 6af0bf9c bellard
            goto likely;
1547 6af0bf9c bellard
        case OPC_BLTZ:
1548 6af0bf9c bellard
            gen_op_ltz();
1549 6af0bf9c bellard
            MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget);
1550 6af0bf9c bellard
            goto not_likely;
1551 6af0bf9c bellard
        case OPC_BLTZL:
1552 6af0bf9c bellard
            gen_op_ltz();
1553 6af0bf9c bellard
            MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget);
1554 6af0bf9c bellard
            goto likely;
1555 6af0bf9c bellard
        case OPC_BLTZAL:
1556 6af0bf9c bellard
            gen_op_ltz();
1557 6af0bf9c bellard
            blink = 31;
1558 6af0bf9c bellard
            MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
1559 6af0bf9c bellard
        not_likely:
1560 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BC;
1561 6af0bf9c bellard
            break;
1562 6af0bf9c bellard
        case OPC_BLTZALL:
1563 6af0bf9c bellard
            gen_op_ltz();
1564 6af0bf9c bellard
            blink = 31;
1565 6af0bf9c bellard
            MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
1566 6af0bf9c bellard
        likely:
1567 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BL;
1568 6af0bf9c bellard
            break;
1569 6af0bf9c bellard
        }
1570 6af0bf9c bellard
        gen_op_set_bcond();
1571 6af0bf9c bellard
    }
1572 6af0bf9c bellard
    MIPS_DEBUG("enter ds: link %d cond %02x target %08x",
1573 6af0bf9c bellard
               blink, ctx->hflags, btarget);
1574 6af0bf9c bellard
    ctx->btarget = btarget;
1575 6af0bf9c bellard
    if (blink > 0) {
1576 6af0bf9c bellard
        gen_op_set_T0(ctx->pc + 8);
1577 6af0bf9c bellard
        gen_op_store_T0_gpr(blink);
1578 6af0bf9c bellard
    }
1579 6af0bf9c bellard
    return;
1580 6af0bf9c bellard
}
1581 6af0bf9c bellard
1582 7a387fff ths
/* special3 bitfield operations */
1583 7a387fff ths
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1584 7a387fff ths
                       int rs, int lsb, int msb)
1585 7a387fff ths
{
1586 7a387fff ths
    GEN_LOAD_REG_TN(T1, rs);
1587 7a387fff ths
    switch (opc) {
1588 7a387fff ths
    case OPC_EXT:
1589 7a387fff ths
        if (lsb + msb > 31)
1590 7a387fff ths
            goto fail;
1591 7a387fff ths
        gen_op_ext(lsb, msb + 1);
1592 7a387fff ths
        break;
1593 7a387fff ths
    case OPC_DEXTM:
1594 7a387fff ths
        if (lsb + msb > 63)
1595 7a387fff ths
            goto fail;
1596 7a387fff ths
        gen_op_ext(lsb, msb + 1 + 32);
1597 7a387fff ths
        break;
1598 7a387fff ths
    case OPC_DEXTU:
1599 7a387fff ths
        if (lsb + msb > 63)
1600 7a387fff ths
            goto fail;
1601 7a387fff ths
        gen_op_ext(lsb + 32, msb + 1);
1602 7a387fff ths
        break;
1603 7a387fff ths
    case OPC_DEXT:
1604 7a387fff ths
        gen_op_ext(lsb, msb + 1);
1605 7a387fff ths
        break;
1606 7a387fff ths
    case OPC_INS:
1607 7a387fff ths
        if (lsb > msb)
1608 7a387fff ths
            goto fail;
1609 7a387fff ths
        GEN_LOAD_REG_TN(T2, rt);
1610 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1);
1611 7a387fff ths
        break;
1612 7a387fff ths
    case OPC_DINSM:
1613 7a387fff ths
        if (lsb > msb)
1614 7a387fff ths
            goto fail;
1615 7a387fff ths
        GEN_LOAD_REG_TN(T2, rt);
1616 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1617 7a387fff ths
        break;
1618 7a387fff ths
    case OPC_DINSU:
1619 7a387fff ths
        if (lsb > msb)
1620 7a387fff ths
            goto fail;
1621 7a387fff ths
        GEN_LOAD_REG_TN(T2, rt);
1622 7a387fff ths
        gen_op_ins(lsb + 32, msb - lsb + 1);
1623 7a387fff ths
        break;
1624 7a387fff ths
    case OPC_DINS:
1625 7a387fff ths
        if (lsb > msb)
1626 7a387fff ths
            goto fail;
1627 7a387fff ths
        GEN_LOAD_REG_TN(T2, rt);
1628 7a387fff ths
        gen_op_ins(lsb, msb - lsb + 1);
1629 7a387fff ths
        break;
1630 7a387fff ths
    default:
1631 7a387fff ths
fail:
1632 7a387fff ths
        MIPS_INVAL("bitops");
1633 7a387fff ths
        generate_exception(ctx, EXCP_RI);
1634 7a387fff ths
        return;
1635 7a387fff ths
    }
1636 7a387fff ths
    GEN_STORE_TN_REG(rt, T0);
1637 7a387fff ths
}
1638 7a387fff ths
1639 6af0bf9c bellard
/* CP0 (MMU and control) */
1640 873eb012 ths
static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1641 873eb012 ths
{
1642 7a387fff ths
    const char *rn = "invalid";
1643 873eb012 ths
1644 873eb012 ths
    switch (reg) {
1645 873eb012 ths
    case 0:
1646 7a387fff ths
        switch (sel) {
1647 7a387fff ths
        case 0:
1648 7a387fff ths
           gen_op_mfc0_index();
1649 7a387fff ths
            rn = "Index";
1650 7a387fff ths
            break;
1651 7a387fff ths
        case 1:
1652 7a387fff ths
//         gen_op_mfc0_mvpcontrol(); /* MT ASE */
1653 7a387fff ths
            rn = "MVPControl";
1654 7a387fff ths
//         break;
1655 7a387fff ths
        case 2:
1656 7a387fff ths
//         gen_op_mfc0_mvpconf0(); /* MT ASE */
1657 7a387fff ths
            rn = "MVPConf0";
1658 7a387fff ths
//         break;
1659 7a387fff ths
        case 3:
1660 7a387fff ths
//         gen_op_mfc0_mvpconf1(); /* MT ASE */
1661 7a387fff ths
            rn = "MVPConf1";
1662 7a387fff ths
//         break;
1663 7a387fff ths
        default:
1664 7a387fff ths
            goto die;
1665 7a387fff ths
        }
1666 873eb012 ths
        break;
1667 873eb012 ths
    case 1:
1668 7a387fff ths
        switch (sel) {
1669 7a387fff ths
        case 0:
1670 7a387fff ths
            gen_op_mfc0_random();
1671 7a387fff ths
            rn = "Random";
1672 7a387fff ths
           break;
1673 7a387fff ths
        case 1:
1674 7a387fff ths
//         gen_op_mfc0_vpecontrol(); /* MT ASE */
1675 7a387fff ths
            rn = "VPEControl";
1676 7a387fff ths
//         break;
1677 7a387fff ths
        case 2:
1678 7a387fff ths
//         gen_op_mfc0_vpeconf0(); /* MT ASE */
1679 7a387fff ths
            rn = "VPEConf0";
1680 7a387fff ths
//         break;
1681 7a387fff ths
        case 3:
1682 7a387fff ths
//         gen_op_mfc0_vpeconf1(); /* MT ASE */
1683 7a387fff ths
            rn = "VPEConf1";
1684 7a387fff ths
//         break;
1685 7a387fff ths
        case 4:
1686 7a387fff ths
//         gen_op_mfc0_YQMask(); /* MT ASE */
1687 7a387fff ths
            rn = "YQMask";
1688 7a387fff ths
//         break;
1689 7a387fff ths
        case 5:
1690 7a387fff ths
//         gen_op_mfc0_vpeschedule(); /* MT ASE */
1691 7a387fff ths
            rn = "VPESchedule";
1692 7a387fff ths
//         break;
1693 7a387fff ths
        case 6:
1694 7a387fff ths
//         gen_op_mfc0_vpeschefback(); /* MT ASE */
1695 7a387fff ths
            rn = "VPEScheFBack";
1696 7a387fff ths
//         break;
1697 7a387fff ths
        case 7:
1698 7a387fff ths
//         gen_op_mfc0_vpeopt(); /* MT ASE */
1699 7a387fff ths
            rn = "VPEOpt";
1700 7a387fff ths
//         break;
1701 7a387fff ths
        default:
1702 7a387fff ths
            goto die;
1703 7a387fff ths
        }
1704 873eb012 ths
        break;
1705 873eb012 ths
    case 2:
1706 7a387fff ths
        switch (sel) {
1707 7a387fff ths
        case 0:
1708 7a387fff ths
           gen_op_mfc0_entrylo0();
1709 7a387fff ths
           rn = "EntryLo0";
1710 7a387fff ths
           break;
1711 7a387fff ths
        case 1:
1712 7a387fff ths
//         gen_op_mfc0_tcstatus(); /* MT ASE */
1713 7a387fff ths
           rn = "TCStatus";
1714 7a387fff ths
//         break;
1715 7a387fff ths
        case 2:
1716 7a387fff ths
//         gen_op_mfc0_tcbind(); /* MT ASE */
1717 7a387fff ths
           rn = "TCBind";
1718 7a387fff ths
//         break;
1719 7a387fff ths
        case 3:
1720 7a387fff ths
//         gen_op_mfc0_tcrestart(); /* MT ASE */
1721 7a387fff ths
           rn = "TCRestart";
1722 7a387fff ths
//         break;
1723 7a387fff ths
        case 4:
1724 7a387fff ths
//         gen_op_mfc0_tchalt(); /* MT ASE */
1725 7a387fff ths
           rn = "TCHalt";
1726 7a387fff ths
//         break;
1727 7a387fff ths
        case 5:
1728 7a387fff ths
//         gen_op_mfc0_tccontext(); /* MT ASE */
1729 7a387fff ths
           rn = "TCContext";
1730 7a387fff ths
//         break;
1731 7a387fff ths
        case 6:
1732 7a387fff ths
//         gen_op_mfc0_tcschedule(); /* MT ASE */
1733 7a387fff ths
           rn = "TCSchedule";
1734 7a387fff ths
//         break;
1735 7a387fff ths
        case 7:
1736 7a387fff ths
//         gen_op_mfc0_tcschefback(); /* MT ASE */
1737 7a387fff ths
           rn = "TCScheFBack";
1738 7a387fff ths
//         break;
1739 7a387fff ths
        default:
1740 7a387fff ths
            goto die;
1741 7a387fff ths
        }
1742 873eb012 ths
        break;
1743 873eb012 ths
    case 3:
1744 7a387fff ths
        switch (sel) {
1745 7a387fff ths
        case 0:
1746 7a387fff ths
           gen_op_mfc0_entrylo1();
1747 7a387fff ths
           rn = "EntryLo1";
1748 7a387fff ths
           break;
1749 7a387fff ths
        default:
1750 7a387fff ths
            goto die;
1751 7a387fff ths
       }
1752 873eb012 ths
        break;
1753 873eb012 ths
    case 4:
1754 7a387fff ths
        switch (sel) {
1755 7a387fff ths
        case 0:
1756 7a387fff ths
           gen_op_mfc0_context();
1757 7a387fff ths
           rn = "Context";
1758 7a387fff ths
           break;
1759 7a387fff ths
        case 1:
1760 7a387fff ths
//         gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
1761 7a387fff ths
           rn = "ContextConfig";
1762 7a387fff ths
//         break;
1763 7a387fff ths
        default:
1764 7a387fff ths
            goto die;
1765 7a387fff ths
       }
1766 873eb012 ths
        break;
1767 873eb012 ths
    case 5:
1768 7a387fff ths
        switch (sel) {
1769 7a387fff ths
        case 0:
1770 7a387fff ths
           gen_op_mfc0_pagemask();
1771 7a387fff ths
           rn = "PageMask";
1772 7a387fff ths
           break;
1773 7a387fff ths
        case 1:
1774 7a387fff ths
           gen_op_mfc0_pagegrain();
1775 7a387fff ths
           rn = "PageGrain";
1776 7a387fff ths
           break;
1777 7a387fff ths
        default:
1778 7a387fff ths
            goto die;
1779 7a387fff ths
       }
1780 873eb012 ths
        break;
1781 873eb012 ths
    case 6:
1782 7a387fff ths
        switch (sel) {
1783 7a387fff ths
        case 0:
1784 7a387fff ths
           gen_op_mfc0_wired();
1785 7a387fff ths
           rn = "Wired";
1786 7a387fff ths
           break;
1787 7a387fff ths
        case 1:
1788 7a387fff ths
//         gen_op_mfc0_srsconf0(); /* shadow registers */
1789 7a387fff ths
           rn = "SRSConf0";
1790 7a387fff ths
//         break;
1791 7a387fff ths
        case 2:
1792 7a387fff ths
//         gen_op_mfc0_srsconf1(); /* shadow registers */
1793 7a387fff ths
           rn = "SRSConf1";
1794 7a387fff ths
//         break;
1795 7a387fff ths
        case 3:
1796 7a387fff ths
//         gen_op_mfc0_srsconf2(); /* shadow registers */
1797 7a387fff ths
           rn = "SRSConf2";
1798 7a387fff ths
//         break;
1799 7a387fff ths
        case 4:
1800 7a387fff ths
//         gen_op_mfc0_srsconf3(); /* shadow registers */
1801 7a387fff ths
           rn = "SRSConf3";
1802 7a387fff ths
//         break;
1803 7a387fff ths
        case 5:
1804 7a387fff ths
//         gen_op_mfc0_srsconf4(); /* shadow registers */
1805 7a387fff ths
           rn = "SRSConf4";
1806 7a387fff ths
//         break;
1807 7a387fff ths
        default:
1808 7a387fff ths
            goto die;
1809 7a387fff ths
       }
1810 873eb012 ths
        break;
1811 8c0fdd85 ths
    case 7:
1812 7a387fff ths
        switch (sel) {
1813 7a387fff ths
        case 0:
1814 7a387fff ths
           gen_op_mfc0_hwrena();
1815 7a387fff ths
           rn = "HWREna";
1816 7a387fff ths
           break;
1817 7a387fff ths
        default:
1818 7a387fff ths
            goto die;
1819 7a387fff ths
       }
1820 8c0fdd85 ths
        break;
1821 873eb012 ths
    case 8:
1822 7a387fff ths
        switch (sel) {
1823 7a387fff ths
        case 0:
1824 7a387fff ths
           gen_op_mfc0_badvaddr();
1825 7a387fff ths
           rn = "BadVaddr";
1826 7a387fff ths
           break;
1827 7a387fff ths
        default:
1828 7a387fff ths
            goto die;
1829 7a387fff ths
       }
1830 873eb012 ths
        break;
1831 873eb012 ths
    case 9:
1832 7a387fff ths
        switch (sel) {
1833 7a387fff ths
        case 0:
1834 7a387fff ths
           gen_op_mfc0_count();
1835 7a387fff ths
           rn = "Count";
1836 7a387fff ths
           break;
1837 7a387fff ths
       /* 6,7 are implementation dependent */
1838 7a387fff ths
        default:
1839 7a387fff ths
            goto die;
1840 7a387fff ths
       }
1841 873eb012 ths
        break;
1842 873eb012 ths
    case 10:
1843 7a387fff ths
        switch (sel) {
1844 7a387fff ths
        case 0:
1845 7a387fff ths
           gen_op_mfc0_entryhi();
1846 7a387fff ths
           rn = "EntryHi";
1847 7a387fff ths
           break;
1848 7a387fff ths
        default:
1849 7a387fff ths
            goto die;
1850 7a387fff ths
       }
1851 873eb012 ths
        break;
1852 873eb012 ths
    case 11:
1853 7a387fff ths
        switch (sel) {
1854 7a387fff ths
        case 0:
1855 7a387fff ths
           gen_op_mfc0_compare();
1856 7a387fff ths
           rn = "Compare";
1857 7a387fff ths
           break;
1858 7a387fff ths
       /* 6,7 are implementation dependent */
1859 7a387fff ths
        default:
1860 7a387fff ths
            goto die;
1861 7a387fff ths
       }
1862 873eb012 ths
        break;
1863 873eb012 ths
    case 12:
1864 7a387fff ths
        switch (sel) {
1865 7a387fff ths
        case 0:
1866 7a387fff ths
           gen_op_mfc0_status();
1867 7a387fff ths
           rn = "Status";
1868 7a387fff ths
           break;
1869 7a387fff ths
        case 1:
1870 7a387fff ths
           gen_op_mfc0_intctl();
1871 7a387fff ths
           rn = "IntCtl";
1872 7a387fff ths
           break;
1873 7a387fff ths
        case 2:
1874 7a387fff ths
           gen_op_mfc0_srsctl();
1875 7a387fff ths
           rn = "SRSCtl";
1876 7a387fff ths
           break;
1877 7a387fff ths
        case 3:
1878 7a387fff ths
//         gen_op_mfc0_srsmap(); /* shadow registers */
1879 7a387fff ths
           rn = "SRSMap";
1880 7a387fff ths
//         break;
1881 7a387fff ths
        default:
1882 7a387fff ths
            goto die;
1883 7a387fff ths
       }
1884 873eb012 ths
        break;
1885 873eb012 ths
    case 13:
1886 7a387fff ths
        switch (sel) {
1887 7a387fff ths
        case 0:
1888 7a387fff ths
           gen_op_mfc0_cause();
1889 7a387fff ths
           rn = "Cause";
1890 7a387fff ths
           break;
1891 7a387fff ths
        default:
1892 7a387fff ths
            goto die;
1893 7a387fff ths
       }
1894 873eb012 ths
        break;
1895 873eb012 ths
    case 14:
1896 7a387fff ths
        switch (sel) {
1897 7a387fff ths
        case 0:
1898 7a387fff ths
           gen_op_mfc0_epc();
1899 7a387fff ths
           rn = "EPC";
1900 7a387fff ths
           break;
1901 7a387fff ths
        default:
1902 7a387fff ths
            goto die;
1903 7a387fff ths
       }
1904 873eb012 ths
        break;
1905 873eb012 ths
    case 15:
1906 7a387fff ths
        switch (sel) {
1907 7a387fff ths
        case 0:
1908 7a387fff ths
           gen_op_mfc0_prid();
1909 7a387fff ths
           rn = "PRid";
1910 7a387fff ths
           break;
1911 7a387fff ths
        case 1:
1912 7a387fff ths
           gen_op_mfc0_ebase();
1913 7a387fff ths
           rn = "EBase";
1914 7a387fff ths
           break;
1915 7a387fff ths
        default:
1916 7a387fff ths
            goto die;
1917 7a387fff ths
       }
1918 873eb012 ths
        break;
1919 873eb012 ths
    case 16:
1920 873eb012 ths
        switch (sel) {
1921 873eb012 ths
        case 0:
1922 873eb012 ths
           gen_op_mfc0_config0();
1923 873eb012 ths
            rn = "Config";
1924 873eb012 ths
            break;
1925 873eb012 ths
        case 1:
1926 873eb012 ths
           gen_op_mfc0_config1();
1927 873eb012 ths
            rn = "Config1";
1928 873eb012 ths
            break;
1929 7a387fff ths
        case 2:
1930 7a387fff ths
           gen_op_mfc0_config2();
1931 7a387fff ths
            rn = "Config2";
1932 7a387fff ths
            break;
1933 7a387fff ths
        case 3:
1934 7a387fff ths
           gen_op_mfc0_config3();
1935 7a387fff ths
            rn = "Config3";
1936 7a387fff ths
            break;
1937 7a387fff ths
       /* 6,7 are implementation dependent */
1938 873eb012 ths
        default:
1939 873eb012 ths
            goto die;
1940 873eb012 ths
        }
1941 873eb012 ths
        break;
1942 873eb012 ths
    case 17:
1943 7a387fff ths
        switch (sel) {
1944 7a387fff ths
        case 0:
1945 7a387fff ths
           gen_op_mfc0_lladdr();
1946 7a387fff ths
           rn = "LLAddr";
1947 7a387fff ths
           break;
1948 7a387fff ths
        default:
1949 7a387fff ths
            goto die;
1950 7a387fff ths
        }
1951 873eb012 ths
        break;
1952 873eb012 ths
    case 18:
1953 7a387fff ths
        switch (sel) {
1954 7a387fff ths
        case 0:
1955 7a387fff ths
           gen_op_mfc0_watchlo0();
1956 7a387fff ths
           rn = "WatchLo";
1957 7a387fff ths
           break;
1958 7a387fff ths
        case 1:
1959 7a387fff ths
//         gen_op_mfc0_watchlo1();
1960 7a387fff ths
           rn = "WatchLo1";
1961 7a387fff ths
//         break;
1962 7a387fff ths
        case 2:
1963 7a387fff ths
//         gen_op_mfc0_watchlo2();
1964 7a387fff ths
           rn = "WatchLo2";
1965 7a387fff ths
//         break;
1966 7a387fff ths
        case 3:
1967 7a387fff ths
//         gen_op_mfc0_watchlo3();
1968 7a387fff ths
           rn = "WatchLo3";
1969 7a387fff ths
//         break;
1970 7a387fff ths
        case 4:
1971 7a387fff ths
//         gen_op_mfc0_watchlo4();
1972 7a387fff ths
           rn = "WatchLo4";
1973 7a387fff ths
//         break;
1974 7a387fff ths
        case 5:
1975 7a387fff ths
//         gen_op_mfc0_watchlo5();
1976 7a387fff ths
           rn = "WatchLo5";
1977 7a387fff ths
//         break;
1978 7a387fff ths
        case 6:
1979 7a387fff ths
//         gen_op_mfc0_watchlo6();
1980 7a387fff ths
           rn = "WatchLo6";
1981 7a387fff ths
//         break;
1982 7a387fff ths
        case 7:
1983 7a387fff ths
//         gen_op_mfc0_watchlo7();
1984 7a387fff ths
           rn = "WatchLo7";
1985 7a387fff ths
//         break;
1986 7a387fff ths
        default:
1987 7a387fff ths
            goto die;
1988 7a387fff ths
        }
1989 873eb012 ths
        break;
1990 873eb012 ths
    case 19:
1991 7a387fff ths
        switch (sel) {
1992 7a387fff ths
        case 0:
1993 7a387fff ths
           gen_op_mfc0_watchhi0();
1994 7a387fff ths
           rn = "WatchHi";
1995 7a387fff ths
           break;
1996 7a387fff ths
        case 1:
1997 7a387fff ths
//         gen_op_mfc0_watchhi1();
1998 7a387fff ths
           rn = "WatchHi1";
1999 7a387fff ths
//         break;
2000 7a387fff ths
        case 2:
2001 7a387fff ths
//         gen_op_mfc0_watchhi2();
2002 7a387fff ths
           rn = "WatchHi2";
2003 7a387fff ths
//         break;
2004 7a387fff ths
        case 3:
2005 7a387fff ths
//         gen_op_mfc0_watchhi3();
2006 7a387fff ths
           rn = "WatchHi3";
2007 7a387fff ths
//         break;
2008 7a387fff ths
        case 4:
2009 7a387fff ths
//         gen_op_mfc0_watchhi4();
2010 7a387fff ths
           rn = "WatchHi4";
2011 7a387fff ths
//         break;
2012 7a387fff ths
        case 5:
2013 7a387fff ths
//         gen_op_mfc0_watchhi5();
2014 7a387fff ths
           rn = "WatchHi5";
2015 7a387fff ths
//         break;
2016 7a387fff ths
        case 6:
2017 7a387fff ths
//         gen_op_mfc0_watchhi6();
2018 7a387fff ths
           rn = "WatchHi6";
2019 7a387fff ths
//         break;
2020 7a387fff ths
        case 7:
2021 7a387fff ths
//         gen_op_mfc0_watchhi7();
2022 7a387fff ths
           rn = "WatchHi7";
2023 7a387fff ths
//         break;
2024 7a387fff ths
        default:
2025 7a387fff ths
            goto die;
2026 7a387fff ths
        }
2027 873eb012 ths
        break;
2028 8c0fdd85 ths
    case 20:
2029 7a387fff ths
        switch (sel) {
2030 7a387fff ths
        case 0:
2031 7a387fff ths
           /* 64 bit MMU only */
2032 7a387fff ths
           gen_op_mfc0_xcontext();
2033 7a387fff ths
           rn = "XContext";
2034 7a387fff ths
           break;
2035 7a387fff ths
        default:
2036 7a387fff ths
            goto die;
2037 7a387fff ths
        }
2038 8c0fdd85 ths
        break;
2039 8c0fdd85 ths
    case 21:
2040 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2041 7a387fff ths
        switch (sel) {
2042 7a387fff ths
        case 0:
2043 7a387fff ths
           gen_op_mfc0_framemask();
2044 7a387fff ths
           rn = "Framemask";
2045 7a387fff ths
           break;
2046 7a387fff ths
        default:
2047 7a387fff ths
            goto die;
2048 7a387fff ths
        }
2049 8c0fdd85 ths
        break;
2050 8c0fdd85 ths
    case 22:
2051 7a387fff ths
       /* ignored */
2052 7a387fff ths
       rn = "'Diagnostic"; /* implementation dependent */
2053 7a387fff ths
       break;
2054 873eb012 ths
    case 23:
2055 7a387fff ths
        switch (sel) {
2056 7a387fff ths
        case 0:
2057 7a387fff ths
           gen_op_mfc0_debug(); /* EJTAG support */
2058 7a387fff ths
           rn = "Debug";
2059 7a387fff ths
           break;
2060 7a387fff ths
        case 1:
2061 7a387fff ths
//         gen_op_mfc0_tracecontrol(); /* PDtrace support */
2062 7a387fff ths
           rn = "TraceControl";
2063 7a387fff ths
//         break;
2064 7a387fff ths
        case 2:
2065 7a387fff ths
//         gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2066 7a387fff ths
           rn = "TraceControl2";
2067 7a387fff ths
//         break;
2068 7a387fff ths
        case 3:
2069 7a387fff ths
//         gen_op_mfc0_usertracedata(); /* PDtrace support */
2070 7a387fff ths
           rn = "UserTraceData";
2071 7a387fff ths
//         break;
2072 7a387fff ths
        case 4:
2073 7a387fff ths
//         gen_op_mfc0_debug(); /* PDtrace support */
2074 7a387fff ths
           rn = "TraceBPC";
2075 7a387fff ths
//         break;
2076 7a387fff ths
        default:
2077 7a387fff ths
            goto die;
2078 7a387fff ths
        }
2079 873eb012 ths
        break;
2080 873eb012 ths
    case 24:
2081 7a387fff ths
        switch (sel) {
2082 7a387fff ths
        case 0:
2083 7a387fff ths
           gen_op_mfc0_depc(); /* EJTAG support */
2084 7a387fff ths
           rn = "DEPC";
2085 7a387fff ths
           break;
2086 7a387fff ths
        default:
2087 7a387fff ths
            goto die;
2088 7a387fff ths
        }
2089 873eb012 ths
        break;
2090 8c0fdd85 ths
    case 25:
2091 7a387fff ths
        switch (sel) {
2092 7a387fff ths
        case 0:
2093 7a387fff ths
           gen_op_mfc0_performance0();
2094 7a387fff ths
           rn = "Performance0";
2095 7a387fff ths
            break;
2096 7a387fff ths
        case 1:
2097 7a387fff ths
//         gen_op_mfc0_performance1();
2098 7a387fff ths
           rn = "Performance1";
2099 7a387fff ths
//         break;
2100 7a387fff ths
        case 2:
2101 7a387fff ths
//         gen_op_mfc0_performance2();
2102 7a387fff ths
           rn = "Performance2";
2103 7a387fff ths
//         break;
2104 7a387fff ths
        case 3:
2105 7a387fff ths
//         gen_op_mfc0_performance3();
2106 7a387fff ths
           rn = "Performance3";
2107 7a387fff ths
//         break;
2108 7a387fff ths
        case 4:
2109 7a387fff ths
//         gen_op_mfc0_performance4();
2110 7a387fff ths
           rn = "Performance4";
2111 7a387fff ths
//         break;
2112 7a387fff ths
        case 5:
2113 7a387fff ths
//         gen_op_mfc0_performance5();
2114 7a387fff ths
           rn = "Performance5";
2115 7a387fff ths
//         break;
2116 7a387fff ths
        case 6:
2117 7a387fff ths
//         gen_op_mfc0_performance6();
2118 7a387fff ths
           rn = "Performance6";
2119 7a387fff ths
//         break;
2120 7a387fff ths
        case 7:
2121 7a387fff ths
//         gen_op_mfc0_performance7();
2122 7a387fff ths
           rn = "Performance7";
2123 7a387fff ths
//         break;
2124 7a387fff ths
        default:
2125 7a387fff ths
            goto die;
2126 7a387fff ths
        }
2127 8c0fdd85 ths
        break;
2128 8c0fdd85 ths
    case 26:
2129 7a387fff ths
       rn = "ECC";
2130 7a387fff ths
       break;
2131 8c0fdd85 ths
    case 27:
2132 7a387fff ths
        switch (sel) {
2133 7a387fff ths
        /* ignored */
2134 7a387fff ths
        case 0 ... 3:
2135 7a387fff ths
           rn = "CacheErr";
2136 7a387fff ths
           break;
2137 7a387fff ths
        default:
2138 7a387fff ths
            goto die;
2139 7a387fff ths
        }
2140 8c0fdd85 ths
        break;
2141 873eb012 ths
    case 28:
2142 873eb012 ths
        switch (sel) {
2143 873eb012 ths
        case 0:
2144 7a387fff ths
        case 2:
2145 7a387fff ths
        case 4:
2146 7a387fff ths
        case 6:
2147 873eb012 ths
            gen_op_mfc0_taglo();
2148 873eb012 ths
            rn = "TagLo";
2149 873eb012 ths
            break;
2150 873eb012 ths
        case 1:
2151 7a387fff ths
        case 3:
2152 7a387fff ths
        case 5:
2153 7a387fff ths
        case 7:
2154 873eb012 ths
            gen_op_mfc0_datalo();
2155 873eb012 ths
            rn = "DataLo";
2156 873eb012 ths
            break;
2157 873eb012 ths
        default:
2158 873eb012 ths
            goto die;
2159 873eb012 ths
        }
2160 873eb012 ths
        break;
2161 8c0fdd85 ths
    case 29:
2162 7a387fff ths
        switch (sel) {
2163 7a387fff ths
        case 0:
2164 7a387fff ths
        case 2:
2165 7a387fff ths
        case 4:
2166 7a387fff ths
        case 6:
2167 7a387fff ths
            gen_op_mfc0_taghi();
2168 7a387fff ths
            rn = "TagHi";
2169 7a387fff ths
            break;
2170 7a387fff ths
        case 1:
2171 7a387fff ths
        case 3:
2172 7a387fff ths
        case 5:
2173 7a387fff ths
        case 7:
2174 7a387fff ths
            gen_op_mfc0_datahi();
2175 7a387fff ths
            rn = "DataHi";
2176 7a387fff ths
            break;
2177 7a387fff ths
        default:
2178 7a387fff ths
            goto die;
2179 7a387fff ths
        }
2180 8c0fdd85 ths
        break;
2181 873eb012 ths
    case 30:
2182 7a387fff ths
        switch (sel) {
2183 7a387fff ths
        case 0:
2184 7a387fff ths
           gen_op_mfc0_errorepc();
2185 7a387fff ths
           rn = "ErrorEPC";
2186 7a387fff ths
           break;
2187 7a387fff ths
        default:
2188 7a387fff ths
            goto die;
2189 7a387fff ths
        }
2190 873eb012 ths
        break;
2191 873eb012 ths
    case 31:
2192 7a387fff ths
        switch (sel) {
2193 7a387fff ths
        case 0:
2194 7a387fff ths
           gen_op_mfc0_desave(); /* EJTAG support */
2195 7a387fff ths
           rn = "DESAVE";
2196 7a387fff ths
           break;
2197 7a387fff ths
        default:
2198 7a387fff ths
            goto die;
2199 7a387fff ths
        }
2200 873eb012 ths
        break;
2201 873eb012 ths
    default:
2202 873eb012 ths
       goto die;
2203 873eb012 ths
    }
2204 873eb012 ths
#if defined MIPS_DEBUG_DISAS
2205 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2206 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2207 7a387fff ths
                rn, reg, sel);
2208 873eb012 ths
    }
2209 873eb012 ths
#endif
2210 873eb012 ths
    return;
2211 873eb012 ths
2212 873eb012 ths
die:
2213 873eb012 ths
#if defined MIPS_DEBUG_DISAS
2214 873eb012 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2215 7a387fff ths
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2216 7a387fff ths
                rn, reg, sel);
2217 873eb012 ths
    }
2218 873eb012 ths
#endif
2219 873eb012 ths
    generate_exception(ctx, EXCP_RI);
2220 873eb012 ths
}
2221 873eb012 ths
2222 8c0fdd85 ths
static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2223 8c0fdd85 ths
{
2224 7a387fff ths
    const char *rn = "invalid";
2225 7a387fff ths
2226 8c0fdd85 ths
    switch (reg) {
2227 8c0fdd85 ths
    case 0:
2228 7a387fff ths
        switch (sel) {
2229 7a387fff ths
        case 0:
2230 7a387fff ths
           gen_op_mtc0_index();
2231 7a387fff ths
            rn = "Index";
2232 7a387fff ths
            break;
2233 7a387fff ths
        case 1:
2234 7a387fff ths
//         gen_op_mtc0_mvpcontrol(); /* MT ASE */
2235 7a387fff ths
            rn = "MVPControl";
2236 7a387fff ths
//         break;
2237 7a387fff ths
        case 2:
2238 7a387fff ths
//         gen_op_mtc0_mvpconf0(); /* MT ASE */
2239 7a387fff ths
            rn = "MVPConf0";
2240 7a387fff ths
//         break;
2241 7a387fff ths
        case 3:
2242 7a387fff ths
//         gen_op_mtc0_mvpconf1(); /* MT ASE */
2243 7a387fff ths
            rn = "MVPConf1";
2244 7a387fff ths
//         break;
2245 7a387fff ths
        default:
2246 7a387fff ths
            goto die;
2247 7a387fff ths
        }
2248 8c0fdd85 ths
        break;
2249 8c0fdd85 ths
    case 1:
2250 7a387fff ths
        switch (sel) {
2251 7a387fff ths
        case 0:
2252 7a387fff ths
           /* ignored */
2253 7a387fff ths
            rn = "Random";
2254 7a387fff ths
           break;
2255 7a387fff ths
        case 1:
2256 7a387fff ths
//         gen_op_mtc0_vpecontrol(); /* MT ASE */
2257 7a387fff ths
            rn = "VPEControl";
2258 7a387fff ths
//         break;
2259 7a387fff ths
        case 2:
2260 7a387fff ths
//         gen_op_mtc0_vpeconf0(); /* MT ASE */
2261 7a387fff ths
            rn = "VPEConf0";
2262 7a387fff ths
//         break;
2263 7a387fff ths
        case 3:
2264 7a387fff ths
//         gen_op_mtc0_vpeconf1(); /* MT ASE */
2265 7a387fff ths
            rn = "VPEConf1";
2266 7a387fff ths
//         break;
2267 7a387fff ths
        case 4:
2268 7a387fff ths
//         gen_op_mtc0_YQMask(); /* MT ASE */
2269 7a387fff ths
            rn = "YQMask";
2270 7a387fff ths
//         break;
2271 7a387fff ths
        case 5:
2272 7a387fff ths
//         gen_op_mtc0_vpeschedule(); /* MT ASE */
2273 7a387fff ths
            rn = "VPESchedule";
2274 7a387fff ths
//         break;
2275 7a387fff ths
        case 6:
2276 7a387fff ths
//         gen_op_mtc0_vpeschefback(); /* MT ASE */
2277 7a387fff ths
            rn = "VPEScheFBack";
2278 7a387fff ths
//         break;
2279 7a387fff ths
        case 7:
2280 7a387fff ths
//         gen_op_mtc0_vpeopt(); /* MT ASE */
2281 7a387fff ths
            rn = "VPEOpt";
2282 7a387fff ths
//         break;
2283 7a387fff ths
        default:
2284 7a387fff ths
            goto die;
2285 7a387fff ths
        }
2286 8c0fdd85 ths
        break;
2287 8c0fdd85 ths
    case 2:
2288 7a387fff ths
        switch (sel) {
2289 7a387fff ths
        case 0:
2290 7a387fff ths
           gen_op_mtc0_entrylo0();
2291 7a387fff ths
           rn = "EntryLo0";
2292 7a387fff ths
           break;
2293 7a387fff ths
        case 1:
2294 7a387fff ths
//         gen_op_mtc0_tcstatus(); /* MT ASE */
2295 7a387fff ths
           rn = "TCStatus";
2296 7a387fff ths
//         break;
2297 7a387fff ths
        case 2:
2298 7a387fff ths
//         gen_op_mtc0_tcbind(); /* MT ASE */
2299 7a387fff ths
           rn = "TCBind";
2300 7a387fff ths
//         break;
2301 7a387fff ths
        case 3:
2302 7a387fff ths
//         gen_op_mtc0_tcrestart(); /* MT ASE */
2303 7a387fff ths
           rn = "TCRestart";
2304 7a387fff ths
//         break;
2305 7a387fff ths
        case 4:
2306 7a387fff ths
//         gen_op_mtc0_tchalt(); /* MT ASE */
2307 7a387fff ths
           rn = "TCHalt";
2308 7a387fff ths
//         break;
2309 7a387fff ths
        case 5:
2310 7a387fff ths
//         gen_op_mtc0_tccontext(); /* MT ASE */
2311 7a387fff ths
           rn = "TCContext";
2312 7a387fff ths
//         break;
2313 7a387fff ths
        case 6:
2314 7a387fff ths
//         gen_op_mtc0_tcschedule(); /* MT ASE */
2315 7a387fff ths
           rn = "TCSchedule";
2316 7a387fff ths
//         break;
2317 7a387fff ths
        case 7:
2318 7a387fff ths
//         gen_op_mtc0_tcschefback(); /* MT ASE */
2319 7a387fff ths
           rn = "TCScheFBack";
2320 7a387fff ths
//         break;
2321 7a387fff ths
        default:
2322 7a387fff ths
            goto die;
2323 7a387fff ths
        }
2324 8c0fdd85 ths
        break;
2325 8c0fdd85 ths
    case 3:
2326 7a387fff ths
        switch (sel) {
2327 7a387fff ths
        case 0:
2328 7a387fff ths
           gen_op_mtc0_entrylo1();
2329 7a387fff ths
           rn = "EntryLo1";
2330 7a387fff ths
           break;
2331 7a387fff ths
        default:
2332 7a387fff ths
            goto die;
2333 7a387fff ths
       }
2334 8c0fdd85 ths
        break;
2335 8c0fdd85 ths
    case 4:
2336 7a387fff ths
        switch (sel) {
2337 7a387fff ths
        case 0:
2338 7a387fff ths
           gen_op_mtc0_context();
2339 7a387fff ths
           rn = "Context";
2340 7a387fff ths
           break;
2341 7a387fff ths
        case 1:
2342 7a387fff ths
//         gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2343 7a387fff ths
           rn = "ContextConfig";
2344 7a387fff ths
//         break;
2345 7a387fff ths
        default:
2346 7a387fff ths
            goto die;
2347 7a387fff ths
       }
2348 8c0fdd85 ths
        break;
2349 8c0fdd85 ths
    case 5:
2350 7a387fff ths
        switch (sel) {
2351 7a387fff ths
        case 0:
2352 7a387fff ths
           gen_op_mtc0_pagemask();
2353 7a387fff ths
           rn = "PageMask";
2354 7a387fff ths
           break;
2355 7a387fff ths
        case 1:
2356 7a387fff ths
           gen_op_mtc0_pagegrain();
2357 7a387fff ths
           rn = "PageGrain";
2358 7a387fff ths
           break;
2359 7a387fff ths
        default:
2360 7a387fff ths
            goto die;
2361 7a387fff ths
       }
2362 8c0fdd85 ths
        break;
2363 8c0fdd85 ths
    case 6:
2364 7a387fff ths
        switch (sel) {
2365 7a387fff ths
        case 0:
2366 7a387fff ths
           gen_op_mtc0_wired();
2367 7a387fff ths
           rn = "Wired";
2368 7a387fff ths
           break;
2369 7a387fff ths
        case 1:
2370 7a387fff ths
//         gen_op_mtc0_srsconf0(); /* shadow registers */
2371 7a387fff ths
           rn = "SRSConf0";
2372 7a387fff ths
//         break;
2373 7a387fff ths
        case 2:
2374 7a387fff ths
//         gen_op_mtc0_srsconf1(); /* shadow registers */
2375 7a387fff ths
           rn = "SRSConf1";
2376 7a387fff ths
//         break;
2377 7a387fff ths
        case 3:
2378 7a387fff ths
//         gen_op_mtc0_srsconf2(); /* shadow registers */
2379 7a387fff ths
           rn = "SRSConf2";
2380 7a387fff ths
//         break;
2381 7a387fff ths
        case 4:
2382 7a387fff ths
//         gen_op_mtc0_srsconf3(); /* shadow registers */
2383 7a387fff ths
           rn = "SRSConf3";
2384 7a387fff ths
//         break;
2385 7a387fff ths
        case 5:
2386 7a387fff ths
//         gen_op_mtc0_srsconf4(); /* shadow registers */
2387 7a387fff ths
           rn = "SRSConf4";
2388 7a387fff ths
//         break;
2389 7a387fff ths
        default:
2390 7a387fff ths
            goto die;
2391 7a387fff ths
       }
2392 8c0fdd85 ths
        break;
2393 8c0fdd85 ths
    case 7:
2394 7a387fff ths
        switch (sel) {
2395 7a387fff ths
        case 0:
2396 7a387fff ths
           gen_op_mtc0_hwrena();
2397 7a387fff ths
           rn = "HWREna";
2398 7a387fff ths
           break;
2399 7a387fff ths
        default:
2400 7a387fff ths
            goto die;
2401 7a387fff ths
       }
2402 8c0fdd85 ths
        break;
2403 8c0fdd85 ths
    case 8:
2404 7a387fff ths
        /* ignored */
2405 8c0fdd85 ths
        rn = "BadVaddr";
2406 8c0fdd85 ths
        break;
2407 8c0fdd85 ths
    case 9:
2408 7a387fff ths
        switch (sel) {
2409 7a387fff ths
        case 0:
2410 7a387fff ths
           gen_op_mtc0_count();
2411 7a387fff ths
           rn = "Count";
2412 7a387fff ths
           break;
2413 7a387fff ths
       /* 6,7 are implementation dependent */
2414 7a387fff ths
        default:
2415 7a387fff ths
            goto die;
2416 7a387fff ths
       }
2417 7a387fff ths
       /* Stop translation as we may have switched the execution mode */
2418 7a387fff ths
       ctx->bstate = BS_STOP;
2419 8c0fdd85 ths
        break;
2420 8c0fdd85 ths
    case 10:
2421 7a387fff ths
        switch (sel) {
2422 7a387fff ths
        case 0:
2423 7a387fff ths
           gen_op_mtc0_entryhi();
2424 7a387fff ths
           rn = "EntryHi";
2425 7a387fff ths
           break;
2426 7a387fff ths
        default:
2427 7a387fff ths
            goto die;
2428 7a387fff ths
       }
2429 8c0fdd85 ths
        break;
2430 8c0fdd85 ths
    case 11:
2431 7a387fff ths
        switch (sel) {
2432 7a387fff ths
        case 0:
2433 7a387fff ths
           gen_op_mtc0_compare();
2434 7a387fff ths
           rn = "Compare";
2435 7a387fff ths
           break;
2436 7a387fff ths
       /* 6,7 are implementation dependent */
2437 7a387fff ths
        default:
2438 7a387fff ths
            goto die;
2439 7a387fff ths
       }
2440 7a387fff ths
       /* Stop translation as we may have switched the execution mode */
2441 7a387fff ths
       ctx->bstate = BS_STOP;
2442 8c0fdd85 ths
        break;
2443 8c0fdd85 ths
    case 12:
2444 7a387fff ths
        switch (sel) {
2445 7a387fff ths
        case 0:
2446 7a387fff ths
           gen_op_mtc0_status();
2447 7a387fff ths
           rn = "Status";
2448 7a387fff ths
           break;
2449 7a387fff ths
        case 1:
2450 7a387fff ths
           gen_op_mtc0_intctl();
2451 7a387fff ths
           rn = "IntCtl";
2452 7a387fff ths
           break;
2453 7a387fff ths
        case 2:
2454 7a387fff ths
           gen_op_mtc0_srsctl();
2455 7a387fff ths
           rn = "SRSCtl";
2456 7a387fff ths
           break;
2457 7a387fff ths
        case 3:
2458 7a387fff ths
//         gen_op_mtc0_srsmap(); /* shadow registers */
2459 7a387fff ths
           rn = "SRSMap";
2460 7a387fff ths
//         break;
2461 7a387fff ths
        default:
2462 7a387fff ths
            goto die;
2463 7a387fff ths
       }
2464 7a387fff ths
       /* Stop translation as we may have switched the execution mode */
2465 7a387fff ths
       ctx->bstate = BS_STOP;
2466 8c0fdd85 ths
        break;
2467 8c0fdd85 ths
    case 13:
2468 7a387fff ths
        switch (sel) {
2469 7a387fff ths
        case 0:
2470 7a387fff ths
           gen_op_mtc0_cause();
2471 7a387fff ths
           rn = "Cause";
2472 7a387fff ths
           break;
2473 7a387fff ths
        default:
2474 7a387fff ths
            goto die;
2475 7a387fff ths
       }
2476 7a387fff ths
       /* Stop translation as we may have switched the execution mode */
2477 7a387fff ths
       ctx->bstate = BS_STOP;
2478 8c0fdd85 ths
        break;
2479 8c0fdd85 ths
    case 14:
2480 7a387fff ths
        switch (sel) {
2481 7a387fff ths
        case 0:
2482 7a387fff ths
           gen_op_mtc0_epc();
2483 7a387fff ths
           rn = "EPC";
2484 7a387fff ths
           break;
2485 7a387fff ths
        default:
2486 7a387fff ths
            goto die;
2487 7a387fff ths
       }
2488 8c0fdd85 ths
        break;
2489 8c0fdd85 ths
    case 15:
2490 7a387fff ths
        switch (sel) {
2491 7a387fff ths
        case 0:
2492 7a387fff ths
           /* ignored */
2493 7a387fff ths
           rn = "PRid";
2494 7a387fff ths
           break;
2495 7a387fff ths
        case 1:
2496 7a387fff ths
           gen_op_mtc0_ebase();
2497 7a387fff ths
           rn = "EBase";
2498 7a387fff ths
           break;
2499 7a387fff ths
        default:
2500 7a387fff ths
            goto die;
2501 7a387fff ths
       }
2502 8c0fdd85 ths
        break;
2503 8c0fdd85 ths
    case 16:
2504 8c0fdd85 ths
        switch (sel) {
2505 8c0fdd85 ths
        case 0:
2506 8c0fdd85 ths
           gen_op_mtc0_config0();
2507 7a387fff ths
            rn = "Config";
2508 7a387fff ths
            break;
2509 7a387fff ths
        case 1:
2510 7a387fff ths
           /* ignored */
2511 7a387fff ths
            rn = "Config1";
2512 7a387fff ths
            break;
2513 7a387fff ths
        case 2:
2514 7a387fff ths
           gen_op_mtc0_config2();
2515 7a387fff ths
            rn = "Config2";
2516 8c0fdd85 ths
            break;
2517 7a387fff ths
        case 3:
2518 7a387fff ths
           /* ignored */
2519 7a387fff ths
            rn = "Config3";
2520 7a387fff ths
            break;
2521 7a387fff ths
       /* 6,7 are implementation dependent */
2522 8c0fdd85 ths
        default:
2523 8c0fdd85 ths
            rn = "Invalid config selector";
2524 8c0fdd85 ths
            goto die;
2525 8c0fdd85 ths
        }
2526 7a387fff ths
       /* Stop translation as we may have switched the execution mode */
2527 7a387fff ths
       ctx->bstate = BS_STOP;
2528 8c0fdd85 ths
        break;
2529 8c0fdd85 ths
    case 17:
2530 7a387fff ths
        switch (sel) {
2531 7a387fff ths
        case 0:
2532 7a387fff ths
           /* ignored */
2533 7a387fff ths
           rn = "LLAddr";
2534 7a387fff ths
           break;
2535 7a387fff ths
        default:
2536 7a387fff ths
            goto die;
2537 7a387fff ths
        }
2538 8c0fdd85 ths
        break;
2539 8c0fdd85 ths
    case 18:
2540 7a387fff ths
        switch (sel) {
2541 7a387fff ths
        case 0:
2542 7a387fff ths
           gen_op_mtc0_watchlo0();
2543 7a387fff ths
           rn = "WatchLo";
2544 7a387fff ths
           break;
2545 7a387fff ths
        case 1:
2546 7a387fff ths
//         gen_op_mtc0_watchlo1();
2547 7a387fff ths
           rn = "WatchLo1";
2548 7a387fff ths
//         break;
2549 7a387fff ths
        case 2:
2550 7a387fff ths
//         gen_op_mtc0_watchlo2();
2551 7a387fff ths
           rn = "WatchLo2";
2552 7a387fff ths
//         break;
2553 7a387fff ths
        case 3:
2554 7a387fff ths
//         gen_op_mtc0_watchlo3();
2555 7a387fff ths
           rn = "WatchLo3";
2556 7a387fff ths
//         break;
2557 7a387fff ths
        case 4:
2558 7a387fff ths
//         gen_op_mtc0_watchlo4();
2559 7a387fff ths
           rn = "WatchLo4";
2560 7a387fff ths
//         break;
2561 7a387fff ths
        case 5:
2562 7a387fff ths
//         gen_op_mtc0_watchlo5();
2563 7a387fff ths
           rn = "WatchLo5";
2564 7a387fff ths
//         break;
2565 7a387fff ths
        case 6:
2566 7a387fff ths
//         gen_op_mtc0_watchlo6();
2567 7a387fff ths
           rn = "WatchLo6";
2568 7a387fff ths
//         break;
2569 7a387fff ths
        case 7:
2570 7a387fff ths
//         gen_op_mtc0_watchlo7();
2571 7a387fff ths
           rn = "WatchLo7";
2572 7a387fff ths
//         break;
2573 7a387fff ths
        default:
2574 7a387fff ths
            goto die;
2575 7a387fff ths
        }
2576 8c0fdd85 ths
        break;
2577 8c0fdd85 ths
    case 19:
2578 7a387fff ths
        switch (sel) {
2579 7a387fff ths
        case 0:
2580 7a387fff ths
           gen_op_mtc0_watchhi0();
2581 7a387fff ths
           rn = "WatchHi";
2582 7a387fff ths
           break;
2583 7a387fff ths
        case 1:
2584 7a387fff ths
//         gen_op_mtc0_watchhi1();
2585 7a387fff ths
           rn = "WatchHi1";
2586 7a387fff ths
//         break;
2587 7a387fff ths
        case 2:
2588 7a387fff ths
//         gen_op_mtc0_watchhi2();
2589 7a387fff ths
           rn = "WatchHi2";
2590 7a387fff ths
//         break;
2591 7a387fff ths
        case 3:
2592 7a387fff ths
//         gen_op_mtc0_watchhi3();
2593 7a387fff ths
           rn = "WatchHi3";
2594 7a387fff ths
//         break;
2595 7a387fff ths
        case 4:
2596 7a387fff ths
//         gen_op_mtc0_watchhi4();
2597 7a387fff ths
           rn = "WatchHi4";
2598 7a387fff ths
//         break;
2599 7a387fff ths
        case 5:
2600 7a387fff ths
//         gen_op_mtc0_watchhi5();
2601 7a387fff ths
           rn = "WatchHi5";
2602 7a387fff ths
//         break;
2603 7a387fff ths
        case 6:
2604 7a387fff ths
//         gen_op_mtc0_watchhi6();
2605 7a387fff ths
           rn = "WatchHi6";
2606 7a387fff ths
//         break;
2607 7a387fff ths
        case 7:
2608 7a387fff ths
//         gen_op_mtc0_watchhi7();
2609 7a387fff ths
           rn = "WatchHi7";
2610 7a387fff ths
//         break;
2611 7a387fff ths
        default:
2612 7a387fff ths
            goto die;
2613 7a387fff ths
        }
2614 8c0fdd85 ths
        break;
2615 8c0fdd85 ths
    case 20:
2616 7a387fff ths
        switch (sel) {
2617 7a387fff ths
        case 0:
2618 7a387fff ths
           /* 64 bit MMU only */
2619 7a387fff ths
           gen_op_mtc0_xcontext();
2620 7a387fff ths
           rn = "XContext";
2621 7a387fff ths
           break;
2622 7a387fff ths
        default:
2623 7a387fff ths
            goto die;
2624 7a387fff ths
        }
2625 8c0fdd85 ths
        break;
2626 8c0fdd85 ths
    case 21:
2627 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2628 7a387fff ths
        switch (sel) {
2629 7a387fff ths
        case 0:
2630 7a387fff ths
           gen_op_mtc0_framemask();
2631 7a387fff ths
           rn = "Framemask";
2632 7a387fff ths
           break;
2633 7a387fff ths
        default:
2634 7a387fff ths
            goto die;
2635 7a387fff ths
        }
2636 7a387fff ths
        break;
2637 8c0fdd85 ths
    case 22:
2638 7a387fff ths
        /* ignored */
2639 7a387fff ths
        rn = "Diagnostic"; /* implementation dependent */
2640 8c0fdd85 ths
       break;
2641 8c0fdd85 ths
    case 23:
2642 7a387fff ths
        switch (sel) {
2643 7a387fff ths
        case 0:
2644 7a387fff ths
           gen_op_mtc0_debug(); /* EJTAG support */
2645 7a387fff ths
           rn = "Debug";
2646 7a387fff ths
           break;
2647 7a387fff ths
        case 1:
2648 7a387fff ths
//         gen_op_mtc0_tracecontrol(); /* PDtrace support */
2649 7a387fff ths
           rn = "TraceControl";
2650 7a387fff ths
//         break;
2651 7a387fff ths
        case 2:
2652 7a387fff ths
//         gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2653 7a387fff ths
           rn = "TraceControl2";
2654 7a387fff ths
//         break;
2655 7a387fff ths
        case 3:
2656 7a387fff ths
//         gen_op_mtc0_usertracedata(); /* PDtrace support */
2657 7a387fff ths
           rn = "UserTraceData";
2658 7a387fff ths
//         break;
2659 7a387fff ths
        case 4:
2660 7a387fff ths
//         gen_op_mtc0_debug(); /* PDtrace support */
2661 7a387fff ths
           rn = "TraceBPC";
2662 7a387fff ths
//         break;
2663 7a387fff ths
        default:
2664 7a387fff ths
            goto die;
2665 7a387fff ths
        }
2666 7a387fff ths
       /* Stop translation as we may have switched the execution mode */
2667 7a387fff ths
       ctx->bstate = BS_STOP;
2668 8c0fdd85 ths
        break;
2669 8c0fdd85 ths
    case 24:
2670 7a387fff ths
        switch (sel) {
2671 7a387fff ths
        case 0:
2672 7a387fff ths
           gen_op_mtc0_depc(); /* EJTAG support */
2673 7a387fff ths
           rn = "DEPC";
2674 7a387fff ths
           break;
2675 7a387fff ths
        default:
2676 7a387fff ths
            goto die;
2677 7a387fff ths
        }
2678 8c0fdd85 ths
        break;
2679 8c0fdd85 ths
    case 25:
2680 7a387fff ths
        switch (sel) {
2681 7a387fff ths
        case 0:
2682 7a387fff ths
           gen_op_mtc0_performance0();
2683 7a387fff ths
           rn = "Performance0";
2684 7a387fff ths
           break;
2685 7a387fff ths
        case 1:
2686 7a387fff ths
//         gen_op_mtc0_performance1();
2687 7a387fff ths
           rn = "Performance1";
2688 7a387fff ths
//         break;
2689 7a387fff ths
        case 2:
2690 7a387fff ths
//         gen_op_mtc0_performance2();
2691 7a387fff ths
           rn = "Performance2";
2692 7a387fff ths
//         break;
2693 7a387fff ths
        case 3:
2694 7a387fff ths
//         gen_op_mtc0_performance3();
2695 7a387fff ths
           rn = "Performance3";
2696 7a387fff ths
//         break;
2697 7a387fff ths
        case 4:
2698 7a387fff ths
//         gen_op_mtc0_performance4();
2699 7a387fff ths
           rn = "Performance4";
2700 7a387fff ths
//         break;
2701 7a387fff ths
        case 5:
2702 7a387fff ths
//         gen_op_mtc0_performance5();
2703 7a387fff ths
           rn = "Performance5";
2704 7a387fff ths
//         break;
2705 7a387fff ths
        case 6:
2706 7a387fff ths
//         gen_op_mtc0_performance6();
2707 7a387fff ths
           rn = "Performance6";
2708 7a387fff ths
//         break;
2709 7a387fff ths
        case 7:
2710 7a387fff ths
//         gen_op_mtc0_performance7();
2711 7a387fff ths
           rn = "Performance7";
2712 7a387fff ths
//         break;
2713 7a387fff ths
        default:
2714 7a387fff ths
            goto die;
2715 7a387fff ths
        }
2716 8c0fdd85 ths
       break;
2717 8c0fdd85 ths
    case 26:
2718 7a387fff ths
       /* ignored */
2719 8c0fdd85 ths
        rn = "ECC";
2720 8c0fdd85 ths
       break;
2721 8c0fdd85 ths
    case 27:
2722 7a387fff ths
        switch (sel) {
2723 7a387fff ths
        case 0 ... 3:
2724 7a387fff ths
           /* ignored */
2725 7a387fff ths
           rn = "CacheErr";
2726 7a387fff ths
           break;
2727 7a387fff ths
        default:
2728 7a387fff ths
            goto die;
2729 7a387fff ths
        }
2730 8c0fdd85 ths
       break;
2731 8c0fdd85 ths
    case 28:
2732 8c0fdd85 ths
        switch (sel) {
2733 8c0fdd85 ths
        case 0:
2734 7a387fff ths
        case 2:
2735 7a387fff ths
        case 4:
2736 7a387fff ths
        case 6:
2737 8c0fdd85 ths
            gen_op_mtc0_taglo();
2738 8c0fdd85 ths
            rn = "TagLo";
2739 8c0fdd85 ths
            break;
2740 7a387fff ths
        case 1:
2741 7a387fff ths
        case 3:
2742 7a387fff ths
        case 5:
2743 7a387fff ths
        case 7:
2744 7a387fff ths
           gen_op_mtc0_datalo();
2745 7a387fff ths
            rn = "DataLo";
2746 7a387fff ths
            break;
2747 8c0fdd85 ths
        default:
2748 8c0fdd85 ths
            goto die;
2749 8c0fdd85 ths
        }
2750 8c0fdd85 ths
        break;
2751 8c0fdd85 ths
    case 29:
2752 7a387fff ths
        switch (sel) {
2753 7a387fff ths
        case 0:
2754 7a387fff ths
        case 2:
2755 7a387fff ths
        case 4:
2756 7a387fff ths
        case 6:
2757 7a387fff ths
            gen_op_mtc0_taghi();
2758 7a387fff ths
            rn = "TagHi";
2759 7a387fff ths
            break;
2760 7a387fff ths
        case 1:
2761 7a387fff ths
        case 3:
2762 7a387fff ths
        case 5:
2763 7a387fff ths
        case 7:
2764 7a387fff ths
           gen_op_mtc0_datahi();
2765 7a387fff ths
            rn = "DataHi";
2766 7a387fff ths
            break;
2767 7a387fff ths
        default:
2768 7a387fff ths
            rn = "invalid sel";
2769 7a387fff ths
            goto die;
2770 7a387fff ths
        }
2771 8c0fdd85 ths
       break;
2772 8c0fdd85 ths
    case 30:
2773 7a387fff ths
        switch (sel) {
2774 7a387fff ths
        case 0:
2775 7a387fff ths
           gen_op_mtc0_errorepc();
2776 7a387fff ths
           rn = "ErrorEPC";
2777 7a387fff ths
           break;
2778 7a387fff ths
        default:
2779 7a387fff ths
            goto die;
2780 7a387fff ths
        }
2781 8c0fdd85 ths
        break;
2782 8c0fdd85 ths
    case 31:
2783 7a387fff ths
        switch (sel) {
2784 7a387fff ths
        case 0:
2785 7a387fff ths
           gen_op_mtc0_desave(); /* EJTAG support */
2786 7a387fff ths
           rn = "DESAVE";
2787 7a387fff ths
           break;
2788 7a387fff ths
        default:
2789 7a387fff ths
            goto die;
2790 7a387fff ths
        }
2791 7a387fff ths
       /* Stop translation as we may have switched the execution mode */
2792 7a387fff ths
       ctx->bstate = BS_STOP;
2793 8c0fdd85 ths
        break;
2794 8c0fdd85 ths
    default:
2795 8c0fdd85 ths
       goto die;
2796 8c0fdd85 ths
    }
2797 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
2798 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2799 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2800 7a387fff ths
                rn, reg, sel);
2801 8c0fdd85 ths
    }
2802 8c0fdd85 ths
#endif
2803 8c0fdd85 ths
    return;
2804 8c0fdd85 ths
2805 8c0fdd85 ths
die:
2806 8c0fdd85 ths
#if defined MIPS_DEBUG_DISAS
2807 8c0fdd85 ths
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2808 7a387fff ths
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2809 7a387fff ths
                rn, reg, sel);
2810 8c0fdd85 ths
    }
2811 8c0fdd85 ths
#endif
2812 8c0fdd85 ths
    generate_exception(ctx, EXCP_RI);
2813 8c0fdd85 ths
}
2814 8c0fdd85 ths
2815 7a387fff ths
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
2816 6af0bf9c bellard
{
2817 7a387fff ths
    const char *opn = "unk";
2818 6af0bf9c bellard
2819 bc2c3909 bellard
    if (!(ctx->CP0_Status & (1 << CP0St_CU0)) &&
2820 cd7dd10f bellard
        (ctx->hflags & MIPS_HFLAG_UM) &&
2821 bc2c3909 bellard
        !(ctx->hflags & MIPS_HFLAG_ERL) &&
2822 bc2c3909 bellard
        !(ctx->hflags & MIPS_HFLAG_EXL)) {
2823 6af0bf9c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2824 6af0bf9c bellard
            fprintf(logfile, "CP0 is not usable\n");
2825 6af0bf9c bellard
        }
2826 7a387fff ths
        generate_exception (ctx, EXCP_CpU);
2827 6af0bf9c bellard
        return;
2828 6af0bf9c bellard
    }
2829 d796321b bellard
2830 6af0bf9c bellard
    switch (opc) {
2831 6af0bf9c bellard
    case OPC_MFC0:
2832 6af0bf9c bellard
        if (rt == 0) {
2833 6af0bf9c bellard
            /* Treat as NOP */
2834 6af0bf9c bellard
            return;
2835 6af0bf9c bellard
        }
2836 873eb012 ths
        gen_mfc0(ctx, rd, ctx->opcode & 0x7);
2837 6af0bf9c bellard
        gen_op_store_T0_gpr(rt);
2838 6af0bf9c bellard
        opn = "mfc0";
2839 6af0bf9c bellard
        break;
2840 6af0bf9c bellard
    case OPC_MTC0:
2841 6af0bf9c bellard
        /* If we get an exception, we want to restart at next instruction */
2842 7a387fff ths
       /* XXX: breaks for mtc in delay slot */
2843 6af0bf9c bellard
        ctx->pc += 4;
2844 6af0bf9c bellard
        save_cpu_state(ctx, 1);
2845 6af0bf9c bellard
        ctx->pc -= 4;
2846 6af0bf9c bellard
        GEN_LOAD_REG_TN(T0, rt);
2847 8c0fdd85 ths
        gen_mtc0(ctx, rd, ctx->opcode & 0x7);
2848 6af0bf9c bellard
        opn = "mtc0";
2849 6af0bf9c bellard
        break;
2850 6af0bf9c bellard
#if defined(MIPS_USES_R4K_TLB)
2851 6af0bf9c bellard
    case OPC_TLBWI:
2852 6af0bf9c bellard
        gen_op_tlbwi();
2853 6af0bf9c bellard
        opn = "tlbwi";
2854 6af0bf9c bellard
        break;
2855 6af0bf9c bellard
    case OPC_TLBWR:
2856 6af0bf9c bellard
        gen_op_tlbwr();
2857 6af0bf9c bellard
        opn = "tlbwr";
2858 6af0bf9c bellard
        break;
2859 6af0bf9c bellard
    case OPC_TLBP:
2860 6af0bf9c bellard
        gen_op_tlbp();
2861 6af0bf9c bellard
        opn = "tlbp";
2862 6af0bf9c bellard
        break;
2863 6af0bf9c bellard
    case OPC_TLBR:
2864 6af0bf9c bellard
        gen_op_tlbr();
2865 6af0bf9c bellard
        opn = "tlbr";
2866 6af0bf9c bellard
        break;
2867 6af0bf9c bellard
#endif
2868 6af0bf9c bellard
    case OPC_ERET:
2869 6af0bf9c bellard
        opn = "eret";
2870 6af0bf9c bellard
        save_cpu_state(ctx, 0);
2871 6af0bf9c bellard
        gen_op_eret();
2872 6af0bf9c bellard
        ctx->bstate = BS_EXCP;
2873 6af0bf9c bellard
        break;
2874 6af0bf9c bellard
    case OPC_DERET:
2875 6af0bf9c bellard
        opn = "deret";
2876 6af0bf9c bellard
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
2877 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
2878 6af0bf9c bellard
        } else {
2879 6af0bf9c bellard
            save_cpu_state(ctx, 0);
2880 6af0bf9c bellard
            gen_op_deret();
2881 6af0bf9c bellard
            ctx->bstate = BS_EXCP;
2882 6af0bf9c bellard
        }
2883 6af0bf9c bellard
        break;
2884 4ad40f36 bellard
    case OPC_WAIT:
2885 4ad40f36 bellard
        opn = "wait";
2886 4ad40f36 bellard
        /* If we get an exception, we want to restart at next instruction */
2887 4ad40f36 bellard
        ctx->pc += 4;
2888 4ad40f36 bellard
        save_cpu_state(ctx, 1);
2889 4ad40f36 bellard
        ctx->pc -= 4;
2890 4ad40f36 bellard
        gen_op_wait();
2891 4ad40f36 bellard
        ctx->bstate = BS_EXCP;
2892 4ad40f36 bellard
        break;
2893 6af0bf9c bellard
    default:
2894 6af0bf9c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2895 6af0bf9c bellard
            fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
2896 6af0bf9c bellard
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
2897 6af0bf9c bellard
                    ((ctx->opcode >> 16) & 0x1F));
2898 6af0bf9c bellard
        }
2899 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
2900 6af0bf9c bellard
        return;
2901 6af0bf9c bellard
    }
2902 6af0bf9c bellard
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
2903 6af0bf9c bellard
}
2904 6af0bf9c bellard
2905 6ea83fed bellard
/* CP1 Branches (before delay slot) */
2906 7a387fff ths
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
2907 6ea83fed bellard
                                 int32_t offset)
2908 6ea83fed bellard
{
2909 6ea83fed bellard
    target_ulong btarget;
2910 6ea83fed bellard
2911 6ea83fed bellard
    btarget = ctx->pc + 4 + offset;
2912 6ea83fed bellard
2913 7a387fff ths
    switch (op) {
2914 7a387fff ths
    case OPC_BC1F:
2915 6ea83fed bellard
        gen_op_bc1f();
2916 6ea83fed bellard
        MIPS_DEBUG("bc1f %08x", btarget);
2917 6ea83fed bellard
        goto not_likely;
2918 7a387fff ths
    case OPC_BC1FL:
2919 6ea83fed bellard
        gen_op_bc1f();
2920 6ea83fed bellard
        MIPS_DEBUG("bc1fl %08x", btarget);
2921 6ea83fed bellard
        goto likely;
2922 7a387fff ths
    case OPC_BC1T:
2923 6ea83fed bellard
        gen_op_bc1t();
2924 6ea83fed bellard
        MIPS_DEBUG("bc1t %08x", btarget);
2925 6ea83fed bellard
    not_likely:
2926 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BC;
2927 6ea83fed bellard
        break;
2928 7a387fff ths
    case OPC_BC1TL:
2929 6ea83fed bellard
        gen_op_bc1t();
2930 6ea83fed bellard
        MIPS_DEBUG("bc1tl %08x", btarget);
2931 6ea83fed bellard
    likely:
2932 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BL;
2933 6ea83fed bellard
        break;
2934 6ea83fed bellard
    default:    
2935 6ea83fed bellard
        MIPS_INVAL("cp1 branch/jump");
2936 7a387fff ths
        generate_exception_err (ctx, EXCP_RI, 1);
2937 6ea83fed bellard
        return;
2938 6ea83fed bellard
    }
2939 6ea83fed bellard
    gen_op_set_bcond();
2940 6ea83fed bellard
2941 6ea83fed bellard
    MIPS_DEBUG("enter ds: cond %02x target %08x",
2942 6ea83fed bellard
               ctx->hflags, btarget);
2943 6ea83fed bellard
    ctx->btarget = btarget;
2944 6ea83fed bellard
2945 6ea83fed bellard
    return;
2946 6ea83fed bellard
}
2947 6ea83fed bellard
2948 6af0bf9c bellard
/* Coprocessor 1 (FPU) */
2949 7a387fff ths
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
2950 6ea83fed bellard
{
2951 7a387fff ths
    const char *opn = "unk";
2952 6ea83fed bellard
2953 6ea83fed bellard
    switch (opc) {
2954 6ea83fed bellard
    case OPC_MFC1:
2955 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
2956 6ea83fed bellard
        gen_op_mfc1();
2957 6ea83fed bellard
        GEN_STORE_TN_REG(rt, T0);
2958 6ea83fed bellard
        opn = "mfc1";
2959 6ea83fed bellard
        break;
2960 6ea83fed bellard
    case OPC_MTC1:
2961 6ea83fed bellard
        GEN_LOAD_REG_TN(T0, rt);
2962 6ea83fed bellard
        gen_op_mtc1();
2963 6ea83fed bellard
        GEN_STORE_FTN_FREG(fs, WT0);
2964 6ea83fed bellard
        opn = "mtc1";
2965 6ea83fed bellard
        break;
2966 6ea83fed bellard
    case OPC_CFC1:
2967 6ea83fed bellard
        if (fs != 0 && fs != 31) {
2968 6ea83fed bellard
            MIPS_INVAL("cfc1 freg");
2969 7a387fff ths
            generate_exception_err (ctx, EXCP_RI, 1);
2970 6ea83fed bellard
            return;
2971 6ea83fed bellard
        }
2972 6ea83fed bellard
        GEN_LOAD_IMM_TN(T1, fs);
2973 6ea83fed bellard
        gen_op_cfc1();
2974 6ea83fed bellard
        GEN_STORE_TN_REG(rt, T0);
2975 6ea83fed bellard
        opn = "cfc1";
2976 6ea83fed bellard
        break;
2977 6ea83fed bellard
    case OPC_CTC1:
2978 7a387fff ths
         if (fs != 0 && fs != 31) {
2979 6ea83fed bellard
            MIPS_INVAL("ctc1 freg");
2980 7a387fff ths
            generate_exception_err (ctx, EXCP_RI, 1);
2981 6ea83fed bellard
            return;
2982 6ea83fed bellard
        }
2983 6ea83fed bellard
        GEN_LOAD_IMM_TN(T1, fs);
2984 6ea83fed bellard
        GEN_LOAD_REG_TN(T0, rt);
2985 6ea83fed bellard
        gen_op_ctc1();
2986 6ea83fed bellard
        opn = "ctc1";
2987 6ea83fed bellard
        break;
2988 6ea83fed bellard
    default:
2989 6ea83fed bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2990 6ea83fed bellard
            fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
2991 6ea83fed bellard
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
2992 6ea83fed bellard
                    ((ctx->opcode >> 16) & 0x1F));
2993 6ea83fed bellard
        }
2994 7a387fff ths
        generate_exception_err (ctx, EXCP_RI, 1);
2995 6ea83fed bellard
        return;
2996 6ea83fed bellard
    }
2997 6ea83fed bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
2998 6ea83fed bellard
}
2999 6ea83fed bellard
3000 6ea83fed bellard
/* verify if floating point register is valid; an operation is not defined
3001 6ea83fed bellard
 * if bit 0 of any register specification is set and the FR bit in the
3002 6ea83fed bellard
 * Status register equals zero, since the register numbers specify an
3003 6ea83fed bellard
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
3004 6ea83fed bellard
 * in the Status register equals one, both even and odd register numbers
3005 6ea83fed bellard
 * are valid.
3006 6ea83fed bellard
 * 
3007 6ea83fed bellard
 * Multiple float registers can be checked by calling
3008 6ea83fed bellard
 * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
3009 6ea83fed bellard
 */
3010 6ea83fed bellard
#define CHECK_FR(ctx, freg) do { \
3011 6ea83fed bellard
        if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
3012 7a387fff ths
            generate_exception_err (ctx, EXCP_RI, 1); \
3013 6ea83fed bellard
            return; \
3014 6ea83fed bellard
        } \
3015 6ea83fed bellard
    } while(0)
3016 6ea83fed bellard
3017 6ea83fed bellard
#define FOP(func, fmt) (((fmt) << 21) | (func))
3018 6ea83fed bellard
3019 7a387fff ths
static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
3020 6ea83fed bellard
{
3021 7a387fff ths
    const char *opn = "unk";
3022 6ea83fed bellard
    const char *condnames[] = {
3023 6ea83fed bellard
            "c.f",
3024 6ea83fed bellard
            "c.un",
3025 6ea83fed bellard
            "c.eq",
3026 6ea83fed bellard
            "c.ueq",
3027 6ea83fed bellard
            "c.olt",
3028 6ea83fed bellard
            "c.ult",
3029 6ea83fed bellard
            "c.ole",
3030 6ea83fed bellard
            "c.ule",
3031 6ea83fed bellard
            "c.sf",
3032 6ea83fed bellard
            "c.ngle",
3033 6ea83fed bellard
            "c.seq",
3034 6ea83fed bellard
            "c.ngl",
3035 6ea83fed bellard
            "c.lt",
3036 6ea83fed bellard
            "c.nge",
3037 6ea83fed bellard
            "c.le",
3038 6ea83fed bellard
            "c.ngt",
3039 6ea83fed bellard
    };
3040 6ea83fed bellard
    int binary = 0;
3041 7a387fff ths
    uint32_t func = ctx->opcode & 0x3f;
3042 7a387fff ths
3043 6ea83fed bellard
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
3044 6ea83fed bellard
    case FOP(0, 17):
3045 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
3046 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3047 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
3048 6ea83fed bellard
        gen_op_float_add_d();
3049 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3050 6ea83fed bellard
        opn = "add.d";
3051 6ea83fed bellard
        binary = 1;
3052 6ea83fed bellard
        break;
3053 6ea83fed bellard
    case FOP(1, 17):
3054 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
3055 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3056 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
3057 6ea83fed bellard
        gen_op_float_sub_d();
3058 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3059 6ea83fed bellard
        opn = "sub.d";
3060 6ea83fed bellard
        binary = 1;
3061 6ea83fed bellard
        break;
3062 6ea83fed bellard
    case FOP(2, 17):
3063 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
3064 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3065 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
3066 6ea83fed bellard
        gen_op_float_mul_d();
3067 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3068 6ea83fed bellard
        opn = "mul.d";
3069 6ea83fed bellard
        binary = 1;
3070 6ea83fed bellard
        break;
3071 6ea83fed bellard
    case FOP(3, 17):
3072 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
3073 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3074 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
3075 6ea83fed bellard
        gen_op_float_div_d();
3076 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3077 6ea83fed bellard
        opn = "div.d";
3078 6ea83fed bellard
        binary = 1;
3079 6ea83fed bellard
        break;
3080 6ea83fed bellard
    case FOP(4, 17):
3081 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3082 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3083 6ea83fed bellard
        gen_op_float_sqrt_d();
3084 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3085 6ea83fed bellard
        opn = "sqrt.d";
3086 6ea83fed bellard
        break;
3087 6ea83fed bellard
    case FOP(5, 17):
3088 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3089 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3090 6ea83fed bellard
        gen_op_float_abs_d();
3091 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3092 6ea83fed bellard
        opn = "abs.d";
3093 6ea83fed bellard
        break;
3094 6ea83fed bellard
    case FOP(6, 17):
3095 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3096 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3097 6ea83fed bellard
        gen_op_float_mov_d();
3098 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3099 6ea83fed bellard
        opn = "mov.d";
3100 6ea83fed bellard
        break;
3101 6ea83fed bellard
    case FOP(7, 17):
3102 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3103 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3104 6ea83fed bellard
        gen_op_float_chs_d();
3105 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3106 6ea83fed bellard
        opn = "neg.d";
3107 6ea83fed bellard
        break;
3108 6ea83fed bellard
    /*  8 - round.l */
3109 6ea83fed bellard
    /*  9 - trunc.l */
3110 6ea83fed bellard
    /* 10 - ceil.l  */
3111 6ea83fed bellard
    /* 11 - floor.l */
3112 6ea83fed bellard
    case FOP(12, 17):
3113 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3114 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3115 6ea83fed bellard
        gen_op_float_roundw_d();
3116 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3117 6ea83fed bellard
        opn = "round.w.d";
3118 6ea83fed bellard
        break;
3119 6ea83fed bellard
    case FOP(13, 17):
3120 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3121 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3122 6ea83fed bellard
        gen_op_float_truncw_d();
3123 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3124 6ea83fed bellard
        opn = "trunc.w.d";
3125 6ea83fed bellard
        break;
3126 6ea83fed bellard
    case FOP(14, 17):
3127 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3128 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3129 6ea83fed bellard
        gen_op_float_ceilw_d();
3130 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3131 6ea83fed bellard
        opn = "ceil.w.d";
3132 6ea83fed bellard
        break;
3133 6ea83fed bellard
    case FOP(15, 17):
3134 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3135 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3136 6ea83fed bellard
        gen_op_float_floorw_d();
3137 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3138 7a387fff ths
        opn = "floor.w.d";
3139 6ea83fed bellard
        break;
3140 dd016883 bellard
    case FOP(33, 16): /* cvt.d.s */
3141 dd016883 bellard
        CHECK_FR(ctx, fs | fd);
3142 dd016883 bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3143 dd016883 bellard
        gen_op_float_cvtd_s();
3144 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3145 dd016883 bellard
        opn = "cvt.d.s";
3146 dd016883 bellard
        break;
3147 6ea83fed bellard
    case FOP(33, 20): /* cvt.d.w */
3148 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3149 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3150 6ea83fed bellard
        gen_op_float_cvtd_w();
3151 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, DT2);
3152 6ea83fed bellard
        opn = "cvt.d.w";
3153 6ea83fed bellard
        break;
3154 6ea83fed bellard
    case FOP(48, 17):
3155 6ea83fed bellard
    case FOP(49, 17):
3156 6ea83fed bellard
    case FOP(50, 17):
3157 6ea83fed bellard
    case FOP(51, 17):
3158 6ea83fed bellard
    case FOP(52, 17):
3159 6ea83fed bellard
    case FOP(53, 17):
3160 6ea83fed bellard
    case FOP(54, 17):
3161 6ea83fed bellard
    case FOP(55, 17):
3162 6ea83fed bellard
    case FOP(56, 17):
3163 6ea83fed bellard
    case FOP(57, 17):
3164 6ea83fed bellard
    case FOP(58, 17):
3165 6ea83fed bellard
    case FOP(59, 17):
3166 6ea83fed bellard
    case FOP(60, 17):
3167 6ea83fed bellard
    case FOP(61, 17):
3168 6ea83fed bellard
    case FOP(62, 17):
3169 6ea83fed bellard
    case FOP(63, 17):
3170 6ea83fed bellard
        CHECK_FR(ctx, fs | ft);
3171 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT0, fs);
3172 6ea83fed bellard
        GEN_LOAD_FREG_FTN(DT1, ft);
3173 6ea83fed bellard
        gen_cmp_d(func-48);
3174 6ea83fed bellard
        opn = condnames[func-48];
3175 6ea83fed bellard
        break;
3176 6ea83fed bellard
    case FOP(0, 16):
3177 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
3178 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3179 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
3180 6ea83fed bellard
        gen_op_float_add_s();
3181 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3182 6ea83fed bellard
        opn = "add.s";
3183 6ea83fed bellard
        binary = 1;
3184 6ea83fed bellard
        break;
3185 6ea83fed bellard
    case FOP(1, 16):
3186 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
3187 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3188 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
3189 6ea83fed bellard
        gen_op_float_sub_s();
3190 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3191 6ea83fed bellard
        opn = "sub.s";
3192 6ea83fed bellard
        binary = 1;
3193 6ea83fed bellard
        break;
3194 6ea83fed bellard
    case FOP(2, 16):
3195 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
3196 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3197 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
3198 6ea83fed bellard
        gen_op_float_mul_s();
3199 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3200 6ea83fed bellard
        opn = "mul.s";
3201 6ea83fed bellard
        binary = 1;
3202 6ea83fed bellard
        break;
3203 6ea83fed bellard
    case FOP(3, 16):
3204 6ea83fed bellard
        CHECK_FR(ctx, fs | ft | fd);
3205 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3206 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
3207 6ea83fed bellard
        gen_op_float_div_s();
3208 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3209 6ea83fed bellard
        opn = "div.s";
3210 6ea83fed bellard
        binary = 1;
3211 6ea83fed bellard
        break;
3212 6ea83fed bellard
    case FOP(4, 16):
3213 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3214 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3215 6ea83fed bellard
        gen_op_float_sqrt_s();
3216 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3217 6ea83fed bellard
        opn = "sqrt.s";
3218 6ea83fed bellard
        break;
3219 6ea83fed bellard
    case FOP(5, 16):
3220 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3221 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3222 6ea83fed bellard
        gen_op_float_abs_s();
3223 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3224 6ea83fed bellard
        opn = "abs.s";
3225 6ea83fed bellard
        break;
3226 6ea83fed bellard
    case FOP(6, 16):
3227 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3228 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3229 6ea83fed bellard
        gen_op_float_mov_s();
3230 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3231 6ea83fed bellard
        opn = "mov.s";
3232 6ea83fed bellard
        break;
3233 6ea83fed bellard
    case FOP(7, 16):
3234 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3235 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3236 6ea83fed bellard
        gen_op_float_chs_s();
3237 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3238 6ea83fed bellard
        opn = "neg.s";
3239 6ea83fed bellard
        break;
3240 6ea83fed bellard
    case FOP(12, 16):
3241 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3242 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3243 6ea83fed bellard
        gen_op_float_roundw_s();
3244 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3245 6ea83fed bellard
        opn = "round.w.s";
3246 6ea83fed bellard
        break;
3247 6ea83fed bellard
    case FOP(13, 16):
3248 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3249 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3250 6ea83fed bellard
        gen_op_float_truncw_s();
3251 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3252 6ea83fed bellard
        opn = "trunc.w.s";
3253 6ea83fed bellard
        break;
3254 dd016883 bellard
    case FOP(32, 17): /* cvt.s.d */
3255 dd016883 bellard
        CHECK_FR(ctx, fs | fd);
3256 417f38f0 pbrook
        GEN_LOAD_FREG_FTN(DT0, fs);
3257 dd016883 bellard
        gen_op_float_cvts_d();
3258 dd016883 bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3259 dd016883 bellard
        opn = "cvt.s.d";
3260 dd016883 bellard
        break;
3261 6ea83fed bellard
    case FOP(32, 20): /* cvt.s.w */
3262 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3263 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3264 6ea83fed bellard
        gen_op_float_cvts_w();
3265 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3266 6ea83fed bellard
        opn = "cvt.s.w";
3267 6ea83fed bellard
        break;
3268 6ea83fed bellard
    case FOP(36, 16): /* cvt.w.s */
3269 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3270 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3271 6ea83fed bellard
        gen_op_float_cvtw_s();
3272 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3273 6ea83fed bellard
        opn = "cvt.w.s";
3274 6ea83fed bellard
        break;
3275 6ea83fed bellard
    case FOP(36, 17): /* cvt.w.d */
3276 6ea83fed bellard
        CHECK_FR(ctx, fs | fd);
3277 417f38f0 pbrook
        GEN_LOAD_FREG_FTN(DT0, fs);
3278 6ea83fed bellard
        gen_op_float_cvtw_d();
3279 6ea83fed bellard
        GEN_STORE_FTN_FREG(fd, WT2);
3280 6ea83fed bellard
        opn = "cvt.w.d";
3281 6ea83fed bellard
        break;
3282 6ea83fed bellard
    case FOP(48, 16):
3283 6ea83fed bellard
    case FOP(49, 16):
3284 6ea83fed bellard
    case FOP(50, 16):
3285 6ea83fed bellard
    case FOP(51, 16):
3286 6ea83fed bellard
    case FOP(52, 16):
3287 6ea83fed bellard
    case FOP(53, 16):
3288 6ea83fed bellard
    case FOP(54, 16):
3289 6ea83fed bellard
    case FOP(55, 16):
3290 6ea83fed bellard
    case FOP(56, 16):
3291 6ea83fed bellard
    case FOP(57, 16):
3292 6ea83fed bellard
    case FOP(58, 16):
3293 6ea83fed bellard
    case FOP(59, 16):
3294 6ea83fed bellard
    case FOP(60, 16):
3295 6ea83fed bellard
    case FOP(61, 16):
3296 6ea83fed bellard
    case FOP(62, 16):
3297 6ea83fed bellard
    case FOP(63, 16):
3298 6ea83fed bellard
        CHECK_FR(ctx, fs | ft);
3299 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT0, fs);
3300 6ea83fed bellard
        GEN_LOAD_FREG_FTN(WT1, ft);
3301 6ea83fed bellard
        gen_cmp_s(func-48);
3302 6ea83fed bellard
        opn = condnames[func-48];
3303 6ea83fed bellard
        break;
3304 6ea83fed bellard
    default:    
3305 6ea83fed bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
3306 7a387fff ths
            fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
3307 6ea83fed bellard
                    ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
3308 6ea83fed bellard
                    ((ctx->opcode >> 16) & 0x1F));
3309 6ea83fed bellard
        }
3310 7a387fff ths
        generate_exception_err (ctx, EXCP_RI, 1);
3311 6ea83fed bellard
        return;
3312 6ea83fed bellard
    }
3313 6ea83fed bellard
    if (binary)
3314 6ea83fed bellard
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
3315 6ea83fed bellard
    else
3316 6ea83fed bellard
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
3317 6ea83fed bellard
}
3318 6af0bf9c bellard
3319 7a387fff ths
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
3320 7a387fff ths
{
3321 7a387fff ths
    uint32_t ccbit;
3322 7a387fff ths
3323 7a387fff ths
    if (cc)
3324 7a387fff ths
        ccbit = 1 << (24 + cc);
3325 7a387fff ths
    else
3326 7a387fff ths
        ccbit = 1 << 23;
3327 7a387fff ths
    if (!tf)
3328 7a387fff ths
        gen_op_movf(ccbit, rd, rs);
3329 7a387fff ths
    else
3330 7a387fff ths
       gen_op_movt(ccbit, rd, rs);
3331 7a387fff ths
}
3332 7a387fff ths
3333 7a387fff ths
/* ISA extensions (ASEs) */
3334 6af0bf9c bellard
/* MIPS16 extension to MIPS32 */
3335 6af0bf9c bellard
/* SmartMIPS extension to MIPS32 */
3336 6af0bf9c bellard
3337 7a387fff ths
#ifdef MIPS_HAS_MIPS64
3338 7a387fff ths
static void gen_arith64 (DisasContext *ctx, uint32_t opc)
3339 6af0bf9c bellard
{
3340 6af0bf9c bellard
    if (func == 0x02 && rd == 0) {
3341 6af0bf9c bellard
        /* NOP */
3342 6af0bf9c bellard
        return;
3343 6af0bf9c bellard
    }
3344 6af0bf9c bellard
    if (rs == 0 || rt == 0) {
3345 6af0bf9c bellard
        gen_op_reset_T0();
3346 6af0bf9c bellard
        gen_op_save64();
3347 6af0bf9c bellard
    } else {
3348 6af0bf9c bellard
        gen_op_load_gpr_T0(rs);
3349 6af0bf9c bellard
        gen_op_load_gpr_T1(rt);
3350 6af0bf9c bellard
        gen_op_save64();
3351 6af0bf9c bellard
        if (func & 0x01)
3352 6af0bf9c bellard
            gen_op_mul64u();
3353 6af0bf9c bellard
        else
3354 6af0bf9c bellard
            gen_op_mul64s();
3355 6af0bf9c bellard
    }
3356 6af0bf9c bellard
    if (func & 0x02)
3357 6af0bf9c bellard
        gen_op_add64();
3358 6af0bf9c bellard
    else
3359 6af0bf9c bellard
        gen_op_sub64();
3360 6af0bf9c bellard
}
3361 6af0bf9c bellard
3362 6af0bf9c bellard
/* Coprocessor 3 (FPU) */
3363 6af0bf9c bellard
3364 6af0bf9c bellard
/* MDMX extension to MIPS64 */
3365 6af0bf9c bellard
/* MIPS-3D extension to MIPS64 */
3366 6af0bf9c bellard
3367 6af0bf9c bellard
#endif
3368 6af0bf9c bellard
3369 c53be334 bellard
static void gen_blikely(DisasContext *ctx)
3370 c53be334 bellard
{
3371 eeef26cd bellard
    int l1;
3372 eeef26cd bellard
    l1 = gen_new_label();
3373 eeef26cd bellard
    gen_op_jnz_T2(l1);
3374 4ad40f36 bellard
    gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
3375 eeef26cd bellard
    gen_goto_tb(ctx, 1, ctx->pc + 4);
3376 eeef26cd bellard
    gen_set_label(l1);
3377 c53be334 bellard
}
3378 c53be334 bellard
3379 6af0bf9c bellard
static void decode_opc (DisasContext *ctx)
3380 6af0bf9c bellard
{
3381 6af0bf9c bellard
    int32_t offset;
3382 6af0bf9c bellard
    int rs, rt, rd, sa;
3383 7a387fff ths
    uint32_t op, op1, op2;
3384 6af0bf9c bellard
    int16_t imm;
3385 6af0bf9c bellard
3386 d796321b bellard
    /* make sure instructions are on a word boundary */
3387 d796321b bellard
    if (ctx->pc & 0x3) {
3388 d796321b bellard
        generate_exception(ctx, EXCP_AdEL);
3389 d796321b bellard
        return;
3390 d796321b bellard
    }
3391 d796321b bellard
3392 4ad40f36 bellard
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
3393 6af0bf9c bellard
        /* Handle blikely not taken case */
3394 6af0bf9c bellard
        MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4);
3395 c53be334 bellard
        gen_blikely(ctx);
3396 6af0bf9c bellard
    }
3397 7a387fff ths
    op = MASK_OP_MAJOR(ctx->opcode);
3398 7a387fff ths
    rs = (ctx->opcode >> 21) & 0x1f;
3399 7a387fff ths
    rt = (ctx->opcode >> 16) & 0x1f;
3400 7a387fff ths
    rd = (ctx->opcode >> 11) & 0x1f;
3401 7a387fff ths
    sa = (ctx->opcode >> 6) & 0x1f;
3402 6af0bf9c bellard
    imm = (int16_t)ctx->opcode;
3403 6af0bf9c bellard
    switch (op) {
3404 7a387fff ths
    case OPC_SPECIAL:
3405 7a387fff ths
        op1 = MASK_SPECIAL(ctx->opcode);
3406 6af0bf9c bellard
        switch (op1) {
3407 7a387fff ths
        case OPC_SLL:          /* Arithmetic with immediate */
3408 7a387fff ths
        case OPC_SRL ... OPC_SRA:
3409 7a387fff ths
            gen_arith_imm(ctx, op1, rd, rt, sa);
3410 7a387fff ths
            break;
3411 7a387fff ths
        case OPC_SLLV:         /* Arithmetic */
3412 7a387fff ths
        case OPC_SRLV ... OPC_SRAV:
3413 7a387fff ths
        case OPC_MOVZ ... OPC_MOVN:
3414 7a387fff ths
        case OPC_ADD ... OPC_NOR:
3415 7a387fff ths
        case OPC_SLT ... OPC_SLTU:
3416 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
3417 7a387fff ths
            break;
3418 7a387fff ths
        case OPC_MULT ... OPC_DIVU:
3419 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
3420 7a387fff ths
            break;
3421 7a387fff ths
        case OPC_JR ... OPC_JALR:
3422 7a387fff ths
            gen_compute_branch(ctx, op1, rs, rd, sa);
3423 6af0bf9c bellard
            return;
3424 7a387fff ths
        case OPC_TGE ... OPC_TEQ: /* Traps */
3425 7a387fff ths
        case OPC_TNE:
3426 7a387fff ths
            gen_trap(ctx, op1, rs, rt, -1);
3427 6af0bf9c bellard
            break;
3428 7a387fff ths
        case OPC_MFHI:          /* Move from HI/LO */
3429 7a387fff ths
        case OPC_MFLO:
3430 7a387fff ths
            gen_HILO(ctx, op1, rd);
3431 6af0bf9c bellard
            break;
3432 7a387fff ths
        case OPC_MTHI:
3433 7a387fff ths
        case OPC_MTLO:          /* Move to HI/LO */
3434 7a387fff ths
            gen_HILO(ctx, op1, rs);
3435 6af0bf9c bellard
            break;
3436 7a387fff ths
        case OPC_PMON:          /* Pmon entry point */
3437 7a387fff ths
            gen_op_pmon(sa);
3438 7a387fff ths
            break;
3439 7a387fff ths
        case OPC_SYSCALL:
3440 6af0bf9c bellard
            generate_exception(ctx, EXCP_SYSCALL);
3441 7a387fff ths
            ctx->bstate = BS_EXCP;
3442 6af0bf9c bellard
            break;
3443 7a387fff ths
        case OPC_BREAK:
3444 6af0bf9c bellard
            generate_exception(ctx, EXCP_BREAK);
3445 6af0bf9c bellard
            break;
3446 7a387fff ths
        case OPC_SPIM:        /* SPIM ? */
3447 7a387fff ths
           /* Implemented as RI exception for now. */
3448 7a387fff ths
            MIPS_INVAL("spim (unofficial)");
3449 7a387fff ths
            generate_exception(ctx, EXCP_RI);
3450 6af0bf9c bellard
            break;
3451 7a387fff ths
        case OPC_SYNC:
3452 7a387fff ths
            /* Treat as a noop. */
3453 6af0bf9c bellard
            break;
3454 4ad40f36 bellard
3455 7a387fff ths
        case OPC_MOVCI:
3456 7a387fff ths
            gen_op_cp1_enabled();
3457 7a387fff ths
            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
3458 7a387fff ths
                      (ctx->opcode >> 16) & 1);
3459 4ad40f36 bellard
            break;
3460 4ad40f36 bellard
3461 7a387fff ths
#ifdef MIPS_HAS_MIPS64
3462 7a387fff ths
       /* MIPS64 specific opcodes */
3463 7a387fff ths
        case OPC_DSLL:
3464 7a387fff ths
        case OPC_DSRL ... OPC_DSRA:
3465 7a387fff ths
        case OPC_DSLL32:
3466 7a387fff ths
        case OPC_DSRL32 ... OPC_DSRA32:
3467 7a387fff ths
            gen_arith_imm(ctx, op1, rd, rt, sa);
3468 7a387fff ths
            break;
3469 7a387fff ths
        case OPC_DSLLV:
3470 7a387fff ths
        case OPC_DSRLV ... OPC_DSRAV:
3471 7a387fff ths
        case OPC_DADD ... OPC_DSUBU:
3472 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
3473 7a387fff ths
            break;
3474 7a387fff ths
        case OPC_DMULT ... OPC_DDIVU:
3475 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
3476 7a387fff ths
            break;
3477 6af0bf9c bellard
#endif
3478 6af0bf9c bellard
        default:            /* Invalid */
3479 6af0bf9c bellard
            MIPS_INVAL("special");
3480 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
3481 6af0bf9c bellard
            break;
3482 6af0bf9c bellard
        }
3483 6af0bf9c bellard
        break;
3484 7a387fff ths
    case OPC_SPECIAL2:
3485 7a387fff ths
        op1 = MASK_SPECIAL2(ctx->opcode);
3486 6af0bf9c bellard
        switch (op1) {
3487 7a387fff ths
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
3488 7a387fff ths
        case OPC_MSUB ... OPC_MSUBU:
3489 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
3490 6af0bf9c bellard
            break;
3491 7a387fff ths
        case OPC_MUL:
3492 7a387fff ths
            gen_arith(ctx, op1, rd, rs, rt);
3493 6af0bf9c bellard
            break;
3494 7a387fff ths
        case OPC_CLZ ... OPC_CLO:
3495 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
3496 6af0bf9c bellard
            break;
3497 7a387fff ths
        case OPC_SDBBP:
3498 6af0bf9c bellard
            /* XXX: not clear which exception should be raised
3499 6af0bf9c bellard
             *      when in debug mode...
3500 6af0bf9c bellard
             */
3501 6af0bf9c bellard
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
3502 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
3503 6af0bf9c bellard
            } else {
3504 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
3505 6af0bf9c bellard
            }
3506 6af0bf9c bellard
            /* Treat as a noop */
3507 6af0bf9c bellard
            break;
3508 7a387fff ths
#ifdef MIPS_HAS_MIPS64
3509 7a387fff ths
        case OPC_DCLZ ... OPC_DCLO:
3510 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
3511 7a387fff ths
            break;
3512 7a387fff ths
#endif
3513 6af0bf9c bellard
        default:            /* Invalid */
3514 6af0bf9c bellard
            MIPS_INVAL("special2");
3515 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
3516 6af0bf9c bellard
            break;
3517 6af0bf9c bellard
        }
3518 6af0bf9c bellard
        break;
3519 7a387fff ths
    case OPC_SPECIAL3:
3520 7a387fff ths
        op1 = MASK_SPECIAL3(ctx->opcode);
3521 6af0bf9c bellard
        switch (op1) {
3522 7a387fff ths
        case OPC_EXT:
3523 7a387fff ths
        case OPC_INS:
3524 7a387fff ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
3525 7a387fff ths
            break;
3526 7a387fff ths
        case OPC_BSHFL:
3527 7a387fff ths
            op2 = MASK_BSHFL(ctx->opcode);
3528 7a387fff ths
            switch (op2) {
3529 7a387fff ths
            case OPC_WSBH:
3530 7a387fff ths
                GEN_LOAD_REG_TN(T1, rt);
3531 7a387fff ths
                gen_op_wsbh();
3532 7a387fff ths
                break;
3533 7a387fff ths
            case OPC_SEB:
3534 7a387fff ths
                GEN_LOAD_REG_TN(T1, rt);
3535 7a387fff ths
                gen_op_seb();
3536 7a387fff ths
                break;
3537 7a387fff ths
            case OPC_SEH:
3538 7a387fff ths
                GEN_LOAD_REG_TN(T1, rt);
3539 7a387fff ths
                gen_op_seh();
3540 7a387fff ths
                break;
3541 7a387fff ths
             default:            /* Invalid */
3542 7a387fff ths
                MIPS_INVAL("bshfl");
3543 7a387fff ths
                generate_exception(ctx, EXCP_RI);
3544 7a387fff ths
                break;
3545 7a387fff ths
           }
3546 7a387fff ths
           GEN_STORE_TN_REG(rd, T0);
3547 7a387fff ths
           break;
3548 7a387fff ths
       case OPC_RDHWR:
3549 7a387fff ths
           switch (rd) {
3550 7a387fff ths
           case 0:
3551 7a387fff ths
               gen_op_rdhwr_cpunum();
3552 7a387fff ths
               break;
3553 7a387fff ths
           case 1:
3554 7a387fff ths
               gen_op_rdhwr_synci_step();
3555 7a387fff ths
               break;
3556 7a387fff ths
           case 2:
3557 7a387fff ths
               gen_op_rdhwr_cc();
3558 7a387fff ths
               break;
3559 7a387fff ths
           case 3:
3560 7a387fff ths
               gen_op_rdhwr_ccres();
3561 7a387fff ths
               break;
3562 7a387fff ths
           default:            /* Invalid */
3563 7a387fff ths
               MIPS_INVAL("rdhwr");
3564 7a387fff ths
               generate_exception(ctx, EXCP_RI);
3565 7a387fff ths
               break;
3566 7a387fff ths
           }
3567 7a387fff ths
           GEN_STORE_TN_REG(rt, T0);
3568 7a387fff ths
           break;
3569 7a387fff ths
#ifdef MIPS_HAS_MIPS64
3570 7a387fff ths
       case OPC_DEXTM ... OPC_DEXT:
3571 7a387fff ths
       case OPC_DINSM ... OPC_DINS:
3572 7a387fff ths
           gen_bitops(ctx, op1, rt, rs, sa, rd);
3573 7a387fff ths
            break;
3574 7a387fff ths
       case OPC_DBSHFL:
3575 7a387fff ths
           op2 = MASK_DBSHFL(ctx->opcode);
3576 7a387fff ths
           switch (op2) {
3577 7a387fff ths
           case OPC_DSBH:
3578 7a387fff ths
               GEN_LOAD_REG_TN(T1, rt);
3579 7a387fff ths
               gen_op_dsbh();
3580 7a387fff ths
               break;
3581 7a387fff ths
           case OPC_DSHD:
3582 7a387fff ths
               GEN_LOAD_REG_TN(T1, rt);
3583 7a387fff ths
               gen_op_dshd();
3584 7a387fff ths
               break;
3585 7a387fff ths
            default:            /* Invalid */
3586 7a387fff ths
                MIPS_INVAL("dbshfl");
3587 7a387fff ths
                generate_exception(ctx, EXCP_RI);
3588 7a387fff ths
                break;
3589 7a387fff ths
           }
3590 7a387fff ths
           GEN_STORE_TN_REG(rd, T0);
3591 7a387fff ths
#endif
3592 7a387fff ths
        default:            /* Invalid */
3593 7a387fff ths
            MIPS_INVAL("special3");
3594 7a387fff ths
            generate_exception(ctx, EXCP_RI);
3595 7a387fff ths
            break;
3596 7a387fff ths
        }
3597 7a387fff ths
        break;
3598 7a387fff ths
    case OPC_REGIMM:
3599 7a387fff ths
        op1 = MASK_REGIMM(ctx->opcode);
3600 7a387fff ths
        switch (op1) {
3601 7a387fff ths
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
3602 7a387fff ths
        case OPC_BLTZAL ... OPC_BGEZALL:
3603 7a387fff ths
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
3604 6af0bf9c bellard
            return;
3605 7a387fff ths
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
3606 7a387fff ths
        case OPC_TNEI:
3607 7a387fff ths
            gen_trap(ctx, op1, rs, -1, imm);
3608 7a387fff ths
            break;
3609 7a387fff ths
        case OPC_SYNCI:
3610 7a387fff ths
           /* treat as noop */
3611 6af0bf9c bellard
            break;
3612 6af0bf9c bellard
        default:            /* Invalid */
3613 6af0bf9c bellard
            MIPS_INVAL("REGIMM");
3614 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
3615 6af0bf9c bellard
            break;
3616 6af0bf9c bellard
        }
3617 6af0bf9c bellard
        break;
3618 7a387fff ths
    case OPC_CP0:
3619 7a387fff ths
        op1 = MASK_CP0(ctx->opcode);
3620 6af0bf9c bellard
        switch (op1) {
3621 7a387fff ths
        case OPC_MFC0:
3622 7a387fff ths
        case OPC_MTC0:
3623 7a387fff ths
#ifdef MIPS_HAS_MIPS64
3624 7a387fff ths
        case OPC_DMFC0:
3625 7a387fff ths
        case OPC_DMTC0:
3626 7a387fff ths
#endif
3627 7a387fff ths
            gen_cp0(ctx, op1, rt, rd);
3628 7a387fff ths
            break;
3629 7a387fff ths
        case OPC_C0_FIRST ... OPC_C0_LAST:
3630 7a387fff ths
            gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
3631 7a387fff ths
            break;
3632 7a387fff ths
        case OPC_MFMC0:
3633 7a387fff ths
            op2 = MASK_MFMC0(ctx->opcode);
3634 7a387fff ths
            switch (op2) {
3635 7a387fff ths
            case OPC_DI:
3636 7a387fff ths
                gen_op_di();
3637 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
3638 7a387fff ths
                ctx->bstate = BS_STOP;
3639 7a387fff ths
                break;
3640 7a387fff ths
            case OPC_EI:
3641 7a387fff ths
                gen_op_ei();
3642 7a387fff ths
                /* Stop translation as we may have switched the execution mode */
3643 7a387fff ths
                ctx->bstate = BS_STOP;
3644 7a387fff ths
                break;
3645 7a387fff ths
            default:            /* Invalid */
3646 7a387fff ths
                MIPS_INVAL("MFMC0");
3647 7a387fff ths
                generate_exception(ctx, EXCP_RI);
3648 7a387fff ths
                break;
3649 7a387fff ths
            }
3650 7a387fff ths
            GEN_STORE_TN_REG(rt, T0);
3651 6af0bf9c bellard
            break;
3652 7a387fff ths
        /* Shadow registers (not implemented). */
3653 7a387fff ths
        case OPC_RDPGPR:
3654 7a387fff ths
        case OPC_WRPGPR:
3655 6af0bf9c bellard
        default:
3656 7a387fff ths
            generate_exception(ctx, EXCP_RI);
3657 6af0bf9c bellard
            break;
3658 6af0bf9c bellard
        }
3659 6af0bf9c bellard
        break;
3660 7a387fff ths
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
3661 7a387fff ths
         gen_arith_imm(ctx, op, rt, rs, imm);
3662 7a387fff ths
         break;
3663 7a387fff ths
    case OPC_J ... OPC_JAL: /* Jump */
3664 7a387fff ths
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
3665 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, offset);
3666 7a387fff ths
         return;
3667 7a387fff ths
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
3668 7a387fff ths
    case OPC_BEQL ... OPC_BGTZL:
3669 7a387fff ths
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
3670 7a387fff ths
         return;
3671 7a387fff ths
    case OPC_LB ... OPC_LWR: /* Load and stores */
3672 7a387fff ths
    case OPC_SB ... OPC_SW:
3673 7a387fff ths
    case OPC_SWR:
3674 7a387fff ths
    case OPC_LL:
3675 7a387fff ths
    case OPC_SC:
3676 7a387fff ths
         gen_ldst(ctx, op, rt, rs, imm);
3677 7a387fff ths
         break;
3678 7a387fff ths
    case OPC_CACHE:
3679 7a387fff ths
         /* Treat as a noop */
3680 7a387fff ths
         break;
3681 7a387fff ths
    case OPC_PREF:
3682 6af0bf9c bellard
        /* Treat as a noop */
3683 6af0bf9c bellard
        break;
3684 4ad40f36 bellard
3685 4ad40f36 bellard
    /* Floating point.  */
3686 7a387fff ths
    case OPC_LWC1:
3687 7a387fff ths
    case OPC_LDC1:
3688 7a387fff ths
    case OPC_SWC1:
3689 7a387fff ths
    case OPC_SDC1:
3690 6ea83fed bellard
#if defined(MIPS_USES_FPU)
3691 417f38f0 pbrook
        save_cpu_state(ctx, 1);
3692 6ea83fed bellard
        gen_op_cp1_enabled();
3693 6ea83fed bellard
        gen_flt_ldst(ctx, op, rt, rs, imm);
3694 6ea83fed bellard
#else
3695 6ea83fed bellard
        generate_exception_err(ctx, EXCP_CpU, 1);
3696 6ea83fed bellard
#endif
3697 6ea83fed bellard
        break;
3698 6ea83fed bellard
3699 7a387fff ths
    case OPC_CP1:
3700 6af0bf9c bellard
#if defined(MIPS_USES_FPU)
3701 417f38f0 pbrook
        save_cpu_state(ctx, 1);
3702 6ea83fed bellard
        gen_op_cp1_enabled();
3703 7a387fff ths
        op1 = MASK_CP1(ctx->opcode);
3704 6ea83fed bellard
        switch (op1) {
3705 7a387fff ths
        case OPC_MFC1:
3706 7a387fff ths
        case OPC_CFC1:
3707 7a387fff ths
        case OPC_MTC1:
3708 7a387fff ths
        case OPC_CTC1:
3709 7a387fff ths
            gen_cp1(ctx, op1, rt, rd);
3710 7a387fff ths
            break;
3711 7a387fff ths
        case OPC_BC1:
3712 7a387fff ths
            gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
3713 6ea83fed bellard
            return;
3714 7a387fff ths
        case OPC_S_FMT:
3715 7a387fff ths
        case OPC_D_FMT:
3716 7a387fff ths
        case OPC_W_FMT:
3717 7a387fff ths
        case OPC_L_FMT:
3718 7a387fff ths
            gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
3719 6ea83fed bellard
            break;
3720 6ea83fed bellard
        default:
3721 6ea83fed bellard
            generate_exception_err(ctx, EXCP_RI, 1);
3722 6ea83fed bellard
            break;
3723 6ea83fed bellard
        }
3724 4ad40f36 bellard
#else
3725 4ad40f36 bellard
        generate_exception_err(ctx, EXCP_CpU, 1);
3726 6af0bf9c bellard
#endif
3727 4ad40f36 bellard
        break;
3728 4ad40f36 bellard
3729 4ad40f36 bellard
    /* COP2.  */
3730 7a387fff ths
    case OPC_LWC2:
3731 7a387fff ths
    case OPC_LDC2:
3732 7a387fff ths
    case OPC_SWC2:
3733 7a387fff ths
    case OPC_SDC2:
3734 7a387fff ths
    case OPC_CP2:
3735 7a387fff ths
        /* COP2: Not implemented. */
3736 4ad40f36 bellard
        generate_exception_err(ctx, EXCP_CpU, 2);
3737 4ad40f36 bellard
        break;
3738 4ad40f36 bellard
3739 7a387fff ths
    case OPC_CP3:
3740 7a387fff ths
        gen_op_cp1_enabled();
3741 7a387fff ths
        op1 = MASK_CP3(ctx->opcode);
3742 7a387fff ths
        switch (op1) {
3743 6af0bf9c bellard
        /* Not implemented */
3744 7a387fff ths
        default:
3745 7a387fff ths
            generate_exception_err(ctx, EXCP_RI, 1);
3746 7a387fff ths
            break;
3747 7a387fff ths
        }
3748 4ad40f36 bellard
        break;
3749 4ad40f36 bellard
3750 7a387fff ths
#ifdef MIPS_HAS_MIPS64
3751 7a387fff ths
    /* MIPS64 opcodes */
3752 7a387fff ths
    case OPC_LWU:
3753 7a387fff ths
    case OPC_LDL ... OPC_LDR:
3754 7a387fff ths
    case OPC_SDL ... OPC_SDR:
3755 7a387fff ths
    case OPC_LLD:
3756 7a387fff ths
    case OPC_LD:
3757 7a387fff ths
    case OPC_SCD:
3758 7a387fff ths
    case OPC_SD:
3759 7a387fff ths
        gen_ldst(ctx, op, rt, rs, imm);
3760 7a387fff ths
        break;
3761 7a387fff ths
    case OPC_DADDI ... OPC_DADDIU:
3762 7a387fff ths
        gen_arith_imm(ctx, op, rt, rs, imm);
3763 7a387fff ths
        break;
3764 6af0bf9c bellard
#endif
3765 7a387fff ths
#ifdef MIPS_HAS_MIPS16
3766 7a387fff ths
    case OPC_JALX:
3767 7a387fff ths
        /* MIPS16: Not implemented. */
3768 7a387fff ths
#endif
3769 7a387fff ths
#ifdef MIPS_HAS_MDMX
3770 7a387fff ths
    case OPC_MDMX:
3771 7a387fff ths
        /* MDMX: Not implemented. */
3772 6af0bf9c bellard
#endif
3773 6af0bf9c bellard
    default:            /* Invalid */
3774 6af0bf9c bellard
        MIPS_INVAL("");
3775 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
3776 6af0bf9c bellard
        break;
3777 6af0bf9c bellard
    }
3778 4ad40f36 bellard
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
3779 6af0bf9c bellard
        int hflags = ctx->hflags;
3780 6af0bf9c bellard
        /* Branches completion */
3781 4ad40f36 bellard
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
3782 6af0bf9c bellard
        ctx->bstate = BS_BRANCH;
3783 6af0bf9c bellard
        save_cpu_state(ctx, 0);
3784 6af0bf9c bellard
        switch (hflags & MIPS_HFLAG_BMASK) {
3785 6af0bf9c bellard
        case MIPS_HFLAG_B:
3786 6af0bf9c bellard
            /* unconditional branch */
3787 6af0bf9c bellard
            MIPS_DEBUG("unconditional branch");
3788 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
3789 6af0bf9c bellard
            break;
3790 6af0bf9c bellard
        case MIPS_HFLAG_BL:
3791 6af0bf9c bellard
            /* blikely taken case */
3792 6af0bf9c bellard
            MIPS_DEBUG("blikely branch taken");
3793 6e256c93 bellard
            gen_goto_tb(ctx, 0, ctx->btarget);
3794 6af0bf9c bellard
            break;
3795 6af0bf9c bellard
        case MIPS_HFLAG_BC:
3796 6af0bf9c bellard
            /* Conditional branch */
3797 6af0bf9c bellard
            MIPS_DEBUG("conditional branch");
3798 c53be334 bellard
            {
3799 c53be334 bellard
              int l1;
3800 c53be334 bellard
              l1 = gen_new_label();
3801 c53be334 bellard
              gen_op_jnz_T2(l1);
3802 6e256c93 bellard
              gen_goto_tb(ctx, 1, ctx->pc + 4);
3803 eeef26cd bellard
              gen_set_label(l1);
3804 eeef26cd bellard
              gen_goto_tb(ctx, 0, ctx->btarget);
3805 c53be334 bellard
            }
3806 6af0bf9c bellard
            break;
3807 6af0bf9c bellard
        case MIPS_HFLAG_BR:
3808 6af0bf9c bellard
            /* unconditional branch to register */
3809 6af0bf9c bellard
            MIPS_DEBUG("branch to register");
3810 6af0bf9c bellard
            gen_op_breg();
3811 6af0bf9c bellard
            break;
3812 6af0bf9c bellard
        default:
3813 6af0bf9c bellard
            MIPS_DEBUG("unknown branch");
3814 6af0bf9c bellard
            break;
3815 6af0bf9c bellard
        }
3816 6af0bf9c bellard
    }
3817 6af0bf9c bellard
}
3818 6af0bf9c bellard
3819 6af0bf9c bellard
int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3820 6af0bf9c bellard
                                    int search_pc)
3821 6af0bf9c bellard
{
3822 6af0bf9c bellard
    DisasContext ctx, *ctxp = &ctx;
3823 6af0bf9c bellard
    target_ulong pc_start;
3824 6af0bf9c bellard
    uint16_t *gen_opc_end;
3825 6af0bf9c bellard
    int j, lj = -1;
3826 6af0bf9c bellard
3827 4ad40f36 bellard
    if (search_pc && loglevel)
3828 6ea83fed bellard
        fprintf (logfile, "search pc %d\n", search_pc);
3829 4ad40f36 bellard
3830 6af0bf9c bellard
    pc_start = tb->pc;
3831 6af0bf9c bellard
    gen_opc_ptr = gen_opc_buf;
3832 6af0bf9c bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3833 6af0bf9c bellard
    gen_opparam_ptr = gen_opparam_buf;
3834 c53be334 bellard
    nb_gen_labels = 0;
3835 6af0bf9c bellard
    ctx.pc = pc_start;
3836 4ad40f36 bellard
    ctx.saved_pc = -1;
3837 6af0bf9c bellard
    ctx.tb = tb;
3838 6af0bf9c bellard
    ctx.bstate = BS_NONE;
3839 4ad40f36 bellard
    /* Restore delay slot state from the tb context.  */
3840 4ad40f36 bellard
    ctx.hflags = tb->flags;
3841 6af0bf9c bellard
    ctx.saved_hflags = ctx.hflags;
3842 6af0bf9c bellard
    if (ctx.hflags & MIPS_HFLAG_BR) {
3843 6af0bf9c bellard
        gen_op_restore_breg_target();
3844 6af0bf9c bellard
    } else if (ctx.hflags & MIPS_HFLAG_B) {
3845 6af0bf9c bellard
        ctx.btarget = env->btarget;
3846 6af0bf9c bellard
    } else if (ctx.hflags & MIPS_HFLAG_BMASK) {
3847 6af0bf9c bellard
        /* If we are in the delay slot of a conditional branch,
3848 6af0bf9c bellard
         * restore the branch condition from env->bcond to T2
3849 6af0bf9c bellard
         */
3850 6af0bf9c bellard
        ctx.btarget = env->btarget;
3851 6af0bf9c bellard
        gen_op_restore_bcond();
3852 6af0bf9c bellard
    }
3853 6af0bf9c bellard
#if defined(CONFIG_USER_ONLY)
3854 6af0bf9c bellard
    ctx.mem_idx = 0;
3855 6af0bf9c bellard
#else
3856 3d9fb9fe bellard
    ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
3857 6af0bf9c bellard
#endif
3858 6af0bf9c bellard
    ctx.CP0_Status = env->CP0_Status;
3859 6af0bf9c bellard
#ifdef DEBUG_DISAS
3860 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
3861 6af0bf9c bellard
        fprintf(logfile, "------------------------------------------------\n");
3862 4ad40f36 bellard
        /* FIXME: This may print out stale hflags from env... */
3863 6af0bf9c bellard
        cpu_dump_state(env, logfile, fprintf, 0);
3864 6af0bf9c bellard
    }
3865 6af0bf9c bellard
#endif
3866 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
3867 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
3868 4ad40f36 bellard
        fprintf(logfile, "\ntb %p super %d cond %04x\n",
3869 4ad40f36 bellard
                tb, ctx.mem_idx, ctx.hflags);
3870 6af0bf9c bellard
#endif
3871 6af0bf9c bellard
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
3872 4ad40f36 bellard
        if (env->nb_breakpoints > 0) {
3873 4ad40f36 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
3874 4ad40f36 bellard
                if (env->breakpoints[j] == ctx.pc) {
3875 4ad40f36 bellard
                    save_cpu_state(ctxp, 1);
3876 4ad40f36 bellard
                    ctx.bstate = BS_BRANCH;
3877 4ad40f36 bellard
                    gen_op_debug();
3878 4ad40f36 bellard
                    goto done_generating;
3879 4ad40f36 bellard
                }
3880 4ad40f36 bellard
            }
3881 4ad40f36 bellard
        }
3882 4ad40f36 bellard
3883 6af0bf9c bellard
        if (search_pc) {
3884 6af0bf9c bellard
            j = gen_opc_ptr - gen_opc_buf;
3885 6af0bf9c bellard
            if (lj < j) {
3886 6af0bf9c bellard
                lj++;
3887 6af0bf9c bellard
                while (lj < j)
3888 6af0bf9c bellard
                    gen_opc_instr_start[lj++] = 0;
3889 6af0bf9c bellard
            }
3890 4ad40f36 bellard
            gen_opc_pc[lj] = ctx.pc;
3891 4ad40f36 bellard
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
3892 4ad40f36 bellard
            gen_opc_instr_start[lj] = 1;
3893 6af0bf9c bellard
        }
3894 6af0bf9c bellard
        ctx.opcode = ldl_code(ctx.pc);
3895 6af0bf9c bellard
        decode_opc(&ctx);
3896 6af0bf9c bellard
        ctx.pc += 4;
3897 4ad40f36 bellard
3898 4ad40f36 bellard
        if (env->singlestep_enabled)
3899 4ad40f36 bellard
            break;
3900 4ad40f36 bellard
3901 6af0bf9c bellard
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
3902 6af0bf9c bellard
            break;
3903 4ad40f36 bellard
3904 6af0bf9c bellard
#if defined (MIPS_SINGLE_STEP)
3905 6af0bf9c bellard
        break;
3906 6af0bf9c bellard
#endif
3907 6af0bf9c bellard
    }
3908 4ad40f36 bellard
    if (env->singlestep_enabled) {
3909 4ad40f36 bellard
        save_cpu_state(ctxp, ctx.bstate == BS_NONE);
3910 4ad40f36 bellard
        gen_op_debug();
3911 4ad40f36 bellard
        goto done_generating;
3912 4ad40f36 bellard
    }
3913 4ad40f36 bellard
    else if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {
3914 6af0bf9c bellard
        save_cpu_state(ctxp, 0);
3915 6e256c93 bellard
        gen_goto_tb(&ctx, 0, ctx.pc);
3916 6af0bf9c bellard
    }
3917 6af0bf9c bellard
    gen_op_reset_T0();
3918 6af0bf9c bellard
    /* Generate the return instruction */
3919 6af0bf9c bellard
    gen_op_exit_tb();
3920 4ad40f36 bellard
done_generating:
3921 6af0bf9c bellard
    *gen_opc_ptr = INDEX_op_end;
3922 6af0bf9c bellard
    if (search_pc) {
3923 6af0bf9c bellard
        j = gen_opc_ptr - gen_opc_buf;
3924 6af0bf9c bellard
        lj++;
3925 6af0bf9c bellard
        while (lj <= j)
3926 6af0bf9c bellard
            gen_opc_instr_start[lj++] = 0;
3927 6af0bf9c bellard
        tb->size = 0;
3928 6af0bf9c bellard
    } else {
3929 6af0bf9c bellard
        tb->size = ctx.pc - pc_start;
3930 6af0bf9c bellard
    }
3931 6af0bf9c bellard
#ifdef DEBUG_DISAS
3932 6af0bf9c bellard
#if defined MIPS_DEBUG_DISAS
3933 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM)
3934 6af0bf9c bellard
        fprintf(logfile, "\n");
3935 6af0bf9c bellard
#endif
3936 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3937 6af0bf9c bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3938 6ea83fed bellard
    target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
3939 6af0bf9c bellard
        fprintf(logfile, "\n");
3940 6af0bf9c bellard
    }
3941 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_OP) {
3942 6af0bf9c bellard
        fprintf(logfile, "OP:\n");
3943 6af0bf9c bellard
        dump_ops(gen_opc_buf, gen_opparam_buf);
3944 6af0bf9c bellard
        fprintf(logfile, "\n");
3945 6af0bf9c bellard
    }
3946 6af0bf9c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
3947 6af0bf9c bellard
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
3948 6af0bf9c bellard
    }
3949 6af0bf9c bellard
#endif
3950 6af0bf9c bellard
    
3951 6af0bf9c bellard
    return 0;
3952 6af0bf9c bellard
}
3953 6af0bf9c bellard
3954 6af0bf9c bellard
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3955 6af0bf9c bellard
{
3956 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 0);
3957 6af0bf9c bellard
}
3958 6af0bf9c bellard
3959 6af0bf9c bellard
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3960 6af0bf9c bellard
{
3961 6af0bf9c bellard
    return gen_intermediate_code_internal(env, tb, 1);
3962 6af0bf9c bellard
}
3963 6af0bf9c bellard
3964 6ea83fed bellard
void fpu_dump_state(CPUState *env, FILE *f, 
3965 6ea83fed bellard
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
3966 6ea83fed bellard
                    int flags)
3967 6ea83fed bellard
{
3968 6ea83fed bellard
    int i;
3969 6ea83fed bellard
3970 6ea83fed bellard
#   define printfpr(fp) do { \
3971 6ea83fed bellard
        fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
3972 6ea83fed bellard
                (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
3973 6ea83fed bellard
    } while(0)
3974 6ea83fed bellard
3975 6ea83fed bellard
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d\n",
3976 6ea83fed bellard
                env->fcr0, env->fcr31,
3977 7a387fff ths
                (env->CP0_Status & (1 << CP0St_FR)) != 0);
3978 6ea83fed bellard
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
3979 6ea83fed bellard
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
3980 6ea83fed bellard
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
3981 7a387fff ths
    for(i = 0; i < 32; i += 2) {
3982 7a387fff ths
        fpu_fprintf(f, "%s: ", fregnames[i]);
3983 6ea83fed bellard
        printfpr(FPR(env, i));
3984 6ea83fed bellard
    }
3985 6ea83fed bellard
3986 6ea83fed bellard
#undef printfpr
3987 6ea83fed bellard
}
3988 6ea83fed bellard
3989 7a387fff ths
void dump_fpu (CPUState *env)
3990 6ea83fed bellard
{
3991 6ea83fed bellard
    if (loglevel) { 
3992 6ea83fed bellard
       fprintf(logfile, "pc=0x%08x HI=0x%08x LO=0x%08x ds %04x %08x %d\n",
3993 6ea83fed bellard
               env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
3994 6ea83fed bellard
       fpu_dump_state(env, logfile, fprintf, 0);
3995 6ea83fed bellard
    }
3996 6ea83fed bellard
}
3997 6ea83fed bellard
3998 6af0bf9c bellard
void cpu_dump_state (CPUState *env, FILE *f, 
3999 6af0bf9c bellard
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4000 6af0bf9c bellard
                     int flags)
4001 6af0bf9c bellard
{
4002 568b600d bellard
    uint32_t c0_status;
4003 6af0bf9c bellard
    int i;
4004 6af0bf9c bellard
    
4005 6af0bf9c bellard
    cpu_fprintf(f, "pc=0x%08x HI=0x%08x LO=0x%08x ds %04x %08x %d\n",
4006 6af0bf9c bellard
                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
4007 6af0bf9c bellard
    for (i = 0; i < 32; i++) {
4008 6af0bf9c bellard
        if ((i & 3) == 0)
4009 6af0bf9c bellard
            cpu_fprintf(f, "GPR%02d:", i);
4010 6af0bf9c bellard
        cpu_fprintf(f, " %s %08x", regnames[i], env->gpr[i]);
4011 6af0bf9c bellard
        if ((i & 3) == 3)
4012 6af0bf9c bellard
            cpu_fprintf(f, "\n");
4013 6af0bf9c bellard
    }
4014 568b600d bellard
4015 568b600d bellard
    c0_status = env->CP0_Status;
4016 568b600d bellard
    if (env->hflags & MIPS_HFLAG_UM)
4017 568b600d bellard
        c0_status |= (1 << CP0St_UM);
4018 568b600d bellard
    if (env->hflags & MIPS_HFLAG_ERL)
4019 568b600d bellard
        c0_status |= (1 << CP0St_ERL);
4020 568b600d bellard
    if (env->hflags & MIPS_HFLAG_EXL)
4021 568b600d bellard
        c0_status |= (1 << CP0St_EXL);
4022 568b600d bellard
4023 6af0bf9c bellard
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x%08x\n",
4024 568b600d bellard
                c0_status, env->CP0_Cause, env->CP0_EPC);
4025 6af0bf9c bellard
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%08x\n",
4026 6af0bf9c bellard
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
4027 7a387fff ths
    if (c0_status & (1 << CP0St_CU1))
4028 7a387fff ths
        fpu_dump_state(env, f, cpu_fprintf, flags);
4029 6af0bf9c bellard
}
4030 6af0bf9c bellard
4031 6af0bf9c bellard
CPUMIPSState *cpu_mips_init (void)
4032 6af0bf9c bellard
{
4033 6af0bf9c bellard
    CPUMIPSState *env;
4034 6af0bf9c bellard
4035 6af0bf9c bellard
    env = qemu_mallocz(sizeof(CPUMIPSState));
4036 6af0bf9c bellard
    if (!env)
4037 6af0bf9c bellard
        return NULL;
4038 173d6cfe bellard
    cpu_exec_init(env);
4039 6ae81775 ths
    cpu_reset(env);
4040 6ae81775 ths
    return env;
4041 6ae81775 ths
}
4042 6ae81775 ths
4043 6ae81775 ths
void cpu_reset (CPUMIPSState *env)
4044 6ae81775 ths
{
4045 6ae81775 ths
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
4046 6ae81775 ths
4047 6af0bf9c bellard
    tlb_flush(env, 1);
4048 6ae81775 ths
4049 6af0bf9c bellard
    /* Minimal init */
4050 6af0bf9c bellard
    env->PC = 0xBFC00000;
4051 6af0bf9c bellard
#if defined (MIPS_USES_R4K_TLB)
4052 6af0bf9c bellard
    env->CP0_random = MIPS_TLB_NB - 1;
4053 814b9a47 ths
    env->tlb_in_use = MIPS_TLB_NB;
4054 6af0bf9c bellard
#endif
4055 6af0bf9c bellard
    env->CP0_Wired = 0;
4056 7a387fff ths
    /* SMP not implemented */
4057 7a387fff ths
    env->CP0_EBase = 0x80000000;
4058 6af0bf9c bellard
    env->CP0_Config0 = MIPS_CONFIG0;
4059 7a387fff ths
    env->CP0_Config1 = MIPS_CONFIG1;
4060 7a387fff ths
    env->CP0_Config2 = MIPS_CONFIG2;
4061 7a387fff ths
    env->CP0_Config3 = MIPS_CONFIG3;
4062 6af0bf9c bellard
    env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
4063 6af0bf9c bellard
    env->CP0_WatchLo = 0;
4064 6af0bf9c bellard
    env->hflags = MIPS_HFLAG_ERL;
4065 6af0bf9c bellard
    /* Count register increments in debug mode, EJTAG version 1 */
4066 6af0bf9c bellard
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
4067 6af0bf9c bellard
    env->CP0_PRid = MIPS_CPU;
4068 6af0bf9c bellard
    env->exception_index = EXCP_NONE;
4069 eeef26cd bellard
#if defined(CONFIG_USER_ONLY)
4070 eeef26cd bellard
    env->hflags |= MIPS_HFLAG_UM;
4071 eeef26cd bellard
#endif
4072 6ea83fed bellard
#ifdef MIPS_USES_FPU
4073 6ea83fed bellard
    env->fcr0 = MIPS_FCR0;        
4074 6ea83fed bellard
#endif
4075 7a387fff ths
    /* XXX some guesswork here, values are CPU specific */
4076 7a387fff ths
    env->SYNCI_Step = 16;
4077 7a387fff ths
    env->CCRes = 2;
4078 6af0bf9c bellard
}