]> git.proxmox.com Git - qemu.git/blame - target-mips/translate.c
MIPS 64-bit FPU support, plus some collateral bugfixes in the
[qemu.git] / target-mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
3 *
4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
6af0bf9c
FB
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <stdarg.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <string.h>
27#include <inttypes.h>
28
29#include "cpu.h"
30#include "exec-all.h"
31#include "disas.h"
32
eeef26cd 33//#define MIPS_DEBUG_DISAS
c570fd16 34//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c
FB
35//#define MIPS_SINGLE_STEP
36
c53be334
FB
37#ifdef USE_DIRECT_JUMP
38#define TBPARAM(x)
39#else
40#define TBPARAM(x) (long)(x)
41#endif
42
6af0bf9c
FB
43enum {
44#define DEF(s, n, copy_size) INDEX_op_ ## s,
45#include "opc.h"
46#undef DEF
47 NB_OPS,
48};
49
50static uint16_t *gen_opc_ptr;
51static uint32_t *gen_opparam_ptr;
52
53#include "gen-op.h"
54
7a387fff
TS
55/* MIPS major opcodes */
56#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
57
58enum {
59 /* indirect opcode tables */
7a387fff
TS
60 OPC_SPECIAL = (0x00 << 26),
61 OPC_REGIMM = (0x01 << 26),
62 OPC_CP0 = (0x10 << 26),
63 OPC_CP1 = (0x11 << 26),
64 OPC_CP2 = (0x12 << 26),
65 OPC_CP3 = (0x13 << 26),
66 OPC_SPECIAL2 = (0x1C << 26),
67 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 68 /* arithmetic with immediate */
7a387fff
TS
69 OPC_ADDI = (0x08 << 26),
70 OPC_ADDIU = (0x09 << 26),
71 OPC_SLTI = (0x0A << 26),
72 OPC_SLTIU = (0x0B << 26),
73 OPC_ANDI = (0x0C << 26),
74 OPC_ORI = (0x0D << 26),
75 OPC_XORI = (0x0E << 26),
76 OPC_LUI = (0x0F << 26),
77 OPC_DADDI = (0x18 << 26),
78 OPC_DADDIU = (0x19 << 26),
e37e863f 79 /* Jump and branches */
7a387fff
TS
80 OPC_J = (0x02 << 26),
81 OPC_JAL = (0x03 << 26),
82 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
83 OPC_BEQL = (0x14 << 26),
84 OPC_BNE = (0x05 << 26),
85 OPC_BNEL = (0x15 << 26),
86 OPC_BLEZ = (0x06 << 26),
87 OPC_BLEZL = (0x16 << 26),
88 OPC_BGTZ = (0x07 << 26),
89 OPC_BGTZL = (0x17 << 26),
90 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
e37e863f 91 /* Load and stores */
7a387fff
TS
92 OPC_LDL = (0x1A << 26),
93 OPC_LDR = (0x1B << 26),
94 OPC_LB = (0x20 << 26),
95 OPC_LH = (0x21 << 26),
96 OPC_LWL = (0x22 << 26),
97 OPC_LW = (0x23 << 26),
98 OPC_LBU = (0x24 << 26),
99 OPC_LHU = (0x25 << 26),
100 OPC_LWR = (0x26 << 26),
101 OPC_LWU = (0x27 << 26),
102 OPC_SB = (0x28 << 26),
103 OPC_SH = (0x29 << 26),
104 OPC_SWL = (0x2A << 26),
105 OPC_SW = (0x2B << 26),
106 OPC_SDL = (0x2C << 26),
107 OPC_SDR = (0x2D << 26),
108 OPC_SWR = (0x2E << 26),
109 OPC_LL = (0x30 << 26),
110 OPC_LLD = (0x34 << 26),
111 OPC_LD = (0x37 << 26),
112 OPC_SC = (0x38 << 26),
113 OPC_SCD = (0x3C << 26),
114 OPC_SD = (0x3F << 26),
e37e863f 115 /* Floating point load/store */
7a387fff
TS
116 OPC_LWC1 = (0x31 << 26),
117 OPC_LWC2 = (0x32 << 26),
118 OPC_LDC1 = (0x35 << 26),
119 OPC_LDC2 = (0x36 << 26),
120 OPC_SWC1 = (0x39 << 26),
121 OPC_SWC2 = (0x3A << 26),
122 OPC_SDC1 = (0x3D << 26),
123 OPC_SDC2 = (0x3E << 26),
124 /* MDMX ASE specific */
125 OPC_MDMX = (0x1E << 26),
e37e863f 126 /* Cache and prefetch */
7a387fff
TS
127 OPC_CACHE = (0x2F << 26),
128 OPC_PREF = (0x33 << 26),
129 /* Reserved major opcode */
130 OPC_MAJOR3B_RESERVED = (0x3B << 26),
e37e863f
FB
131};
132
133/* MIPS special opcodes */
7a387fff
TS
134#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
135
e37e863f
FB
136enum {
137 /* Shifts */
7a387fff 138 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
139 /* NOP is SLL r0, r0, 0 */
140 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
141 /* EHB is SLL r0, r0, 3 */
142 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
143 OPC_SRA = 0x03 | OPC_SPECIAL,
144 OPC_SLLV = 0x04 | OPC_SPECIAL,
145 OPC_SRLV = 0x06 | OPC_SPECIAL,
146 OPC_SRAV = 0x07 | OPC_SPECIAL,
147 OPC_DSLLV = 0x14 | OPC_SPECIAL,
148 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
149 OPC_DSRAV = 0x17 | OPC_SPECIAL,
150 OPC_DSLL = 0x38 | OPC_SPECIAL,
151 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
152 OPC_DSRA = 0x3B | OPC_SPECIAL,
153 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
154 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
155 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 156 /* Multiplication / division */
7a387fff
TS
157 OPC_MULT = 0x18 | OPC_SPECIAL,
158 OPC_MULTU = 0x19 | OPC_SPECIAL,
159 OPC_DIV = 0x1A | OPC_SPECIAL,
160 OPC_DIVU = 0x1B | OPC_SPECIAL,
161 OPC_DMULT = 0x1C | OPC_SPECIAL,
162 OPC_DMULTU = 0x1D | OPC_SPECIAL,
163 OPC_DDIV = 0x1E | OPC_SPECIAL,
164 OPC_DDIVU = 0x1F | OPC_SPECIAL,
e37e863f 165 /* 2 registers arithmetic / logic */
7a387fff
TS
166 OPC_ADD = 0x20 | OPC_SPECIAL,
167 OPC_ADDU = 0x21 | OPC_SPECIAL,
168 OPC_SUB = 0x22 | OPC_SPECIAL,
169 OPC_SUBU = 0x23 | OPC_SPECIAL,
170 OPC_AND = 0x24 | OPC_SPECIAL,
171 OPC_OR = 0x25 | OPC_SPECIAL,
172 OPC_XOR = 0x26 | OPC_SPECIAL,
173 OPC_NOR = 0x27 | OPC_SPECIAL,
174 OPC_SLT = 0x2A | OPC_SPECIAL,
175 OPC_SLTU = 0x2B | OPC_SPECIAL,
176 OPC_DADD = 0x2C | OPC_SPECIAL,
177 OPC_DADDU = 0x2D | OPC_SPECIAL,
178 OPC_DSUB = 0x2E | OPC_SPECIAL,
179 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 180 /* Jumps */
7a387fff
TS
181 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
182 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 183 /* Traps */
7a387fff
TS
184 OPC_TGE = 0x30 | OPC_SPECIAL,
185 OPC_TGEU = 0x31 | OPC_SPECIAL,
186 OPC_TLT = 0x32 | OPC_SPECIAL,
187 OPC_TLTU = 0x33 | OPC_SPECIAL,
188 OPC_TEQ = 0x34 | OPC_SPECIAL,
189 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 190 /* HI / LO registers load & stores */
7a387fff
TS
191 OPC_MFHI = 0x10 | OPC_SPECIAL,
192 OPC_MTHI = 0x11 | OPC_SPECIAL,
193 OPC_MFLO = 0x12 | OPC_SPECIAL,
194 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 195 /* Conditional moves */
7a387fff
TS
196 OPC_MOVZ = 0x0A | OPC_SPECIAL,
197 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 198
7a387fff 199 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
200
201 /* Special */
7a387fff
TS
202 OPC_PMON = 0x05 | OPC_SPECIAL, /* inofficial */
203 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
204 OPC_BREAK = 0x0D | OPC_SPECIAL,
205 OPC_SPIM = 0x0E | OPC_SPECIAL, /* inofficial */
206 OPC_SYNC = 0x0F | OPC_SPECIAL,
207
208 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
209 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
210 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
211 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
212 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
213 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
214 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
215};
216
217/* REGIMM (rt field) opcodes */
218#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
219
220enum {
221 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
222 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
223 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
224 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
225 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
226 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
227 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
228 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
229 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
230 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
231 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
232 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
233 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
234 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
235 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
e37e863f
FB
236};
237
7a387fff
TS
238/* Special2 opcodes */
239#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
240
e37e863f 241enum {
7a387fff
TS
242 /* Multiply & xxx operations */
243 OPC_MADD = 0x00 | OPC_SPECIAL2,
244 OPC_MADDU = 0x01 | OPC_SPECIAL2,
245 OPC_MUL = 0x02 | OPC_SPECIAL2,
246 OPC_MSUB = 0x04 | OPC_SPECIAL2,
247 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
e37e863f 248 /* Misc */
7a387fff
TS
249 OPC_CLZ = 0x20 | OPC_SPECIAL2,
250 OPC_CLO = 0x21 | OPC_SPECIAL2,
251 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
252 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 253 /* Special */
7a387fff
TS
254 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
255};
256
257/* Special3 opcodes */
258#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
259
260enum {
261 OPC_EXT = 0x00 | OPC_SPECIAL3,
262 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
263 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
264 OPC_DEXT = 0x03 | OPC_SPECIAL3,
265 OPC_INS = 0x04 | OPC_SPECIAL3,
266 OPC_DINSM = 0x05 | OPC_SPECIAL3,
267 OPC_DINSU = 0x06 | OPC_SPECIAL3,
268 OPC_DINS = 0x07 | OPC_SPECIAL3,
269 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
270 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
271 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
e37e863f
FB
272};
273
7a387fff
TS
274/* BSHFL opcodes */
275#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
276
e37e863f 277enum {
7a387fff
TS
278 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
279 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
280 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
e37e863f
FB
281};
282
7a387fff
TS
283/* DBSHFL opcodes */
284#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
285
e37e863f 286enum {
7a387fff
TS
287 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
288 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
e37e863f
FB
289};
290
7a387fff
TS
291/* Coprocessor 0 (rs field) */
292#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
293
6ea83fed 294enum {
7a387fff
TS
295 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
296 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
297 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
298 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
299 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
300 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
301 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
302 OPC_C0 = (0x10 << 21) | OPC_CP0,
303 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
304 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 305};
7a387fff
TS
306
307/* MFMC0 opcodes */
b48cfdff 308#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
309
310enum {
311 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
312 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
313};
314
315/* Coprocessor 0 (with rs == C0) */
316#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
317
318enum {
319 OPC_TLBR = 0x01 | OPC_C0,
320 OPC_TLBWI = 0x02 | OPC_C0,
321 OPC_TLBWR = 0x06 | OPC_C0,
322 OPC_TLBP = 0x08 | OPC_C0,
323 OPC_RFE = 0x10 | OPC_C0,
324 OPC_ERET = 0x18 | OPC_C0,
325 OPC_DERET = 0x1F | OPC_C0,
326 OPC_WAIT = 0x20 | OPC_C0,
327};
328
329/* Coprocessor 1 (rs field) */
330#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
331
332enum {
333 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
334 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
335 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 336 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
337 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
338 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
339 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 340 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 341 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
342 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
343 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
7a387fff
TS
344 OPC_S_FMT = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
345 OPC_D_FMT = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
346 OPC_E_FMT = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
347 OPC_Q_FMT = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
348 OPC_W_FMT = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
349 OPC_L_FMT = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
5a5012ec 350 OPC_PS_FMT = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
7a387fff
TS
351};
352
5a5012ec
TS
353#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
354#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
355
7a387fff
TS
356enum {
357 OPC_BC1F = (0x00 << 16) | OPC_BC1,
358 OPC_BC1T = (0x01 << 16) | OPC_BC1,
359 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
360 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
361};
362
5a5012ec
TS
363enum {
364 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
365 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
366};
367
368enum {
369 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
370 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
371};
7a387fff
TS
372
373#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
374
375enum {
376 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
377 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
378 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
379 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
380 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
381 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
382 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
383 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
384 OPC_BC2 = (0x08 << 21) | OPC_CP2,
385};
386
387#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
388
389enum {
390 OPC_LWXC1 = 0x00 | OPC_CP3,
391 OPC_LDXC1 = 0x01 | OPC_CP3,
392 OPC_LUXC1 = 0x05 | OPC_CP3,
393 OPC_SWXC1 = 0x08 | OPC_CP3,
394 OPC_SDXC1 = 0x09 | OPC_CP3,
395 OPC_SUXC1 = 0x0D | OPC_CP3,
396 OPC_PREFX = 0x0F | OPC_CP3,
397 OPC_ALNV_PS = 0x1E | OPC_CP3,
398 OPC_MADD_S = 0x20 | OPC_CP3,
399 OPC_MADD_D = 0x21 | OPC_CP3,
400 OPC_MADD_PS = 0x26 | OPC_CP3,
401 OPC_MSUB_S = 0x28 | OPC_CP3,
402 OPC_MSUB_D = 0x29 | OPC_CP3,
403 OPC_MSUB_PS = 0x2E | OPC_CP3,
404 OPC_NMADD_S = 0x30 | OPC_CP3,
405 OPC_NMADD_D = 0x32 | OPC_CP3,
406 OPC_NMADD_PS= 0x36 | OPC_CP3,
407 OPC_NMSUB_S = 0x38 | OPC_CP3,
408 OPC_NMSUB_D = 0x39 | OPC_CP3,
409 OPC_NMSUB_PS= 0x3E | OPC_CP3,
410};
411
6ea83fed 412
6af0bf9c
FB
413const unsigned char *regnames[] =
414 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
415 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
416 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
417 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
418
419/* Warning: no function for r0 register (hard wired to zero) */
5a5012ec
TS
420#define GEN32(func, NAME) \
421static GenOpFunc *NAME ## _table [32] = { \
422NULL, NAME ## 1, NAME ## 2, NAME ## 3, \
423NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
424NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
425NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
426NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
427NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
428NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
429NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
430}; \
431static inline void func(int n) \
432{ \
433 NAME ## _table[n](); \
6af0bf9c
FB
434}
435
436/* General purpose registers moves */
437GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
438GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
439GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
440
441GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
442GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
443
7a387fff 444static const char *fregnames[] =
6ea83fed
FB
445 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
446 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
447 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
448 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
449
5a5012ec
TS
450#define FGEN32(func, NAME) \
451static GenOpFunc *NAME ## _table [32] = { \
452NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
453NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
454NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
455NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
456NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
457NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
458NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
459NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
460}; \
461static inline void func(int n) \
462{ \
463 NAME ## _table[n](); \
6ea83fed
FB
464}
465
5a5012ec
TS
466FGEN32(gen_op_load_fpr_WT0, gen_op_load_fpr_WT0_fpr);
467FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
468
469FGEN32(gen_op_load_fpr_WT1, gen_op_load_fpr_WT1_fpr);
470FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
6ea83fed 471
5a5012ec
TS
472FGEN32(gen_op_load_fpr_WT2, gen_op_load_fpr_WT2_fpr);
473FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
6ea83fed 474
5a5012ec
TS
475FGEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fpr);
476FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
6ea83fed 477
5a5012ec
TS
478FGEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fpr);
479FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
6ea83fed 480
5a5012ec
TS
481FGEN32(gen_op_load_fpr_DT2, gen_op_load_fpr_DT2_fpr);
482FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
6ea83fed 483
5a5012ec
TS
484FGEN32(gen_op_load_fpr_WTH0, gen_op_load_fpr_WTH0_fpr);
485FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
6ea83fed 486
5a5012ec
TS
487FGEN32(gen_op_load_fpr_WTH1, gen_op_load_fpr_WTH1_fpr);
488FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
489
490FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr);
491FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
6ea83fed
FB
492
493#define FOP_CONDS(fmt) \
5a5012ec 494static GenOpFunc1 * cond_ ## fmt ## _table[16] = { \
6ea83fed
FB
495 gen_op_cmp_ ## fmt ## _f, \
496 gen_op_cmp_ ## fmt ## _un, \
497 gen_op_cmp_ ## fmt ## _eq, \
498 gen_op_cmp_ ## fmt ## _ueq, \
499 gen_op_cmp_ ## fmt ## _olt, \
500 gen_op_cmp_ ## fmt ## _ult, \
501 gen_op_cmp_ ## fmt ## _ole, \
502 gen_op_cmp_ ## fmt ## _ule, \
503 gen_op_cmp_ ## fmt ## _sf, \
504 gen_op_cmp_ ## fmt ## _ngle, \
505 gen_op_cmp_ ## fmt ## _seq, \
506 gen_op_cmp_ ## fmt ## _ngl, \
507 gen_op_cmp_ ## fmt ## _lt, \
508 gen_op_cmp_ ## fmt ## _nge, \
509 gen_op_cmp_ ## fmt ## _le, \
510 gen_op_cmp_ ## fmt ## _ngt, \
511}; \
5a5012ec 512static inline void gen_cmp_ ## fmt(int n, long cc) \
6ea83fed 513{ \
5a5012ec 514 cond_ ## fmt ## _table[n](cc); \
6ea83fed
FB
515}
516
517FOP_CONDS(d)
518FOP_CONDS(s)
5a5012ec 519FOP_CONDS(ps)
6ea83fed 520
6af0bf9c
FB
521typedef struct DisasContext {
522 struct TranslationBlock *tb;
523 target_ulong pc, saved_pc;
524 uint32_t opcode;
5a5012ec 525 uint32_t fp_status, saved_fp_status;
6af0bf9c
FB
526 /* Routine used to access memory */
527 int mem_idx;
528 uint32_t hflags, saved_hflags;
529 uint32_t CP0_Status;
530 int bstate;
531 target_ulong btarget;
532} DisasContext;
533
534enum {
535 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
536 * exception condition
537 */
538 BS_STOP = 1, /* We want to stop translation for any reason */
539 BS_BRANCH = 2, /* We reached a branch condition */
540 BS_EXCP = 3, /* We reached an exception condition */
541};
542
543#if defined MIPS_DEBUG_DISAS
544#define MIPS_DEBUG(fmt, args...) \
545do { \
546 if (loglevel & CPU_LOG_TB_IN_ASM) { \
3594c774 547 fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n", \
6af0bf9c
FB
548 ctx->pc, ctx->opcode , ##args); \
549 } \
550} while (0)
551#else
552#define MIPS_DEBUG(fmt, args...) do { } while(0)
553#endif
554
555#define MIPS_INVAL(op) \
556do { \
557 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
558 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
559} while (0)
560
561#define GEN_LOAD_REG_TN(Tn, Rn) \
562do { \
563 if (Rn == 0) { \
564 glue(gen_op_reset_, Tn)(); \
565 } else { \
566 glue(gen_op_load_gpr_, Tn)(Rn); \
567 } \
568} while (0)
569
570#define GEN_LOAD_IMM_TN(Tn, Imm) \
571do { \
572 if (Imm == 0) { \
573 glue(gen_op_reset_, Tn)(); \
574 } else { \
575 glue(gen_op_set_, Tn)(Imm); \
576 } \
577} while (0)
578
579#define GEN_STORE_TN_REG(Rn, Tn) \
580do { \
581 if (Rn != 0) { \
582 glue(glue(gen_op_store_, Tn),_gpr)(Rn); \
583 } \
584} while (0)
585
7a387fff 586#define GEN_LOAD_FREG_FTN(FTn, Fn) \
6ea83fed
FB
587do { \
588 glue(gen_op_load_fpr_, FTn)(Fn); \
589} while (0)
590
591#define GEN_STORE_FTN_FREG(Fn, FTn) \
592do { \
593 glue(gen_op_store_fpr_, FTn)(Fn); \
594} while (0)
595
6af0bf9c
FB
596static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
597{
598#if defined MIPS_DEBUG_DISAS
599 if (loglevel & CPU_LOG_TB_IN_ASM) {
600 fprintf(logfile, "hflags %08x saved %08x\n",
601 ctx->hflags, ctx->saved_hflags);
602 }
603#endif
604 if (do_save_pc && ctx->pc != ctx->saved_pc) {
605 gen_op_save_pc(ctx->pc);
606 ctx->saved_pc = ctx->pc;
607 }
608 if (ctx->hflags != ctx->saved_hflags) {
609 gen_op_save_state(ctx->hflags);
610 ctx->saved_hflags = ctx->hflags;
5a5012ec
TS
611 switch (ctx->hflags & MIPS_HFLAG_BMASK) {
612 case MIPS_HFLAG_BR:
6af0bf9c 613 gen_op_save_breg_target();
5a5012ec
TS
614 break;
615 case MIPS_HFLAG_BC:
6af0bf9c 616 gen_op_save_bcond();
5a5012ec
TS
617 /* fall through */
618 case MIPS_HFLAG_BL:
619 /* bcond was already saved by the BL insn */
620 /* fall through */
621 case MIPS_HFLAG_B:
6af0bf9c 622 gen_op_save_btarget(ctx->btarget);
5a5012ec 623 break;
6af0bf9c
FB
624 }
625 }
626}
627
5a5012ec
TS
628static inline void save_fpu_state (DisasContext *ctx)
629{
630 if (ctx->fp_status != ctx->saved_fp_status) {
631 gen_op_save_fp_status(ctx->fp_status);
632 ctx->saved_fp_status = ctx->fp_status;
633 }
634}
635
4ad40f36 636static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
6af0bf9c
FB
637{
638#if defined MIPS_DEBUG_DISAS
639 if (loglevel & CPU_LOG_TB_IN_ASM)
640 fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
641#endif
642 save_cpu_state(ctx, 1);
4ad40f36
FB
643 if (err == 0)
644 gen_op_raise_exception(excp);
645 else
646 gen_op_raise_exception_err(excp, err);
6af0bf9c
FB
647 ctx->bstate = BS_EXCP;
648}
649
4ad40f36
FB
650static inline void generate_exception (DisasContext *ctx, int excp)
651{
652 generate_exception_err (ctx, excp, 0);
653}
654
6af0bf9c
FB
655#if defined(CONFIG_USER_ONLY)
656#define op_ldst(name) gen_op_##name##_raw()
657#define OP_LD_TABLE(width)
658#define OP_ST_TABLE(width)
659#else
660#define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()
661#define OP_LD_TABLE(width) \
662static GenOpFunc *gen_op_l##width[] = { \
663 &gen_op_l##width##_user, \
664 &gen_op_l##width##_kernel, \
665}
666#define OP_ST_TABLE(width) \
667static GenOpFunc *gen_op_s##width[] = { \
668 &gen_op_s##width##_user, \
669 &gen_op_s##width##_kernel, \
670}
671#endif
672
60aa19ab 673#ifdef TARGET_MIPS64
6af0bf9c
FB
674OP_LD_TABLE(d);
675OP_LD_TABLE(dl);
676OP_LD_TABLE(dr);
677OP_ST_TABLE(d);
678OP_ST_TABLE(dl);
679OP_ST_TABLE(dr);
c570fd16
TS
680OP_LD_TABLE(ld);
681OP_ST_TABLE(cd);
6af0bf9c
FB
682#endif
683OP_LD_TABLE(w);
d796321b 684OP_LD_TABLE(wu);
6af0bf9c
FB
685OP_LD_TABLE(wl);
686OP_LD_TABLE(wr);
687OP_ST_TABLE(w);
688OP_ST_TABLE(wl);
689OP_ST_TABLE(wr);
690OP_LD_TABLE(h);
691OP_LD_TABLE(hu);
692OP_ST_TABLE(h);
693OP_LD_TABLE(b);
694OP_LD_TABLE(bu);
695OP_ST_TABLE(b);
696OP_LD_TABLE(l);
697OP_ST_TABLE(c);
6ea83fed
FB
698OP_LD_TABLE(wc1);
699OP_ST_TABLE(wc1);
700OP_LD_TABLE(dc1);
701OP_ST_TABLE(dc1);
5a5012ec
TS
702OP_LD_TABLE(wxc1);
703OP_ST_TABLE(wxc1);
704OP_LD_TABLE(dxc1);
705OP_ST_TABLE(dxc1);
706OP_LD_TABLE(uxc1);
707OP_ST_TABLE(uxc1);
6af0bf9c
FB
708
709/* Load and store */
7a387fff 710static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
6af0bf9c
FB
711 int base, int16_t offset)
712{
7a387fff 713 const char *opn = "unk";
6af0bf9c
FB
714
715 if (base == 0) {
716 GEN_LOAD_IMM_TN(T0, offset);
717 } else if (offset == 0) {
718 gen_op_load_gpr_T0(base);
719 } else {
720 gen_op_load_gpr_T0(base);
721 gen_op_set_T1(offset);
722 gen_op_add();
723 }
724 /* Don't do NOP if destination is zero: we must perform the actual
725 * memory access
726 */
727 switch (opc) {
60aa19ab 728#ifdef TARGET_MIPS64
6af0bf9c 729 case OPC_LD:
6af0bf9c
FB
730 op_ldst(ld);
731 GEN_STORE_TN_REG(rt, T0);
732 opn = "ld";
733 break;
7a387fff
TS
734 case OPC_LLD:
735 op_ldst(lld);
736 GEN_STORE_TN_REG(rt, T0);
737 opn = "lld";
738 break;
6af0bf9c 739 case OPC_SD:
6af0bf9c
FB
740 GEN_LOAD_REG_TN(T1, rt);
741 op_ldst(sd);
742 opn = "sd";
743 break;
7a387fff 744 case OPC_SCD:
62c5609a 745 save_cpu_state(ctx, 1);
7a387fff
TS
746 GEN_LOAD_REG_TN(T1, rt);
747 op_ldst(scd);
748 opn = "scd";
749 break;
6af0bf9c
FB
750 case OPC_LDL:
751 op_ldst(ldl);
752 GEN_STORE_TN_REG(rt, T0);
753 opn = "ldl";
754 break;
755 case OPC_SDL:
756 GEN_LOAD_REG_TN(T1, rt);
757 op_ldst(sdl);
758 opn = "sdl";
759 break;
760 case OPC_LDR:
761 op_ldst(ldr);
762 GEN_STORE_TN_REG(rt, T0);
763 opn = "ldr";
764 break;
765 case OPC_SDR:
766 GEN_LOAD_REG_TN(T1, rt);
767 op_ldst(sdr);
768 opn = "sdr";
769 break;
770#endif
771 case OPC_LW:
6af0bf9c
FB
772 op_ldst(lw);
773 GEN_STORE_TN_REG(rt, T0);
774 opn = "lw";
775 break;
d796321b
FB
776 case OPC_LWU:
777 op_ldst(lwu);
778 GEN_STORE_TN_REG(rt, T0);
779 opn = "lwu";
780 break;
6af0bf9c 781 case OPC_SW:
6af0bf9c
FB
782 GEN_LOAD_REG_TN(T1, rt);
783 op_ldst(sw);
784 opn = "sw";
785 break;
786 case OPC_LH:
6af0bf9c
FB
787 op_ldst(lh);
788 GEN_STORE_TN_REG(rt, T0);
789 opn = "lh";
790 break;
791 case OPC_SH:
6af0bf9c
FB
792 GEN_LOAD_REG_TN(T1, rt);
793 op_ldst(sh);
794 opn = "sh";
795 break;
796 case OPC_LHU:
6af0bf9c
FB
797 op_ldst(lhu);
798 GEN_STORE_TN_REG(rt, T0);
799 opn = "lhu";
800 break;
801 case OPC_LB:
802 op_ldst(lb);
803 GEN_STORE_TN_REG(rt, T0);
804 opn = "lb";
805 break;
806 case OPC_SB:
807 GEN_LOAD_REG_TN(T1, rt);
808 op_ldst(sb);
809 opn = "sb";
810 break;
811 case OPC_LBU:
812 op_ldst(lbu);
813 GEN_STORE_TN_REG(rt, T0);
814 opn = "lbu";
815 break;
816 case OPC_LWL:
9d1d106a 817 GEN_LOAD_REG_TN(T1, rt);
6af0bf9c
FB
818 op_ldst(lwl);
819 GEN_STORE_TN_REG(rt, T0);
820 opn = "lwl";
821 break;
822 case OPC_SWL:
823 GEN_LOAD_REG_TN(T1, rt);
824 op_ldst(swl);
825 opn = "swr";
826 break;
827 case OPC_LWR:
9d1d106a 828 GEN_LOAD_REG_TN(T1, rt);
6af0bf9c
FB
829 op_ldst(lwr);
830 GEN_STORE_TN_REG(rt, T0);
831 opn = "lwr";
832 break;
833 case OPC_SWR:
834 GEN_LOAD_REG_TN(T1, rt);
835 op_ldst(swr);
836 opn = "swr";
837 break;
838 case OPC_LL:
839 op_ldst(ll);
840 GEN_STORE_TN_REG(rt, T0);
841 opn = "ll";
842 break;
843 case OPC_SC:
62c5609a 844 save_cpu_state(ctx, 1);
6af0bf9c
FB
845 GEN_LOAD_REG_TN(T1, rt);
846 op_ldst(sc);
847 GEN_STORE_TN_REG(rt, T0);
848 opn = "sc";
849 break;
850 default:
851 MIPS_INVAL("load/store");
852 generate_exception(ctx, EXCP_RI);
853 return;
854 }
855 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
856}
857
6ea83fed 858/* Load and store */
7a387fff 859static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
6ea83fed
FB
860 int base, int16_t offset)
861{
7a387fff 862 const char *opn = "unk";
6ea83fed
FB
863
864 if (base == 0) {
865 GEN_LOAD_IMM_TN(T0, offset);
866 } else if (offset == 0) {
867 gen_op_load_gpr_T0(base);
868 } else {
869 gen_op_load_gpr_T0(base);
870 gen_op_set_T1(offset);
871 gen_op_add();
872 }
873 /* Don't do NOP if destination is zero: we must perform the actual
874 * memory access
875 */
876 switch (opc) {
877 case OPC_LWC1:
878 op_ldst(lwc1);
879 GEN_STORE_FTN_FREG(ft, WT0);
880 opn = "lwc1";
881 break;
882 case OPC_SWC1:
883 GEN_LOAD_FREG_FTN(WT0, ft);
884 op_ldst(swc1);
885 opn = "swc1";
886 break;
887 case OPC_LDC1:
888 op_ldst(ldc1);
889 GEN_STORE_FTN_FREG(ft, DT0);
890 opn = "ldc1";
891 break;
892 case OPC_SDC1:
893 GEN_LOAD_FREG_FTN(DT0, ft);
894 op_ldst(sdc1);
895 opn = "sdc1";
896 break;
897 default:
898 MIPS_INVAL("float load/store");
e397ee33 899 generate_exception(ctx, EXCP_RI);
6ea83fed
FB
900 return;
901 }
902 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
903}
6ea83fed 904
6af0bf9c 905/* Arithmetic with immediate operand */
7a387fff 906static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
6af0bf9c
FB
907 int rs, int16_t imm)
908{
909 uint32_t uimm;
7a387fff 910 const char *opn = "unk";
6af0bf9c 911
7a387fff 912 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
6af0bf9c
FB
913 /* if no destination, treat it as a NOP
914 * For addi, we must generate the overflow exception when needed.
915 */
916 MIPS_DEBUG("NOP");
917 return;
918 }
5a63bcb2
TS
919 uimm = (uint16_t)imm;
920 switch (opc) {
921 case OPC_ADDI:
922 case OPC_ADDIU:
923#ifdef TARGET_MIPS64
924 case OPC_DADDI:
925 case OPC_DADDIU:
926#endif
927 case OPC_SLTI:
928 case OPC_SLTIU:
7a387fff 929 uimm = (int32_t)imm; /* Sign extend to 32 bits */
5a63bcb2
TS
930 /* Fall through. */
931 case OPC_ANDI:
932 case OPC_ORI:
933 case OPC_XORI:
6af0bf9c
FB
934 GEN_LOAD_REG_TN(T0, rs);
935 GEN_LOAD_IMM_TN(T1, uimm);
5a63bcb2
TS
936 break;
937 case OPC_LUI:
d6929309 938 GEN_LOAD_IMM_TN(T0, uimm << 16);
5a63bcb2
TS
939 break;
940 case OPC_SLL:
941 case OPC_SRA:
942 case OPC_SRL:
943#ifdef TARGET_MIPS64
944 case OPC_DSLL:
945 case OPC_DSRA:
946 case OPC_DSRL:
947 case OPC_DSLL32:
948 case OPC_DSRA32:
949 case OPC_DSRL32:
950#endif
951 uimm &= 0x1f;
952 GEN_LOAD_REG_TN(T0, rs);
953 GEN_LOAD_IMM_TN(T1, uimm);
954 break;
6af0bf9c
FB
955 }
956 switch (opc) {
957 case OPC_ADDI:
958 save_cpu_state(ctx, 1);
959 gen_op_addo();
960 opn = "addi";
961 break;
962 case OPC_ADDIU:
963 gen_op_add();
964 opn = "addiu";
965 break;
60aa19ab 966#ifdef TARGET_MIPS64
7a387fff
TS
967 case OPC_DADDI:
968 save_cpu_state(ctx, 1);
969 gen_op_daddo();
970 opn = "daddi";
971 break;
972 case OPC_DADDIU:
973 gen_op_dadd();
974 opn = "daddiu";
975 break;
976#endif
6af0bf9c
FB
977 case OPC_SLTI:
978 gen_op_lt();
979 opn = "slti";
980 break;
981 case OPC_SLTIU:
982 gen_op_ltu();
983 opn = "sltiu";
984 break;
985 case OPC_ANDI:
986 gen_op_and();
987 opn = "andi";
988 break;
989 case OPC_ORI:
990 gen_op_or();
991 opn = "ori";
992 break;
993 case OPC_XORI:
994 gen_op_xor();
995 opn = "xori";
996 break;
997 case OPC_LUI:
998 opn = "lui";
999 break;
1000 case OPC_SLL:
1001 gen_op_sll();
1002 opn = "sll";
1003 break;
1004 case OPC_SRA:
1005 gen_op_sra();
1006 opn = "sra";
1007 break;
1008 case OPC_SRL:
5a63bcb2
TS
1009 switch ((ctx->opcode >> 21) & 0x1f) {
1010 case 0:
7a387fff
TS
1011 gen_op_srl();
1012 opn = "srl";
5a63bcb2
TS
1013 break;
1014 case 1:
1015 gen_op_rotr();
1016 opn = "rotr";
1017 break;
1018 default:
1019 MIPS_INVAL("invalid srl flag");
1020 generate_exception(ctx, EXCP_RI);
1021 break;
1022 }
7a387fff 1023 break;
60aa19ab 1024#ifdef TARGET_MIPS64
7a387fff
TS
1025 case OPC_DSLL:
1026 gen_op_dsll();
1027 opn = "dsll";
1028 break;
1029 case OPC_DSRA:
1030 gen_op_dsra();
1031 opn = "dsra";
1032 break;
1033 case OPC_DSRL:
5a63bcb2
TS
1034 switch ((ctx->opcode >> 21) & 0x1f) {
1035 case 0:
7a387fff
TS
1036 gen_op_dsrl();
1037 opn = "dsrl";
5a63bcb2
TS
1038 break;
1039 case 1:
1040 gen_op_drotr();
1041 opn = "drotr";
1042 break;
1043 default:
1044 MIPS_INVAL("invalid dsrl flag");
1045 generate_exception(ctx, EXCP_RI);
1046 break;
1047 }
7a387fff
TS
1048 break;
1049 case OPC_DSLL32:
1050 gen_op_dsll32();
1051 opn = "dsll32";
1052 break;
1053 case OPC_DSRA32:
1054 gen_op_dsra32();
1055 opn = "dsra32";
1056 break;
1057 case OPC_DSRL32:
5a63bcb2
TS
1058 switch ((ctx->opcode >> 21) & 0x1f) {
1059 case 0:
7a387fff
TS
1060 gen_op_dsrl32();
1061 opn = "dsrl32";
5a63bcb2
TS
1062 break;
1063 case 1:
1064 gen_op_drotr32();
1065 opn = "drotr32";
1066 break;
1067 default:
1068 MIPS_INVAL("invalid dsrl32 flag");
1069 generate_exception(ctx, EXCP_RI);
1070 break;
1071 }
6af0bf9c 1072 break;
7a387fff 1073#endif
6af0bf9c
FB
1074 default:
1075 MIPS_INVAL("imm arith");
1076 generate_exception(ctx, EXCP_RI);
1077 return;
1078 }
1079 GEN_STORE_TN_REG(rt, T0);
1080 MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
1081}
1082
1083/* Arithmetic */
7a387fff 1084static void gen_arith (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
1085 int rd, int rs, int rt)
1086{
7a387fff 1087 const char *opn = "unk";
6af0bf9c 1088
7a387fff
TS
1089 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1090 && opc != OPC_DADD && opc != OPC_DSUB) {
6af0bf9c
FB
1091 /* if no destination, treat it as a NOP
1092 * For add & sub, we must generate the overflow exception when needed.
1093 */
1094 MIPS_DEBUG("NOP");
1095 return;
1096 }
1097 GEN_LOAD_REG_TN(T0, rs);
1098 GEN_LOAD_REG_TN(T1, rt);
1099 switch (opc) {
1100 case OPC_ADD:
1101 save_cpu_state(ctx, 1);
1102 gen_op_addo();
1103 opn = "add";
1104 break;
1105 case OPC_ADDU:
1106 gen_op_add();
1107 opn = "addu";
1108 break;
1109 case OPC_SUB:
1110 save_cpu_state(ctx, 1);
1111 gen_op_subo();
1112 opn = "sub";
1113 break;
1114 case OPC_SUBU:
1115 gen_op_sub();
1116 opn = "subu";
1117 break;
60aa19ab 1118#ifdef TARGET_MIPS64
7a387fff
TS
1119 case OPC_DADD:
1120 save_cpu_state(ctx, 1);
1121 gen_op_daddo();
1122 opn = "dadd";
1123 break;
1124 case OPC_DADDU:
1125 gen_op_dadd();
1126 opn = "daddu";
1127 break;
1128 case OPC_DSUB:
1129 save_cpu_state(ctx, 1);
1130 gen_op_dsubo();
1131 opn = "dsub";
1132 break;
1133 case OPC_DSUBU:
1134 gen_op_dsub();
1135 opn = "dsubu";
1136 break;
1137#endif
6af0bf9c
FB
1138 case OPC_SLT:
1139 gen_op_lt();
1140 opn = "slt";
1141 break;
1142 case OPC_SLTU:
1143 gen_op_ltu();
1144 opn = "sltu";
1145 break;
1146 case OPC_AND:
1147 gen_op_and();
1148 opn = "and";
1149 break;
1150 case OPC_NOR:
1151 gen_op_nor();
1152 opn = "nor";
1153 break;
1154 case OPC_OR:
1155 gen_op_or();
1156 opn = "or";
1157 break;
1158 case OPC_XOR:
1159 gen_op_xor();
1160 opn = "xor";
1161 break;
1162 case OPC_MUL:
1163 gen_op_mul();
1164 opn = "mul";
1165 break;
1166 case OPC_MOVN:
1167 gen_op_movn(rd);
1168 opn = "movn";
1169 goto print;
1170 case OPC_MOVZ:
1171 gen_op_movz(rd);
1172 opn = "movz";
1173 goto print;
1174 case OPC_SLLV:
1175 gen_op_sllv();
1176 opn = "sllv";
1177 break;
1178 case OPC_SRAV:
1179 gen_op_srav();
1180 opn = "srav";
1181 break;
1182 case OPC_SRLV:
5a63bcb2
TS
1183 switch ((ctx->opcode >> 6) & 0x1f) {
1184 case 0:
7a387fff
TS
1185 gen_op_srlv();
1186 opn = "srlv";
5a63bcb2
TS
1187 break;
1188 case 1:
1189 gen_op_rotrv();
1190 opn = "rotrv";
1191 break;
1192 default:
1193 MIPS_INVAL("invalid srlv flag");
1194 generate_exception(ctx, EXCP_RI);
1195 break;
1196 }
7a387fff 1197 break;
60aa19ab 1198#ifdef TARGET_MIPS64
7a387fff
TS
1199 case OPC_DSLLV:
1200 gen_op_dsllv();
1201 opn = "dsllv";
1202 break;
1203 case OPC_DSRAV:
1204 gen_op_dsrav();
1205 opn = "dsrav";
1206 break;
1207 case OPC_DSRLV:
5a63bcb2
TS
1208 switch ((ctx->opcode >> 6) & 0x1f) {
1209 case 0:
7a387fff
TS
1210 gen_op_dsrlv();
1211 opn = "dsrlv";
5a63bcb2
TS
1212 break;
1213 case 1:
1214 gen_op_drotrv();
1215 opn = "drotrv";
1216 break;
1217 default:
1218 MIPS_INVAL("invalid dsrlv flag");
1219 generate_exception(ctx, EXCP_RI);
1220 break;
1221 }
6af0bf9c 1222 break;
7a387fff 1223#endif
6af0bf9c
FB
1224 default:
1225 MIPS_INVAL("arith");
1226 generate_exception(ctx, EXCP_RI);
1227 return;
1228 }
1229 GEN_STORE_TN_REG(rd, T0);
1230 print:
1231 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1232}
1233
1234/* Arithmetic on HI/LO registers */
7a387fff 1235static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
6af0bf9c 1236{
7a387fff 1237 const char *opn = "unk";
6af0bf9c
FB
1238
1239 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1240 /* Treat as a NOP */
1241 MIPS_DEBUG("NOP");
1242 return;
1243 }
1244 switch (opc) {
1245 case OPC_MFHI:
1246 gen_op_load_HI();
1247 GEN_STORE_TN_REG(reg, T0);
1248 opn = "mfhi";
1249 break;
1250 case OPC_MFLO:
1251 gen_op_load_LO();
1252 GEN_STORE_TN_REG(reg, T0);
1253 opn = "mflo";
1254 break;
1255 case OPC_MTHI:
1256 GEN_LOAD_REG_TN(T0, reg);
1257 gen_op_store_HI();
1258 opn = "mthi";
1259 break;
1260 case OPC_MTLO:
1261 GEN_LOAD_REG_TN(T0, reg);
1262 gen_op_store_LO();
1263 opn = "mtlo";
1264 break;
1265 default:
1266 MIPS_INVAL("HILO");
1267 generate_exception(ctx, EXCP_RI);
1268 return;
1269 }
1270 MIPS_DEBUG("%s %s", opn, regnames[reg]);
1271}
1272
7a387fff 1273static void gen_muldiv (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
1274 int rs, int rt)
1275{
7a387fff 1276 const char *opn = "unk";
6af0bf9c
FB
1277
1278 GEN_LOAD_REG_TN(T0, rs);
1279 GEN_LOAD_REG_TN(T1, rt);
1280 switch (opc) {
1281 case OPC_DIV:
1282 gen_op_div();
1283 opn = "div";
1284 break;
1285 case OPC_DIVU:
1286 gen_op_divu();
1287 opn = "divu";
1288 break;
1289 case OPC_MULT:
1290 gen_op_mult();
1291 opn = "mult";
1292 break;
1293 case OPC_MULTU:
1294 gen_op_multu();
1295 opn = "multu";
1296 break;
60aa19ab 1297#ifdef TARGET_MIPS64
7a387fff
TS
1298 case OPC_DDIV:
1299 gen_op_ddiv();
1300 opn = "ddiv";
1301 break;
1302 case OPC_DDIVU:
1303 gen_op_ddivu();
1304 opn = "ddivu";
1305 break;
1306 case OPC_DMULT:
1307 gen_op_dmult();
1308 opn = "dmult";
1309 break;
1310 case OPC_DMULTU:
1311 gen_op_dmultu();
1312 opn = "dmultu";
1313 break;
1314#endif
6af0bf9c
FB
1315 case OPC_MADD:
1316 gen_op_madd();
1317 opn = "madd";
1318 break;
1319 case OPC_MADDU:
1320 gen_op_maddu();
1321 opn = "maddu";
1322 break;
1323 case OPC_MSUB:
1324 gen_op_msub();
1325 opn = "msub";
1326 break;
1327 case OPC_MSUBU:
1328 gen_op_msubu();
1329 opn = "msubu";
1330 break;
1331 default:
1332 MIPS_INVAL("mul/div");
1333 generate_exception(ctx, EXCP_RI);
1334 return;
1335 }
1336 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1337}
1338
7a387fff 1339static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
1340 int rd, int rs)
1341{
7a387fff 1342 const char *opn = "unk";
6af0bf9c
FB
1343 if (rd == 0) {
1344 /* Treat as a NOP */
1345 MIPS_DEBUG("NOP");
1346 return;
1347 }
1348 GEN_LOAD_REG_TN(T0, rs);
1349 switch (opc) {
1350 case OPC_CLO:
6af0bf9c
FB
1351 gen_op_clo();
1352 opn = "clo";
1353 break;
1354 case OPC_CLZ:
6af0bf9c
FB
1355 gen_op_clz();
1356 opn = "clz";
1357 break;
60aa19ab 1358#ifdef TARGET_MIPS64
7a387fff
TS
1359 case OPC_DCLO:
1360 gen_op_dclo();
1361 opn = "dclo";
1362 break;
1363 case OPC_DCLZ:
1364 gen_op_dclz();
1365 opn = "dclz";
1366 break;
1367#endif
6af0bf9c
FB
1368 default:
1369 MIPS_INVAL("CLx");
1370 generate_exception(ctx, EXCP_RI);
1371 return;
1372 }
1373 gen_op_store_T0_gpr(rd);
1374 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1375}
1376
1377/* Traps */
7a387fff 1378static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
1379 int rs, int rt, int16_t imm)
1380{
1381 int cond;
1382
1383 cond = 0;
1384 /* Load needed operands */
1385 switch (opc) {
1386 case OPC_TEQ:
1387 case OPC_TGE:
1388 case OPC_TGEU:
1389 case OPC_TLT:
1390 case OPC_TLTU:
1391 case OPC_TNE:
1392 /* Compare two registers */
1393 if (rs != rt) {
1394 GEN_LOAD_REG_TN(T0, rs);
1395 GEN_LOAD_REG_TN(T1, rt);
1396 cond = 1;
1397 }
179e32bb 1398 break;
6af0bf9c
FB
1399 case OPC_TEQI:
1400 case OPC_TGEI:
1401 case OPC_TGEIU:
1402 case OPC_TLTI:
1403 case OPC_TLTIU:
1404 case OPC_TNEI:
1405 /* Compare register to immediate */
1406 if (rs != 0 || imm != 0) {
1407 GEN_LOAD_REG_TN(T0, rs);
1408 GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1409 cond = 1;
1410 }
1411 break;
1412 }
1413 if (cond == 0) {
1414 switch (opc) {
1415 case OPC_TEQ: /* rs == rs */
1416 case OPC_TEQI: /* r0 == 0 */
1417 case OPC_TGE: /* rs >= rs */
1418 case OPC_TGEI: /* r0 >= 0 */
1419 case OPC_TGEU: /* rs >= rs unsigned */
1420 case OPC_TGEIU: /* r0 >= 0 unsigned */
1421 /* Always trap */
1422 gen_op_set_T0(1);
1423 break;
1424 case OPC_TLT: /* rs < rs */
1425 case OPC_TLTI: /* r0 < 0 */
1426 case OPC_TLTU: /* rs < rs unsigned */
1427 case OPC_TLTIU: /* r0 < 0 unsigned */
1428 case OPC_TNE: /* rs != rs */
1429 case OPC_TNEI: /* r0 != 0 */
1430 /* Never trap: treat as NOP */
1431 return;
1432 default:
1433 MIPS_INVAL("TRAP");
1434 generate_exception(ctx, EXCP_RI);
1435 return;
1436 }
1437 } else {
1438 switch (opc) {
1439 case OPC_TEQ:
1440 case OPC_TEQI:
1441 gen_op_eq();
1442 break;
1443 case OPC_TGE:
1444 case OPC_TGEI:
1445 gen_op_ge();
1446 break;
1447 case OPC_TGEU:
1448 case OPC_TGEIU:
1449 gen_op_geu();
1450 break;
1451 case OPC_TLT:
1452 case OPC_TLTI:
1453 gen_op_lt();
1454 break;
1455 case OPC_TLTU:
1456 case OPC_TLTIU:
1457 gen_op_ltu();
1458 break;
1459 case OPC_TNE:
1460 case OPC_TNEI:
1461 gen_op_ne();
1462 break;
1463 default:
1464 MIPS_INVAL("TRAP");
1465 generate_exception(ctx, EXCP_RI);
1466 return;
1467 }
1468 }
1469 save_cpu_state(ctx, 1);
1470 gen_op_trap();
1471 ctx->bstate = BS_STOP;
1472}
1473
6e256c93 1474static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 1475{
6e256c93
FB
1476 TranslationBlock *tb;
1477 tb = ctx->tb;
1478 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1479 if (n == 0)
1480 gen_op_goto_tb0(TBPARAM(tb));
1481 else
1482 gen_op_goto_tb1(TBPARAM(tb));
1483 gen_op_save_pc(dest);
1484 gen_op_set_T0((long)tb + n);
6e256c93
FB
1485 } else {
1486 gen_op_save_pc(dest);
9898128f 1487 gen_op_reset_T0();
6e256c93 1488 }
9898128f 1489 gen_op_exit_tb();
c53be334
FB
1490}
1491
6af0bf9c 1492/* Branches (before delay slot) */
7a387fff 1493static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
1494 int rs, int rt, int32_t offset)
1495{
3ad4bb2d
TS
1496 target_ulong btarget = -1;
1497 int blink = 0;
1498 int bcond = 0;
1499
1500 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1501 if (loglevel & CPU_LOG_TB_IN_ASM) {
1502 fprintf(logfile,
5a5012ec 1503 "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
38121543 1504 ctx->pc);
3ad4bb2d
TS
1505 }
1506 MIPS_INVAL("branch/jump in bdelay slot");
1507 generate_exception(ctx, EXCP_RI);
1508 return;
1509 }
6af0bf9c 1510
6af0bf9c
FB
1511 /* Load needed operands */
1512 switch (opc) {
1513 case OPC_BEQ:
1514 case OPC_BEQL:
1515 case OPC_BNE:
1516 case OPC_BNEL:
1517 /* Compare two registers */
1518 if (rs != rt) {
1519 GEN_LOAD_REG_TN(T0, rs);
1520 GEN_LOAD_REG_TN(T1, rt);
1521 bcond = 1;
1522 }
1523 btarget = ctx->pc + 4 + offset;
1524 break;
1525 case OPC_BGEZ:
1526 case OPC_BGEZAL:
1527 case OPC_BGEZALL:
1528 case OPC_BGEZL:
1529 case OPC_BGTZ:
1530 case OPC_BGTZL:
1531 case OPC_BLEZ:
1532 case OPC_BLEZL:
1533 case OPC_BLTZ:
1534 case OPC_BLTZAL:
1535 case OPC_BLTZALL:
1536 case OPC_BLTZL:
1537 /* Compare to zero */
1538 if (rs != 0) {
1539 gen_op_load_gpr_T0(rs);
1540 bcond = 1;
1541 }
1542 btarget = ctx->pc + 4 + offset;
1543 break;
1544 case OPC_J:
1545 case OPC_JAL:
1546 /* Jump to immediate */
5dc4b744 1547 btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset;
6af0bf9c
FB
1548 break;
1549 case OPC_JR:
1550 case OPC_JALR:
1551 /* Jump to register */
7a387fff
TS
1552 if (offset != 0 && offset != 16) {
1553 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 1554 others are reserved. */
6af0bf9c
FB
1555 generate_exception(ctx, EXCP_RI);
1556 return;
1557 }
1558 GEN_LOAD_REG_TN(T2, rs);
1559 break;
1560 default:
1561 MIPS_INVAL("branch/jump");
1562 generate_exception(ctx, EXCP_RI);
1563 return;
1564 }
1565 if (bcond == 0) {
1566 /* No condition to be computed */
1567 switch (opc) {
1568 case OPC_BEQ: /* rx == rx */
1569 case OPC_BEQL: /* rx == rx likely */
1570 case OPC_BGEZ: /* 0 >= 0 */
1571 case OPC_BGEZL: /* 0 >= 0 likely */
1572 case OPC_BLEZ: /* 0 <= 0 */
1573 case OPC_BLEZL: /* 0 <= 0 likely */
1574 /* Always take */
4ad40f36 1575 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
1576 MIPS_DEBUG("balways");
1577 break;
1578 case OPC_BGEZAL: /* 0 >= 0 */
1579 case OPC_BGEZALL: /* 0 >= 0 likely */
1580 /* Always take and link */
1581 blink = 31;
4ad40f36 1582 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
1583 MIPS_DEBUG("balways and link");
1584 break;
1585 case OPC_BNE: /* rx != rx */
1586 case OPC_BGTZ: /* 0 > 0 */
1587 case OPC_BLTZ: /* 0 < 0 */
6af0bf9c
FB
1588 /* Treated as NOP */
1589 MIPS_DEBUG("bnever (NOP)");
1590 return;
eeef26cd
FB
1591 case OPC_BLTZAL: /* 0 < 0 */
1592 gen_op_set_T0(ctx->pc + 8);
1593 gen_op_store_T0_gpr(31);
9898128f 1594 MIPS_DEBUG("bnever and link");
eeef26cd
FB
1595 return;
1596 case OPC_BLTZALL: /* 0 < 0 likely */
1597 gen_op_set_T0(ctx->pc + 8);
1598 gen_op_store_T0_gpr(31);
9898128f
TS
1599 /* Skip the instruction in the delay slot */
1600 MIPS_DEBUG("bnever, link and skip");
1601 ctx->pc += 4;
eeef26cd 1602 return;
6af0bf9c
FB
1603 case OPC_BNEL: /* rx != rx likely */
1604 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
1605 case OPC_BLTZL: /* 0 < 0 likely */
1606 /* Skip the instruction in the delay slot */
1607 MIPS_DEBUG("bnever and skip");
9898128f 1608 ctx->pc += 4;
6af0bf9c
FB
1609 return;
1610 case OPC_J:
4ad40f36 1611 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
1612 MIPS_DEBUG("j %08x", btarget);
1613 break;
1614 case OPC_JAL:
1615 blink = 31;
4ad40f36 1616 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
1617 MIPS_DEBUG("jal %08x", btarget);
1618 break;
1619 case OPC_JR:
4ad40f36 1620 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
1621 MIPS_DEBUG("jr %s", regnames[rs]);
1622 break;
1623 case OPC_JALR:
1624 blink = rt;
4ad40f36 1625 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
1626 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1627 break;
1628 default:
1629 MIPS_INVAL("branch/jump");
1630 generate_exception(ctx, EXCP_RI);
1631 return;
1632 }
1633 } else {
1634 switch (opc) {
1635 case OPC_BEQ:
1636 gen_op_eq();
1637 MIPS_DEBUG("beq %s, %s, %08x",
1638 regnames[rs], regnames[rt], btarget);
1639 goto not_likely;
1640 case OPC_BEQL:
1641 gen_op_eq();
1642 MIPS_DEBUG("beql %s, %s, %08x",
1643 regnames[rs], regnames[rt], btarget);
1644 goto likely;
1645 case OPC_BNE:
1646 gen_op_ne();
1647 MIPS_DEBUG("bne %s, %s, %08x",
1648 regnames[rs], regnames[rt], btarget);
1649 goto not_likely;
1650 case OPC_BNEL:
1651 gen_op_ne();
1652 MIPS_DEBUG("bnel %s, %s, %08x",
1653 regnames[rs], regnames[rt], btarget);
1654 goto likely;
1655 case OPC_BGEZ:
1656 gen_op_gez();
1657 MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget);
1658 goto not_likely;
1659 case OPC_BGEZL:
1660 gen_op_gez();
1661 MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget);
1662 goto likely;
1663 case OPC_BGEZAL:
1664 gen_op_gez();
1665 MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget);
1666 blink = 31;
1667 goto not_likely;
1668 case OPC_BGEZALL:
1669 gen_op_gez();
1670 blink = 31;
1671 MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget);
1672 goto likely;
1673 case OPC_BGTZ:
1674 gen_op_gtz();
1675 MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget);
1676 goto not_likely;
1677 case OPC_BGTZL:
1678 gen_op_gtz();
1679 MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget);
1680 goto likely;
1681 case OPC_BLEZ:
1682 gen_op_lez();
1683 MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget);
1684 goto not_likely;
1685 case OPC_BLEZL:
1686 gen_op_lez();
1687 MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget);
1688 goto likely;
1689 case OPC_BLTZ:
1690 gen_op_ltz();
1691 MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget);
1692 goto not_likely;
1693 case OPC_BLTZL:
1694 gen_op_ltz();
1695 MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget);
1696 goto likely;
1697 case OPC_BLTZAL:
1698 gen_op_ltz();
1699 blink = 31;
1700 MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
1701 not_likely:
4ad40f36 1702 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec 1703 gen_op_set_bcond();
6af0bf9c
FB
1704 break;
1705 case OPC_BLTZALL:
1706 gen_op_ltz();
1707 blink = 31;
1708 MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
1709 likely:
4ad40f36 1710 ctx->hflags |= MIPS_HFLAG_BL;
5a5012ec
TS
1711 gen_op_set_bcond();
1712 gen_op_save_bcond();
6af0bf9c 1713 break;
c53f4a62
TS
1714 default:
1715 MIPS_INVAL("conditional branch/jump");
1716 generate_exception(ctx, EXCP_RI);
1717 return;
6af0bf9c 1718 }
6af0bf9c
FB
1719 }
1720 MIPS_DEBUG("enter ds: link %d cond %02x target %08x",
1721 blink, ctx->hflags, btarget);
1722 ctx->btarget = btarget;
1723 if (blink > 0) {
1724 gen_op_set_T0(ctx->pc + 8);
1725 gen_op_store_T0_gpr(blink);
1726 }
6af0bf9c
FB
1727}
1728
7a387fff
TS
1729/* special3 bitfield operations */
1730static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1731 int rs, int lsb, int msb)
1732{
1733 GEN_LOAD_REG_TN(T1, rs);
1734 switch (opc) {
1735 case OPC_EXT:
1736 if (lsb + msb > 31)
1737 goto fail;
1738 gen_op_ext(lsb, msb + 1);
1739 break;
1740 case OPC_DEXTM:
1741 if (lsb + msb > 63)
1742 goto fail;
1743 gen_op_ext(lsb, msb + 1 + 32);
1744 break;
1745 case OPC_DEXTU:
1746 if (lsb + msb > 63)
1747 goto fail;
1748 gen_op_ext(lsb + 32, msb + 1);
1749 break;
1750 case OPC_DEXT:
1751 gen_op_ext(lsb, msb + 1);
1752 break;
1753 case OPC_INS:
1754 if (lsb > msb)
1755 goto fail;
171b31e7 1756 GEN_LOAD_REG_TN(T0, rt);
7a387fff
TS
1757 gen_op_ins(lsb, msb - lsb + 1);
1758 break;
1759 case OPC_DINSM:
1760 if (lsb > msb)
1761 goto fail;
171b31e7 1762 GEN_LOAD_REG_TN(T0, rt);
7a387fff
TS
1763 gen_op_ins(lsb, msb - lsb + 1 + 32);
1764 break;
1765 case OPC_DINSU:
1766 if (lsb > msb)
1767 goto fail;
171b31e7 1768 GEN_LOAD_REG_TN(T0, rt);
7a387fff
TS
1769 gen_op_ins(lsb + 32, msb - lsb + 1);
1770 break;
1771 case OPC_DINS:
1772 if (lsb > msb)
1773 goto fail;
171b31e7 1774 GEN_LOAD_REG_TN(T0, rt);
7a387fff
TS
1775 gen_op_ins(lsb, msb - lsb + 1);
1776 break;
1777 default:
1778fail:
1779 MIPS_INVAL("bitops");
1780 generate_exception(ctx, EXCP_RI);
1781 return;
1782 }
1783 GEN_STORE_TN_REG(rt, T0);
1784}
1785
6af0bf9c 1786/* CP0 (MMU and control) */
873eb012
TS
1787static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1788{
7a387fff 1789 const char *rn = "invalid";
873eb012 1790
873eb012
TS
1791 switch (reg) {
1792 case 0:
7a387fff
TS
1793 switch (sel) {
1794 case 0:
2423f660 1795 gen_op_mfc0_index();
7a387fff
TS
1796 rn = "Index";
1797 break;
1798 case 1:
2423f660 1799// gen_op_mfc0_mvpcontrol(); /* MT ASE */
7a387fff 1800 rn = "MVPControl";
2423f660 1801// break;
7a387fff 1802 case 2:
2423f660 1803// gen_op_mfc0_mvpconf0(); /* MT ASE */
7a387fff 1804 rn = "MVPConf0";
2423f660 1805// break;
7a387fff 1806 case 3:
2423f660 1807// gen_op_mfc0_mvpconf1(); /* MT ASE */
7a387fff 1808 rn = "MVPConf1";
2423f660 1809// break;
7a387fff
TS
1810 default:
1811 goto die;
1812 }
873eb012
TS
1813 break;
1814 case 1:
7a387fff
TS
1815 switch (sel) {
1816 case 0:
1817 gen_op_mfc0_random();
1818 rn = "Random";
2423f660 1819 break;
7a387fff 1820 case 1:
2423f660 1821// gen_op_mfc0_vpecontrol(); /* MT ASE */
7a387fff 1822 rn = "VPEControl";
2423f660 1823// break;
7a387fff 1824 case 2:
2423f660 1825// gen_op_mfc0_vpeconf0(); /* MT ASE */
7a387fff 1826 rn = "VPEConf0";
2423f660 1827// break;
7a387fff 1828 case 3:
2423f660 1829// gen_op_mfc0_vpeconf1(); /* MT ASE */
7a387fff 1830 rn = "VPEConf1";
2423f660 1831// break;
7a387fff 1832 case 4:
2423f660 1833// gen_op_mfc0_YQMask(); /* MT ASE */
7a387fff 1834 rn = "YQMask";
2423f660 1835// break;
7a387fff 1836 case 5:
2423f660 1837// gen_op_mfc0_vpeschedule(); /* MT ASE */
7a387fff 1838 rn = "VPESchedule";
2423f660 1839// break;
7a387fff 1840 case 6:
2423f660 1841// gen_op_mfc0_vpeschefback(); /* MT ASE */
7a387fff 1842 rn = "VPEScheFBack";
2423f660 1843// break;
7a387fff 1844 case 7:
2423f660 1845// gen_op_mfc0_vpeopt(); /* MT ASE */
7a387fff 1846 rn = "VPEOpt";
2423f660 1847// break;
7a387fff
TS
1848 default:
1849 goto die;
1850 }
873eb012
TS
1851 break;
1852 case 2:
7a387fff
TS
1853 switch (sel) {
1854 case 0:
2423f660
TS
1855 gen_op_mfc0_entrylo0();
1856 rn = "EntryLo0";
1857 break;
7a387fff 1858 case 1:
2423f660
TS
1859// gen_op_mfc0_tcstatus(); /* MT ASE */
1860 rn = "TCStatus";
1861// break;
7a387fff 1862 case 2:
2423f660
TS
1863// gen_op_mfc0_tcbind(); /* MT ASE */
1864 rn = "TCBind";
1865// break;
7a387fff 1866 case 3:
2423f660
TS
1867// gen_op_mfc0_tcrestart(); /* MT ASE */
1868 rn = "TCRestart";
1869// break;
7a387fff 1870 case 4:
2423f660
TS
1871// gen_op_mfc0_tchalt(); /* MT ASE */
1872 rn = "TCHalt";
1873// break;
7a387fff 1874 case 5:
2423f660
TS
1875// gen_op_mfc0_tccontext(); /* MT ASE */
1876 rn = "TCContext";
1877// break;
7a387fff 1878 case 6:
2423f660
TS
1879// gen_op_mfc0_tcschedule(); /* MT ASE */
1880 rn = "TCSchedule";
1881// break;
7a387fff 1882 case 7:
2423f660
TS
1883// gen_op_mfc0_tcschefback(); /* MT ASE */
1884 rn = "TCScheFBack";
1885// break;
7a387fff
TS
1886 default:
1887 goto die;
1888 }
873eb012
TS
1889 break;
1890 case 3:
7a387fff
TS
1891 switch (sel) {
1892 case 0:
2423f660
TS
1893 gen_op_mfc0_entrylo1();
1894 rn = "EntryLo1";
1895 break;
7a387fff
TS
1896 default:
1897 goto die;
1579a72e 1898 }
873eb012
TS
1899 break;
1900 case 4:
7a387fff
TS
1901 switch (sel) {
1902 case 0:
2423f660
TS
1903 gen_op_mfc0_context();
1904 rn = "Context";
1905 break;
7a387fff 1906 case 1:
2423f660
TS
1907// gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
1908 rn = "ContextConfig";
1909// break;
7a387fff
TS
1910 default:
1911 goto die;
1579a72e 1912 }
873eb012
TS
1913 break;
1914 case 5:
7a387fff
TS
1915 switch (sel) {
1916 case 0:
2423f660
TS
1917 gen_op_mfc0_pagemask();
1918 rn = "PageMask";
1919 break;
7a387fff 1920 case 1:
2423f660
TS
1921 gen_op_mfc0_pagegrain();
1922 rn = "PageGrain";
1923 break;
7a387fff
TS
1924 default:
1925 goto die;
1579a72e 1926 }
873eb012
TS
1927 break;
1928 case 6:
7a387fff
TS
1929 switch (sel) {
1930 case 0:
2423f660
TS
1931 gen_op_mfc0_wired();
1932 rn = "Wired";
1933 break;
7a387fff 1934 case 1:
2423f660
TS
1935// gen_op_mfc0_srsconf0(); /* shadow registers */
1936 rn = "SRSConf0";
1937// break;
7a387fff 1938 case 2:
2423f660
TS
1939// gen_op_mfc0_srsconf1(); /* shadow registers */
1940 rn = "SRSConf1";
1941// break;
7a387fff 1942 case 3:
2423f660
TS
1943// gen_op_mfc0_srsconf2(); /* shadow registers */
1944 rn = "SRSConf2";
1945// break;
7a387fff 1946 case 4:
2423f660
TS
1947// gen_op_mfc0_srsconf3(); /* shadow registers */
1948 rn = "SRSConf3";
1949// break;
7a387fff 1950 case 5:
2423f660
TS
1951// gen_op_mfc0_srsconf4(); /* shadow registers */
1952 rn = "SRSConf4";
1953// break;
7a387fff
TS
1954 default:
1955 goto die;
1579a72e 1956 }
873eb012 1957 break;
8c0fdd85 1958 case 7:
7a387fff
TS
1959 switch (sel) {
1960 case 0:
2423f660
TS
1961 gen_op_mfc0_hwrena();
1962 rn = "HWREna";
1963 break;
7a387fff
TS
1964 default:
1965 goto die;
1579a72e 1966 }
8c0fdd85 1967 break;
873eb012 1968 case 8:
7a387fff
TS
1969 switch (sel) {
1970 case 0:
2423f660
TS
1971 gen_op_mfc0_badvaddr();
1972 rn = "BadVaddr";
1973 break;
7a387fff
TS
1974 default:
1975 goto die;
1976 }
873eb012
TS
1977 break;
1978 case 9:
7a387fff
TS
1979 switch (sel) {
1980 case 0:
2423f660
TS
1981 gen_op_mfc0_count();
1982 rn = "Count";
1983 break;
1984 /* 6,7 are implementation dependent */
7a387fff
TS
1985 default:
1986 goto die;
2423f660 1987 }
873eb012
TS
1988 break;
1989 case 10:
7a387fff
TS
1990 switch (sel) {
1991 case 0:
2423f660
TS
1992 gen_op_mfc0_entryhi();
1993 rn = "EntryHi";
1994 break;
7a387fff
TS
1995 default:
1996 goto die;
1579a72e 1997 }
873eb012
TS
1998 break;
1999 case 11:
7a387fff
TS
2000 switch (sel) {
2001 case 0:
2423f660
TS
2002 gen_op_mfc0_compare();
2003 rn = "Compare";
2004 break;
2005 /* 6,7 are implementation dependent */
7a387fff
TS
2006 default:
2007 goto die;
2423f660 2008 }
873eb012
TS
2009 break;
2010 case 12:
7a387fff
TS
2011 switch (sel) {
2012 case 0:
2423f660
TS
2013 gen_op_mfc0_status();
2014 rn = "Status";
2015 break;
7a387fff 2016 case 1:
2423f660
TS
2017 gen_op_mfc0_intctl();
2018 rn = "IntCtl";
2019 break;
7a387fff 2020 case 2:
2423f660
TS
2021 gen_op_mfc0_srsctl();
2022 rn = "SRSCtl";
2023 break;
7a387fff 2024 case 3:
2423f660
TS
2025// gen_op_mfc0_srsmap(); /* shadow registers */
2026 rn = "SRSMap";
2027// break;
7a387fff
TS
2028 default:
2029 goto die;
2030 }
873eb012
TS
2031 break;
2032 case 13:
7a387fff
TS
2033 switch (sel) {
2034 case 0:
2423f660
TS
2035 gen_op_mfc0_cause();
2036 rn = "Cause";
2037 break;
7a387fff
TS
2038 default:
2039 goto die;
2040 }
873eb012
TS
2041 break;
2042 case 14:
7a387fff
TS
2043 switch (sel) {
2044 case 0:
2423f660
TS
2045 gen_op_mfc0_epc();
2046 rn = "EPC";
2047 break;
7a387fff
TS
2048 default:
2049 goto die;
1579a72e 2050 }
873eb012
TS
2051 break;
2052 case 15:
7a387fff
TS
2053 switch (sel) {
2054 case 0:
2423f660
TS
2055 gen_op_mfc0_prid();
2056 rn = "PRid";
2057 break;
7a387fff 2058 case 1:
2423f660
TS
2059 gen_op_mfc0_ebase();
2060 rn = "EBase";
2061 break;
7a387fff
TS
2062 default:
2063 goto die;
2064 }
873eb012
TS
2065 break;
2066 case 16:
2067 switch (sel) {
2068 case 0:
e397ee33 2069 gen_op_mfc0_config0();
873eb012
TS
2070 rn = "Config";
2071 break;
2072 case 1:
e397ee33 2073 gen_op_mfc0_config1();
873eb012
TS
2074 rn = "Config1";
2075 break;
7a387fff 2076 case 2:
e397ee33 2077 gen_op_mfc0_config2();
7a387fff
TS
2078 rn = "Config2";
2079 break;
2080 case 3:
e397ee33 2081 gen_op_mfc0_config3();
7a387fff
TS
2082 rn = "Config3";
2083 break;
e397ee33
TS
2084 /* 4,5 are reserved */
2085 /* 6,7 are implementation dependent */
2086 case 6:
2087 gen_op_mfc0_config6();
2088 rn = "Config6";
2089 break;
2090 case 7:
2091 gen_op_mfc0_config7();
2092 rn = "Config7";
2093 break;
873eb012 2094 default:
873eb012
TS
2095 goto die;
2096 }
2097 break;
2098 case 17:
7a387fff
TS
2099 switch (sel) {
2100 case 0:
2423f660
TS
2101 gen_op_mfc0_lladdr();
2102 rn = "LLAddr";
2103 break;
7a387fff
TS
2104 default:
2105 goto die;
2106 }
873eb012
TS
2107 break;
2108 case 18:
7a387fff
TS
2109 switch (sel) {
2110 case 0:
2423f660
TS
2111 gen_op_mfc0_watchlo0();
2112 rn = "WatchLo";
2113 break;
7a387fff 2114 case 1:
2423f660
TS
2115// gen_op_mfc0_watchlo1();
2116 rn = "WatchLo1";
2117// break;
7a387fff 2118 case 2:
2423f660
TS
2119// gen_op_mfc0_watchlo2();
2120 rn = "WatchLo2";
2121// break;
7a387fff 2122 case 3:
2423f660
TS
2123// gen_op_mfc0_watchlo3();
2124 rn = "WatchLo3";
2125// break;
7a387fff 2126 case 4:
2423f660
TS
2127// gen_op_mfc0_watchlo4();
2128 rn = "WatchLo4";
2129// break;
7a387fff 2130 case 5:
2423f660
TS
2131// gen_op_mfc0_watchlo5();
2132 rn = "WatchLo5";
2133// break;
7a387fff 2134 case 6:
2423f660
TS
2135// gen_op_mfc0_watchlo6();
2136 rn = "WatchLo6";
2137// break;
7a387fff 2138 case 7:
2423f660
TS
2139// gen_op_mfc0_watchlo7();
2140 rn = "WatchLo7";
2141// break;
7a387fff
TS
2142 default:
2143 goto die;
2144 }
873eb012
TS
2145 break;
2146 case 19:
7a387fff
TS
2147 switch (sel) {
2148 case 0:
2423f660
TS
2149 gen_op_mfc0_watchhi0();
2150 rn = "WatchHi";
2151 break;
7a387fff 2152 case 1:
2423f660
TS
2153// gen_op_mfc0_watchhi1();
2154 rn = "WatchHi1";
2155// break;
7a387fff 2156 case 2:
2423f660
TS
2157// gen_op_mfc0_watchhi2();
2158 rn = "WatchHi2";
2159// break;
7a387fff 2160 case 3:
2423f660
TS
2161// gen_op_mfc0_watchhi3();
2162 rn = "WatchHi3";
2163// break;
7a387fff 2164 case 4:
2423f660
TS
2165// gen_op_mfc0_watchhi4();
2166 rn = "WatchHi4";
2167// break;
7a387fff 2168 case 5:
2423f660
TS
2169// gen_op_mfc0_watchhi5();
2170 rn = "WatchHi5";
2171// break;
7a387fff 2172 case 6:
2423f660
TS
2173// gen_op_mfc0_watchhi6();
2174 rn = "WatchHi6";
2175// break;
7a387fff 2176 case 7:
2423f660
TS
2177// gen_op_mfc0_watchhi7();
2178 rn = "WatchHi7";
2179// break;
7a387fff
TS
2180 default:
2181 goto die;
2182 }
873eb012 2183 break;
8c0fdd85 2184 case 20:
7a387fff
TS
2185 switch (sel) {
2186 case 0:
2423f660
TS
2187 /* 64 bit MMU only */
2188 gen_op_mfc0_xcontext();
2189 rn = "XContext";
2190 break;
7a387fff
TS
2191 default:
2192 goto die;
2193 }
8c0fdd85
TS
2194 break;
2195 case 21:
7a387fff
TS
2196 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2197 switch (sel) {
2198 case 0:
2423f660
TS
2199 gen_op_mfc0_framemask();
2200 rn = "Framemask";
2201 break;
7a387fff
TS
2202 default:
2203 goto die;
2204 }
8c0fdd85
TS
2205 break;
2206 case 22:
2423f660
TS
2207 /* ignored */
2208 rn = "'Diagnostic"; /* implementation dependent */
2209 break;
873eb012 2210 case 23:
7a387fff
TS
2211 switch (sel) {
2212 case 0:
2423f660
TS
2213 gen_op_mfc0_debug(); /* EJTAG support */
2214 rn = "Debug";
2215 break;
7a387fff 2216 case 1:
2423f660
TS
2217// gen_op_mfc0_tracecontrol(); /* PDtrace support */
2218 rn = "TraceControl";
2219// break;
7a387fff 2220 case 2:
2423f660
TS
2221// gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2222 rn = "TraceControl2";
2223// break;
7a387fff 2224 case 3:
2423f660
TS
2225// gen_op_mfc0_usertracedata(); /* PDtrace support */
2226 rn = "UserTraceData";
2227// break;
7a387fff 2228 case 4:
2423f660
TS
2229// gen_op_mfc0_debug(); /* PDtrace support */
2230 rn = "TraceBPC";
2231// break;
7a387fff
TS
2232 default:
2233 goto die;
2234 }
873eb012
TS
2235 break;
2236 case 24:
7a387fff
TS
2237 switch (sel) {
2238 case 0:
2423f660
TS
2239 gen_op_mfc0_depc(); /* EJTAG support */
2240 rn = "DEPC";
2241 break;
7a387fff
TS
2242 default:
2243 goto die;
2244 }
873eb012 2245 break;
8c0fdd85 2246 case 25:
7a387fff
TS
2247 switch (sel) {
2248 case 0:
2423f660
TS
2249 gen_op_mfc0_performance0();
2250 rn = "Performance0";
7a387fff
TS
2251 break;
2252 case 1:
2423f660
TS
2253// gen_op_mfc0_performance1();
2254 rn = "Performance1";
2255// break;
7a387fff 2256 case 2:
2423f660
TS
2257// gen_op_mfc0_performance2();
2258 rn = "Performance2";
2259// break;
7a387fff 2260 case 3:
2423f660
TS
2261// gen_op_mfc0_performance3();
2262 rn = "Performance3";
2263// break;
7a387fff 2264 case 4:
2423f660
TS
2265// gen_op_mfc0_performance4();
2266 rn = "Performance4";
2267// break;
7a387fff 2268 case 5:
2423f660
TS
2269// gen_op_mfc0_performance5();
2270 rn = "Performance5";
2271// break;
7a387fff 2272 case 6:
2423f660
TS
2273// gen_op_mfc0_performance6();
2274 rn = "Performance6";
2275// break;
7a387fff 2276 case 7:
2423f660
TS
2277// gen_op_mfc0_performance7();
2278 rn = "Performance7";
2279// break;
7a387fff
TS
2280 default:
2281 goto die;
2282 }
8c0fdd85
TS
2283 break;
2284 case 26:
7a387fff
TS
2285 rn = "ECC";
2286 break;
8c0fdd85 2287 case 27:
7a387fff
TS
2288 switch (sel) {
2289 /* ignored */
2290 case 0 ... 3:
2423f660
TS
2291 rn = "CacheErr";
2292 break;
7a387fff
TS
2293 default:
2294 goto die;
2295 }
8c0fdd85 2296 break;
873eb012
TS
2297 case 28:
2298 switch (sel) {
2299 case 0:
7a387fff
TS
2300 case 2:
2301 case 4:
2302 case 6:
873eb012
TS
2303 gen_op_mfc0_taglo();
2304 rn = "TagLo";
2305 break;
2306 case 1:
7a387fff
TS
2307 case 3:
2308 case 5:
2309 case 7:
873eb012
TS
2310 gen_op_mfc0_datalo();
2311 rn = "DataLo";
2312 break;
2313 default:
873eb012
TS
2314 goto die;
2315 }
2316 break;
8c0fdd85 2317 case 29:
7a387fff
TS
2318 switch (sel) {
2319 case 0:
2320 case 2:
2321 case 4:
2322 case 6:
2323 gen_op_mfc0_taghi();
2324 rn = "TagHi";
2325 break;
2326 case 1:
2327 case 3:
2328 case 5:
2329 case 7:
2330 gen_op_mfc0_datahi();
2331 rn = "DataHi";
2332 break;
2333 default:
2334 goto die;
2335 }
8c0fdd85 2336 break;
873eb012 2337 case 30:
7a387fff
TS
2338 switch (sel) {
2339 case 0:
2423f660
TS
2340 gen_op_mfc0_errorepc();
2341 rn = "ErrorEPC";
2342 break;
7a387fff
TS
2343 default:
2344 goto die;
2345 }
873eb012
TS
2346 break;
2347 case 31:
7a387fff
TS
2348 switch (sel) {
2349 case 0:
2423f660
TS
2350 gen_op_mfc0_desave(); /* EJTAG support */
2351 rn = "DESAVE";
2352 break;
7a387fff
TS
2353 default:
2354 goto die;
2355 }
873eb012
TS
2356 break;
2357 default:
873eb012
TS
2358 goto die;
2359 }
2360#if defined MIPS_DEBUG_DISAS
2361 if (loglevel & CPU_LOG_TB_IN_ASM) {
7a387fff
TS
2362 fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2363 rn, reg, sel);
873eb012
TS
2364 }
2365#endif
2366 return;
2367
2368die:
2369#if defined MIPS_DEBUG_DISAS
2370 if (loglevel & CPU_LOG_TB_IN_ASM) {
7a387fff
TS
2371 fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2372 rn, reg, sel);
873eb012
TS
2373 }
2374#endif
2375 generate_exception(ctx, EXCP_RI);
2376}
2377
8c0fdd85
TS
2378static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2379{
7a387fff
TS
2380 const char *rn = "invalid";
2381
8c0fdd85
TS
2382 switch (reg) {
2383 case 0:
7a387fff
TS
2384 switch (sel) {
2385 case 0:
2386 gen_op_mtc0_index();
2387 rn = "Index";
2388 break;
2389 case 1:
2423f660 2390// gen_op_mtc0_mvpcontrol(); /* MT ASE */
7a387fff 2391 rn = "MVPControl";
2423f660 2392// break;
7a387fff 2393 case 2:
2423f660 2394// gen_op_mtc0_mvpconf0(); /* MT ASE */
7a387fff 2395 rn = "MVPConf0";
2423f660 2396// break;
7a387fff 2397 case 3:
2423f660 2398// gen_op_mtc0_mvpconf1(); /* MT ASE */
7a387fff 2399 rn = "MVPConf1";
2423f660 2400// break;
7a387fff
TS
2401 default:
2402 goto die;
2403 }
8c0fdd85
TS
2404 break;
2405 case 1:
7a387fff
TS
2406 switch (sel) {
2407 case 0:
2423f660 2408 /* ignored */
7a387fff 2409 rn = "Random";
2423f660 2410 break;
7a387fff 2411 case 1:
2423f660 2412// gen_op_mtc0_vpecontrol(); /* MT ASE */
7a387fff 2413 rn = "VPEControl";
2423f660 2414// break;
7a387fff 2415 case 2:
2423f660 2416// gen_op_mtc0_vpeconf0(); /* MT ASE */
7a387fff 2417 rn = "VPEConf0";
2423f660 2418// break;
7a387fff 2419 case 3:
2423f660 2420// gen_op_mtc0_vpeconf1(); /* MT ASE */
7a387fff 2421 rn = "VPEConf1";
2423f660 2422// break;
7a387fff 2423 case 4:
2423f660 2424// gen_op_mtc0_YQMask(); /* MT ASE */
7a387fff 2425 rn = "YQMask";
2423f660 2426// break;
7a387fff 2427 case 5:
2423f660 2428// gen_op_mtc0_vpeschedule(); /* MT ASE */
7a387fff 2429 rn = "VPESchedule";
2423f660 2430// break;
7a387fff 2431 case 6:
2423f660 2432// gen_op_mtc0_vpeschefback(); /* MT ASE */
7a387fff 2433 rn = "VPEScheFBack";
2423f660 2434// break;
7a387fff 2435 case 7:
2423f660 2436// gen_op_mtc0_vpeopt(); /* MT ASE */
7a387fff 2437 rn = "VPEOpt";
2423f660 2438// break;
7a387fff
TS
2439 default:
2440 goto die;
2441 }
8c0fdd85
TS
2442 break;
2443 case 2:
7a387fff
TS
2444 switch (sel) {
2445 case 0:
2423f660
TS
2446 gen_op_mtc0_entrylo0();
2447 rn = "EntryLo0";
2448 break;
7a387fff 2449 case 1:
2423f660
TS
2450// gen_op_mtc0_tcstatus(); /* MT ASE */
2451 rn = "TCStatus";
2452// break;
7a387fff 2453 case 2:
2423f660
TS
2454// gen_op_mtc0_tcbind(); /* MT ASE */
2455 rn = "TCBind";
2456// break;
7a387fff 2457 case 3:
2423f660
TS
2458// gen_op_mtc0_tcrestart(); /* MT ASE */
2459 rn = "TCRestart";
2460// break;
7a387fff 2461 case 4:
2423f660
TS
2462// gen_op_mtc0_tchalt(); /* MT ASE */
2463 rn = "TCHalt";
2464// break;
7a387fff 2465 case 5:
2423f660
TS
2466// gen_op_mtc0_tccontext(); /* MT ASE */
2467 rn = "TCContext";
2468// break;
7a387fff 2469 case 6:
2423f660
TS
2470// gen_op_mtc0_tcschedule(); /* MT ASE */
2471 rn = "TCSchedule";
2472// break;
7a387fff 2473 case 7:
2423f660
TS
2474// gen_op_mtc0_tcschefback(); /* MT ASE */
2475 rn = "TCScheFBack";
2476// break;
7a387fff
TS
2477 default:
2478 goto die;
2479 }
8c0fdd85
TS
2480 break;
2481 case 3:
7a387fff
TS
2482 switch (sel) {
2483 case 0:
2423f660
TS
2484 gen_op_mtc0_entrylo1();
2485 rn = "EntryLo1";
2486 break;
7a387fff
TS
2487 default:
2488 goto die;
876d4b07 2489 }
8c0fdd85
TS
2490 break;
2491 case 4:
7a387fff
TS
2492 switch (sel) {
2493 case 0:
2423f660
TS
2494 gen_op_mtc0_context();
2495 rn = "Context";
2496 break;
7a387fff 2497 case 1:
2423f660
TS
2498// gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2499 rn = "ContextConfig";
2500// break;
7a387fff
TS
2501 default:
2502 goto die;
876d4b07 2503 }
8c0fdd85
TS
2504 break;
2505 case 5:
7a387fff
TS
2506 switch (sel) {
2507 case 0:
2423f660
TS
2508 gen_op_mtc0_pagemask();
2509 rn = "PageMask";
2510 break;
7a387fff 2511 case 1:
2423f660
TS
2512 gen_op_mtc0_pagegrain();
2513 rn = "PageGrain";
2514 break;
7a387fff
TS
2515 default:
2516 goto die;
876d4b07 2517 }
8c0fdd85
TS
2518 break;
2519 case 6:
7a387fff
TS
2520 switch (sel) {
2521 case 0:
2423f660
TS
2522 gen_op_mtc0_wired();
2523 rn = "Wired";
2524 break;
7a387fff 2525 case 1:
2423f660
TS
2526// gen_op_mtc0_srsconf0(); /* shadow registers */
2527 rn = "SRSConf0";
2528// break;
7a387fff 2529 case 2:
2423f660
TS
2530// gen_op_mtc0_srsconf1(); /* shadow registers */
2531 rn = "SRSConf1";
2532// break;
7a387fff 2533 case 3:
2423f660
TS
2534// gen_op_mtc0_srsconf2(); /* shadow registers */
2535 rn = "SRSConf2";
2536// break;
7a387fff 2537 case 4:
2423f660
TS
2538// gen_op_mtc0_srsconf3(); /* shadow registers */
2539 rn = "SRSConf3";
2540// break;
7a387fff 2541 case 5:
2423f660
TS
2542// gen_op_mtc0_srsconf4(); /* shadow registers */
2543 rn = "SRSConf4";
2544// break;
7a387fff
TS
2545 default:
2546 goto die;
876d4b07 2547 }
8c0fdd85
TS
2548 break;
2549 case 7:
7a387fff
TS
2550 switch (sel) {
2551 case 0:
2423f660
TS
2552 gen_op_mtc0_hwrena();
2553 rn = "HWREna";
2554 break;
7a387fff
TS
2555 default:
2556 goto die;
876d4b07 2557 }
8c0fdd85
TS
2558 break;
2559 case 8:
7a387fff 2560 /* ignored */
8c0fdd85
TS
2561 rn = "BadVaddr";
2562 break;
2563 case 9:
7a387fff
TS
2564 switch (sel) {
2565 case 0:
2423f660
TS
2566 gen_op_mtc0_count();
2567 rn = "Count";
2568 break;
876d4b07 2569 /* 6,7 are implementation dependent */
7a387fff
TS
2570 default:
2571 goto die;
876d4b07
TS
2572 }
2573 /* Stop translation as we may have switched the execution mode */
2574 ctx->bstate = BS_STOP;
8c0fdd85
TS
2575 break;
2576 case 10:
7a387fff
TS
2577 switch (sel) {
2578 case 0:
2423f660
TS
2579 gen_op_mtc0_entryhi();
2580 rn = "EntryHi";
2581 break;
7a387fff
TS
2582 default:
2583 goto die;
876d4b07 2584 }
8c0fdd85
TS
2585 break;
2586 case 11:
7a387fff
TS
2587 switch (sel) {
2588 case 0:
2423f660
TS
2589 gen_op_mtc0_compare();
2590 rn = "Compare";
2591 break;
2592 /* 6,7 are implementation dependent */
7a387fff
TS
2593 default:
2594 goto die;
876d4b07
TS
2595 }
2596 /* Stop translation as we may have switched the execution mode */
2597 ctx->bstate = BS_STOP;
8c0fdd85
TS
2598 break;
2599 case 12:
7a387fff
TS
2600 switch (sel) {
2601 case 0:
2423f660
TS
2602 gen_op_mtc0_status();
2603 rn = "Status";
2604 break;
7a387fff 2605 case 1:
2423f660
TS
2606 gen_op_mtc0_intctl();
2607 rn = "IntCtl";
2608 break;
7a387fff 2609 case 2:
2423f660
TS
2610 gen_op_mtc0_srsctl();
2611 rn = "SRSCtl";
2612 break;
7a387fff 2613 case 3:
2423f660
TS
2614// gen_op_mtc0_srsmap(); /* shadow registers */
2615 rn = "SRSMap";
2616// break;
7a387fff
TS
2617 default:
2618 goto die;
876d4b07
TS
2619 }
2620 /* Stop translation as we may have switched the execution mode */
2621 ctx->bstate = BS_STOP;
8c0fdd85
TS
2622 break;
2623 case 13:
7a387fff
TS
2624 switch (sel) {
2625 case 0:
2423f660
TS
2626 gen_op_mtc0_cause();
2627 rn = "Cause";
2628 break;
7a387fff
TS
2629 default:
2630 goto die;
876d4b07
TS
2631 }
2632 /* Stop translation as we may have switched the execution mode */
2633 ctx->bstate = BS_STOP;
8c0fdd85
TS
2634 break;
2635 case 14:
7a387fff
TS
2636 switch (sel) {
2637 case 0:
2423f660
TS
2638 gen_op_mtc0_epc();
2639 rn = "EPC";
2640 break;
7a387fff
TS
2641 default:
2642 goto die;
876d4b07 2643 }
8c0fdd85
TS
2644 break;
2645 case 15:
7a387fff
TS
2646 switch (sel) {
2647 case 0:
2423f660
TS
2648 /* ignored */
2649 rn = "PRid";
2650 break;
7a387fff 2651 case 1:
2423f660
TS
2652 gen_op_mtc0_ebase();
2653 rn = "EBase";
2654 break;
7a387fff
TS
2655 default:
2656 goto die;
1579a72e 2657 }
8c0fdd85
TS
2658 break;
2659 case 16:
2660 switch (sel) {
2661 case 0:
e397ee33 2662 gen_op_mtc0_config0();
7a387fff 2663 rn = "Config";
2423f660
TS
2664 /* Stop translation as we may have switched the execution mode */
2665 ctx->bstate = BS_STOP;
7a387fff
TS
2666 break;
2667 case 1:
e397ee33 2668 /* ignored, read only */
7a387fff
TS
2669 rn = "Config1";
2670 break;
2671 case 2:
e397ee33 2672 gen_op_mtc0_config2();
7a387fff 2673 rn = "Config2";
2423f660
TS
2674 /* Stop translation as we may have switched the execution mode */
2675 ctx->bstate = BS_STOP;
8c0fdd85 2676 break;
7a387fff 2677 case 3:
e397ee33 2678 /* ignored, read only */
7a387fff
TS
2679 rn = "Config3";
2680 break;
e397ee33
TS
2681 /* 4,5 are reserved */
2682 /* 6,7 are implementation dependent */
2683 case 6:
2684 /* ignored */
2685 rn = "Config6";
2686 break;
2687 case 7:
2688 /* ignored */
2689 rn = "Config7";
2690 break;
8c0fdd85
TS
2691 default:
2692 rn = "Invalid config selector";
2693 goto die;
2694 }
2695 break;
2696 case 17:
7a387fff
TS
2697 switch (sel) {
2698 case 0:
2423f660
TS
2699 /* ignored */
2700 rn = "LLAddr";
2701 break;
7a387fff
TS
2702 default:
2703 goto die;
2704 }
8c0fdd85
TS
2705 break;
2706 case 18:
7a387fff
TS
2707 switch (sel) {
2708 case 0:
2423f660
TS
2709 gen_op_mtc0_watchlo0();
2710 rn = "WatchLo";
2711 break;
7a387fff 2712 case 1:
2423f660
TS
2713// gen_op_mtc0_watchlo1();
2714 rn = "WatchLo1";
2715// break;
7a387fff 2716 case 2:
2423f660
TS
2717// gen_op_mtc0_watchlo2();
2718 rn = "WatchLo2";
2719// break;
7a387fff 2720 case 3:
2423f660
TS
2721// gen_op_mtc0_watchlo3();
2722 rn = "WatchLo3";
2723// break;
7a387fff 2724 case 4:
2423f660
TS
2725// gen_op_mtc0_watchlo4();
2726 rn = "WatchLo4";
2727// break;
7a387fff 2728 case 5:
2423f660
TS
2729// gen_op_mtc0_watchlo5();
2730 rn = "WatchLo5";
2731// break;
7a387fff 2732 case 6:
2423f660
TS
2733// gen_op_mtc0_watchlo6();
2734 rn = "WatchLo6";
2735// break;
7a387fff 2736 case 7:
2423f660
TS
2737// gen_op_mtc0_watchlo7();
2738 rn = "WatchLo7";
2739// break;
7a387fff
TS
2740 default:
2741 goto die;
2742 }
8c0fdd85
TS
2743 break;
2744 case 19:
7a387fff
TS
2745 switch (sel) {
2746 case 0:
2423f660
TS
2747 gen_op_mtc0_watchhi0();
2748 rn = "WatchHi";
2749 break;
7a387fff 2750 case 1:
2423f660
TS
2751// gen_op_mtc0_watchhi1();
2752 rn = "WatchHi1";
2753// break;
7a387fff 2754 case 2:
2423f660
TS
2755// gen_op_mtc0_watchhi2();
2756 rn = "WatchHi2";
2757// break;
7a387fff 2758 case 3:
2423f660
TS
2759// gen_op_mtc0_watchhi3();
2760 rn = "WatchHi3";
2761// break;
7a387fff 2762 case 4:
2423f660
TS
2763// gen_op_mtc0_watchhi4();
2764 rn = "WatchHi4";
2765// break;
7a387fff 2766 case 5:
2423f660
TS
2767// gen_op_mtc0_watchhi5();
2768 rn = "WatchHi5";
2769// break;
7a387fff 2770 case 6:
2423f660
TS
2771// gen_op_mtc0_watchhi6();
2772 rn = "WatchHi6";
2773// break;
7a387fff 2774 case 7:
2423f660
TS
2775// gen_op_mtc0_watchhi7();
2776 rn = "WatchHi7";
2777// break;
7a387fff
TS
2778 default:
2779 goto die;
2780 }
8c0fdd85
TS
2781 break;
2782 case 20:
7a387fff
TS
2783 switch (sel) {
2784 case 0:
2423f660
TS
2785 /* 64 bit MMU only */
2786 /* Nothing writable in lower 32 bits */
2787 rn = "XContext";
2788 break;
7a387fff
TS
2789 default:
2790 goto die;
2791 }
8c0fdd85
TS
2792 break;
2793 case 21:
7a387fff
TS
2794 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2795 switch (sel) {
2796 case 0:
2423f660
TS
2797 gen_op_mtc0_framemask();
2798 rn = "Framemask";
2799 break;
7a387fff
TS
2800 default:
2801 goto die;
2802 }
2803 break;
8c0fdd85 2804 case 22:
7a387fff
TS
2805 /* ignored */
2806 rn = "Diagnostic"; /* implementation dependent */
2423f660 2807 break;
8c0fdd85 2808 case 23:
7a387fff
TS
2809 switch (sel) {
2810 case 0:
2423f660
TS
2811 gen_op_mtc0_debug(); /* EJTAG support */
2812 rn = "Debug";
2813 break;
7a387fff 2814 case 1:
2423f660
TS
2815// gen_op_mtc0_tracecontrol(); /* PDtrace support */
2816 rn = "TraceControl";
2817// break;
7a387fff 2818 case 2:
2423f660
TS
2819// gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2820 rn = "TraceControl2";
2821// break;
7a387fff 2822 case 3:
2423f660
TS
2823// gen_op_mtc0_usertracedata(); /* PDtrace support */
2824 rn = "UserTraceData";
2825// break;
7a387fff 2826 case 4:
2423f660
TS
2827// gen_op_mtc0_debug(); /* PDtrace support */
2828 rn = "TraceBPC";
2829// break;
7a387fff
TS
2830 default:
2831 goto die;
2832 }
2423f660
TS
2833 /* Stop translation as we may have switched the execution mode */
2834 ctx->bstate = BS_STOP;
8c0fdd85
TS
2835 break;
2836 case 24:
7a387fff
TS
2837 switch (sel) {
2838 case 0:
2423f660
TS
2839 gen_op_mtc0_depc(); /* EJTAG support */
2840 rn = "DEPC";
2841 break;
7a387fff
TS
2842 default:
2843 goto die;
2844 }
8c0fdd85
TS
2845 break;
2846 case 25:
7a387fff
TS
2847 switch (sel) {
2848 case 0:
2423f660
TS
2849 gen_op_mtc0_performance0();
2850 rn = "Performance0";
2851 break;
7a387fff 2852 case 1:
2423f660
TS
2853// gen_op_mtc0_performance1();
2854 rn = "Performance1";
2855// break;
7a387fff 2856 case 2:
2423f660
TS
2857// gen_op_mtc0_performance2();
2858 rn = "Performance2";
2859// break;
7a387fff 2860 case 3:
2423f660
TS
2861// gen_op_mtc0_performance3();
2862 rn = "Performance3";
2863// break;
7a387fff 2864 case 4:
2423f660
TS
2865// gen_op_mtc0_performance4();
2866 rn = "Performance4";
2867// break;
7a387fff 2868 case 5:
2423f660
TS
2869// gen_op_mtc0_performance5();
2870 rn = "Performance5";
2871// break;
7a387fff 2872 case 6:
2423f660
TS
2873// gen_op_mtc0_performance6();
2874 rn = "Performance6";
2875// break;
7a387fff 2876 case 7:
2423f660
TS
2877// gen_op_mtc0_performance7();
2878 rn = "Performance7";
2879// break;
7a387fff
TS
2880 default:
2881 goto die;
2882 }
8c0fdd85
TS
2883 break;
2884 case 26:
2423f660 2885 /* ignored */
8c0fdd85 2886 rn = "ECC";
2423f660 2887 break;
8c0fdd85 2888 case 27:
7a387fff
TS
2889 switch (sel) {
2890 case 0 ... 3:
2423f660
TS
2891 /* ignored */
2892 rn = "CacheErr";
2893 break;
7a387fff
TS
2894 default:
2895 goto die;
2896 }
8c0fdd85
TS
2897 break;
2898 case 28:
2899 switch (sel) {
2900 case 0:
7a387fff
TS
2901 case 2:
2902 case 4:
2903 case 6:
8c0fdd85
TS
2904 gen_op_mtc0_taglo();
2905 rn = "TagLo";
2906 break;
7a387fff
TS
2907 case 1:
2908 case 3:
2909 case 5:
2910 case 7:
2423f660 2911 gen_op_mtc0_datalo();
7a387fff
TS
2912 rn = "DataLo";
2913 break;
8c0fdd85 2914 default:
8c0fdd85
TS
2915 goto die;
2916 }
2917 break;
2918 case 29:
7a387fff
TS
2919 switch (sel) {
2920 case 0:
2921 case 2:
2922 case 4:
2923 case 6:
2924 gen_op_mtc0_taghi();
2925 rn = "TagHi";
2926 break;
2927 case 1:
2928 case 3:
2929 case 5:
2930 case 7:
2423f660 2931 gen_op_mtc0_datahi();
7a387fff
TS
2932 rn = "DataHi";
2933 break;
2934 default:
2935 rn = "invalid sel";
2936 goto die;
2937 }
8c0fdd85
TS
2938 break;
2939 case 30:
7a387fff
TS
2940 switch (sel) {
2941 case 0:
2423f660
TS
2942 gen_op_mtc0_errorepc();
2943 rn = "ErrorEPC";
2944 break;
7a387fff
TS
2945 default:
2946 goto die;
2947 }
8c0fdd85
TS
2948 break;
2949 case 31:
7a387fff
TS
2950 switch (sel) {
2951 case 0:
2423f660
TS
2952 gen_op_mtc0_desave(); /* EJTAG support */
2953 rn = "DESAVE";
2954 break;
7a387fff
TS
2955 default:
2956 goto die;
2957 }
2423f660
TS
2958 /* Stop translation as we may have switched the execution mode */
2959 ctx->bstate = BS_STOP;
8c0fdd85
TS
2960 break;
2961 default:
8c0fdd85
TS
2962 goto die;
2963 }
2964#if defined MIPS_DEBUG_DISAS
2965 if (loglevel & CPU_LOG_TB_IN_ASM) {
7a387fff
TS
2966 fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2967 rn, reg, sel);
8c0fdd85
TS
2968 }
2969#endif
2970 return;
2971
2972die:
2973#if defined MIPS_DEBUG_DISAS
2974 if (loglevel & CPU_LOG_TB_IN_ASM) {
7a387fff
TS
2975 fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2976 rn, reg, sel);
8c0fdd85
TS
2977 }
2978#endif
2979 generate_exception(ctx, EXCP_RI);
2980}
2981
534ce69f 2982#ifdef TARGET_MIPS64
9c2149c8
TS
2983static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2984{
2985 const char *rn = "invalid";
2986
2987 switch (reg) {
2988 case 0:
2989 switch (sel) {
2990 case 0:
2423f660 2991 gen_op_mfc0_index();
9c2149c8
TS
2992 rn = "Index";
2993 break;
2994 case 1:
2423f660 2995// gen_op_dmfc0_mvpcontrol(); /* MT ASE */
9c2149c8 2996 rn = "MVPControl";
2423f660 2997// break;
9c2149c8 2998 case 2:
2423f660 2999// gen_op_dmfc0_mvpconf0(); /* MT ASE */
9c2149c8 3000 rn = "MVPConf0";
2423f660 3001// break;
9c2149c8 3002 case 3:
2423f660 3003// gen_op_dmfc0_mvpconf1(); /* MT ASE */
9c2149c8 3004 rn = "MVPConf1";
2423f660 3005// break;
9c2149c8
TS
3006 default:
3007 goto die;
3008 }
3009 break;
3010 case 1:
3011 switch (sel) {
3012 case 0:
3013 gen_op_mfc0_random();
3014 rn = "Random";
2423f660 3015 break;
9c2149c8 3016 case 1:
2423f660 3017// gen_op_dmfc0_vpecontrol(); /* MT ASE */
9c2149c8 3018 rn = "VPEControl";
2423f660 3019// break;
9c2149c8 3020 case 2:
2423f660 3021// gen_op_dmfc0_vpeconf0(); /* MT ASE */
9c2149c8 3022 rn = "VPEConf0";
2423f660 3023// break;
9c2149c8 3024 case 3:
2423f660 3025// gen_op_dmfc0_vpeconf1(); /* MT ASE */
9c2149c8 3026 rn = "VPEConf1";
2423f660 3027// break;
9c2149c8 3028 case 4:
2423f660 3029// gen_op_dmfc0_YQMask(); /* MT ASE */
9c2149c8 3030 rn = "YQMask";
2423f660 3031// break;
9c2149c8 3032 case 5:
2423f660 3033// gen_op_dmfc0_vpeschedule(); /* MT ASE */
9c2149c8 3034 rn = "VPESchedule";
2423f660 3035// break;
9c2149c8 3036 case 6:
2423f660 3037// gen_op_dmfc0_vpeschefback(); /* MT ASE */
9c2149c8 3038 rn = "VPEScheFBack";
2423f660 3039// break;
9c2149c8 3040 case 7:
2423f660 3041// gen_op_dmfc0_vpeopt(); /* MT ASE */
9c2149c8 3042 rn = "VPEOpt";
2423f660 3043// break;
9c2149c8
TS
3044 default:
3045 goto die;
3046 }
3047 break;
3048 case 2:
3049 switch (sel) {
3050 case 0:
2423f660
TS
3051 gen_op_dmfc0_entrylo0();
3052 rn = "EntryLo0";
3053 break;
9c2149c8 3054 case 1:
2423f660
TS
3055// gen_op_dmfc0_tcstatus(); /* MT ASE */
3056 rn = "TCStatus";
3057// break;
9c2149c8 3058 case 2:
2423f660
TS
3059// gen_op_dmfc0_tcbind(); /* MT ASE */
3060 rn = "TCBind";
3061// break;
9c2149c8 3062 case 3:
2423f660
TS
3063// gen_op_dmfc0_tcrestart(); /* MT ASE */
3064 rn = "TCRestart";
3065// break;
9c2149c8 3066 case 4:
2423f660
TS
3067// gen_op_dmfc0_tchalt(); /* MT ASE */
3068 rn = "TCHalt";
3069// break;
9c2149c8 3070 case 5:
2423f660
TS
3071// gen_op_dmfc0_tccontext(); /* MT ASE */
3072 rn = "TCContext";
3073// break;
9c2149c8 3074 case 6:
2423f660
TS
3075// gen_op_dmfc0_tcschedule(); /* MT ASE */
3076 rn = "TCSchedule";
3077// break;
9c2149c8 3078 case 7:
2423f660
TS
3079// gen_op_dmfc0_tcschefback(); /* MT ASE */
3080 rn = "TCScheFBack";
3081// break;
9c2149c8
TS
3082 default:
3083 goto die;
3084 }
3085 break;
3086 case 3:
3087 switch (sel) {
3088 case 0:
2423f660
TS
3089 gen_op_dmfc0_entrylo1();
3090 rn = "EntryLo1";
3091 break;
9c2149c8
TS
3092 default:
3093 goto die;
1579a72e 3094 }
9c2149c8
TS
3095 break;
3096 case 4:
3097 switch (sel) {
3098 case 0:
2423f660
TS
3099 gen_op_dmfc0_context();
3100 rn = "Context";
3101 break;
9c2149c8 3102 case 1:
2423f660
TS
3103// gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3104 rn = "ContextConfig";
3105// break;
9c2149c8
TS
3106 default:
3107 goto die;
876d4b07 3108 }
9c2149c8
TS
3109 break;
3110 case 5:
3111 switch (sel) {
3112 case 0:
2423f660
TS
3113 gen_op_mfc0_pagemask();
3114 rn = "PageMask";
3115 break;
9c2149c8 3116 case 1:
2423f660
TS
3117 gen_op_mfc0_pagegrain();
3118 rn = "PageGrain";
3119 break;
9c2149c8
TS
3120 default:
3121 goto die;
876d4b07 3122 }
9c2149c8
TS
3123 break;
3124 case 6:
3125 switch (sel) {
3126 case 0:
2423f660
TS
3127 gen_op_mfc0_wired();
3128 rn = "Wired";
3129 break;
9c2149c8 3130 case 1:
2423f660
TS
3131// gen_op_dmfc0_srsconf0(); /* shadow registers */
3132 rn = "SRSConf0";
3133// break;
9c2149c8 3134 case 2:
2423f660
TS
3135// gen_op_dmfc0_srsconf1(); /* shadow registers */
3136 rn = "SRSConf1";
3137// break;
9c2149c8 3138 case 3:
2423f660
TS
3139// gen_op_dmfc0_srsconf2(); /* shadow registers */
3140 rn = "SRSConf2";
3141// break;
9c2149c8 3142 case 4:
2423f660
TS
3143// gen_op_dmfc0_srsconf3(); /* shadow registers */
3144 rn = "SRSConf3";
3145// break;
9c2149c8 3146 case 5:
2423f660
TS
3147// gen_op_dmfc0_srsconf4(); /* shadow registers */
3148 rn = "SRSConf4";
3149// break;
9c2149c8
TS
3150 default:
3151 goto die;
876d4b07 3152 }
9c2149c8
TS
3153 break;
3154 case 7:
3155 switch (sel) {
3156 case 0:
2423f660
TS
3157 gen_op_mfc0_hwrena();
3158 rn = "HWREna";
3159 break;
9c2149c8
TS
3160 default:
3161 goto die;
876d4b07 3162 }
9c2149c8
TS
3163 break;
3164 case 8:
3165 switch (sel) {
3166 case 0:
2423f660
TS
3167 gen_op_dmfc0_badvaddr();
3168 rn = "BadVaddr";
3169 break;
9c2149c8
TS
3170 default:
3171 goto die;
876d4b07 3172 }
9c2149c8
TS
3173 break;
3174 case 9:
3175 switch (sel) {
3176 case 0:
2423f660
TS
3177 gen_op_mfc0_count();
3178 rn = "Count";
3179 break;
3180 /* 6,7 are implementation dependent */
9c2149c8
TS
3181 default:
3182 goto die;
876d4b07 3183 }
9c2149c8
TS
3184 break;
3185 case 10:
3186 switch (sel) {
3187 case 0:
2423f660
TS
3188 gen_op_dmfc0_entryhi();
3189 rn = "EntryHi";
3190 break;
9c2149c8
TS
3191 default:
3192 goto die;
876d4b07 3193 }
9c2149c8
TS
3194 break;
3195 case 11:
3196 switch (sel) {
3197 case 0:
2423f660
TS
3198 gen_op_mfc0_compare();
3199 rn = "Compare";
3200 break;
876d4b07 3201 /* 6,7 are implementation dependent */
9c2149c8
TS
3202 default:
3203 goto die;
876d4b07 3204 }
9c2149c8
TS
3205 break;
3206 case 12:
3207 switch (sel) {
3208 case 0:
2423f660
TS
3209 gen_op_mfc0_status();
3210 rn = "Status";
3211 break;
9c2149c8 3212 case 1:
2423f660
TS
3213 gen_op_mfc0_intctl();
3214 rn = "IntCtl";
3215 break;
9c2149c8 3216 case 2:
2423f660
TS
3217 gen_op_mfc0_srsctl();
3218 rn = "SRSCtl";
3219 break;
9c2149c8 3220 case 3:
2423f660
TS
3221 gen_op_mfc0_srsmap(); /* shadow registers */
3222 rn = "SRSMap";
3223 break;
9c2149c8
TS
3224 default:
3225 goto die;
876d4b07 3226 }
9c2149c8
TS
3227 break;
3228 case 13:
3229 switch (sel) {
3230 case 0:
2423f660
TS
3231 gen_op_mfc0_cause();
3232 rn = "Cause";
3233 break;
9c2149c8
TS
3234 default:
3235 goto die;
876d4b07 3236 }
9c2149c8
TS
3237 break;
3238 case 14:
3239 switch (sel) {
3240 case 0:
2423f660
TS
3241 gen_op_dmfc0_epc();
3242 rn = "EPC";
3243 break;
9c2149c8
TS
3244 default:
3245 goto die;
876d4b07 3246 }
9c2149c8
TS
3247 break;
3248 case 15:
3249 switch (sel) {
3250 case 0:
2423f660
TS
3251 gen_op_mfc0_prid();
3252 rn = "PRid";
3253 break;
9c2149c8 3254 case 1:
2423f660
TS
3255 gen_op_mfc0_ebase();
3256 rn = "EBase";
3257 break;
9c2149c8
TS
3258 default:
3259 goto die;
876d4b07 3260 }
9c2149c8
TS
3261 break;
3262 case 16:
3263 switch (sel) {
3264 case 0:
2423f660 3265 gen_op_mfc0_config0();
9c2149c8
TS
3266 rn = "Config";
3267 break;
3268 case 1:
2423f660 3269 gen_op_mfc0_config1();
9c2149c8
TS
3270 rn = "Config1";
3271 break;
3272 case 2:
2423f660 3273 gen_op_mfc0_config2();
9c2149c8
TS
3274 rn = "Config2";
3275 break;
3276 case 3:
2423f660 3277 gen_op_mfc0_config3();
9c2149c8
TS
3278 rn = "Config3";
3279 break;
3280 /* 6,7 are implementation dependent */
3281 default:
3282 goto die;
3283 }
3284 break;
3285 case 17:
3286 switch (sel) {
3287 case 0:
2423f660
TS
3288 gen_op_dmfc0_lladdr();
3289 rn = "LLAddr";
3290 break;
9c2149c8
TS
3291 default:
3292 goto die;
3293 }
3294 break;
3295 case 18:
3296 switch (sel) {
3297 case 0:
2423f660
TS
3298 gen_op_dmfc0_watchlo0();
3299 rn = "WatchLo";
3300 break;
9c2149c8 3301 case 1:
2423f660
TS
3302// gen_op_dmfc0_watchlo1();
3303 rn = "WatchLo1";
3304// break;
9c2149c8 3305 case 2:
2423f660
TS
3306// gen_op_dmfc0_watchlo2();
3307 rn = "WatchLo2";
3308// break;
9c2149c8 3309 case 3:
2423f660
TS
3310// gen_op_dmfc0_watchlo3();
3311 rn = "WatchLo3";
3312// break;
9c2149c8 3313 case 4:
2423f660
TS
3314// gen_op_dmfc0_watchlo4();
3315 rn = "WatchLo4";
3316// break;
9c2149c8 3317 case 5:
2423f660
TS
3318// gen_op_dmfc0_watchlo5();
3319 rn = "WatchLo5";
3320// break;
9c2149c8 3321 case 6:
2423f660
TS
3322// gen_op_dmfc0_watchlo6();
3323 rn = "WatchLo6";
3324// break;
9c2149c8 3325 case 7:
2423f660
TS
3326// gen_op_dmfc0_watchlo7();
3327 rn = "WatchLo7";
3328// break;
9c2149c8
TS
3329 default:
3330 goto die;
3331 }
3332 break;
3333 case 19:
3334 switch (sel) {
3335 case 0:
2423f660
TS
3336 gen_op_mfc0_watchhi0();
3337 rn = "WatchHi";
3338 break;
9c2149c8 3339 case 1:
2423f660
TS
3340// gen_op_mfc0_watchhi1();
3341 rn = "WatchHi1";
3342// break;
9c2149c8 3343 case 2:
2423f660
TS
3344// gen_op_mfc0_watchhi2();
3345 rn = "WatchHi2";
3346// break;
9c2149c8 3347 case 3:
2423f660
TS
3348// gen_op_mfc0_watchhi3();
3349 rn = "WatchHi3";
3350// break;
9c2149c8 3351 case 4:
2423f660
TS
3352// gen_op_mfc0_watchhi4();
3353 rn = "WatchHi4";
3354// break;
9c2149c8 3355 case 5:
2423f660
TS
3356// gen_op_mfc0_watchhi5();
3357 rn = "WatchHi5";
3358// break;
9c2149c8 3359 case 6:
2423f660
TS
3360// gen_op_mfc0_watchhi6();
3361 rn = "WatchHi6";
3362// break;
9c2149c8 3363 case 7:
2423f660
TS
3364// gen_op_mfc0_watchhi7();
3365 rn = "WatchHi7";
3366// break;
9c2149c8
TS
3367 default:
3368 goto die;
3369 }
3370 break;
3371 case 20:
3372 switch (sel) {
3373 case 0:
2423f660
TS
3374 /* 64 bit MMU only */
3375 gen_op_dmfc0_xcontext();
3376 rn = "XContext";
3377 break;
9c2149c8
TS
3378 default:
3379 goto die;
3380 }
3381 break;
3382 case 21:
3383 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3384 switch (sel) {
3385 case 0:
2423f660
TS
3386 gen_op_mfc0_framemask();
3387 rn = "Framemask";
3388 break;
9c2149c8
TS
3389 default:
3390 goto die;
3391 }
3392 break;
3393 case 22:
2423f660
TS
3394 /* ignored */
3395 rn = "'Diagnostic"; /* implementation dependent */
3396 break;
9c2149c8
TS
3397 case 23:
3398 switch (sel) {
3399 case 0:
2423f660
TS
3400 gen_op_mfc0_debug(); /* EJTAG support */
3401 rn = "Debug";
3402 break;
9c2149c8 3403 case 1:
2423f660
TS
3404// gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3405 rn = "TraceControl";
3406// break;
9c2149c8 3407 case 2:
2423f660
TS
3408// gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3409 rn = "TraceControl2";
3410// break;
9c2149c8 3411 case 3:
2423f660
TS
3412// gen_op_dmfc0_usertracedata(); /* PDtrace support */
3413 rn = "UserTraceData";
3414// break;
9c2149c8 3415 case 4:
2423f660
TS
3416// gen_op_dmfc0_debug(); /* PDtrace support */
3417 rn = "TraceBPC";
3418// break;
9c2149c8
TS
3419 default:
3420 goto die;
3421 }
3422 break;
3423 case 24:
3424 switch (sel) {
3425 case 0:
2423f660
TS
3426 gen_op_dmfc0_depc(); /* EJTAG support */
3427 rn = "DEPC";
3428 break;
9c2149c8
TS
3429 default:
3430 goto die;
3431 }
3432 break;
3433 case 25:
3434 switch (sel) {
3435 case 0:
2423f660
TS
3436 gen_op_mfc0_performance0();
3437 rn = "Performance0";
9c2149c8
TS
3438 break;
3439 case 1:
2423f660
TS
3440// gen_op_dmfc0_performance1();
3441 rn = "Performance1";
3442// break;
9c2149c8 3443 case 2:
2423f660
TS
3444// gen_op_dmfc0_performance2();
3445 rn = "Performance2";
3446// break;
9c2149c8 3447 case 3:
2423f660
TS
3448// gen_op_dmfc0_performance3();
3449 rn = "Performance3";
3450// break;
9c2149c8 3451 case 4:
2423f660
TS
3452// gen_op_dmfc0_performance4();
3453 rn = "Performance4";
3454// break;
9c2149c8 3455 case 5:
2423f660
TS
3456// gen_op_dmfc0_performance5();
3457 rn = "Performance5";
3458// break;
9c2149c8 3459 case 6:
2423f660
TS
3460// gen_op_dmfc0_performance6();
3461 rn = "Performance6";
3462// break;
9c2149c8 3463 case 7:
2423f660
TS
3464// gen_op_dmfc0_performance7();
3465 rn = "Performance7";
3466// break;
9c2149c8
TS
3467 default:
3468 goto die;
3469 }
3470 break;
3471 case 26:
3472 rn = "ECC";
3473 break;
3474 case 27:
3475 switch (sel) {
3476 /* ignored */
3477 case 0 ... 3:
2423f660
TS
3478 rn = "CacheErr";
3479 break;
9c2149c8
TS
3480 default:
3481 goto die;
3482 }
3483 break;
3484 case 28:
3485 switch (sel) {
3486 case 0:
3487 case 2:
3488 case 4:
3489 case 6:
3490 gen_op_mfc0_taglo();
3491 rn = "TagLo";
3492 break;
3493 case 1:
3494 case 3:
3495 case 5:
3496 case 7:
3497 gen_op_mfc0_datalo();
3498 rn = "DataLo";
3499 break;
3500 default:
3501 goto die;
3502 }
3503 break;
3504 case 29:
3505 switch (sel) {
3506 case 0:
3507 case 2:
3508 case 4:
3509 case 6:
3510 gen_op_mfc0_taghi();
3511 rn = "TagHi";
3512 break;
3513 case 1:
3514 case 3:
3515 case 5:
3516 case 7:
3517 gen_op_mfc0_datahi();
3518 rn = "DataHi";
3519 break;
3520 default:
3521 goto die;
3522 }
3523 break;
3524 case 30:
3525 switch (sel) {
3526 case 0:
2423f660
TS
3527 gen_op_dmfc0_errorepc();
3528 rn = "ErrorEPC";
3529 break;
9c2149c8
TS
3530 default:
3531 goto die;
3532 }
3533 break;
3534 case 31:
3535 switch (sel) {
3536 case 0:
2423f660
TS
3537 gen_op_mfc0_desave(); /* EJTAG support */
3538 rn = "DESAVE";
3539 break;
9c2149c8
TS
3540 default:
3541 goto die;
3542 }
3543 break;
3544 default:
876d4b07 3545 goto die;
9c2149c8
TS
3546 }
3547#if defined MIPS_DEBUG_DISAS
3548 if (loglevel & CPU_LOG_TB_IN_ASM) {
3549 fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3550 rn, reg, sel);
3551 }
3552#endif
3553 return;
3554
3555die:
3556#if defined MIPS_DEBUG_DISAS
3557 if (loglevel & CPU_LOG_TB_IN_ASM) {
3558 fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3559 rn, reg, sel);
3560 }
3561#endif
3562 generate_exception(ctx, EXCP_RI);
3563}
3564
3565static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3566{
3567 const char *rn = "invalid";
3568
3569 switch (reg) {
3570 case 0:
3571 switch (sel) {
3572 case 0:
3573 gen_op_mtc0_index();
3574 rn = "Index";
3575 break;
3576 case 1:
2423f660 3577// gen_op_dmtc0_mvpcontrol(); /* MT ASE */
9c2149c8 3578 rn = "MVPControl";
2423f660 3579// break;
9c2149c8 3580 case 2:
2423f660 3581// gen_op_dmtc0_mvpconf0(); /* MT ASE */
9c2149c8 3582 rn = "MVPConf0";
2423f660 3583// break;
9c2149c8 3584 case 3:
2423f660 3585// gen_op_dmtc0_mvpconf1(); /* MT ASE */
9c2149c8 3586 rn = "MVPConf1";
2423f660 3587// break;
9c2149c8
TS
3588 default:
3589 goto die;
3590 }
3591 break;
3592 case 1:
3593 switch (sel) {
3594 case 0:
2423f660 3595 /* ignored */
9c2149c8 3596 rn = "Random";
2423f660 3597 break;
9c2149c8 3598 case 1:
2423f660 3599// gen_op_dmtc0_vpecontrol(); /* MT ASE */
9c2149c8 3600 rn = "VPEControl";
2423f660 3601// break;
9c2149c8 3602 case 2:
2423f660 3603// gen_op_dmtc0_vpeconf0(); /* MT ASE */
9c2149c8 3604 rn = "VPEConf0";
2423f660 3605// break;
9c2149c8 3606 case 3:
2423f660 3607// gen_op_dmtc0_vpeconf1(); /* MT ASE */
9c2149c8 3608 rn = "VPEConf1";
2423f660 3609// break;
9c2149c8 3610 case 4:
2423f660 3611// gen_op_dmtc0_YQMask(); /* MT ASE */
9c2149c8 3612 rn = "YQMask";
2423f660 3613// break;
9c2149c8 3614 case 5:
2423f660 3615// gen_op_dmtc0_vpeschedule(); /* MT ASE */
9c2149c8 3616 rn = "VPESchedule";
2423f660 3617// break;
9c2149c8 3618 case 6:
2423f660 3619// gen_op_dmtc0_vpeschefback(); /* MT ASE */
9c2149c8 3620 rn = "VPEScheFBack";
2423f660 3621// break;
9c2149c8 3622 case 7:
2423f660 3623// gen_op_dmtc0_vpeopt(); /* MT ASE */
9c2149c8 3624 rn = "VPEOpt";
2423f660 3625// break;
9c2149c8
TS
3626 default:
3627 goto die;
3628 }
3629 break;
3630 case 2:
3631 switch (sel) {
3632 case 0:
2423f660
TS
3633 gen_op_dmtc0_entrylo0();
3634 rn = "EntryLo0";
3635 break;
9c2149c8 3636 case 1:
2423f660
TS
3637// gen_op_dmtc0_tcstatus(); /* MT ASE */
3638 rn = "TCStatus";
3639// break;
9c2149c8 3640 case 2:
2423f660
TS
3641// gen_op_dmtc0_tcbind(); /* MT ASE */
3642 rn = "TCBind";
3643// break;
9c2149c8 3644 case 3:
2423f660
TS
3645// gen_op_dmtc0_tcrestart(); /* MT ASE */
3646 rn = "TCRestart";
3647// break;
9c2149c8 3648 case 4:
2423f660
TS
3649// gen_op_dmtc0_tchalt(); /* MT ASE */
3650 rn = "TCHalt";
3651// break;
9c2149c8 3652 case 5:
2423f660
TS
3653// gen_op_dmtc0_tccontext(); /* MT ASE */
3654 rn = "TCContext";
3655// break;
9c2149c8 3656 case 6:
2423f660
TS
3657// gen_op_dmtc0_tcschedule(); /* MT ASE */
3658 rn = "TCSchedule";
3659// break;
9c2149c8 3660 case 7:
2423f660
TS
3661// gen_op_dmtc0_tcschefback(); /* MT ASE */
3662 rn = "TCScheFBack";
3663// break;
9c2149c8
TS
3664 default:
3665 goto die;
3666 }
3667 break;
3668 case 3:
3669 switch (sel) {
3670 case 0:
2423f660
TS
3671 gen_op_dmtc0_entrylo1();
3672 rn = "EntryLo1";
3673 break;
9c2149c8
TS
3674 default:
3675 goto die;
876d4b07 3676 }
9c2149c8
TS
3677 break;
3678 case 4:
3679 switch (sel) {
3680 case 0:
2423f660
TS
3681 gen_op_dmtc0_context();
3682 rn = "Context";
3683 break;
9c2149c8 3684 case 1:
2423f660
TS
3685// gen_op_dmtc0_contextconfig(); /* SmartMIPS ASE */
3686 rn = "ContextConfig";
3687// break;
9c2149c8
TS
3688 default:
3689 goto die;
876d4b07 3690 }
9c2149c8
TS
3691 break;
3692 case 5:
3693 switch (sel) {
3694 case 0:
2423f660
TS
3695 gen_op_mtc0_pagemask();
3696 rn = "PageMask";
3697 break;
9c2149c8 3698 case 1:
2423f660
TS
3699 gen_op_mtc0_pagegrain();
3700 rn = "PageGrain";
3701 break;
9c2149c8
TS
3702 default:
3703 goto die;
876d4b07 3704 }
9c2149c8
TS
3705 break;
3706 case 6:
3707 switch (sel) {
3708 case 0:
2423f660
TS
3709 gen_op_mtc0_wired();
3710 rn = "Wired";
3711 break;
9c2149c8 3712 case 1:
2423f660
TS
3713// gen_op_dmtc0_srsconf0(); /* shadow registers */
3714 rn = "SRSConf0";
3715// break;
9c2149c8 3716 case 2:
2423f660
TS
3717// gen_op_dmtc0_srsconf1(); /* shadow registers */
3718 rn = "SRSConf1";
3719// break;
9c2149c8 3720 case 3:
2423f660
TS
3721// gen_op_dmtc0_srsconf2(); /* shadow registers */
3722 rn = "SRSConf2";
3723// break;
9c2149c8 3724 case 4:
2423f660
TS
3725// gen_op_dmtc0_srsconf3(); /* shadow registers */
3726 rn = "SRSConf3";
3727// break;
9c2149c8 3728 case 5:
2423f660
TS
3729// gen_op_dmtc0_srsconf4(); /* shadow registers */
3730 rn = "SRSConf4";
3731// break;
9c2149c8
TS
3732 default:
3733 goto die;
876d4b07 3734 }
9c2149c8
TS
3735 break;
3736 case 7:
3737 switch (sel) {
3738 case 0:
2423f660
TS
3739 gen_op_mtc0_hwrena();
3740 rn = "HWREna";
3741 break;
9c2149c8
TS
3742 default:
3743 goto die;
876d4b07 3744 }
9c2149c8
TS
3745 break;
3746 case 8:
3747 /* ignored */
3748 rn = "BadVaddr";
3749 break;
3750 case 9:
3751 switch (sel) {
3752 case 0:
2423f660
TS
3753 gen_op_mtc0_count();
3754 rn = "Count";
3755 break;
876d4b07 3756 /* 6,7 are implementation dependent */
9c2149c8
TS
3757 default:
3758 goto die;
876d4b07
TS
3759 }
3760 /* Stop translation as we may have switched the execution mode */
3761 ctx->bstate = BS_STOP;
9c2149c8
TS
3762 break;
3763 case 10:
3764 switch (sel) {
3765 case 0:
2423f660
TS
3766 gen_op_mtc0_entryhi();
3767 rn = "EntryHi";
3768 break;
9c2149c8
TS
3769 default:
3770 goto die;
876d4b07 3771 }
9c2149c8
TS
3772 break;
3773 case 11:
3774 switch (sel) {
3775 case 0:
2423f660
TS
3776 gen_op_mtc0_compare();
3777 rn = "Compare";
3778 break;
876d4b07 3779 /* 6,7 are implementation dependent */
9c2149c8
TS
3780 default:
3781 goto die;
876d4b07
TS
3782 }
3783 /* Stop translation as we may have switched the execution mode */
3784 ctx->bstate = BS_STOP;
9c2149c8
TS
3785 break;
3786 case 12:
3787 switch (sel) {
3788 case 0:
2423f660
TS
3789 gen_op_mtc0_status();
3790 rn = "Status";
3791 break;
9c2149c8 3792 case 1:
2423f660
TS
3793 gen_op_mtc0_intctl();
3794 rn = "IntCtl";
3795 break;
9c2149c8 3796 case 2:
2423f660
TS
3797 gen_op_mtc0_srsctl();
3798 rn = "SRSCtl";
3799 break;
9c2149c8 3800 case 3:
2423f660
TS
3801 gen_op_mtc0_srsmap(); /* shadow registers */
3802 rn = "SRSMap";
3803 break;
3804 default:
9c2149c8 3805 goto die;
876d4b07
TS
3806 }
3807 /* Stop translation as we may have switched the execution mode */
3808 ctx->bstate = BS_STOP;
9c2149c8
TS
3809 break;
3810 case 13:
3811 switch (sel) {
3812 case 0:
2423f660
TS
3813 gen_op_mtc0_cause();
3814 rn = "Cause";
3815 break;
9c2149c8
TS
3816 default:
3817 goto die;
876d4b07
TS
3818 }
3819 /* Stop translation as we may have switched the execution mode */
3820 ctx->bstate = BS_STOP;
9c2149c8
TS
3821 break;
3822 case 14:
3823 switch (sel) {
3824 case 0:
2423f660
TS
3825 gen_op_dmtc0_epc();
3826 rn = "EPC";
3827 break;
9c2149c8
TS
3828 default:
3829 goto die;
876d4b07 3830 }
9c2149c8
TS
3831 break;
3832 case 15:
3833 switch (sel) {
3834 case 0:
2423f660
TS
3835 /* ignored */
3836 rn = "PRid";
3837 break;
9c2149c8 3838 case 1:
2423f660
TS
3839 gen_op_mtc0_ebase();
3840 rn = "EBase";
3841 break;
9c2149c8
TS
3842 default:
3843 goto die;
876d4b07 3844 }
9c2149c8
TS
3845 break;
3846 case 16:
3847 switch (sel) {
3848 case 0:
3849 gen_op_mtc0_config0();
3850 rn = "Config";
2423f660
TS
3851 /* Stop translation as we may have switched the execution mode */
3852 ctx->bstate = BS_STOP;
9c2149c8
TS
3853 break;
3854 case 1:
2423f660 3855 /* ignored */
9c2149c8
TS
3856 rn = "Config1";
3857 break;
3858 case 2:
3859 gen_op_mtc0_config2();
3860 rn = "Config2";
2423f660
TS
3861 /* Stop translation as we may have switched the execution mode */
3862 ctx->bstate = BS_STOP;
9c2149c8
TS
3863 break;
3864 case 3:
2423f660 3865 /* ignored */
9c2149c8
TS
3866 rn = "Config3";
3867 break;
3868 /* 6,7 are implementation dependent */
3869 default:
3870 rn = "Invalid config selector";
3871 goto die;
3872 }
9c2149c8
TS
3873 break;
3874 case 17:
3875 switch (sel) {
3876 case 0:
2423f660
TS
3877 /* ignored */
3878 rn = "LLAddr";
3879 break;
9c2149c8
TS
3880 default:
3881 goto die;
3882 }
3883 break;
3884 case 18:
3885 switch (sel) {
3886 case 0:
2423f660
TS
3887 gen_op_dmtc0_watchlo0();
3888 rn = "WatchLo";
3889 break;
9c2149c8 3890 case 1:
2423f660
TS
3891// gen_op_dmtc0_watchlo1();
3892 rn = "WatchLo1";
3893// break;
9c2149c8 3894 case 2:
2423f660
TS
3895// gen_op_dmtc0_watchlo2();
3896 rn = "WatchLo2";
3897// break;
9c2149c8 3898 case 3:
2423f660
TS
3899// gen_op_dmtc0_watchlo3();
3900 rn = "WatchLo3";
3901// break;
9c2149c8 3902 case 4:
2423f660
TS
3903// gen_op_dmtc0_watchlo4();
3904 rn = "WatchLo4";
3905// break;
9c2149c8 3906 case 5:
2423f660
TS
3907// gen_op_dmtc0_watchlo5();
3908 rn = "WatchLo5";
3909// break;
9c2149c8 3910 case 6:
2423f660
TS
3911// gen_op_dmtc0_watchlo6();
3912 rn = "WatchLo6";
3913// break;
9c2149c8 3914 case 7:
2423f660
TS
3915// gen_op_dmtc0_watchlo7();
3916 rn = "WatchLo7";
3917// break;
9c2149c8
TS
3918 default:
3919 goto die;
3920 }
3921 break;
3922 case 19:
3923 switch (sel) {
3924 case 0:
2423f660
TS
3925 gen_op_mtc0_watchhi0();
3926 rn = "WatchHi";
3927 break;
9c2149c8 3928 case 1:
2423f660
TS
3929// gen_op_dmtc0_watchhi1();
3930 rn = "WatchHi1";
3931// break;
9c2149c8 3932 case 2:
2423f660
TS
3933// gen_op_dmtc0_watchhi2();
3934 rn = "WatchHi2";
3935// break;
9c2149c8 3936 case 3:
2423f660
TS
3937// gen_op_dmtc0_watchhi3();
3938 rn = "WatchHi3";
3939// break;
9c2149c8 3940 case 4:
2423f660
TS
3941// gen_op_dmtc0_watchhi4();
3942 rn = "WatchHi4";
3943// break;
9c2149c8 3944 case 5:
2423f660
TS
3945// gen_op_dmtc0_watchhi5();
3946 rn = "WatchHi5";
3947// break;
9c2149c8 3948 case 6:
2423f660
TS
3949// gen_op_dmtc0_watchhi6();
3950 rn = "WatchHi6";
3951// break;
9c2149c8 3952 case 7:
2423f660
TS
3953// gen_op_dmtc0_watchhi7();
3954 rn = "WatchHi7";
3955// break;
9c2149c8
TS
3956 default:
3957 goto die;
3958 }
3959 break;
3960 case 20:
3961 switch (sel) {
3962 case 0:
2423f660
TS
3963 /* 64 bit MMU only */
3964 gen_op_dmtc0_xcontext();
3965 rn = "XContext";
3966 break;
9c2149c8
TS
3967 default:
3968 goto die;
3969 }
3970 break;
3971 case 21:
3972 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3973 switch (sel) {
3974 case 0:
2423f660
TS
3975 gen_op_mtc0_framemask();
3976 rn = "Framemask";
3977 break;
9c2149c8
TS
3978 default:
3979 goto die;
3980 }
3981 break;
3982 case 22:
3983 /* ignored */
3984 rn = "Diagnostic"; /* implementation dependent */
876d4b07 3985 break;
9c2149c8
TS
3986 case 23:
3987 switch (sel) {
3988 case 0:
2423f660
TS
3989 gen_op_mtc0_debug(); /* EJTAG support */
3990 rn = "Debug";
3991 break;
9c2149c8 3992 case 1:
2423f660
TS
3993// gen_op_dmtc0_tracecontrol(); /* PDtrace support */
3994 rn = "TraceControl";
3995// break;
9c2149c8 3996 case 2:
2423f660
TS
3997// gen_op_dmtc0_tracecontrol2(); /* PDtrace support */
3998 rn = "TraceControl2";
3999// break;
9c2149c8 4000 case 3:
2423f660
TS
4001// gen_op_dmtc0_usertracedata(); /* PDtrace support */
4002 rn = "UserTraceData";
4003// break;
9c2149c8 4004 case 4:
2423f660
TS
4005// gen_op_dmtc0_debug(); /* PDtrace support */
4006 rn = "TraceBPC";
4007// break;
9c2149c8
TS
4008 default:
4009 goto die;
4010 }
2423f660
TS
4011 /* Stop translation as we may have switched the execution mode */
4012 ctx->bstate = BS_STOP;
9c2149c8
TS
4013 break;
4014 case 24:
4015 switch (sel) {
4016 case 0:
2423f660
TS
4017 gen_op_dmtc0_depc(); /* EJTAG support */
4018 rn = "DEPC";
4019 break;
9c2149c8
TS
4020 default:
4021 goto die;
4022 }
4023 break;
4024 case 25:
4025 switch (sel) {
4026 case 0:
2423f660
TS
4027 gen_op_mtc0_performance0();
4028 rn = "Performance0";
4029 break;
9c2149c8 4030 case 1:
2423f660
TS
4031// gen_op_dmtc0_performance1();
4032 rn = "Performance1";
4033// break;
9c2149c8 4034 case 2:
2423f660
TS
4035// gen_op_dmtc0_performance2();
4036 rn = "Performance2";
4037// break;
9c2149c8 4038 case 3:
2423f660
TS
4039// gen_op_dmtc0_performance3();
4040 rn = "Performance3";
4041// break;
9c2149c8 4042 case 4:
2423f660
TS
4043// gen_op_dmtc0_performance4();
4044 rn = "Performance4";
4045// break;
9c2149c8 4046 case 5:
2423f660
TS
4047// gen_op_dmtc0_performance5();
4048 rn = "Performance5";
4049// break;
9c2149c8 4050 case 6:
2423f660
TS
4051// gen_op_dmtc0_performance6();
4052 rn = "Performance6";
4053// break;
9c2149c8 4054 case 7:
2423f660
TS
4055// gen_op_dmtc0_performance7();
4056 rn = "Performance7";
4057// break;
9c2149c8
TS
4058 default:
4059 goto die;
4060 }
876d4b07 4061 break;
9c2149c8 4062 case 26:
876d4b07 4063 /* ignored */
9c2149c8 4064 rn = "ECC";
876d4b07 4065 break;
9c2149c8
TS
4066 case 27:
4067 switch (sel) {
4068 case 0 ... 3:
2423f660
TS
4069 /* ignored */
4070 rn = "CacheErr";
4071 break;
9c2149c8
TS
4072 default:
4073 goto die;
4074 }
876d4b07 4075 break;
9c2149c8
TS
4076 case 28:
4077 switch (sel) {
4078 case 0:
4079 case 2:
4080 case 4:
4081 case 6:
4082 gen_op_mtc0_taglo();
4083 rn = "TagLo";
4084 break;
4085 case 1:
4086 case 3:
4087 case 5:
4088 case 7:
2423f660 4089 gen_op_mtc0_datalo();
9c2149c8
TS
4090 rn = "DataLo";
4091 break;
4092 default:
4093 goto die;
4094 }
4095 break;
4096 case 29:
4097 switch (sel) {
4098 case 0:
4099 case 2:
4100 case 4:
4101 case 6:
4102 gen_op_mtc0_taghi();
4103 rn = "TagHi";
4104 break;
4105 case 1:
4106 case 3:
4107 case 5:
4108 case 7:
2423f660 4109 gen_op_mtc0_datahi();
9c2149c8
TS
4110 rn = "DataHi";
4111 break;
4112 default:
4113 rn = "invalid sel";
4114 goto die;
4115 }
876d4b07 4116 break;
9c2149c8
TS
4117 case 30:
4118 switch (sel) {
4119 case 0:
2423f660
TS
4120 gen_op_dmtc0_errorepc();
4121 rn = "ErrorEPC";
4122 break;
9c2149c8
TS
4123 default:
4124 goto die;
4125 }
4126 break;
4127 case 31:
4128 switch (sel) {
4129 case 0:
2423f660
TS
4130 gen_op_mtc0_desave(); /* EJTAG support */
4131 rn = "DESAVE";
4132 break;
9c2149c8
TS
4133 default:
4134 goto die;
4135 }
876d4b07
TS
4136 /* Stop translation as we may have switched the execution mode */
4137 ctx->bstate = BS_STOP;
9c2149c8
TS
4138 break;
4139 default:
876d4b07 4140 goto die;
9c2149c8
TS
4141 }
4142#if defined MIPS_DEBUG_DISAS
4143 if (loglevel & CPU_LOG_TB_IN_ASM) {
4144 fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4145 rn, reg, sel);
4146 }
4147#endif
4148 return;
4149
4150die:
4151#if defined MIPS_DEBUG_DISAS
4152 if (loglevel & CPU_LOG_TB_IN_ASM) {
4153 fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4154 rn, reg, sel);
4155 }
4156#endif
4157 generate_exception(ctx, EXCP_RI);
4158}
534ce69f 4159#endif /* TARGET_MIPS64 */
9c2149c8 4160
7a387fff 4161static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 4162{
7a387fff 4163 const char *opn = "unk";
6af0bf9c 4164
6af0bf9c
FB
4165 switch (opc) {
4166 case OPC_MFC0:
4167 if (rt == 0) {
4168 /* Treat as NOP */
4169 return;
4170 }
873eb012 4171 gen_mfc0(ctx, rd, ctx->opcode & 0x7);
6af0bf9c
FB
4172 gen_op_store_T0_gpr(rt);
4173 opn = "mfc0";
4174 break;
4175 case OPC_MTC0:
6af0bf9c 4176 GEN_LOAD_REG_TN(T0, rt);
8c0fdd85 4177 gen_mtc0(ctx, rd, ctx->opcode & 0x7);
6af0bf9c
FB
4178 opn = "mtc0";
4179 break;
534ce69f 4180#ifdef TARGET_MIPS64
9c2149c8
TS
4181 case OPC_DMFC0:
4182 if (rt == 0) {
4183 /* Treat as NOP */
4184 return;
4185 }
4186 gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4187 gen_op_store_T0_gpr(rt);
4188 opn = "dmfc0";
4189 break;
4190 case OPC_DMTC0:
9c2149c8
TS
4191 GEN_LOAD_REG_TN(T0, rt);
4192 gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4193 opn = "dmtc0";
4194 break;
534ce69f 4195#endif
6af0bf9c
FB
4196#if defined(MIPS_USES_R4K_TLB)
4197 case OPC_TLBWI:
4198 gen_op_tlbwi();
4199 opn = "tlbwi";
4200 break;
4201 case OPC_TLBWR:
4202 gen_op_tlbwr();
4203 opn = "tlbwr";
4204 break;
4205 case OPC_TLBP:
4206 gen_op_tlbp();
4207 opn = "tlbp";
4208 break;
4209 case OPC_TLBR:
4210 gen_op_tlbr();
4211 opn = "tlbr";
4212 break;
4213#endif
4214 case OPC_ERET:
4215 opn = "eret";
4216 save_cpu_state(ctx, 0);
4217 gen_op_eret();
4218 ctx->bstate = BS_EXCP;
4219 break;
4220 case OPC_DERET:
4221 opn = "deret";
4222 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4223 generate_exception(ctx, EXCP_RI);
4224 } else {
4225 save_cpu_state(ctx, 0);
4226 gen_op_deret();
4227 ctx->bstate = BS_EXCP;
4228 }
4229 break;
4ad40f36
FB
4230 case OPC_WAIT:
4231 opn = "wait";
4232 /* If we get an exception, we want to restart at next instruction */
4233 ctx->pc += 4;
4234 save_cpu_state(ctx, 1);
4235 ctx->pc -= 4;
4236 gen_op_wait();
4237 ctx->bstate = BS_EXCP;
4238 break;
6af0bf9c
FB
4239 default:
4240 if (loglevel & CPU_LOG_TB_IN_ASM) {
4241 fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
4242 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4243 ((ctx->opcode >> 16) & 0x1F));
4244 }
4245 generate_exception(ctx, EXCP_RI);
4246 return;
4247 }
4248 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4249}
4250
6ea83fed 4251/* CP1 Branches (before delay slot) */
7a387fff 4252static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
5a5012ec 4253 int32_t cc, int32_t offset)
6ea83fed
FB
4254{
4255 target_ulong btarget;
4256
4257 btarget = ctx->pc + 4 + offset;
4258
7a387fff
TS
4259 switch (op) {
4260 case OPC_BC1F:
5a5012ec 4261 gen_op_bc1f(cc);
3594c774 4262 MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
6ea83fed 4263 goto not_likely;
7a387fff 4264 case OPC_BC1FL:
5a5012ec 4265 gen_op_bc1f(cc);
3594c774 4266 MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
6ea83fed 4267 goto likely;
7a387fff 4268 case OPC_BC1T:
5a5012ec 4269 gen_op_bc1t(cc);
3594c774 4270 MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
5a5012ec 4271 goto not_likely;
7a387fff 4272 case OPC_BC1TL:
5a5012ec 4273 gen_op_bc1t(cc);
3594c774 4274 MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
6ea83fed
FB
4275 likely:
4276 ctx->hflags |= MIPS_HFLAG_BL;
5a5012ec
TS
4277 gen_op_set_bcond();
4278 gen_op_save_bcond();
6ea83fed 4279 break;
5a5012ec
TS
4280 case OPC_BC1FANY2:
4281 gen_op_bc1fany2(cc);
4282 MIPS_DEBUG("bc1fany2 " TARGET_FMT_lx, btarget);
4283 goto not_likely;
4284 case OPC_BC1TANY2:
4285 gen_op_bc1tany2(cc);
4286 MIPS_DEBUG("bc1tany2 " TARGET_FMT_lx, btarget);
4287 goto not_likely;
4288 case OPC_BC1FANY4:
4289 gen_op_bc1fany4(cc);
4290 MIPS_DEBUG("bc1fany4 " TARGET_FMT_lx, btarget);
4291 goto not_likely;
4292 case OPC_BC1TANY4:
4293 gen_op_bc1tany4(cc);
4294 MIPS_DEBUG("bc1tany4 " TARGET_FMT_lx, btarget);
4295 not_likely:
4296 ctx->hflags |= MIPS_HFLAG_BC;
4297 gen_op_set_bcond();
4298 break;
4299 default:
4300 MIPS_INVAL("cp1 branch");
e397ee33 4301 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
4302 return;
4303 }
6ea83fed 4304
3594c774 4305 MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
6ea83fed
FB
4306 ctx->hflags, btarget);
4307 ctx->btarget = btarget;
4308
4309 return;
4310}
4311
6af0bf9c 4312/* Coprocessor 1 (FPU) */
5a5012ec
TS
4313
4314/* verify if floating point register is valid; an operation is not defined
4315 * if bit 0 of any register specification is set and the FR bit in the
4316 * Status register equals zero, since the register numbers specify an
4317 * even-odd pair of adjacent coprocessor general registers. When the FR bit
4318 * in the Status register equals one, both even and odd register numbers
4319 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
4320 *
4321 * Multiple 64 bit wide registers can be checked by calling
4322 * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
4323 *
4324 * FIXME: This is broken for R2, it needs to be checked at runtime, not
4325 * at translation time.
4326 */
4327#define CHECK_FR(ctx, freg) do { \
4328 if (!((ctx)->CP0_Status & (1 << CP0St_FR)) && ((freg) & 1)) { \
4329 generate_exception (ctx, EXCP_RI); \
4330 return; \
4331 } \
4332 } while(0)
4333
4334#define FOP(func, fmt) (((fmt) << 21) | (func))
4335
7a387fff 4336static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 4337{
7a387fff 4338 const char *opn = "unk";
6ea83fed
FB
4339
4340 switch (opc) {
4341 case OPC_MFC1:
4342 GEN_LOAD_FREG_FTN(WT0, fs);
4343 gen_op_mfc1();
4344 GEN_STORE_TN_REG(rt, T0);
4345 opn = "mfc1";
4346 break;
4347 case OPC_MTC1:
4348 GEN_LOAD_REG_TN(T0, rt);
4349 gen_op_mtc1();
4350 GEN_STORE_FTN_FREG(fs, WT0);
4351 opn = "mtc1";
4352 break;
4353 case OPC_CFC1:
6ea83fed
FB
4354 GEN_LOAD_IMM_TN(T1, fs);
4355 gen_op_cfc1();
4356 GEN_STORE_TN_REG(rt, T0);
4357 opn = "cfc1";
4358 break;
4359 case OPC_CTC1:
6ea83fed
FB
4360 GEN_LOAD_IMM_TN(T1, fs);
4361 GEN_LOAD_REG_TN(T0, rt);
4362 gen_op_ctc1();
4363 opn = "ctc1";
4364 break;
9c2149c8 4365 case OPC_DMFC1:
5a5012ec
TS
4366 GEN_LOAD_FREG_FTN(DT0, fs);
4367 gen_op_dmfc1();
4368 GEN_STORE_TN_REG(rt, T0);
4369 opn = "dmfc1";
4370 break;
9c2149c8 4371 case OPC_DMTC1:
5a5012ec
TS
4372 GEN_LOAD_REG_TN(T0, rt);
4373 gen_op_dmtc1();
4374 GEN_STORE_FTN_FREG(fs, DT0);
4375 opn = "dmtc1";
4376 break;
4377 case OPC_MFHC1:
4378 CHECK_FR(ctx, fs);
4379 GEN_LOAD_FREG_FTN(WTH0, fs);
4380 gen_op_mfhc1();
4381 GEN_STORE_TN_REG(rt, T0);
4382 opn = "mfhc1";
4383 break;
4384 case OPC_MTHC1:
4385 CHECK_FR(ctx, fs);
4386 GEN_LOAD_REG_TN(T0, rt);
4387 gen_op_mthc1();
4388 GEN_STORE_FTN_FREG(fs, WTH0);
4389 opn = "mthc1";
4390 break;
6ea83fed
FB
4391 default:
4392 if (loglevel & CPU_LOG_TB_IN_ASM) {
4393 fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
4394 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4395 ((ctx->opcode >> 16) & 0x1F));
4396 }
e397ee33 4397 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
4398 return;
4399 }
4400 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4401}
4402
5a5012ec
TS
4403static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4404{
4405 uint32_t ccbit;
6ea83fed 4406
5a5012ec
TS
4407 GEN_LOAD_REG_TN(T0, rd);
4408 GEN_LOAD_REG_TN(T1, rs);
4409 if (cc)
4410 ccbit = 1 << (24 + cc);
4411 else
4412 ccbit = 1 << 23;
4413 if (!tf)
4414 gen_op_movf(ccbit);
4415 else
4416 gen_op_movt(ccbit);
4417 GEN_STORE_TN_REG(rd, T0);
4418}
4419
4420#define GEN_MOVCF(fmt) \
4421static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4422{ \
4423 uint32_t ccbit; \
4424 \
4425 if (cc) \
4426 ccbit = 1 << (24 + cc); \
4427 else \
4428 ccbit = 1 << 23; \
4429 if (!tf) \
4430 glue(gen_op_float_movf_, fmt)(ccbit); \
4431 else \
4432 glue(gen_op_float_movt_, fmt)(ccbit); \
4433}
4434GEN_MOVCF(d);
4435GEN_MOVCF(s);
4436GEN_MOVCF(ps);
4437#undef GEN_MOVCF
6ea83fed 4438
5a5012ec
TS
4439static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4440 int fs, int fd, int cc)
6ea83fed 4441{
7a387fff 4442 const char *opn = "unk";
6ea83fed
FB
4443 const char *condnames[] = {
4444 "c.f",
4445 "c.un",
4446 "c.eq",
4447 "c.ueq",
4448 "c.olt",
4449 "c.ult",
4450 "c.ole",
4451 "c.ule",
4452 "c.sf",
4453 "c.ngle",
4454 "c.seq",
4455 "c.ngl",
4456 "c.lt",
4457 "c.nge",
4458 "c.le",
4459 "c.ngt",
4460 };
4461 int binary = 0;
7a387fff
TS
4462 uint32_t func = ctx->opcode & 0x3f;
4463
6ea83fed 4464 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5a5012ec
TS
4465 case FOP(0, 16):
4466 GEN_LOAD_FREG_FTN(WT0, fs);
4467 GEN_LOAD_FREG_FTN(WT1, ft);
4468 gen_op_float_add_s();
4469 GEN_STORE_FTN_FREG(fd, WT2);
4470 opn = "add.s";
4471 binary = 1;
4472 break;
4473 case FOP(1, 16):
4474 GEN_LOAD_FREG_FTN(WT0, fs);
4475 GEN_LOAD_FREG_FTN(WT1, ft);
4476 gen_op_float_sub_s();
4477 GEN_STORE_FTN_FREG(fd, WT2);
4478 opn = "sub.s";
4479 binary = 1;
4480 break;
4481 case FOP(2, 16):
4482 GEN_LOAD_FREG_FTN(WT0, fs);
4483 GEN_LOAD_FREG_FTN(WT1, ft);
4484 gen_op_float_mul_s();
4485 GEN_STORE_FTN_FREG(fd, WT2);
4486 opn = "mul.s";
4487 binary = 1;
4488 break;
4489 case FOP(3, 16):
4490 GEN_LOAD_FREG_FTN(WT0, fs);
4491 GEN_LOAD_FREG_FTN(WT1, ft);
4492 gen_op_float_div_s();
4493 GEN_STORE_FTN_FREG(fd, WT2);
4494 opn = "div.s";
4495 binary = 1;
4496 break;
4497 case FOP(4, 16):
4498 GEN_LOAD_FREG_FTN(WT0, fs);
4499 gen_op_float_sqrt_s();
4500 GEN_STORE_FTN_FREG(fd, WT2);
4501 opn = "sqrt.s";
4502 break;
4503 case FOP(5, 16):
4504 GEN_LOAD_FREG_FTN(WT0, fs);
4505 gen_op_float_abs_s();
4506 GEN_STORE_FTN_FREG(fd, WT2);
4507 opn = "abs.s";
4508 break;
4509 case FOP(6, 16):
4510 GEN_LOAD_FREG_FTN(WT0, fs);
4511 gen_op_float_mov_s();
4512 GEN_STORE_FTN_FREG(fd, WT2);
4513 opn = "mov.s";
4514 break;
4515 case FOP(7, 16):
4516 GEN_LOAD_FREG_FTN(WT0, fs);
4517 gen_op_float_chs_s();
4518 GEN_STORE_FTN_FREG(fd, WT2);
4519 opn = "neg.s";
4520 break;
4521 case FOP(8, 16):
4522 CHECK_FR(ctx, fs);
4523 GEN_LOAD_FREG_FTN(WT0, fs);
4524 gen_op_float_roundl_s();
4525 GEN_STORE_FTN_FREG(fd, DT2);
4526 opn = "round.l.s";
4527 break;
4528 case FOP(9, 16):
4529 CHECK_FR(ctx, fs);
4530 GEN_LOAD_FREG_FTN(WT0, fs);
4531 gen_op_float_truncl_s();
4532 GEN_STORE_FTN_FREG(fd, DT2);
4533 opn = "trunc.l.s";
4534 break;
4535 case FOP(10, 16):
4536 CHECK_FR(ctx, fs);
4537 GEN_LOAD_FREG_FTN(WT0, fs);
4538 gen_op_float_ceill_s();
4539 GEN_STORE_FTN_FREG(fd, DT2);
4540 opn = "ceil.l.s";
4541 break;
4542 case FOP(11, 16):
4543 CHECK_FR(ctx, fs);
4544 GEN_LOAD_FREG_FTN(WT0, fs);
4545 gen_op_float_floorl_s();
4546 GEN_STORE_FTN_FREG(fd, DT2);
4547 opn = "floor.l.s";
4548 break;
4549 case FOP(12, 16):
4550 GEN_LOAD_FREG_FTN(WT0, fs);
4551 gen_op_float_roundw_s();
4552 GEN_STORE_FTN_FREG(fd, WT2);
4553 opn = "round.w.s";
4554 break;
4555 case FOP(13, 16):
4556 GEN_LOAD_FREG_FTN(WT0, fs);
4557 gen_op_float_truncw_s();
4558 GEN_STORE_FTN_FREG(fd, WT2);
4559 opn = "trunc.w.s";
4560 break;
4561 case FOP(14, 16):
4562 GEN_LOAD_FREG_FTN(WT0, fs);
4563 gen_op_float_ceilw_s();
4564 GEN_STORE_FTN_FREG(fd, WT2);
4565 opn = "ceil.w.s";
4566 break;
4567 case FOP(15, 16):
4568 GEN_LOAD_FREG_FTN(WT0, fs);
4569 gen_op_float_floorw_s();
4570 GEN_STORE_FTN_FREG(fd, WT2);
4571 opn = "floor.w.s";
4572 break;
4573 case FOP(17, 16):
4574 GEN_LOAD_REG_TN(T0, ft);
4575 GEN_LOAD_FREG_FTN(WT0, fs);
4576 GEN_LOAD_FREG_FTN(WT2, fd);
4577 gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
4578 GEN_STORE_FTN_FREG(fd, WT2);
4579 opn = "movcf.s";
4580 break;
4581 case FOP(18, 16):
4582 GEN_LOAD_REG_TN(T0, ft);
4583 GEN_LOAD_FREG_FTN(WT0, fs);
4584 GEN_LOAD_FREG_FTN(WT2, fd);
4585 gen_op_float_movz_s();
4586 GEN_STORE_FTN_FREG(fd, WT2);
4587 opn = "movz.s";
4588 break;
4589 case FOP(19, 16):
4590 GEN_LOAD_REG_TN(T0, ft);
4591 GEN_LOAD_FREG_FTN(WT0, fs);
4592 GEN_LOAD_FREG_FTN(WT2, fd);
4593 gen_op_float_movn_s();
4594 GEN_STORE_FTN_FREG(fd, WT2);
4595 opn = "movn.s";
4596 break;
4597 case FOP(33, 16):
4598 CHECK_FR(ctx, fd);
4599 GEN_LOAD_FREG_FTN(WT0, fs);
4600 gen_op_float_cvtd_s();
4601 GEN_STORE_FTN_FREG(fd, DT2);
4602 opn = "cvt.d.s";
4603 break;
4604 case FOP(36, 16):
4605 GEN_LOAD_FREG_FTN(WT0, fs);
4606 gen_op_float_cvtw_s();
4607 GEN_STORE_FTN_FREG(fd, WT2);
4608 opn = "cvt.w.s";
4609 break;
4610 case FOP(37, 16):
4611 CHECK_FR(ctx, fs | fd);
4612 GEN_LOAD_FREG_FTN(WT0, fs);
4613 gen_op_float_cvtl_s();
4614 GEN_STORE_FTN_FREG(fd, DT2);
4615 opn = "cvt.l.s";
4616 break;
4617 case FOP(38, 16):
4618 CHECK_FR(ctx, fs | ft | fd);
4619 GEN_LOAD_FREG_FTN(WT1, fs);
4620 GEN_LOAD_FREG_FTN(WT0, ft);
4621 gen_op_float_cvtps_s();
4622 GEN_STORE_FTN_FREG(fd, DT2);
4623 opn = "cvt.ps.s";
4624 break;
4625 case FOP(48, 16):
4626 case FOP(49, 16):
4627 case FOP(50, 16):
4628 case FOP(51, 16):
4629 case FOP(52, 16):
4630 case FOP(53, 16):
4631 case FOP(54, 16):
4632 case FOP(55, 16):
4633 case FOP(56, 16):
4634 case FOP(57, 16):
4635 case FOP(58, 16):
4636 case FOP(59, 16):
4637 case FOP(60, 16):
4638 case FOP(61, 16):
4639 case FOP(62, 16):
4640 case FOP(63, 16):
4641 GEN_LOAD_FREG_FTN(WT0, fs);
4642 GEN_LOAD_FREG_FTN(WT1, ft);
4643 gen_cmp_s(func-48, cc);
4644 opn = condnames[func-48];
4645 break;
6ea83fed
FB
4646 case FOP(0, 17):
4647 CHECK_FR(ctx, fs | ft | fd);
4648 GEN_LOAD_FREG_FTN(DT0, fs);
4649 GEN_LOAD_FREG_FTN(DT1, ft);
4650 gen_op_float_add_d();
4651 GEN_STORE_FTN_FREG(fd, DT2);
4652 opn = "add.d";
4653 binary = 1;
4654 break;
4655 case FOP(1, 17):
4656 CHECK_FR(ctx, fs | ft | fd);
4657 GEN_LOAD_FREG_FTN(DT0, fs);
4658 GEN_LOAD_FREG_FTN(DT1, ft);
4659 gen_op_float_sub_d();
4660 GEN_STORE_FTN_FREG(fd, DT2);
4661 opn = "sub.d";
4662 binary = 1;
4663 break;
4664 case FOP(2, 17):
4665 CHECK_FR(ctx, fs | ft | fd);
4666 GEN_LOAD_FREG_FTN(DT0, fs);
4667 GEN_LOAD_FREG_FTN(DT1, ft);
4668 gen_op_float_mul_d();
4669 GEN_STORE_FTN_FREG(fd, DT2);
4670 opn = "mul.d";
4671 binary = 1;
4672 break;
4673 case FOP(3, 17):
4674 CHECK_FR(ctx, fs | ft | fd);
4675 GEN_LOAD_FREG_FTN(DT0, fs);
4676 GEN_LOAD_FREG_FTN(DT1, ft);
4677 gen_op_float_div_d();
4678 GEN_STORE_FTN_FREG(fd, DT2);
4679 opn = "div.d";
4680 binary = 1;
4681 break;
4682 case FOP(4, 17):
4683 CHECK_FR(ctx, fs | fd);
4684 GEN_LOAD_FREG_FTN(DT0, fs);
4685 gen_op_float_sqrt_d();
4686 GEN_STORE_FTN_FREG(fd, DT2);
4687 opn = "sqrt.d";
4688 break;
4689 case FOP(5, 17):
4690 CHECK_FR(ctx, fs | fd);
4691 GEN_LOAD_FREG_FTN(DT0, fs);
4692 gen_op_float_abs_d();
4693 GEN_STORE_FTN_FREG(fd, DT2);
4694 opn = "abs.d";
4695 break;
4696 case FOP(6, 17):
4697 CHECK_FR(ctx, fs | fd);
4698 GEN_LOAD_FREG_FTN(DT0, fs);
4699 gen_op_float_mov_d();
4700 GEN_STORE_FTN_FREG(fd, DT2);
4701 opn = "mov.d";
4702 break;
4703 case FOP(7, 17):
4704 CHECK_FR(ctx, fs | fd);
4705 GEN_LOAD_FREG_FTN(DT0, fs);
4706 gen_op_float_chs_d();
4707 GEN_STORE_FTN_FREG(fd, DT2);
4708 opn = "neg.d";
4709 break;
5a5012ec
TS
4710 case FOP(8, 17):
4711 CHECK_FR(ctx, fs);
4712 GEN_LOAD_FREG_FTN(DT0, fs);
4713 gen_op_float_roundl_d();
4714 GEN_STORE_FTN_FREG(fd, DT2);
4715 opn = "round.l.d";
4716 break;
4717 case FOP(9, 17):
4718 CHECK_FR(ctx, fs);
4719 GEN_LOAD_FREG_FTN(DT0, fs);
4720 gen_op_float_truncl_d();
4721 GEN_STORE_FTN_FREG(fd, DT2);
4722 opn = "trunc.l.d";
4723 break;
4724 case FOP(10, 17):
4725 CHECK_FR(ctx, fs);
4726 GEN_LOAD_FREG_FTN(DT0, fs);
4727 gen_op_float_ceill_d();
4728 GEN_STORE_FTN_FREG(fd, DT2);
4729 opn = "ceil.l.d";
4730 break;
4731 case FOP(11, 17):
4732 CHECK_FR(ctx, fs);
4733 GEN_LOAD_FREG_FTN(DT0, fs);
4734 gen_op_float_floorl_d();
4735 GEN_STORE_FTN_FREG(fd, DT2);
4736 opn = "floor.l.d";
4737 break;
6ea83fed 4738 case FOP(12, 17):
00a709c7 4739 CHECK_FR(ctx, fs);
6ea83fed
FB
4740 GEN_LOAD_FREG_FTN(DT0, fs);
4741 gen_op_float_roundw_d();
4742 GEN_STORE_FTN_FREG(fd, WT2);
4743 opn = "round.w.d";
4744 break;
4745 case FOP(13, 17):
00a709c7 4746 CHECK_FR(ctx, fs);
6ea83fed
FB
4747 GEN_LOAD_FREG_FTN(DT0, fs);
4748 gen_op_float_truncw_d();
4749 GEN_STORE_FTN_FREG(fd, WT2);
4750 opn = "trunc.w.d";
4751 break;
4752 case FOP(14, 17):
00a709c7 4753 CHECK_FR(ctx, fs);
6ea83fed
FB
4754 GEN_LOAD_FREG_FTN(DT0, fs);
4755 gen_op_float_ceilw_d();
4756 GEN_STORE_FTN_FREG(fd, WT2);
4757 opn = "ceil.w.d";
4758 break;
4759 case FOP(15, 17):
00a709c7 4760 CHECK_FR(ctx, fs);
6ea83fed
FB
4761 GEN_LOAD_FREG_FTN(DT0, fs);
4762 gen_op_float_floorw_d();
4763 GEN_STORE_FTN_FREG(fd, WT2);
7a387fff 4764 opn = "floor.w.d";
6ea83fed 4765 break;
5a5012ec
TS
4766 case FOP(17, 17):
4767 GEN_LOAD_REG_TN(T0, ft);
4768 GEN_LOAD_FREG_FTN(DT0, fs);
4769 GEN_LOAD_FREG_FTN(DT2, fd);
4770 gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
dd016883 4771 GEN_STORE_FTN_FREG(fd, DT2);
5a5012ec 4772 opn = "movcf.d";
dd016883 4773 break;
5a5012ec
TS
4774 case FOP(18, 17):
4775 GEN_LOAD_REG_TN(T0, ft);
4776 GEN_LOAD_FREG_FTN(DT0, fs);
4777 GEN_LOAD_FREG_FTN(DT2, fd);
4778 gen_op_float_movz_d();
6ea83fed 4779 GEN_STORE_FTN_FREG(fd, DT2);
5a5012ec
TS
4780 opn = "movz.d";
4781 break;
4782 case FOP(19, 17):
4783 GEN_LOAD_REG_TN(T0, ft);
4784 GEN_LOAD_FREG_FTN(DT0, fs);
4785 GEN_LOAD_FREG_FTN(DT2, fd);
4786 gen_op_float_movn_d();
4787 GEN_STORE_FTN_FREG(fd, DT2);
4788 opn = "movn.d";
6ea83fed
FB
4789 break;
4790 case FOP(48, 17):
4791 case FOP(49, 17):
4792 case FOP(50, 17):
4793 case FOP(51, 17):
4794 case FOP(52, 17):
4795 case FOP(53, 17):
4796 case FOP(54, 17):
4797 case FOP(55, 17):
4798 case FOP(56, 17):
4799 case FOP(57, 17):
4800 case FOP(58, 17):
4801 case FOP(59, 17):
4802 case FOP(60, 17):
4803 case FOP(61, 17):
4804 case FOP(62, 17):
4805 case FOP(63, 17):
4806 CHECK_FR(ctx, fs | ft);
4807 GEN_LOAD_FREG_FTN(DT0, fs);
4808 GEN_LOAD_FREG_FTN(DT1, ft);
5a5012ec 4809 gen_cmp_d(func-48, cc);
6ea83fed
FB
4810 opn = condnames[func-48];
4811 break;
5a5012ec
TS
4812 case FOP(32, 17):
4813 CHECK_FR(ctx, fs);
4814 GEN_LOAD_FREG_FTN(DT0, fs);
4815 gen_op_float_cvts_d();
4816 GEN_STORE_FTN_FREG(fd, WT2);
4817 opn = "cvt.s.d";
4818 break;
4819 case FOP(36, 17):
4820 CHECK_FR(ctx, fs);
4821 GEN_LOAD_FREG_FTN(DT0, fs);
4822 gen_op_float_cvtw_d();
4823 GEN_STORE_FTN_FREG(fd, WT2);
4824 opn = "cvt.w.d";
4825 break;
4826 case FOP(37, 17):
4827 CHECK_FR(ctx, fs | fd);
4828 GEN_LOAD_FREG_FTN(DT0, fs);
4829 gen_op_float_cvtl_d();
4830 GEN_STORE_FTN_FREG(fd, DT2);
4831 opn = "cvt.l.d";
4832 break;
4833 case FOP(32, 20):
6ea83fed 4834 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec 4835 gen_op_float_cvts_w();
6ea83fed 4836 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec 4837 opn = "cvt.s.w";
6ea83fed 4838 break;
5a5012ec
TS
4839 case FOP(33, 20):
4840 CHECK_FR(ctx, fd);
6ea83fed 4841 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec
TS
4842 gen_op_float_cvtd_w();
4843 GEN_STORE_FTN_FREG(fd, DT2);
4844 opn = "cvt.d.w";
4845 break;
4846 case FOP(32, 21):
4847 CHECK_FR(ctx, fs);
4848 GEN_LOAD_FREG_FTN(DT0, fs);
4849 gen_op_float_cvts_l();
4850 GEN_STORE_FTN_FREG(fd, WT2);
4851 opn = "cvt.s.l";
4852 break;
4853 case FOP(33, 21):
4854 CHECK_FR(ctx, fs | fd);
4855 GEN_LOAD_FREG_FTN(DT0, fs);
4856 gen_op_float_cvtd_l();
4857 GEN_STORE_FTN_FREG(fd, DT2);
4858 opn = "cvt.d.l";
4859 break;
4860 case FOP(38, 20):
4861 case FOP(38, 21):
4862 CHECK_FR(ctx, fs | fd);
4863 GEN_LOAD_FREG_FTN(WT0, fs);
4864 GEN_LOAD_FREG_FTN(WTH0, fs);
4865 gen_op_float_cvtps_pw();
4866 GEN_STORE_FTN_FREG(fd, WT2);
4867 GEN_STORE_FTN_FREG(fd, WTH2);
4868 opn = "cvt.ps.pw";
4869 break;
4870 case FOP(0, 22):
4871 CHECK_FR(ctx, fs | ft | fd);
4872 GEN_LOAD_FREG_FTN(WT0, fs);
4873 GEN_LOAD_FREG_FTN(WTH0, fs);
6ea83fed 4874 GEN_LOAD_FREG_FTN(WT1, ft);
5a5012ec
TS
4875 GEN_LOAD_FREG_FTN(WTH1, ft);
4876 gen_op_float_add_ps();
6ea83fed 4877 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4878 GEN_STORE_FTN_FREG(fd, WTH2);
4879 opn = "add.ps";
6ea83fed 4880 break;
5a5012ec
TS
4881 case FOP(1, 22):
4882 CHECK_FR(ctx, fs | ft | fd);
6ea83fed 4883 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec 4884 GEN_LOAD_FREG_FTN(WTH0, fs);
6ea83fed 4885 GEN_LOAD_FREG_FTN(WT1, ft);
5a5012ec
TS
4886 GEN_LOAD_FREG_FTN(WTH1, ft);
4887 gen_op_float_sub_ps();
6ea83fed 4888 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4889 GEN_STORE_FTN_FREG(fd, WTH2);
4890 opn = "sub.ps";
6ea83fed 4891 break;
5a5012ec
TS
4892 case FOP(2, 22):
4893 CHECK_FR(ctx, fs | ft | fd);
6ea83fed 4894 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec 4895 GEN_LOAD_FREG_FTN(WTH0, fs);
6ea83fed 4896 GEN_LOAD_FREG_FTN(WT1, ft);
5a5012ec
TS
4897 GEN_LOAD_FREG_FTN(WTH1, ft);
4898 gen_op_float_mul_ps();
6ea83fed 4899 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4900 GEN_STORE_FTN_FREG(fd, WTH2);
4901 opn = "mul.ps";
6ea83fed 4902 break;
5a5012ec
TS
4903 case FOP(5, 22):
4904 CHECK_FR(ctx, fs | fd);
6ea83fed 4905 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec
TS
4906 GEN_LOAD_FREG_FTN(WTH0, fs);
4907 gen_op_float_abs_ps();
6ea83fed 4908 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4909 GEN_STORE_FTN_FREG(fd, WTH2);
4910 opn = "abs.ps";
6ea83fed 4911 break;
5a5012ec
TS
4912 case FOP(6, 22):
4913 CHECK_FR(ctx, fs | fd);
6ea83fed 4914 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec
TS
4915 GEN_LOAD_FREG_FTN(WTH0, fs);
4916 gen_op_float_mov_ps();
6ea83fed 4917 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4918 GEN_STORE_FTN_FREG(fd, WTH2);
4919 opn = "mov.ps";
6ea83fed 4920 break;
5a5012ec
TS
4921 case FOP(7, 22):
4922 CHECK_FR(ctx, fs | fd);
6ea83fed 4923 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec
TS
4924 GEN_LOAD_FREG_FTN(WTH0, fs);
4925 gen_op_float_chs_ps();
6ea83fed 4926 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4927 GEN_STORE_FTN_FREG(fd, WTH2);
4928 opn = "neg.ps";
6ea83fed 4929 break;
5a5012ec
TS
4930 case FOP(17, 22):
4931 GEN_LOAD_REG_TN(T0, ft);
6ea83fed 4932 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec
TS
4933 GEN_LOAD_FREG_FTN(WTH0, fs);
4934 GEN_LOAD_FREG_FTN(WT2, fd);
4935 GEN_LOAD_FREG_FTN(WTH2, fd);
4936 gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 4937 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4938 GEN_STORE_FTN_FREG(fd, WTH2);
4939 opn = "movcf.ps";
6ea83fed 4940 break;
5a5012ec
TS
4941 case FOP(18, 22):
4942 GEN_LOAD_REG_TN(T0, ft);
6ea83fed 4943 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec
TS
4944 GEN_LOAD_FREG_FTN(WTH0, fs);
4945 GEN_LOAD_FREG_FTN(WT2, fd);
4946 GEN_LOAD_FREG_FTN(WTH2, fd);
4947 gen_op_float_movz_ps();
6ea83fed 4948 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4949 GEN_STORE_FTN_FREG(fd, WTH2);
4950 opn = "movz.ps";
6ea83fed 4951 break;
5a5012ec
TS
4952 case FOP(19, 22):
4953 GEN_LOAD_REG_TN(T0, ft);
6ea83fed 4954 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec
TS
4955 GEN_LOAD_FREG_FTN(WTH0, fs);
4956 GEN_LOAD_FREG_FTN(WT2, fd);
4957 GEN_LOAD_FREG_FTN(WTH2, fd);
4958 gen_op_float_movn_ps();
6ea83fed 4959 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4960 GEN_STORE_FTN_FREG(fd, WTH2);
4961 opn = "movn.ps";
6ea83fed 4962 break;
5a5012ec 4963 case FOP(32, 22):
00a709c7 4964 CHECK_FR(ctx, fs);
5a5012ec
TS
4965 GEN_LOAD_FREG_FTN(WTH0, fs);
4966 gen_op_float_cvts_pu();
dd016883 4967 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec 4968 opn = "cvt.s.pu";
dd016883 4969 break;
5a5012ec
TS
4970 case FOP(36, 22):
4971 CHECK_FR(ctx, fs | fd);
6ea83fed 4972 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec
TS
4973 GEN_LOAD_FREG_FTN(WTH0, fs);
4974 gen_op_float_cvtpw_ps();
6ea83fed 4975 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec
TS
4976 GEN_STORE_FTN_FREG(fd, WTH2);
4977 opn = "cvt.pw.ps";
6ea83fed 4978 break;
5a5012ec
TS
4979 case FOP(40, 22):
4980 CHECK_FR(ctx, fs);
6ea83fed 4981 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec 4982 gen_op_float_cvts_pl();
6ea83fed 4983 GEN_STORE_FTN_FREG(fd, WT2);
5a5012ec 4984 opn = "cvt.s.pl";
6ea83fed 4985 break;
5a5012ec
TS
4986 case FOP(44, 22):
4987 CHECK_FR(ctx, fs | ft | fd);
4988 GEN_LOAD_FREG_FTN(WT0, fs);
4989 GEN_LOAD_FREG_FTN(WT1, ft);
4990 gen_op_float_pll_ps();
4991 GEN_STORE_FTN_FREG(fd, DT2);
4992 opn = "pll.ps";
6ea83fed 4993 break;
5a5012ec
TS
4994 case FOP(45, 22):
4995 CHECK_FR(ctx, fs | ft | fd);
6ea83fed 4996 GEN_LOAD_FREG_FTN(WT0, fs);
5a5012ec
TS
4997 GEN_LOAD_FREG_FTN(WTH1, ft);
4998 gen_op_float_plu_ps();
4999 GEN_STORE_FTN_FREG(fd, DT2);
5000 opn = "plu.ps";
5001 break;
5002 case FOP(46, 22):
5003 CHECK_FR(ctx, fs | ft | fd);
5004 GEN_LOAD_FREG_FTN(WTH0, fs);
6ea83fed 5005 GEN_LOAD_FREG_FTN(WT1, ft);
5a5012ec
TS
5006 gen_op_float_pul_ps();
5007 GEN_STORE_FTN_FREG(fd, DT2);
5008 opn = "pul.ps";
5009 break;
5010 case FOP(47, 22):
5011 CHECK_FR(ctx, fs | ft | fd);
5012 GEN_LOAD_FREG_FTN(WTH0, fs);
5013 GEN_LOAD_FREG_FTN(WTH1, ft);
5014 gen_op_float_puu_ps();
5015 GEN_STORE_FTN_FREG(fd, DT2);
5016 opn = "puu.ps";
5017 break;
5018 case FOP(48, 22):
5019 case FOP(49, 22):
5020 case FOP(50, 22):
5021 case FOP(51, 22):
5022 case FOP(52, 22):
5023 case FOP(53, 22):
5024 case FOP(54, 22):
5025 case FOP(55, 22):
5026 case FOP(56, 22):
5027 case FOP(57, 22):
5028 case FOP(58, 22):
5029 case FOP(59, 22):
5030 case FOP(60, 22):
5031 case FOP(61, 22):
5032 case FOP(62, 22):
5033 case FOP(63, 22):
5034 CHECK_FR(ctx, fs | ft);
5035 GEN_LOAD_FREG_FTN(WT0, fs);
5036 GEN_LOAD_FREG_FTN(WTH0, fs);
5037 GEN_LOAD_FREG_FTN(WT1, ft);
5038 GEN_LOAD_FREG_FTN(WTH1, ft);
5039 gen_cmp_ps(func-48, cc);
6ea83fed
FB
5040 opn = condnames[func-48];
5041 break;
5a5012ec 5042 default:
6ea83fed 5043 if (loglevel & CPU_LOG_TB_IN_ASM) {
7a387fff 5044 fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
6ea83fed
FB
5045 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
5046 ((ctx->opcode >> 16) & 0x1F));
5047 }
e397ee33 5048 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
5049 return;
5050 }
5051 if (binary)
5052 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5053 else
5054 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5055}
6af0bf9c 5056
5a5012ec
TS
5057/* Coprocessor 3 (FPU) */
5058static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
5059 int base, int index)
7a387fff 5060{
5a5012ec 5061 const char *opn = "unk";
7a387fff 5062
5a5012ec
TS
5063 GEN_LOAD_REG_TN(T0, base);
5064 GEN_LOAD_REG_TN(T1, index);
5065 /* Don't do NOP if destination is zero: we must perform the actual
5066 * memory access
5067 */
5068 switch (opc) {
5069 case OPC_LWXC1:
5070 op_ldst(lwxc1);
5071 GEN_STORE_FTN_FREG(fd, WT0);
5072 opn = "lwxc1";
5073 break;
5074 case OPC_LDXC1:
5075 op_ldst(ldxc1);
5076 GEN_STORE_FTN_FREG(fd, DT0);
5077 opn = "ldxc1";
5078 break;
5079 case OPC_LUXC1:
5080 op_ldst(luxc1);
5081 GEN_STORE_FTN_FREG(fd, DT0);
5082 opn = "luxc1";
5083 break;
5084 case OPC_SWXC1:
5085 GEN_LOAD_FREG_FTN(WT0, fd);
5086 op_ldst(swxc1);
5087 opn = "swxc1";
5088 break;
5089 case OPC_SDXC1:
5090 GEN_LOAD_FREG_FTN(DT0, fd);
5091 op_ldst(sdxc1);
5092 opn = "sdxc1";
5093 break;
5094 case OPC_SUXC1:
5095 GEN_LOAD_FREG_FTN(DT0, fd);
5096 op_ldst(suxc1);
5097 opn = "suxc1";
5098 break;
5099 default:
5100 MIPS_INVAL("extended float load/store");
5101 generate_exception(ctx, EXCP_RI);
5102 return;
5103 }
5104 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[fd],regnames[index], regnames[base]);
5105}
5106
5107static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5108 int fr, int fs, int ft)
5109{
5110 const char *opn = "unk";
5111
5112 /* All of those work only on 64bit FPUs. */
5113 CHECK_FR(ctx, fd | fr | fs | ft);
5114 switch (opc) {
5115 case OPC_ALNV_PS:
5116 GEN_LOAD_REG_TN(T0, fr);
5117 GEN_LOAD_FREG_FTN(DT0, fs);
5118 GEN_LOAD_FREG_FTN(DT1, ft);
5119 gen_op_float_alnv_ps();
5120 GEN_STORE_FTN_FREG(fd, DT2);
5121 opn = "alnv.ps";
5122 break;
5123 case OPC_MADD_S:
5124 GEN_LOAD_FREG_FTN(WT0, fs);
5125 GEN_LOAD_FREG_FTN(WT1, ft);
5126 GEN_LOAD_FREG_FTN(WT2, fr);
5127 gen_op_float_muladd_s();
5128 GEN_STORE_FTN_FREG(fd, WT2);
5129 opn = "madd.s";
5130 break;
5131 case OPC_MADD_D:
5132 generate_exception (ctx, EXCP_RI);
5133 opn = "madd.d";
5134 break;
5135 case OPC_MADD_PS:
5136 generate_exception (ctx, EXCP_RI);
5137 opn = "madd.ps";
5138 break;
5139 case OPC_MSUB_S:
5140 generate_exception (ctx, EXCP_RI);
5141 opn = "msub.s";
5142 break;
5143 case OPC_MSUB_D:
5144 generate_exception (ctx, EXCP_RI);
5145 opn = "msub.d";
5146 break;
5147 case OPC_MSUB_PS:
5148 generate_exception (ctx, EXCP_RI);
5149 opn = "msub.ps";
5150 break;
5151 case OPC_NMADD_S:
5152 generate_exception (ctx, EXCP_RI);
5153 opn = "nmadd.s";
5154 break;
5155 case OPC_NMADD_D:
5156 generate_exception (ctx, EXCP_RI);
5157 opn = "nmadd.d";
5158 break;
5159 case OPC_NMADD_PS:
5160 generate_exception (ctx, EXCP_RI);
5161 opn = "nmadd.ps";
5162 break;
5163 case OPC_NMSUB_S:
5164 generate_exception (ctx, EXCP_RI);
5165 opn = "nmsub.s";
5166 break;
5167 case OPC_NMSUB_D:
5168 generate_exception (ctx, EXCP_RI);
5169 opn = "nmsub.d";
5170 break;
5171 case OPC_NMSUB_PS:
5172 generate_exception (ctx, EXCP_RI);
5173 opn = "nmsub.ps";
5174 break;
5175 default:
5176 if (loglevel & CPU_LOG_TB_IN_ASM) {
5177 fprintf(logfile, "Invalid extended FP arith function: %08x %03x %03x\n",
5178 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F);
5179 }
5180 generate_exception (ctx, EXCP_RI);
5181 return;
5182 }
5183 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5184 fregnames[fs], fregnames[ft]);
7a387fff
TS
5185}
5186
5187/* ISA extensions (ASEs) */
6af0bf9c
FB
5188/* MIPS16 extension to MIPS32 */
5189/* SmartMIPS extension to MIPS32 */
5190
60aa19ab 5191#ifdef TARGET_MIPS64
6af0bf9c
FB
5192
5193/* MDMX extension to MIPS64 */
5194/* MIPS-3D extension to MIPS64 */
5195
5196#endif
5197
36d23958 5198static void decode_opc (CPUState *env, DisasContext *ctx)
6af0bf9c
FB
5199{
5200 int32_t offset;
5201 int rs, rt, rd, sa;
7a387fff 5202 uint32_t op, op1, op2;
6af0bf9c
FB
5203 int16_t imm;
5204
d796321b
FB
5205 /* make sure instructions are on a word boundary */
5206 if (ctx->pc & 0x3) {
cbeb0857 5207 env->CP0_BadVAddr = ctx->pc;
d796321b
FB
5208 generate_exception(ctx, EXCP_AdEL);
5209 return;
5210 }
5211
4ad40f36 5212 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5a5012ec 5213 int l1;
6af0bf9c 5214 /* Handle blikely not taken case */
3594c774 5215 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5a5012ec
TS
5216 l1 = gen_new_label();
5217 gen_op_jnz_T2(l1);
5218 gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5219 gen_goto_tb(ctx, 1, ctx->pc + 4);
5220 gen_set_label(l1);
6af0bf9c 5221 }
7a387fff
TS
5222 op = MASK_OP_MAJOR(ctx->opcode);
5223 rs = (ctx->opcode >> 21) & 0x1f;
5224 rt = (ctx->opcode >> 16) & 0x1f;
5225 rd = (ctx->opcode >> 11) & 0x1f;
5226 sa = (ctx->opcode >> 6) & 0x1f;
6af0bf9c
FB
5227 imm = (int16_t)ctx->opcode;
5228 switch (op) {
7a387fff
TS
5229 case OPC_SPECIAL:
5230 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 5231 switch (op1) {
7a387fff
TS
5232 case OPC_SLL: /* Arithmetic with immediate */
5233 case OPC_SRL ... OPC_SRA:
5234 gen_arith_imm(ctx, op1, rd, rt, sa);
5235 break;
5236 case OPC_SLLV: /* Arithmetic */
5237 case OPC_SRLV ... OPC_SRAV:
5238 case OPC_MOVZ ... OPC_MOVN:
5239 case OPC_ADD ... OPC_NOR:
5240 case OPC_SLT ... OPC_SLTU:
5241 gen_arith(ctx, op1, rd, rs, rt);
5242 break;
5243 case OPC_MULT ... OPC_DIVU:
5244 gen_muldiv(ctx, op1, rs, rt);
5245 break;
5246 case OPC_JR ... OPC_JALR:
5247 gen_compute_branch(ctx, op1, rs, rd, sa);
6af0bf9c 5248 return;
7a387fff
TS
5249 case OPC_TGE ... OPC_TEQ: /* Traps */
5250 case OPC_TNE:
5251 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 5252 break;
7a387fff
TS
5253 case OPC_MFHI: /* Move from HI/LO */
5254 case OPC_MFLO:
5255 gen_HILO(ctx, op1, rd);
6af0bf9c 5256 break;
7a387fff
TS
5257 case OPC_MTHI:
5258 case OPC_MTLO: /* Move to HI/LO */
5259 gen_HILO(ctx, op1, rs);
6af0bf9c 5260 break;
b48cfdff
TS
5261 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
5262#ifdef MIPS_STRICT_STANDARD
5263 MIPS_INVAL("PMON / selsl");
5264 generate_exception(ctx, EXCP_RI);
5265#else
7a387fff 5266 gen_op_pmon(sa);
b48cfdff 5267#endif
7a387fff
TS
5268 break;
5269 case OPC_SYSCALL:
6af0bf9c
FB
5270 generate_exception(ctx, EXCP_SYSCALL);
5271 break;
7a387fff 5272 case OPC_BREAK:
6af0bf9c
FB
5273 generate_exception(ctx, EXCP_BREAK);
5274 break;
b48cfdff
TS
5275 case OPC_SPIM:
5276#ifdef MIPS_STRICT_STANDARD
5277 MIPS_INVAL("SPIM");
5278 generate_exception(ctx, EXCP_RI);
5279#else
7a387fff
TS
5280 /* Implemented as RI exception for now. */
5281 MIPS_INVAL("spim (unofficial)");
5282 generate_exception(ctx, EXCP_RI);
b48cfdff 5283#endif
6af0bf9c 5284 break;
7a387fff
TS
5285 case OPC_SYNC:
5286 /* Treat as a noop. */
6af0bf9c 5287 break;
4ad40f36 5288
7a387fff 5289 case OPC_MOVCI:
36d23958 5290 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
e397ee33 5291 save_cpu_state(ctx, 1);
36d23958
TS
5292 gen_op_cp1_enabled();
5293 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5294 (ctx->opcode >> 16) & 1);
5295 } else {
e397ee33 5296 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 5297 }
4ad40f36
FB
5298 break;
5299
60aa19ab 5300#ifdef TARGET_MIPS64
7a387fff
TS
5301 /* MIPS64 specific opcodes */
5302 case OPC_DSLL:
5303 case OPC_DSRL ... OPC_DSRA:
5304 case OPC_DSLL32:
5305 case OPC_DSRL32 ... OPC_DSRA32:
5306 gen_arith_imm(ctx, op1, rd, rt, sa);
5307 break;
5308 case OPC_DSLLV:
5309 case OPC_DSRLV ... OPC_DSRAV:
5310 case OPC_DADD ... OPC_DSUBU:
5311 gen_arith(ctx, op1, rd, rs, rt);
5312 break;
5313 case OPC_DMULT ... OPC_DDIVU:
5314 gen_muldiv(ctx, op1, rs, rt);
5315 break;
6af0bf9c
FB
5316#endif
5317 default: /* Invalid */
5318 MIPS_INVAL("special");
5319 generate_exception(ctx, EXCP_RI);
5320 break;
5321 }
5322 break;
7a387fff
TS
5323 case OPC_SPECIAL2:
5324 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 5325 switch (op1) {
7a387fff
TS
5326 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
5327 case OPC_MSUB ... OPC_MSUBU:
5328 gen_muldiv(ctx, op1, rs, rt);
6af0bf9c 5329 break;
7a387fff
TS
5330 case OPC_MUL:
5331 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 5332 break;
7a387fff
TS
5333 case OPC_CLZ ... OPC_CLO:
5334 gen_cl(ctx, op1, rd, rs);
6af0bf9c 5335 break;
7a387fff 5336 case OPC_SDBBP:
6af0bf9c
FB
5337 /* XXX: not clear which exception should be raised
5338 * when in debug mode...
5339 */
5340 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5341 generate_exception(ctx, EXCP_DBp);
5342 } else {
5343 generate_exception(ctx, EXCP_DBp);
5344 }
5345 /* Treat as a noop */
5346 break;
60aa19ab 5347#ifdef TARGET_MIPS64
7a387fff
TS
5348 case OPC_DCLZ ... OPC_DCLO:
5349 gen_cl(ctx, op1, rd, rs);
5350 break;
5351#endif
6af0bf9c
FB
5352 default: /* Invalid */
5353 MIPS_INVAL("special2");
5354 generate_exception(ctx, EXCP_RI);
5355 break;
5356 }
5357 break;
7a387fff 5358 case OPC_SPECIAL3:
1579a72e
TS
5359 op1 = MASK_SPECIAL3(ctx->opcode);
5360 switch (op1) {
5361 case OPC_EXT:
5362 case OPC_INS:
5363 gen_bitops(ctx, op1, rt, rs, sa, rd);
5364 break;
5365 case OPC_BSHFL:
5366 op2 = MASK_BSHFL(ctx->opcode);
5367 switch (op2) {
5368 case OPC_WSBH:
5369 GEN_LOAD_REG_TN(T1, rt);
5370 gen_op_wsbh();
5371 break;
5372 case OPC_SEB:
5373 GEN_LOAD_REG_TN(T1, rt);
5374 gen_op_seb();
5375 break;
5376 case OPC_SEH:
5377 GEN_LOAD_REG_TN(T1, rt);
5378 gen_op_seh();
5379 break;
5380 default: /* Invalid */
5381 MIPS_INVAL("bshfl");
5382 generate_exception(ctx, EXCP_RI);
5383 break;
5384 }
5385 GEN_STORE_TN_REG(rd, T0);
7a387fff 5386 break;
1579a72e
TS
5387 case OPC_RDHWR:
5388 switch (rd) {
5389 case 0:
97428a4d 5390 save_cpu_state(ctx, 1);
1579a72e 5391 gen_op_rdhwr_cpunum();
7a387fff 5392 break;
1579a72e 5393 case 1:
97428a4d 5394 save_cpu_state(ctx, 1);
1579a72e 5395 gen_op_rdhwr_synci_step();
7a387fff 5396 break;
1579a72e 5397 case 2:
97428a4d 5398 save_cpu_state(ctx, 1);
1579a72e 5399 gen_op_rdhwr_cc();
7a387fff 5400 break;
1579a72e 5401 case 3:
97428a4d 5402 save_cpu_state(ctx, 1);
1579a72e 5403 gen_op_rdhwr_ccres();
7a387fff 5404 break;
1579a72e 5405 case 29:
6f5b89a0 5406#if defined (CONFIG_USER_ONLY)
1579a72e 5407 gen_op_tls_value ();
1579a72e 5408 break;
97428a4d 5409#endif
1579a72e
TS
5410 default: /* Invalid */
5411 MIPS_INVAL("rdhwr");
5412 generate_exception(ctx, EXCP_RI);
5413 break;
5414 }
5415 GEN_STORE_TN_REG(rt, T0);
5416 break;
60aa19ab 5417#ifdef TARGET_MIPS64
1579a72e
TS
5418 case OPC_DEXTM ... OPC_DEXT:
5419 case OPC_DINSM ... OPC_DINS:
5420 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 5421 break;
1579a72e
TS
5422 case OPC_DBSHFL:
5423 op2 = MASK_DBSHFL(ctx->opcode);
5424 switch (op2) {
5425 case OPC_DSBH:
5426 GEN_LOAD_REG_TN(T1, rt);
5427 gen_op_dsbh();
5428 break;
5429 case OPC_DSHD:
5430 GEN_LOAD_REG_TN(T1, rt);
5431 gen_op_dshd();
5432 break;
7a387fff
TS
5433 default: /* Invalid */
5434 MIPS_INVAL("dbshfl");
5435 generate_exception(ctx, EXCP_RI);
5436 break;
1579a72e
TS
5437 }
5438 GEN_STORE_TN_REG(rd, T0);
7a387fff
TS
5439#endif
5440 default: /* Invalid */
5441 MIPS_INVAL("special3");
5442 generate_exception(ctx, EXCP_RI);
5443 break;
5444 }
5445 break;
5446 case OPC_REGIMM:
5447 op1 = MASK_REGIMM(ctx->opcode);
5448 switch (op1) {
5449 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
5450 case OPC_BLTZAL ... OPC_BGEZALL:
5451 gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6af0bf9c 5452 return;
7a387fff
TS
5453 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
5454 case OPC_TNEI:
5455 gen_trap(ctx, op1, rs, -1, imm);
5456 break;
5457 case OPC_SYNCI:
24c7b0e3 5458 /* treat as noop */
6af0bf9c
FB
5459 break;
5460 default: /* Invalid */
5461 MIPS_INVAL("REGIMM");
5462 generate_exception(ctx, EXCP_RI);
5463 break;
5464 }
5465 break;
7a387fff 5466 case OPC_CP0:
f41c52f1 5467 save_cpu_state(ctx, 1);
24c7b0e3 5468 gen_op_cp0_enabled();
7a387fff 5469 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 5470 switch (op1) {
7a387fff
TS
5471 case OPC_MFC0:
5472 case OPC_MTC0:
60aa19ab 5473#ifdef TARGET_MIPS64
7a387fff
TS
5474 case OPC_DMFC0:
5475 case OPC_DMTC0:
5476#endif
5477 gen_cp0(ctx, op1, rt, rd);
5478 break;
5479 case OPC_C0_FIRST ... OPC_C0_LAST:
5480 gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
5481 break;
5482 case OPC_MFMC0:
5483 op2 = MASK_MFMC0(ctx->opcode);
5484 switch (op2) {
5485 case OPC_DI:
5486 gen_op_di();
5487 /* Stop translation as we may have switched the execution mode */
5488 ctx->bstate = BS_STOP;
5489 break;
5490 case OPC_EI:
5491 gen_op_ei();
5492 /* Stop translation as we may have switched the execution mode */
5493 ctx->bstate = BS_STOP;
5494 break;
5495 default: /* Invalid */
5496 MIPS_INVAL("MFMC0");
5497 generate_exception(ctx, EXCP_RI);
5498 break;
5499 }
5500 GEN_STORE_TN_REG(rt, T0);
6af0bf9c 5501 break;
7a387fff
TS
5502 case OPC_RDPGPR:
5503 case OPC_WRPGPR:
38121543
TS
5504 if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
5505 /* Shadow registers not implemented. */
5506 GEN_LOAD_REG_TN(T0, rt);
5507 GEN_STORE_TN_REG(rd, T0);
5508 } else
5509 generate_exception(ctx, EXCP_RI);
5510 break;
6af0bf9c 5511 default:
7a387fff 5512 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
5513 break;
5514 }
5515 break;
7a387fff
TS
5516 case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
5517 gen_arith_imm(ctx, op, rt, rs, imm);
5518 break;
5519 case OPC_J ... OPC_JAL: /* Jump */
5520 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
5521 gen_compute_branch(ctx, op, rs, rt, offset);
5522 return;
5523 case OPC_BEQ ... OPC_BGTZ: /* Branch */
5524 case OPC_BEQL ... OPC_BGTZL:
5525 gen_compute_branch(ctx, op, rs, rt, imm << 2);
5526 return;
5527 case OPC_LB ... OPC_LWR: /* Load and stores */
5528 case OPC_SB ... OPC_SW:
5529 case OPC_SWR:
5530 case OPC_LL:
5531 case OPC_SC:
5532 gen_ldst(ctx, op, rt, rs, imm);
5533 break;
5534 case OPC_CACHE:
5535 /* Treat as a noop */
5536 break;
5537 case OPC_PREF:
6af0bf9c
FB
5538 /* Treat as a noop */
5539 break;
4ad40f36
FB
5540
5541 /* Floating point. */
7a387fff
TS
5542 case OPC_LWC1:
5543 case OPC_LDC1:
5544 case OPC_SWC1:
5545 case OPC_SDC1:
36d23958
TS
5546 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5547 save_cpu_state(ctx, 1);
5548 gen_op_cp1_enabled();
5549 gen_flt_ldst(ctx, op, rt, rs, imm);
5550 } else {
5551 generate_exception_err(ctx, EXCP_CpU, 1);
5552 }
6ea83fed
FB
5553 break;
5554
7a387fff 5555 case OPC_CP1:
36d23958
TS
5556 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5557 save_cpu_state(ctx, 1);
5558 gen_op_cp1_enabled();
5559 op1 = MASK_CP1(ctx->opcode);
5560 switch (op1) {
5561 case OPC_MFC1:
5562 case OPC_CFC1:
5563 case OPC_MTC1:
5564 case OPC_CTC1:
60aa19ab 5565#ifdef TARGET_MIPS64
36d23958
TS
5566 case OPC_DMFC1:
5567 case OPC_DMTC1:
9c2149c8 5568#endif
5a5012ec
TS
5569 case OPC_MFHC1:
5570 case OPC_MTHC1:
36d23958
TS
5571 gen_cp1(ctx, op1, rt, rd);
5572 break;
5573 case OPC_BC1:
5a5012ec
TS
5574 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5575 (rt >> 2) & 0x7, imm << 2);
36d23958
TS
5576 return;
5577 case OPC_S_FMT:
5578 case OPC_D_FMT:
5579 case OPC_W_FMT:
5580 case OPC_L_FMT:
5a5012ec
TS
5581 case OPC_PS_FMT:
5582 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
5583 (imm >> 8) & 0x7);
36d23958
TS
5584 break;
5585 default:
e397ee33 5586 generate_exception (ctx, EXCP_RI);
36d23958
TS
5587 break;
5588 }
5589 } else {
5590 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 5591 }
4ad40f36
FB
5592 break;
5593
5594 /* COP2. */
7a387fff
TS
5595 case OPC_LWC2:
5596 case OPC_LDC2:
5597 case OPC_SWC2:
5598 case OPC_SDC2:
5599 case OPC_CP2:
5600 /* COP2: Not implemented. */
4ad40f36
FB
5601 generate_exception_err(ctx, EXCP_CpU, 2);
5602 break;
5603
7a387fff 5604 case OPC_CP3:
36d23958 5605 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
e397ee33 5606 save_cpu_state(ctx, 1);
36d23958
TS
5607 gen_op_cp1_enabled();
5608 op1 = MASK_CP3(ctx->opcode);
5609 switch (op1) {
5a5012ec
TS
5610 case OPC_LWXC1:
5611 case OPC_LDXC1:
5612 case OPC_LUXC1:
5613 case OPC_SWXC1:
5614 case OPC_SDXC1:
5615 case OPC_SUXC1:
5616 gen_flt3_ldst(ctx, op1, sa, rs, rt);
5617 break;
e0c84da7
TS
5618 case OPC_PREFX:
5619 /* treat as noop */
5620 break;
5a5012ec
TS
5621 case OPC_ALNV_PS:
5622 case OPC_MADD_S:
5623 case OPC_MADD_D:
5624 case OPC_MADD_PS:
5625 case OPC_MSUB_S:
5626 case OPC_MSUB_D:
5627 case OPC_MSUB_PS:
5628 case OPC_NMADD_S:
5629 case OPC_NMADD_D:
5630 case OPC_NMADD_PS:
5631 case OPC_NMSUB_S:
5632 case OPC_NMSUB_D:
5633 case OPC_NMSUB_PS:
5634 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
5635 break;
36d23958 5636 default:
e397ee33 5637 generate_exception (ctx, EXCP_RI);
36d23958
TS
5638 break;
5639 }
5640 } else {
e397ee33 5641 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 5642 }
4ad40f36
FB
5643 break;
5644
60aa19ab 5645#ifdef TARGET_MIPS64
7a387fff
TS
5646 /* MIPS64 opcodes */
5647 case OPC_LWU:
5648 case OPC_LDL ... OPC_LDR:
5649 case OPC_SDL ... OPC_SDR:
5650 case OPC_LLD:
5651 case OPC_LD:
5652 case OPC_SCD:
5653 case OPC_SD:
5654 gen_ldst(ctx, op, rt, rs, imm);
5655 break;
5656 case OPC_DADDI ... OPC_DADDIU:
5657 gen_arith_imm(ctx, op, rt, rs, imm);
5658 break;
6af0bf9c 5659#endif
7a387fff
TS
5660#ifdef MIPS_HAS_MIPS16
5661 case OPC_JALX:
5662 /* MIPS16: Not implemented. */
5663#endif
5664#ifdef MIPS_HAS_MDMX
5665 case OPC_MDMX:
5666 /* MDMX: Not implemented. */
6af0bf9c 5667#endif
6af0bf9c
FB
5668 default: /* Invalid */
5669 MIPS_INVAL("");
5670 generate_exception(ctx, EXCP_RI);
5671 break;
5672 }
4ad40f36 5673 if (ctx->hflags & MIPS_HFLAG_BMASK) {
c53f4a62 5674 int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
6af0bf9c 5675 /* Branches completion */
4ad40f36 5676 ctx->hflags &= ~MIPS_HFLAG_BMASK;
6af0bf9c
FB
5677 ctx->bstate = BS_BRANCH;
5678 save_cpu_state(ctx, 0);
5a5012ec 5679 switch (hflags) {
6af0bf9c
FB
5680 case MIPS_HFLAG_B:
5681 /* unconditional branch */
5682 MIPS_DEBUG("unconditional branch");
6e256c93 5683 gen_goto_tb(ctx, 0, ctx->btarget);
6af0bf9c
FB
5684 break;
5685 case MIPS_HFLAG_BL:
5686 /* blikely taken case */
5687 MIPS_DEBUG("blikely branch taken");
6e256c93 5688 gen_goto_tb(ctx, 0, ctx->btarget);
6af0bf9c
FB
5689 break;
5690 case MIPS_HFLAG_BC:
5691 /* Conditional branch */
5692 MIPS_DEBUG("conditional branch");
c53be334
FB
5693 {
5694 int l1;
5695 l1 = gen_new_label();
5696 gen_op_jnz_T2(l1);
6e256c93 5697 gen_goto_tb(ctx, 1, ctx->pc + 4);
eeef26cd
FB
5698 gen_set_label(l1);
5699 gen_goto_tb(ctx, 0, ctx->btarget);
c53be334 5700 }
6af0bf9c
FB
5701 break;
5702 case MIPS_HFLAG_BR:
5703 /* unconditional branch to register */
5704 MIPS_DEBUG("branch to register");
5705 gen_op_breg();
5a5012ec
TS
5706 gen_op_reset_T0();
5707 gen_op_exit_tb();
6af0bf9c
FB
5708 break;
5709 default:
5710 MIPS_DEBUG("unknown branch");
5711 break;
5712 }
5713 }
5714}
5715
820e00f2
TS
5716static inline int
5717gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5718 int search_pc)
6af0bf9c
FB
5719{
5720 DisasContext ctx, *ctxp = &ctx;
5721 target_ulong pc_start;
5722 uint16_t *gen_opc_end;
5723 int j, lj = -1;
5724
4ad40f36 5725 if (search_pc && loglevel)
6ea83fed 5726 fprintf (logfile, "search pc %d\n", search_pc);
4ad40f36 5727
6af0bf9c
FB
5728 pc_start = tb->pc;
5729 gen_opc_ptr = gen_opc_buf;
5730 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5731 gen_opparam_ptr = gen_opparam_buf;
c53be334 5732 nb_gen_labels = 0;
6af0bf9c 5733 ctx.pc = pc_start;
4ad40f36 5734 ctx.saved_pc = -1;
6af0bf9c
FB
5735 ctx.tb = tb;
5736 ctx.bstate = BS_NONE;
4ad40f36
FB
5737 /* Restore delay slot state from the tb context. */
5738 ctx.hflags = tb->flags;
6af0bf9c 5739 ctx.saved_hflags = ctx.hflags;
5a5012ec
TS
5740 switch (ctx.hflags & MIPS_HFLAG_BMASK) {
5741 case MIPS_HFLAG_BR:
6af0bf9c 5742 gen_op_restore_breg_target();
5a5012ec
TS
5743 break;
5744 case MIPS_HFLAG_B:
6af0bf9c 5745 ctx.btarget = env->btarget;
5a5012ec
TS
5746 break;
5747 case MIPS_HFLAG_BC:
5748 case MIPS_HFLAG_BL:
6af0bf9c
FB
5749 ctx.btarget = env->btarget;
5750 gen_op_restore_bcond();
5a5012ec 5751 break;
6af0bf9c
FB
5752 }
5753#if defined(CONFIG_USER_ONLY)
5754 ctx.mem_idx = 0;
5755#else
3d9fb9fe 5756 ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
6af0bf9c
FB
5757#endif
5758 ctx.CP0_Status = env->CP0_Status;
5759#ifdef DEBUG_DISAS
5760 if (loglevel & CPU_LOG_TB_CPU) {
5761 fprintf(logfile, "------------------------------------------------\n");
4ad40f36 5762 /* FIXME: This may print out stale hflags from env... */
6af0bf9c
FB
5763 cpu_dump_state(env, logfile, fprintf, 0);
5764 }
5765#endif
5766#if defined MIPS_DEBUG_DISAS
5767 if (loglevel & CPU_LOG_TB_IN_ASM)
4ad40f36
FB
5768 fprintf(logfile, "\ntb %p super %d cond %04x\n",
5769 tb, ctx.mem_idx, ctx.hflags);
6af0bf9c
FB
5770#endif
5771 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
4ad40f36
FB
5772 if (env->nb_breakpoints > 0) {
5773 for(j = 0; j < env->nb_breakpoints; j++) {
5774 if (env->breakpoints[j] == ctx.pc) {
5775 save_cpu_state(ctxp, 1);
5776 ctx.bstate = BS_BRANCH;
5777 gen_op_debug();
5778 goto done_generating;
5779 }
5780 }
5781 }
5782
6af0bf9c
FB
5783 if (search_pc) {
5784 j = gen_opc_ptr - gen_opc_buf;
6af0bf9c
FB
5785 if (lj < j) {
5786 lj++;
5787 while (lj < j)
5788 gen_opc_instr_start[lj++] = 0;
6af0bf9c 5789 }
4ad40f36
FB
5790 gen_opc_pc[lj] = ctx.pc;
5791 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5792 gen_opc_instr_start[lj] = 1;
6af0bf9c
FB
5793 }
5794 ctx.opcode = ldl_code(ctx.pc);
36d23958 5795 decode_opc(env, &ctx);
6af0bf9c 5796 ctx.pc += 4;
4ad40f36
FB
5797
5798 if (env->singlestep_enabled)
5799 break;
5800
6af0bf9c
FB
5801 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5802 break;
4ad40f36 5803
6af0bf9c
FB
5804#if defined (MIPS_SINGLE_STEP)
5805 break;
5806#endif
5807 }
4ad40f36
FB
5808 if (env->singlestep_enabled) {
5809 save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5810 gen_op_debug();
16c00cb2
TS
5811 } else {
5812 switch (ctx.bstate) {
16c00cb2
TS
5813 case BS_STOP:
5814 gen_op_interrupt_restart();
5815 /* Fall through. */
5816 case BS_NONE:
5817 save_cpu_state(ctxp, 0);
5818 gen_goto_tb(&ctx, 0, ctx.pc);
5819 break;
5a5012ec
TS
5820 case BS_EXCP:
5821 gen_op_interrupt_restart();
a85427b1 5822 gen_op_reset_T0();
a85427b1 5823 gen_op_exit_tb();
16c00cb2 5824 break;
5a5012ec
TS
5825 case BS_BRANCH:
5826 default:
5827 break;
16c00cb2 5828 }
6af0bf9c 5829 }
4ad40f36 5830done_generating:
6af0bf9c
FB
5831 *gen_opc_ptr = INDEX_op_end;
5832 if (search_pc) {
5833 j = gen_opc_ptr - gen_opc_buf;
5834 lj++;
5835 while (lj <= j)
5836 gen_opc_instr_start[lj++] = 0;
5837 tb->size = 0;
5838 } else {
5839 tb->size = ctx.pc - pc_start;
5840 }
5841#ifdef DEBUG_DISAS
5842#if defined MIPS_DEBUG_DISAS
5843 if (loglevel & CPU_LOG_TB_IN_ASM)
5844 fprintf(logfile, "\n");
5845#endif
5846 if (loglevel & CPU_LOG_TB_IN_ASM) {
5847 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
9898128f 5848 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
6af0bf9c
FB
5849 fprintf(logfile, "\n");
5850 }
5851 if (loglevel & CPU_LOG_TB_OP) {
5852 fprintf(logfile, "OP:\n");
5853 dump_ops(gen_opc_buf, gen_opparam_buf);
5854 fprintf(logfile, "\n");
5855 }
5856 if (loglevel & CPU_LOG_TB_CPU) {
5857 fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5858 }
5859#endif
5860
5861 return 0;
5862}
5863
5864int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5865{
5866 return gen_intermediate_code_internal(env, tb, 0);
5867}
5868
5869int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5870{
5871 return gen_intermediate_code_internal(env, tb, 1);
5872}
5873
6ea83fed
FB
5874void fpu_dump_state(CPUState *env, FILE *f,
5875 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5876 int flags)
5877{
5878 int i;
5a5012ec
TS
5879 int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
5880
5881#define printfpr(fp) \
5882 do { \
5883 if (is_fpu64) \
5884 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n", \
5885 (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd, \
5886 (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
5887 else { \
5888 fpr_t tmp; \
5889 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
5890 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
5891 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n", \
5892 tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd, \
5893 tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]); \
5894 } \
6ea83fed
FB
5895 } while(0)
5896
5a5012ec
TS
5897
5898 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
5899 env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
6ea83fed
FB
5900 fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5901 fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5902 fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5a5012ec
TS
5903 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
5904 fpu_fprintf(f, "%3s: ", fregnames[i]);
5905 printfpr(&env->fpr[i]);
6ea83fed
FB
5906 }
5907
5908#undef printfpr
5909}
5910
7a387fff 5911void dump_fpu (CPUState *env)
6ea83fed
FB
5912{
5913 if (loglevel) {
3594c774 5914 fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6ea83fed
FB
5915 env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5916 fpu_dump_state(env, logfile, fprintf, 0);
5917 }
5918}
6ea83fed 5919
60aa19ab 5920#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
5921/* Debug help: The architecture requires 32bit code to maintain proper
5922 sign-extened values on 64bit machines. */
5923
5924#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5925
5926void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5927 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5928 int flags)
5929{
5930 int i;
5931
5932 if (!SIGN_EXT_P(env->PC))
3594c774 5933 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
c570fd16 5934 if (!SIGN_EXT_P(env->HI))
3594c774 5935 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
c570fd16 5936 if (!SIGN_EXT_P(env->LO))
3594c774 5937 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
c570fd16 5938 if (!SIGN_EXT_P(env->btarget))
3594c774 5939 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
5940
5941 for (i = 0; i < 32; i++) {
5942 if (!SIGN_EXT_P(env->gpr[i]))
3594c774 5943 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
c570fd16
TS
5944 }
5945
5946 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 5947 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
c570fd16 5948 if (!SIGN_EXT_P(env->CP0_LLAddr))
3594c774 5949 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
c570fd16
TS
5950}
5951#endif
5952
6af0bf9c
FB
5953void cpu_dump_state (CPUState *env, FILE *f,
5954 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5955 int flags)
5956{
568b600d 5957 uint32_t c0_status;
6af0bf9c
FB
5958 int i;
5959
3594c774 5960 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6af0bf9c
FB
5961 env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5962 for (i = 0; i < 32; i++) {
5963 if ((i & 3) == 0)
5964 cpu_fprintf(f, "GPR%02d:", i);
3594c774 5965 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
6af0bf9c
FB
5966 if ((i & 3) == 3)
5967 cpu_fprintf(f, "\n");
5968 }
568b600d
FB
5969
5970 c0_status = env->CP0_Status;
568b600d 5971
3594c774 5972 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
568b600d 5973 c0_status, env->CP0_Cause, env->CP0_EPC);
3594c774 5974 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6af0bf9c 5975 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7a387fff
TS
5976 if (c0_status & (1 << CP0St_CU1))
5977 fpu_dump_state(env, f, cpu_fprintf, flags);
60aa19ab 5978#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
5979 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5980#endif
6af0bf9c
FB
5981}
5982
5983CPUMIPSState *cpu_mips_init (void)
5984{
5985 CPUMIPSState *env;
5986
6af0bf9c
FB
5987 env = qemu_mallocz(sizeof(CPUMIPSState));
5988 if (!env)
5989 return NULL;
173d6cfe 5990 cpu_exec_init(env);
6ae81775
TS
5991 cpu_reset(env);
5992 return env;
5993}
5994
5995void cpu_reset (CPUMIPSState *env)
5996{
5997 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5998
6af0bf9c 5999 tlb_flush(env, 1);
6ae81775 6000
6af0bf9c 6001 /* Minimal init */
ca7c2b1b 6002#if !defined(CONFIG_USER_ONLY)
aa328add
TS
6003 if (env->hflags & MIPS_HFLAG_BMASK) {
6004 /* If the exception was raised from a delay slot,
6005 * come back to the jump. */
6006 env->CP0_ErrorEPC = env->PC - 4;
6007 env->hflags &= ~MIPS_HFLAG_BMASK;
6008 } else {
6009 env->CP0_ErrorEPC = env->PC;
6010 }
24c7b0e3 6011 env->hflags = 0;
5dc4b744 6012 env->PC = (int32_t)0xBFC00000;
6af0bf9c 6013 env->CP0_Wired = 0;
7a387fff 6014 /* SMP not implemented */
b29a0341 6015 env->CP0_EBase = 0x80000000;
aa328add 6016 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
c090a8f4
TS
6017 /* vectored interrupts not implemented, timer on int 7,
6018 no performance counters. */
6019 env->CP0_IntCtl = 0xe0000000;
6af0bf9c 6020 env->CP0_WatchLo = 0;
4e7a4a4e 6021 env->CP0_WatchHi = 0;
6af0bf9c
FB
6022 /* Count register increments in debug mode, EJTAG version 1 */
6023 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
ca7c2b1b 6024#endif
6af0bf9c 6025 env->exception_index = EXCP_NONE;
eeef26cd
FB
6026#if defined(CONFIG_USER_ONLY)
6027 env->hflags |= MIPS_HFLAG_UM;
ca7c2b1b 6028 env->user_mode_only = 1;
6ea83fed 6029#endif
6af0bf9c 6030}
33d68b5f
TS
6031
6032#include "translate_init.c"