Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 9e56e756

History | View | Annotate | Download (364 kB)

1 6af0bf9c bellard
/*
2 6af0bf9c bellard
 *  MIPS32 emulation for qemu: main translation routines.
3 5fafdf24 ths
 *
4 6af0bf9c bellard
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5 6ea83fed bellard
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6 bb8a53ad ths
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 3c824109 Nathan Froyd
 *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 6af0bf9c bellard
 *
9 6af0bf9c bellard
 * This library is free software; you can redistribute it and/or
10 6af0bf9c bellard
 * modify it under the terms of the GNU Lesser General Public
11 6af0bf9c bellard
 * License as published by the Free Software Foundation; either
12 6af0bf9c bellard
 * version 2 of the License, or (at your option) any later version.
13 6af0bf9c bellard
 *
14 6af0bf9c bellard
 * This library is distributed in the hope that it will be useful,
15 6af0bf9c bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 6af0bf9c bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 6af0bf9c bellard
 * Lesser General Public License for more details.
18 6af0bf9c bellard
 *
19 6af0bf9c bellard
 * You should have received a copy of the GNU Lesser General Public
20 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 6af0bf9c bellard
 */
22 6af0bf9c bellard
23 6af0bf9c bellard
#include <stdarg.h>
24 6af0bf9c bellard
#include <stdlib.h>
25 6af0bf9c bellard
#include <stdio.h>
26 6af0bf9c bellard
#include <string.h>
27 6af0bf9c bellard
#include <inttypes.h>
28 6af0bf9c bellard
29 6af0bf9c bellard
#include "cpu.h"
30 6af0bf9c bellard
#include "disas.h"
31 57fec1fe bellard
#include "tcg-op.h"
32 ca10f867 aurel32
#include "qemu-common.h"
33 6af0bf9c bellard
34 a7812ae4 pbrook
#include "helper.h"
35 a7812ae4 pbrook
#define GEN_HELPER 1
36 a7812ae4 pbrook
#include "helper.h"
37 a7812ae4 pbrook
38 eeef26cd bellard
//#define MIPS_DEBUG_DISAS
39 c570fd16 ths
//#define MIPS_DEBUG_SIGN_EXTENSIONS
40 6af0bf9c bellard
41 7a387fff ths
/* MIPS major opcodes */
42 7a387fff ths
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
43 e37e863f bellard
44 e37e863f bellard
enum {
45 e37e863f bellard
    /* indirect opcode tables */
46 7a387fff ths
    OPC_SPECIAL  = (0x00 << 26),
47 7a387fff ths
    OPC_REGIMM   = (0x01 << 26),
48 7a387fff ths
    OPC_CP0      = (0x10 << 26),
49 7a387fff ths
    OPC_CP1      = (0x11 << 26),
50 7a387fff ths
    OPC_CP2      = (0x12 << 26),
51 7a387fff ths
    OPC_CP3      = (0x13 << 26),
52 7a387fff ths
    OPC_SPECIAL2 = (0x1C << 26),
53 7a387fff ths
    OPC_SPECIAL3 = (0x1F << 26),
54 e37e863f bellard
    /* arithmetic with immediate */
55 7a387fff ths
    OPC_ADDI     = (0x08 << 26),
56 7a387fff ths
    OPC_ADDIU    = (0x09 << 26),
57 7a387fff ths
    OPC_SLTI     = (0x0A << 26),
58 7a387fff ths
    OPC_SLTIU    = (0x0B << 26),
59 324d9e32 aurel32
    /* logic with immediate */
60 7a387fff ths
    OPC_ANDI     = (0x0C << 26),
61 7a387fff ths
    OPC_ORI      = (0x0D << 26),
62 7a387fff ths
    OPC_XORI     = (0x0E << 26),
63 7a387fff ths
    OPC_LUI      = (0x0F << 26),
64 324d9e32 aurel32
    /* arithmetic with immediate */
65 7a387fff ths
    OPC_DADDI    = (0x18 << 26),
66 7a387fff ths
    OPC_DADDIU   = (0x19 << 26),
67 e37e863f bellard
    /* Jump and branches */
68 7a387fff ths
    OPC_J        = (0x02 << 26),
69 7a387fff ths
    OPC_JAL      = (0x03 << 26),
70 620e48f6 Nathan Froyd
    OPC_JALS     = OPC_JAL | 0x5,
71 7a387fff ths
    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
72 7a387fff ths
    OPC_BEQL     = (0x14 << 26),
73 7a387fff ths
    OPC_BNE      = (0x05 << 26),
74 7a387fff ths
    OPC_BNEL     = (0x15 << 26),
75 7a387fff ths
    OPC_BLEZ     = (0x06 << 26),
76 7a387fff ths
    OPC_BLEZL    = (0x16 << 26),
77 7a387fff ths
    OPC_BGTZ     = (0x07 << 26),
78 7a387fff ths
    OPC_BGTZL    = (0x17 << 26),
79 7a387fff ths
    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
80 620e48f6 Nathan Froyd
    OPC_JALXS    = OPC_JALX | 0x5,
81 e37e863f bellard
    /* Load and stores */
82 7a387fff ths
    OPC_LDL      = (0x1A << 26),
83 7a387fff ths
    OPC_LDR      = (0x1B << 26),
84 7a387fff ths
    OPC_LB       = (0x20 << 26),
85 7a387fff ths
    OPC_LH       = (0x21 << 26),
86 7a387fff ths
    OPC_LWL      = (0x22 << 26),
87 7a387fff ths
    OPC_LW       = (0x23 << 26),
88 364d4831 Nathan Froyd
    OPC_LWPC     = OPC_LW | 0x5,
89 7a387fff ths
    OPC_LBU      = (0x24 << 26),
90 7a387fff ths
    OPC_LHU      = (0x25 << 26),
91 7a387fff ths
    OPC_LWR      = (0x26 << 26),
92 7a387fff ths
    OPC_LWU      = (0x27 << 26),
93 7a387fff ths
    OPC_SB       = (0x28 << 26),
94 7a387fff ths
    OPC_SH       = (0x29 << 26),
95 7a387fff ths
    OPC_SWL      = (0x2A << 26),
96 7a387fff ths
    OPC_SW       = (0x2B << 26),
97 7a387fff ths
    OPC_SDL      = (0x2C << 26),
98 7a387fff ths
    OPC_SDR      = (0x2D << 26),
99 7a387fff ths
    OPC_SWR      = (0x2E << 26),
100 7a387fff ths
    OPC_LL       = (0x30 << 26),
101 7a387fff ths
    OPC_LLD      = (0x34 << 26),
102 7a387fff ths
    OPC_LD       = (0x37 << 26),
103 364d4831 Nathan Froyd
    OPC_LDPC     = OPC_LD | 0x5,
104 7a387fff ths
    OPC_SC       = (0x38 << 26),
105 7a387fff ths
    OPC_SCD      = (0x3C << 26),
106 7a387fff ths
    OPC_SD       = (0x3F << 26),
107 e37e863f bellard
    /* Floating point load/store */
108 7a387fff ths
    OPC_LWC1     = (0x31 << 26),
109 7a387fff ths
    OPC_LWC2     = (0x32 << 26),
110 7a387fff ths
    OPC_LDC1     = (0x35 << 26),
111 7a387fff ths
    OPC_LDC2     = (0x36 << 26),
112 7a387fff ths
    OPC_SWC1     = (0x39 << 26),
113 7a387fff ths
    OPC_SWC2     = (0x3A << 26),
114 7a387fff ths
    OPC_SDC1     = (0x3D << 26),
115 7a387fff ths
    OPC_SDC2     = (0x3E << 26),
116 7a387fff ths
    /* MDMX ASE specific */
117 7a387fff ths
    OPC_MDMX     = (0x1E << 26),
118 e37e863f bellard
    /* Cache and prefetch */
119 7a387fff ths
    OPC_CACHE    = (0x2F << 26),
120 7a387fff ths
    OPC_PREF     = (0x33 << 26),
121 7a387fff ths
    /* Reserved major opcode */
122 7a387fff ths
    OPC_MAJOR3B_RESERVED = (0x3B << 26),
123 e37e863f bellard
};
124 e37e863f bellard
125 e37e863f bellard
/* MIPS special opcodes */
126 7a387fff ths
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
127 7a387fff ths
128 e37e863f bellard
enum {
129 e37e863f bellard
    /* Shifts */
130 7a387fff ths
    OPC_SLL      = 0x00 | OPC_SPECIAL,
131 e37e863f bellard
    /* NOP is SLL r0, r0, 0   */
132 e37e863f bellard
    /* SSNOP is SLL r0, r0, 1 */
133 7a387fff ths
    /* EHB is SLL r0, r0, 3 */
134 7a387fff ths
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
135 ea63e2c3 Nathan Froyd
    OPC_ROTR     = OPC_SRL | (1 << 21),
136 7a387fff ths
    OPC_SRA      = 0x03 | OPC_SPECIAL,
137 7a387fff ths
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
138 e189e748 ths
    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
139 ea63e2c3 Nathan Froyd
    OPC_ROTRV    = OPC_SRLV | (1 << 6),
140 7a387fff ths
    OPC_SRAV     = 0x07 | OPC_SPECIAL,
141 7a387fff ths
    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
142 7a387fff ths
    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
143 ea63e2c3 Nathan Froyd
    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
144 7a387fff ths
    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
145 7a387fff ths
    OPC_DSLL     = 0x38 | OPC_SPECIAL,
146 7a387fff ths
    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
147 ea63e2c3 Nathan Froyd
    OPC_DROTR    = OPC_DSRL | (1 << 21),
148 7a387fff ths
    OPC_DSRA     = 0x3B | OPC_SPECIAL,
149 7a387fff ths
    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
150 7a387fff ths
    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
151 ea63e2c3 Nathan Froyd
    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
152 7a387fff ths
    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
153 e37e863f bellard
    /* Multiplication / division */
154 7a387fff ths
    OPC_MULT     = 0x18 | OPC_SPECIAL,
155 7a387fff ths
    OPC_MULTU    = 0x19 | OPC_SPECIAL,
156 7a387fff ths
    OPC_DIV      = 0x1A | OPC_SPECIAL,
157 7a387fff ths
    OPC_DIVU     = 0x1B | OPC_SPECIAL,
158 7a387fff ths
    OPC_DMULT    = 0x1C | OPC_SPECIAL,
159 7a387fff ths
    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
160 7a387fff ths
    OPC_DDIV     = 0x1E | OPC_SPECIAL,
161 7a387fff ths
    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
162 e37e863f bellard
    /* 2 registers arithmetic / logic */
163 7a387fff ths
    OPC_ADD      = 0x20 | OPC_SPECIAL,
164 7a387fff ths
    OPC_ADDU     = 0x21 | OPC_SPECIAL,
165 7a387fff ths
    OPC_SUB      = 0x22 | OPC_SPECIAL,
166 7a387fff ths
    OPC_SUBU     = 0x23 | OPC_SPECIAL,
167 7a387fff ths
    OPC_AND      = 0x24 | OPC_SPECIAL,
168 7a387fff ths
    OPC_OR       = 0x25 | OPC_SPECIAL,
169 7a387fff ths
    OPC_XOR      = 0x26 | OPC_SPECIAL,
170 7a387fff ths
    OPC_NOR      = 0x27 | OPC_SPECIAL,
171 7a387fff ths
    OPC_SLT      = 0x2A | OPC_SPECIAL,
172 7a387fff ths
    OPC_SLTU     = 0x2B | OPC_SPECIAL,
173 7a387fff ths
    OPC_DADD     = 0x2C | OPC_SPECIAL,
174 7a387fff ths
    OPC_DADDU    = 0x2D | OPC_SPECIAL,
175 7a387fff ths
    OPC_DSUB     = 0x2E | OPC_SPECIAL,
176 7a387fff ths
    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
177 e37e863f bellard
    /* Jumps */
178 7a387fff ths
    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
179 7a387fff ths
    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
180 364d4831 Nathan Froyd
    OPC_JALRC    = OPC_JALR | (0x5 << 6),
181 620e48f6 Nathan Froyd
    OPC_JALRS    = 0x10 | OPC_SPECIAL | (0x5 << 6),
182 e37e863f bellard
    /* Traps */
183 7a387fff ths
    OPC_TGE      = 0x30 | OPC_SPECIAL,
184 7a387fff ths
    OPC_TGEU     = 0x31 | OPC_SPECIAL,
185 7a387fff ths
    OPC_TLT      = 0x32 | OPC_SPECIAL,
186 7a387fff ths
    OPC_TLTU     = 0x33 | OPC_SPECIAL,
187 7a387fff ths
    OPC_TEQ      = 0x34 | OPC_SPECIAL,
188 7a387fff ths
    OPC_TNE      = 0x36 | OPC_SPECIAL,
189 e37e863f bellard
    /* HI / LO registers load & stores */
190 7a387fff ths
    OPC_MFHI     = 0x10 | OPC_SPECIAL,
191 7a387fff ths
    OPC_MTHI     = 0x11 | OPC_SPECIAL,
192 7a387fff ths
    OPC_MFLO     = 0x12 | OPC_SPECIAL,
193 7a387fff ths
    OPC_MTLO     = 0x13 | OPC_SPECIAL,
194 e37e863f bellard
    /* Conditional moves */
195 7a387fff ths
    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
196 7a387fff ths
    OPC_MOVN     = 0x0B | OPC_SPECIAL,
197 e37e863f bellard
198 7a387fff ths
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
199 e37e863f bellard
200 e37e863f bellard
    /* Special */
201 a0d700e4 Stefan Weil
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
202 7a387fff ths
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
203 7a387fff ths
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
204 a0d700e4 Stefan Weil
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
205 7a387fff ths
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
206 7a387fff ths
207 7a387fff ths
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
208 7a387fff ths
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
209 7a387fff ths
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
210 7a387fff ths
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
211 7a387fff ths
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
212 7a387fff ths
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
213 7a387fff ths
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
214 7a387fff ths
};
215 7a387fff ths
216 e9c71dd1 ths
/* Multiplication variants of the vr54xx. */
217 e9c71dd1 ths
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
218 e9c71dd1 ths
219 e9c71dd1 ths
enum {
220 e9c71dd1 ths
    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
221 e9c71dd1 ths
    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
222 e9c71dd1 ths
    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
223 e9c71dd1 ths
    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
224 e9c71dd1 ths
    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
225 e9c71dd1 ths
    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
226 e9c71dd1 ths
    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
227 e9c71dd1 ths
    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
228 e9c71dd1 ths
    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
229 e9c71dd1 ths
    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
230 e9c71dd1 ths
    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
231 e9c71dd1 ths
    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
232 e9c71dd1 ths
    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
233 e9c71dd1 ths
    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
234 e9c71dd1 ths
};
235 e9c71dd1 ths
236 7a387fff ths
/* REGIMM (rt field) opcodes */
237 7a387fff ths
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
238 7a387fff ths
239 7a387fff ths
enum {
240 7a387fff ths
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
241 7a387fff ths
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
242 7a387fff ths
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
243 7a387fff ths
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
244 7a387fff ths
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
245 3c824109 Nathan Froyd
    OPC_BLTZALS  = OPC_BLTZAL | 0x5, /* microMIPS */
246 7a387fff ths
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
247 7a387fff ths
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
248 3c824109 Nathan Froyd
    OPC_BGEZALS  = OPC_BGEZAL | 0x5, /* microMIPS */
249 7a387fff ths
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
250 7a387fff ths
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
251 7a387fff ths
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
252 7a387fff ths
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
253 7a387fff ths
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
254 7a387fff ths
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
255 7a387fff ths
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
256 7a387fff ths
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
257 e37e863f bellard
};
258 e37e863f bellard
259 7a387fff ths
/* Special2 opcodes */
260 7a387fff ths
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
261 7a387fff ths
262 e37e863f bellard
enum {
263 7a387fff ths
    /* Multiply & xxx operations */
264 7a387fff ths
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
265 7a387fff ths
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
266 7a387fff ths
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
267 7a387fff ths
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
268 7a387fff ths
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
269 161f85e6 Aurelien Jarno
    /* Loongson 2F */
270 161f85e6 Aurelien Jarno
    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
271 161f85e6 Aurelien Jarno
    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
272 161f85e6 Aurelien Jarno
    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
273 161f85e6 Aurelien Jarno
    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
274 161f85e6 Aurelien Jarno
    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
275 161f85e6 Aurelien Jarno
    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
276 161f85e6 Aurelien Jarno
    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
277 161f85e6 Aurelien Jarno
    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
278 161f85e6 Aurelien Jarno
    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
279 161f85e6 Aurelien Jarno
    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
280 161f85e6 Aurelien Jarno
    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
281 161f85e6 Aurelien Jarno
    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
282 e37e863f bellard
    /* Misc */
283 7a387fff ths
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
284 7a387fff ths
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
285 7a387fff ths
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
286 7a387fff ths
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
287 e37e863f bellard
    /* Special */
288 7a387fff ths
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
289 7a387fff ths
};
290 7a387fff ths
291 7a387fff ths
/* Special3 opcodes */
292 7a387fff ths
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
293 7a387fff ths
294 7a387fff ths
enum {
295 7a387fff ths
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
296 7a387fff ths
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
297 7a387fff ths
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
298 7a387fff ths
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
299 7a387fff ths
    OPC_INS      = 0x04 | OPC_SPECIAL3,
300 7a387fff ths
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
301 7a387fff ths
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
302 7a387fff ths
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
303 ead9360e ths
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
304 ead9360e ths
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
305 7a387fff ths
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
306 7a387fff ths
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
307 7a387fff ths
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
308 161f85e6 Aurelien Jarno
309 161f85e6 Aurelien Jarno
    /* Loongson 2E */
310 161f85e6 Aurelien Jarno
    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
311 161f85e6 Aurelien Jarno
    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
312 161f85e6 Aurelien Jarno
    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
313 161f85e6 Aurelien Jarno
    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
314 161f85e6 Aurelien Jarno
    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
315 161f85e6 Aurelien Jarno
    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
316 161f85e6 Aurelien Jarno
    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
317 161f85e6 Aurelien Jarno
    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
318 161f85e6 Aurelien Jarno
    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
319 161f85e6 Aurelien Jarno
    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
320 161f85e6 Aurelien Jarno
    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
321 161f85e6 Aurelien Jarno
    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
322 e37e863f bellard
};
323 e37e863f bellard
324 7a387fff ths
/* BSHFL opcodes */
325 7a387fff ths
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
326 7a387fff ths
327 e37e863f bellard
enum {
328 7a387fff ths
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
329 7a387fff ths
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
330 7a387fff ths
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
331 e37e863f bellard
};
332 e37e863f bellard
333 7a387fff ths
/* DBSHFL opcodes */
334 7a387fff ths
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
335 7a387fff ths
336 e37e863f bellard
enum {
337 7a387fff ths
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
338 7a387fff ths
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
339 e37e863f bellard
};
340 e37e863f bellard
341 7a387fff ths
/* Coprocessor 0 (rs field) */
342 7a387fff ths
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
343 7a387fff ths
344 6ea83fed bellard
enum {
345 7a387fff ths
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
346 7a387fff ths
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
347 7a387fff ths
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
348 7a387fff ths
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
349 ead9360e ths
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
350 7a387fff ths
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
351 7a387fff ths
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
352 ead9360e ths
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
353 7a387fff ths
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
354 7a387fff ths
    OPC_C0       = (0x10 << 21) | OPC_CP0,
355 7a387fff ths
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
356 7a387fff ths
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
357 6ea83fed bellard
};
358 7a387fff ths
359 7a387fff ths
/* MFMC0 opcodes */
360 b48cfdff ths
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
361 7a387fff ths
362 7a387fff ths
enum {
363 ead9360e ths
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
364 ead9360e ths
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
365 ead9360e ths
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
366 ead9360e ths
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
367 7a387fff ths
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
368 7a387fff ths
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
369 7a387fff ths
};
370 7a387fff ths
371 7a387fff ths
/* Coprocessor 0 (with rs == C0) */
372 7a387fff ths
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
373 7a387fff ths
374 7a387fff ths
enum {
375 7a387fff ths
    OPC_TLBR     = 0x01 | OPC_C0,
376 7a387fff ths
    OPC_TLBWI    = 0x02 | OPC_C0,
377 7a387fff ths
    OPC_TLBWR    = 0x06 | OPC_C0,
378 7a387fff ths
    OPC_TLBP     = 0x08 | OPC_C0,
379 7a387fff ths
    OPC_RFE      = 0x10 | OPC_C0,
380 7a387fff ths
    OPC_ERET     = 0x18 | OPC_C0,
381 7a387fff ths
    OPC_DERET    = 0x1F | OPC_C0,
382 7a387fff ths
    OPC_WAIT     = 0x20 | OPC_C0,
383 7a387fff ths
};
384 7a387fff ths
385 7a387fff ths
/* Coprocessor 1 (rs field) */
386 7a387fff ths
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
387 7a387fff ths
388 bf4120ad Nathan Froyd
/* Values for the fmt field in FP instructions */
389 bf4120ad Nathan Froyd
enum {
390 bf4120ad Nathan Froyd
    /* 0 - 15 are reserved */
391 e459440a Aurelien Jarno
    FMT_S = 16,          /* single fp */
392 e459440a Aurelien Jarno
    FMT_D = 17,          /* double fp */
393 e459440a Aurelien Jarno
    FMT_E = 18,          /* extended fp */
394 e459440a Aurelien Jarno
    FMT_Q = 19,          /* quad fp */
395 e459440a Aurelien Jarno
    FMT_W = 20,          /* 32-bit fixed */
396 e459440a Aurelien Jarno
    FMT_L = 21,          /* 64-bit fixed */
397 e459440a Aurelien Jarno
    FMT_PS = 22,         /* paired single fp */
398 bf4120ad Nathan Froyd
    /* 23 - 31 are reserved */
399 bf4120ad Nathan Froyd
};
400 bf4120ad Nathan Froyd
401 7a387fff ths
enum {
402 7a387fff ths
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
403 7a387fff ths
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
404 7a387fff ths
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
405 5a5012ec ths
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
406 7a387fff ths
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
407 7a387fff ths
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
408 7a387fff ths
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
409 5a5012ec ths
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
410 7a387fff ths
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
411 5a5012ec ths
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
412 5a5012ec ths
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
413 e459440a Aurelien Jarno
    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
414 e459440a Aurelien Jarno
    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
415 e459440a Aurelien Jarno
    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
416 e459440a Aurelien Jarno
    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
417 e459440a Aurelien Jarno
    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
418 e459440a Aurelien Jarno
    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
419 e459440a Aurelien Jarno
    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
420 7a387fff ths
};
421 7a387fff ths
422 5a5012ec ths
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
423 5a5012ec ths
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
424 5a5012ec ths
425 7a387fff ths
enum {
426 7a387fff ths
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
427 7a387fff ths
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
428 7a387fff ths
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
429 7a387fff ths
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
430 7a387fff ths
};
431 7a387fff ths
432 5a5012ec ths
enum {
433 5a5012ec ths
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
434 5a5012ec ths
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
435 5a5012ec ths
};
436 5a5012ec ths
437 5a5012ec ths
enum {
438 5a5012ec ths
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
439 5a5012ec ths
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
440 5a5012ec ths
};
441 7a387fff ths
442 7a387fff ths
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
443 e0c84da7 ths
444 e0c84da7 ths
enum {
445 e0c84da7 ths
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
446 e0c84da7 ths
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
447 e0c84da7 ths
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
448 e0c84da7 ths
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
449 e0c84da7 ths
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
450 e0c84da7 ths
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
451 e0c84da7 ths
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
452 e0c84da7 ths
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
453 e0c84da7 ths
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
454 e0c84da7 ths
};
455 e0c84da7 ths
456 e0c84da7 ths
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
457 e0c84da7 ths
458 e0c84da7 ths
enum {
459 e0c84da7 ths
    OPC_LWXC1   = 0x00 | OPC_CP3,
460 e0c84da7 ths
    OPC_LDXC1   = 0x01 | OPC_CP3,
461 e0c84da7 ths
    OPC_LUXC1   = 0x05 | OPC_CP3,
462 e0c84da7 ths
    OPC_SWXC1   = 0x08 | OPC_CP3,
463 e0c84da7 ths
    OPC_SDXC1   = 0x09 | OPC_CP3,
464 e0c84da7 ths
    OPC_SUXC1   = 0x0D | OPC_CP3,
465 e0c84da7 ths
    OPC_PREFX   = 0x0F | OPC_CP3,
466 e0c84da7 ths
    OPC_ALNV_PS = 0x1E | OPC_CP3,
467 e0c84da7 ths
    OPC_MADD_S  = 0x20 | OPC_CP3,
468 e0c84da7 ths
    OPC_MADD_D  = 0x21 | OPC_CP3,
469 e0c84da7 ths
    OPC_MADD_PS = 0x26 | OPC_CP3,
470 e0c84da7 ths
    OPC_MSUB_S  = 0x28 | OPC_CP3,
471 e0c84da7 ths
    OPC_MSUB_D  = 0x29 | OPC_CP3,
472 e0c84da7 ths
    OPC_MSUB_PS = 0x2E | OPC_CP3,
473 e0c84da7 ths
    OPC_NMADD_S = 0x30 | OPC_CP3,
474 fbcc6828 ths
    OPC_NMADD_D = 0x31 | OPC_CP3,
475 e0c84da7 ths
    OPC_NMADD_PS= 0x36 | OPC_CP3,
476 e0c84da7 ths
    OPC_NMSUB_S = 0x38 | OPC_CP3,
477 e0c84da7 ths
    OPC_NMSUB_D = 0x39 | OPC_CP3,
478 e0c84da7 ths
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
479 e0c84da7 ths
};
480 e0c84da7 ths
481 39454628 ths
/* global register indices */
482 a7812ae4 pbrook
static TCGv_ptr cpu_env;
483 a7812ae4 pbrook
static TCGv cpu_gpr[32], cpu_PC;
484 4b2eb8d2 ths
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
485 41db4607 aurel32
static TCGv cpu_dspctrl, btarget, bcond;
486 41db4607 aurel32
static TCGv_i32 hflags;
487 a7812ae4 pbrook
static TCGv_i32 fpu_fcr0, fpu_fcr31;
488 aa0bf00b ths
489 1a7ff922 Paolo Bonzini
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
490 1a7ff922 Paolo Bonzini
491 2e70f6ef pbrook
#include "gen-icount.h"
492 2e70f6ef pbrook
493 a7812ae4 pbrook
#define gen_helper_0i(name, arg) do {                             \
494 a7812ae4 pbrook
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
495 a7812ae4 pbrook
    gen_helper_##name(helper_tmp);                                \
496 a7812ae4 pbrook
    tcg_temp_free_i32(helper_tmp);                                \
497 a7812ae4 pbrook
    } while(0)
498 be24bb4f ths
499 a7812ae4 pbrook
#define gen_helper_1i(name, arg1, arg2) do {                      \
500 a7812ae4 pbrook
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
501 a7812ae4 pbrook
    gen_helper_##name(arg1, helper_tmp);                          \
502 a7812ae4 pbrook
    tcg_temp_free_i32(helper_tmp);                                \
503 a7812ae4 pbrook
    } while(0)
504 be24bb4f ths
505 a7812ae4 pbrook
#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
506 a7812ae4 pbrook
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
507 a7812ae4 pbrook
    gen_helper_##name(arg1, arg2, helper_tmp);                    \
508 a7812ae4 pbrook
    tcg_temp_free_i32(helper_tmp);                                \
509 a7812ae4 pbrook
    } while(0)
510 be24bb4f ths
511 a7812ae4 pbrook
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
512 a7812ae4 pbrook
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
513 a7812ae4 pbrook
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
514 a7812ae4 pbrook
    tcg_temp_free_i32(helper_tmp);                                \
515 a7812ae4 pbrook
    } while(0)
516 c239529e ths
517 8e9ade68 ths
typedef struct DisasContext {
518 8e9ade68 ths
    struct TranslationBlock *tb;
519 8e9ade68 ths
    target_ulong pc, saved_pc;
520 8e9ade68 ths
    uint32_t opcode;
521 7b270ef2 Nathan Froyd
    int singlestep_enabled;
522 8e9ade68 ths
    /* Routine used to access memory */
523 8e9ade68 ths
    int mem_idx;
524 8e9ade68 ths
    uint32_t hflags, saved_hflags;
525 8e9ade68 ths
    int bstate;
526 8e9ade68 ths
    target_ulong btarget;
527 8e9ade68 ths
} DisasContext;
528 8e9ade68 ths
529 8e9ade68 ths
enum {
530 8e9ade68 ths
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
531 d077b6f7 ths
                      * exception condition */
532 8e9ade68 ths
    BS_STOP     = 1, /* We want to stop translation for any reason */
533 8e9ade68 ths
    BS_BRANCH   = 2, /* We reached a branch condition     */
534 8e9ade68 ths
    BS_EXCP     = 3, /* We reached an exception condition */
535 8e9ade68 ths
};
536 8e9ade68 ths
537 8e9ade68 ths
static const char *regnames[] =
538 6af0bf9c bellard
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
539 6af0bf9c bellard
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
540 6af0bf9c bellard
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
541 6af0bf9c bellard
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
542 6af0bf9c bellard
543 4b2eb8d2 ths
static const char *regnames_HI[] =
544 4b2eb8d2 ths
    { "HI0", "HI1", "HI2", "HI3", };
545 4b2eb8d2 ths
546 4b2eb8d2 ths
static const char *regnames_LO[] =
547 4b2eb8d2 ths
    { "LO0", "LO1", "LO2", "LO3", };
548 4b2eb8d2 ths
549 4b2eb8d2 ths
static const char *regnames_ACX[] =
550 4b2eb8d2 ths
    { "ACX0", "ACX1", "ACX2", "ACX3", };
551 4b2eb8d2 ths
552 8e9ade68 ths
static const char *fregnames[] =
553 8e9ade68 ths
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
554 8e9ade68 ths
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
555 8e9ade68 ths
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
556 8e9ade68 ths
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
557 958fb4a9 ths
558 8e9ade68 ths
#ifdef MIPS_DEBUG_DISAS
559 001faf32 Blue Swirl
#define MIPS_DEBUG(fmt, ...)                         \
560 93fcfe39 aliguori
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
561 93fcfe39 aliguori
                       TARGET_FMT_lx ": %08x " fmt "\n", \
562 001faf32 Blue Swirl
                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
563 93fcfe39 aliguori
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
564 8e9ade68 ths
#else
565 001faf32 Blue Swirl
#define MIPS_DEBUG(fmt, ...) do { } while(0)
566 d12d51d5 aliguori
#define LOG_DISAS(...) do { } while (0)
567 8e9ade68 ths
#endif
568 958fb4a9 ths
569 8e9ade68 ths
#define MIPS_INVAL(op)                                                        \
570 8e9ade68 ths
do {                                                                          \
571 8e9ade68 ths
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
572 8e9ade68 ths
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
573 8e9ade68 ths
} while (0)
574 ead9360e ths
575 8e9ade68 ths
/* General purpose registers moves. */
576 8e9ade68 ths
static inline void gen_load_gpr (TCGv t, int reg)
577 aaa9128a ths
{
578 8e9ade68 ths
    if (reg == 0)
579 8e9ade68 ths
        tcg_gen_movi_tl(t, 0);
580 8e9ade68 ths
    else
581 4b2eb8d2 ths
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
582 aaa9128a ths
}
583 aaa9128a ths
584 8e9ade68 ths
static inline void gen_store_gpr (TCGv t, int reg)
585 aaa9128a ths
{
586 8e9ade68 ths
    if (reg != 0)
587 4b2eb8d2 ths
        tcg_gen_mov_tl(cpu_gpr[reg], t);
588 aaa9128a ths
}
589 aaa9128a ths
590 b10fa3c9 aurel32
/* Moves to/from ACX register.  */
591 4b2eb8d2 ths
static inline void gen_load_ACX (TCGv t, int reg)
592 893f9865 ths
{
593 4b2eb8d2 ths
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
594 893f9865 ths
}
595 893f9865 ths
596 4b2eb8d2 ths
static inline void gen_store_ACX (TCGv t, int reg)
597 893f9865 ths
{
598 4b2eb8d2 ths
    tcg_gen_mov_tl(cpu_ACX[reg], t);
599 893f9865 ths
}
600 893f9865 ths
601 8e9ade68 ths
/* Moves to/from shadow registers. */
602 be24bb4f ths
static inline void gen_load_srsgpr (int from, int to)
603 aaa9128a ths
{
604 d9bea114 aurel32
    TCGv t0 = tcg_temp_new();
605 be24bb4f ths
606 be24bb4f ths
    if (from == 0)
607 d9bea114 aurel32
        tcg_gen_movi_tl(t0, 0);
608 8e9ade68 ths
    else {
609 d9bea114 aurel32
        TCGv_i32 t2 = tcg_temp_new_i32();
610 a7812ae4 pbrook
        TCGv_ptr addr = tcg_temp_new_ptr();
611 aaa9128a ths
612 d9bea114 aurel32
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
613 d9bea114 aurel32
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
614 d9bea114 aurel32
        tcg_gen_andi_i32(t2, t2, 0xf);
615 d9bea114 aurel32
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
616 d9bea114 aurel32
        tcg_gen_ext_i32_ptr(addr, t2);
617 a7812ae4 pbrook
        tcg_gen_add_ptr(addr, cpu_env, addr);
618 aaa9128a ths
619 d9bea114 aurel32
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
620 a7812ae4 pbrook
        tcg_temp_free_ptr(addr);
621 d9bea114 aurel32
        tcg_temp_free_i32(t2);
622 8e9ade68 ths
    }
623 d9bea114 aurel32
    gen_store_gpr(t0, to);
624 d9bea114 aurel32
    tcg_temp_free(t0);
625 aaa9128a ths
}
626 aaa9128a ths
627 be24bb4f ths
static inline void gen_store_srsgpr (int from, int to)
628 aaa9128a ths
{
629 be24bb4f ths
    if (to != 0) {
630 d9bea114 aurel32
        TCGv t0 = tcg_temp_new();
631 d9bea114 aurel32
        TCGv_i32 t2 = tcg_temp_new_i32();
632 a7812ae4 pbrook
        TCGv_ptr addr = tcg_temp_new_ptr();
633 be24bb4f ths
634 d9bea114 aurel32
        gen_load_gpr(t0, from);
635 d9bea114 aurel32
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
636 d9bea114 aurel32
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
637 d9bea114 aurel32
        tcg_gen_andi_i32(t2, t2, 0xf);
638 d9bea114 aurel32
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
639 d9bea114 aurel32
        tcg_gen_ext_i32_ptr(addr, t2);
640 a7812ae4 pbrook
        tcg_gen_add_ptr(addr, cpu_env, addr);
641 be24bb4f ths
642 d9bea114 aurel32
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
643 a7812ae4 pbrook
        tcg_temp_free_ptr(addr);
644 d9bea114 aurel32
        tcg_temp_free_i32(t2);
645 d9bea114 aurel32
        tcg_temp_free(t0);
646 8e9ade68 ths
    }
647 aaa9128a ths
}
648 aaa9128a ths
649 aaa9128a ths
/* Floating point register moves. */
650 a7812ae4 pbrook
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
651 aa0bf00b ths
{
652 6d066274 aurel32
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
653 6ea83fed bellard
}
654 6ea83fed bellard
655 a7812ae4 pbrook
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
656 aa0bf00b ths
{
657 6d066274 aurel32
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
658 6d066274 aurel32
}
659 6d066274 aurel32
660 6d066274 aurel32
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
661 6d066274 aurel32
{
662 6d066274 aurel32
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
663 6d066274 aurel32
}
664 6d066274 aurel32
665 6d066274 aurel32
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
666 6d066274 aurel32
{
667 6d066274 aurel32
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
668 aa0bf00b ths
}
669 6ea83fed bellard
670 a7812ae4 pbrook
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
671 aa0bf00b ths
{
672 f364515c aurel32
    if (ctx->hflags & MIPS_HFLAG_F64) {
673 6d066274 aurel32
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
674 f364515c aurel32
    } else {
675 6d066274 aurel32
        TCGv_i32 t0 = tcg_temp_new_i32();
676 6d066274 aurel32
        TCGv_i32 t1 = tcg_temp_new_i32();
677 6d066274 aurel32
        gen_load_fpr32(t0, reg & ~1);
678 6d066274 aurel32
        gen_load_fpr32(t1, reg | 1);
679 6d066274 aurel32
        tcg_gen_concat_i32_i64(t, t0, t1);
680 6d066274 aurel32
        tcg_temp_free_i32(t0);
681 6d066274 aurel32
        tcg_temp_free_i32(t1);
682 aa0bf00b ths
    }
683 aa0bf00b ths
}
684 6ea83fed bellard
685 a7812ae4 pbrook
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
686 aa0bf00b ths
{
687 f364515c aurel32
    if (ctx->hflags & MIPS_HFLAG_F64) {
688 6d066274 aurel32
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
689 f364515c aurel32
    } else {
690 6d066274 aurel32
        TCGv_i64 t0 = tcg_temp_new_i64();
691 6d066274 aurel32
        TCGv_i32 t1 = tcg_temp_new_i32();
692 6d066274 aurel32
        tcg_gen_trunc_i64_i32(t1, t);
693 6d066274 aurel32
        gen_store_fpr32(t1, reg & ~1);
694 6d066274 aurel32
        tcg_gen_shri_i64(t0, t, 32);
695 6d066274 aurel32
        tcg_gen_trunc_i64_i32(t1, t0);
696 6d066274 aurel32
        gen_store_fpr32(t1, reg | 1);
697 6d066274 aurel32
        tcg_temp_free_i32(t1);
698 6d066274 aurel32
        tcg_temp_free_i64(t0);
699 aa0bf00b ths
    }
700 aa0bf00b ths
}
701 6ea83fed bellard
702 d94536f4 aurel32
static inline int get_fp_bit (int cc)
703 a16336e4 ths
{
704 d94536f4 aurel32
    if (cc)
705 d94536f4 aurel32
        return 24 + cc;
706 d94536f4 aurel32
    else
707 d94536f4 aurel32
        return 23;
708 a16336e4 ths
}
709 a16336e4 ths
710 30898801 ths
/* Tests */
711 8e9ade68 ths
static inline void gen_save_pc(target_ulong pc)
712 8e9ade68 ths
{
713 1eb75d4a aurel32
    tcg_gen_movi_tl(cpu_PC, pc);
714 8e9ade68 ths
}
715 30898801 ths
716 356265ae ths
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
717 6af0bf9c bellard
{
718 d12d51d5 aliguori
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
719 6af0bf9c bellard
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
720 9b9e4393 ths
        gen_save_pc(ctx->pc);
721 6af0bf9c bellard
        ctx->saved_pc = ctx->pc;
722 6af0bf9c bellard
    }
723 6af0bf9c bellard
    if (ctx->hflags != ctx->saved_hflags) {
724 41db4607 aurel32
        tcg_gen_movi_i32(hflags, ctx->hflags);
725 6af0bf9c bellard
        ctx->saved_hflags = ctx->hflags;
726 364d4831 Nathan Froyd
        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
727 5a5012ec ths
        case MIPS_HFLAG_BR:
728 5a5012ec ths
            break;
729 5a5012ec ths
        case MIPS_HFLAG_BC:
730 5a5012ec ths
        case MIPS_HFLAG_BL:
731 5a5012ec ths
        case MIPS_HFLAG_B:
732 d077b6f7 ths
            tcg_gen_movi_tl(btarget, ctx->btarget);
733 5a5012ec ths
            break;
734 6af0bf9c bellard
        }
735 6af0bf9c bellard
    }
736 6af0bf9c bellard
}
737 6af0bf9c bellard
738 356265ae ths
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
739 5a5012ec ths
{
740 fd4a04eb ths
    ctx->saved_hflags = ctx->hflags;
741 364d4831 Nathan Froyd
    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
742 fd4a04eb ths
    case MIPS_HFLAG_BR:
743 fd4a04eb ths
        break;
744 fd4a04eb ths
    case MIPS_HFLAG_BC:
745 fd4a04eb ths
    case MIPS_HFLAG_BL:
746 39454628 ths
    case MIPS_HFLAG_B:
747 fd4a04eb ths
        ctx->btarget = env->btarget;
748 fd4a04eb ths
        break;
749 5a5012ec ths
    }
750 5a5012ec ths
}
751 5a5012ec ths
752 356265ae ths
static inline void
753 48d38ca5 ths
generate_exception_err (DisasContext *ctx, int excp, int err)
754 aaa9128a ths
{
755 a7812ae4 pbrook
    TCGv_i32 texcp = tcg_const_i32(excp);
756 a7812ae4 pbrook
    TCGv_i32 terr = tcg_const_i32(err);
757 aaa9128a ths
    save_cpu_state(ctx, 1);
758 a7812ae4 pbrook
    gen_helper_raise_exception_err(texcp, terr);
759 a7812ae4 pbrook
    tcg_temp_free_i32(terr);
760 a7812ae4 pbrook
    tcg_temp_free_i32(texcp);
761 aaa9128a ths
}
762 aaa9128a ths
763 356265ae ths
static inline void
764 48d38ca5 ths
generate_exception (DisasContext *ctx, int excp)
765 aaa9128a ths
{
766 6af0bf9c bellard
    save_cpu_state(ctx, 1);
767 a7812ae4 pbrook
    gen_helper_0i(raise_exception, excp);
768 6af0bf9c bellard
}
769 6af0bf9c bellard
770 48d38ca5 ths
/* Addresses computation */
771 941694d0 Aurelien Jarno
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
772 4ad40f36 bellard
{
773 941694d0 Aurelien Jarno
    tcg_gen_add_tl(ret, arg0, arg1);
774 48d38ca5 ths
775 48d38ca5 ths
#if defined(TARGET_MIPS64)
776 48d38ca5 ths
    /* For compatibility with 32-bit code, data reference in user mode
777 48d38ca5 ths
       with Status_UX = 0 should be casted to 32-bit and sign extended.
778 48d38ca5 ths
       See the MIPS64 PRA manual, section 4.10. */
779 2623c1ec aurel32
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
780 2623c1ec aurel32
        !(ctx->hflags & MIPS_HFLAG_UX)) {
781 941694d0 Aurelien Jarno
        tcg_gen_ext32s_i64(ret, ret);
782 48d38ca5 ths
    }
783 48d38ca5 ths
#endif
784 4ad40f36 bellard
}
785 4ad40f36 bellard
786 356265ae ths
static inline void check_cp0_enabled(DisasContext *ctx)
787 387a8fe5 ths
{
788 fe253235 ths
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
789 c2c65dab Nathan Froyd
        generate_exception_err(ctx, EXCP_CpU, 0);
790 387a8fe5 ths
}
791 387a8fe5 ths
792 356265ae ths
static inline void check_cp1_enabled(DisasContext *ctx)
793 5e755519 ths
{
794 fe253235 ths
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
795 5e755519 ths
        generate_exception_err(ctx, EXCP_CpU, 1);
796 5e755519 ths
}
797 5e755519 ths
798 b8aa4598 ths
/* Verify that the processor is running with COP1X instructions enabled.
799 b8aa4598 ths
   This is associated with the nabla symbol in the MIPS32 and MIPS64
800 b8aa4598 ths
   opcode tables.  */
801 b8aa4598 ths
802 356265ae ths
static inline void check_cop1x(DisasContext *ctx)
803 b8aa4598 ths
{
804 b8aa4598 ths
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
805 b8aa4598 ths
        generate_exception(ctx, EXCP_RI);
806 b8aa4598 ths
}
807 b8aa4598 ths
808 b8aa4598 ths
/* Verify that the processor is running with 64-bit floating-point
809 b8aa4598 ths
   operations enabled.  */
810 b8aa4598 ths
811 356265ae ths
static inline void check_cp1_64bitmode(DisasContext *ctx)
812 5e755519 ths
{
813 b8aa4598 ths
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
814 5e755519 ths
        generate_exception(ctx, EXCP_RI);
815 5e755519 ths
}
816 5e755519 ths
817 5e755519 ths
/*
818 5e755519 ths
 * Verify if floating point register is valid; an operation is not defined
819 5e755519 ths
 * if bit 0 of any register specification is set and the FR bit in the
820 5e755519 ths
 * Status register equals zero, since the register numbers specify an
821 5e755519 ths
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
822 5e755519 ths
 * in the Status register equals one, both even and odd register numbers
823 5e755519 ths
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
824 5e755519 ths
 *
825 5e755519 ths
 * Multiple 64 bit wide registers can be checked by calling
826 5e755519 ths
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
827 5e755519 ths
 */
828 356265ae ths
static inline void check_cp1_registers(DisasContext *ctx, int regs)
829 5e755519 ths
{
830 fe253235 ths
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
831 5e755519 ths
        generate_exception(ctx, EXCP_RI);
832 5e755519 ths
}
833 5e755519 ths
834 3a95e3a7 ths
/* This code generates a "reserved instruction" exception if the
835 e189e748 ths
   CPU does not support the instruction set corresponding to flags. */
836 356265ae ths
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
837 3a95e3a7 ths
{
838 e189e748 ths
    if (unlikely(!(env->insn_flags & flags)))
839 3a95e3a7 ths
        generate_exception(ctx, EXCP_RI);
840 3a95e3a7 ths
}
841 3a95e3a7 ths
842 e189e748 ths
/* This code generates a "reserved instruction" exception if 64-bit
843 e189e748 ths
   instructions are not enabled. */
844 356265ae ths
static inline void check_mips_64(DisasContext *ctx)
845 e189e748 ths
{
846 fe253235 ths
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
847 e189e748 ths
        generate_exception(ctx, EXCP_RI);
848 e189e748 ths
}
849 e189e748 ths
850 8153667c Nathan Froyd
/* Define small wrappers for gen_load_fpr* so that we have a uniform
851 8153667c Nathan Froyd
   calling interface for 32 and 64-bit FPRs.  No sense in changing
852 8153667c Nathan Froyd
   all callers for gen_load_fpr32 when we need the CTX parameter for
853 8153667c Nathan Froyd
   this one use.  */
854 8153667c Nathan Froyd
#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
855 8153667c Nathan Froyd
#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
856 8153667c Nathan Froyd
#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
857 8153667c Nathan Froyd
static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
858 8153667c Nathan Froyd
                                               int ft, int fs, int cc)        \
859 8153667c Nathan Froyd
{                                                                             \
860 8153667c Nathan Froyd
    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
861 8153667c Nathan Froyd
    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
862 8153667c Nathan Froyd
    switch (ifmt) {                                                           \
863 8153667c Nathan Froyd
    case FMT_PS:                                                              \
864 8153667c Nathan Froyd
        check_cp1_64bitmode(ctx);                                             \
865 8153667c Nathan Froyd
        break;                                                                \
866 8153667c Nathan Froyd
    case FMT_D:                                                               \
867 8153667c Nathan Froyd
        if (abs) {                                                            \
868 8153667c Nathan Froyd
            check_cop1x(ctx);                                                 \
869 8153667c Nathan Froyd
        }                                                                     \
870 8153667c Nathan Froyd
        check_cp1_registers(ctx, fs | ft);                                    \
871 8153667c Nathan Froyd
        break;                                                                \
872 8153667c Nathan Froyd
    case FMT_S:                                                               \
873 8153667c Nathan Froyd
        if (abs) {                                                            \
874 8153667c Nathan Froyd
            check_cop1x(ctx);                                                 \
875 8153667c Nathan Froyd
        }                                                                     \
876 8153667c Nathan Froyd
        break;                                                                \
877 8153667c Nathan Froyd
    }                                                                         \
878 8153667c Nathan Froyd
    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
879 8153667c Nathan Froyd
    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
880 8153667c Nathan Froyd
    switch (n) {                                                              \
881 8153667c Nathan Froyd
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
882 8153667c Nathan Froyd
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
883 8153667c Nathan Froyd
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
884 8153667c Nathan Froyd
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
885 8153667c Nathan Froyd
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
886 8153667c Nathan Froyd
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
887 8153667c Nathan Froyd
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
888 8153667c Nathan Froyd
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
889 8153667c Nathan Froyd
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
890 8153667c Nathan Froyd
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
891 8153667c Nathan Froyd
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
892 8153667c Nathan Froyd
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
893 8153667c Nathan Froyd
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
894 8153667c Nathan Froyd
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
895 8153667c Nathan Froyd
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
896 8153667c Nathan Froyd
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
897 8153667c Nathan Froyd
    default: abort();                                                         \
898 8153667c Nathan Froyd
    }                                                                         \
899 8153667c Nathan Froyd
    tcg_temp_free_i##bits (fp0);                                              \
900 8153667c Nathan Froyd
    tcg_temp_free_i##bits (fp1);                                              \
901 8153667c Nathan Froyd
}
902 8153667c Nathan Froyd
903 8153667c Nathan Froyd
FOP_CONDS(, 0, d, FMT_D, 64)
904 8153667c Nathan Froyd
FOP_CONDS(abs, 1, d, FMT_D, 64)
905 8153667c Nathan Froyd
FOP_CONDS(, 0, s, FMT_S, 32)
906 8153667c Nathan Froyd
FOP_CONDS(abs, 1, s, FMT_S, 32)
907 8153667c Nathan Froyd
FOP_CONDS(, 0, ps, FMT_PS, 64)
908 8153667c Nathan Froyd
FOP_CONDS(abs, 1, ps, FMT_PS, 64)
909 8153667c Nathan Froyd
#undef FOP_CONDS
910 8153667c Nathan Froyd
#undef gen_ldcmp_fpr32
911 8153667c Nathan Froyd
#undef gen_ldcmp_fpr64
912 8153667c Nathan Froyd
913 958fb4a9 ths
/* load/store instructions. */
914 d9bea114 aurel32
#define OP_LD(insn,fname)                                                 \
915 5c13fdfd Aurelien Jarno
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)   \
916 d9bea114 aurel32
{                                                                         \
917 d9bea114 aurel32
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
918 aaa9128a ths
}
919 aaa9128a ths
OP_LD(lb,ld8s);
920 aaa9128a ths
OP_LD(lbu,ld8u);
921 aaa9128a ths
OP_LD(lh,ld16s);
922 aaa9128a ths
OP_LD(lhu,ld16u);
923 aaa9128a ths
OP_LD(lw,ld32s);
924 aaa9128a ths
#if defined(TARGET_MIPS64)
925 aaa9128a ths
OP_LD(lwu,ld32u);
926 aaa9128a ths
OP_LD(ld,ld64);
927 aaa9128a ths
#endif
928 aaa9128a ths
#undef OP_LD
929 aaa9128a ths
930 d9bea114 aurel32
#define OP_ST(insn,fname)                                                  \
931 5c13fdfd Aurelien Jarno
static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx)   \
932 d9bea114 aurel32
{                                                                          \
933 d9bea114 aurel32
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
934 aaa9128a ths
}
935 aaa9128a ths
OP_ST(sb,st8);
936 aaa9128a ths
OP_ST(sh,st16);
937 aaa9128a ths
OP_ST(sw,st32);
938 aaa9128a ths
#if defined(TARGET_MIPS64)
939 aaa9128a ths
OP_ST(sd,st64);
940 aaa9128a ths
#endif
941 aaa9128a ths
#undef OP_ST
942 aaa9128a ths
943 e7139c44 Aurelien Jarno
#ifdef CONFIG_USER_ONLY
944 d9bea114 aurel32
#define OP_LD_ATOMIC(insn,fname)                                           \
945 5c13fdfd Aurelien Jarno
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
946 d9bea114 aurel32
{                                                                          \
947 d9bea114 aurel32
    TCGv t0 = tcg_temp_new();                                              \
948 d9bea114 aurel32
    tcg_gen_mov_tl(t0, arg1);                                              \
949 d9bea114 aurel32
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
950 e7139c44 Aurelien Jarno
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
951 590bc601 Paul Brook
    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
952 d9bea114 aurel32
    tcg_temp_free(t0);                                                     \
953 aaa9128a ths
}
954 e7139c44 Aurelien Jarno
#else
955 e7139c44 Aurelien Jarno
#define OP_LD_ATOMIC(insn,fname)                                           \
956 5c13fdfd Aurelien Jarno
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
957 e7139c44 Aurelien Jarno
{                                                                          \
958 e7139c44 Aurelien Jarno
    gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
959 e7139c44 Aurelien Jarno
}
960 e7139c44 Aurelien Jarno
#endif
961 aaa9128a ths
OP_LD_ATOMIC(ll,ld32s);
962 aaa9128a ths
#if defined(TARGET_MIPS64)
963 aaa9128a ths
OP_LD_ATOMIC(lld,ld64);
964 aaa9128a ths
#endif
965 aaa9128a ths
#undef OP_LD_ATOMIC
966 aaa9128a ths
967 590bc601 Paul Brook
#ifdef CONFIG_USER_ONLY
968 590bc601 Paul Brook
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
969 5c13fdfd Aurelien Jarno
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
970 590bc601 Paul Brook
{                                                                            \
971 590bc601 Paul Brook
    TCGv t0 = tcg_temp_new();                                                \
972 590bc601 Paul Brook
    int l1 = gen_new_label();                                                \
973 590bc601 Paul Brook
    int l2 = gen_new_label();                                                \
974 590bc601 Paul Brook
                                                                             \
975 590bc601 Paul Brook
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
976 590bc601 Paul Brook
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
977 590bc601 Paul Brook
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
978 590bc601 Paul Brook
    generate_exception(ctx, EXCP_AdES);                                      \
979 590bc601 Paul Brook
    gen_set_label(l1);                                                       \
980 e7139c44 Aurelien Jarno
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
981 590bc601 Paul Brook
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
982 590bc601 Paul Brook
    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
983 590bc601 Paul Brook
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
984 590bc601 Paul Brook
    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
985 590bc601 Paul Brook
    gen_helper_0i(raise_exception, EXCP_SC);                                 \
986 590bc601 Paul Brook
    gen_set_label(l2);                                                       \
987 590bc601 Paul Brook
    tcg_gen_movi_tl(t0, 0);                                                  \
988 590bc601 Paul Brook
    gen_store_gpr(t0, rt);                                                   \
989 590bc601 Paul Brook
    tcg_temp_free(t0);                                                       \
990 590bc601 Paul Brook
}
991 590bc601 Paul Brook
#else
992 590bc601 Paul Brook
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
993 5c13fdfd Aurelien Jarno
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
994 590bc601 Paul Brook
{                                                                            \
995 590bc601 Paul Brook
    TCGv t0 = tcg_temp_new();                                                \
996 e7139c44 Aurelien Jarno
    gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
997 590bc601 Paul Brook
    gen_store_gpr(t0, rt);                                                   \
998 590bc601 Paul Brook
    tcg_temp_free(t0);                                                       \
999 590bc601 Paul Brook
}
1000 590bc601 Paul Brook
#endif
1001 590bc601 Paul Brook
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1002 aaa9128a ths
#if defined(TARGET_MIPS64)
1003 590bc601 Paul Brook
OP_ST_ATOMIC(scd,st64,ld64,0x7);
1004 aaa9128a ths
#endif
1005 aaa9128a ths
#undef OP_ST_ATOMIC
1006 aaa9128a ths
1007 662d7485 Nathan Froyd
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1008 662d7485 Nathan Froyd
                                  int base, int16_t offset)
1009 662d7485 Nathan Froyd
{
1010 662d7485 Nathan Froyd
    if (base == 0) {
1011 662d7485 Nathan Froyd
        tcg_gen_movi_tl(addr, offset);
1012 662d7485 Nathan Froyd
    } else if (offset == 0) {
1013 662d7485 Nathan Froyd
        gen_load_gpr(addr, base);
1014 662d7485 Nathan Froyd
    } else {
1015 662d7485 Nathan Froyd
        tcg_gen_movi_tl(addr, offset);
1016 662d7485 Nathan Froyd
        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1017 662d7485 Nathan Froyd
    }
1018 662d7485 Nathan Froyd
}
1019 662d7485 Nathan Froyd
1020 364d4831 Nathan Froyd
static target_ulong pc_relative_pc (DisasContext *ctx)
1021 364d4831 Nathan Froyd
{
1022 364d4831 Nathan Froyd
    target_ulong pc = ctx->pc;
1023 364d4831 Nathan Froyd
1024 364d4831 Nathan Froyd
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1025 364d4831 Nathan Froyd
        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1026 364d4831 Nathan Froyd
1027 364d4831 Nathan Froyd
        pc -= branch_bytes;
1028 364d4831 Nathan Froyd
    }
1029 364d4831 Nathan Froyd
1030 364d4831 Nathan Froyd
    pc &= ~(target_ulong)3;
1031 364d4831 Nathan Froyd
    return pc;
1032 364d4831 Nathan Froyd
}
1033 364d4831 Nathan Froyd
1034 5c13fdfd Aurelien Jarno
/* Load */
1035 afa88c3a Aurelien Jarno
static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
1036 afa88c3a Aurelien Jarno
                    int rt, int base, int16_t offset)
1037 6af0bf9c bellard
{
1038 5c13fdfd Aurelien Jarno
    const char *opn = "ld";
1039 afa88c3a Aurelien Jarno
    TCGv t0, t1;
1040 afa88c3a Aurelien Jarno
1041 afa88c3a Aurelien Jarno
    if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1042 afa88c3a Aurelien Jarno
        /* Loongson CPU uses a load to zero register for prefetch.
1043 afa88c3a Aurelien Jarno
           We emulate it as a NOP. On other CPU we must perform the
1044 afa88c3a Aurelien Jarno
           actual memory access. */
1045 afa88c3a Aurelien Jarno
        MIPS_DEBUG("NOP");
1046 afa88c3a Aurelien Jarno
        return;
1047 afa88c3a Aurelien Jarno
    }
1048 6af0bf9c bellard
1049 afa88c3a Aurelien Jarno
    t0 = tcg_temp_new();
1050 afa88c3a Aurelien Jarno
    t1 = tcg_temp_new();
1051 662d7485 Nathan Froyd
    gen_base_offset_addr(ctx, t0, base, offset);
1052 afa88c3a Aurelien Jarno
1053 6af0bf9c bellard
    switch (opc) {
1054 d26bc211 ths
#if defined(TARGET_MIPS64)
1055 6e473128 ths
    case OPC_LWU:
1056 d66c7132 aurel32
        save_cpu_state(ctx, 0);
1057 5c13fdfd Aurelien Jarno
        op_ld_lwu(t0, t0, ctx);
1058 78723684 ths
        gen_store_gpr(t0, rt);
1059 6e473128 ths
        opn = "lwu";
1060 6e473128 ths
        break;
1061 6af0bf9c bellard
    case OPC_LD:
1062 d66c7132 aurel32
        save_cpu_state(ctx, 0);
1063 5c13fdfd Aurelien Jarno
        op_ld_ld(t0, t0, ctx);
1064 78723684 ths
        gen_store_gpr(t0, rt);
1065 6af0bf9c bellard
        opn = "ld";
1066 6af0bf9c bellard
        break;
1067 7a387fff ths
    case OPC_LLD:
1068 b835e919 Aurelien Jarno
        save_cpu_state(ctx, 1);
1069 5c13fdfd Aurelien Jarno
        op_ld_lld(t0, t0, ctx);
1070 78723684 ths
        gen_store_gpr(t0, rt);
1071 7a387fff ths
        opn = "lld";
1072 7a387fff ths
        break;
1073 6af0bf9c bellard
    case OPC_LDL:
1074 c8c2227e ths
        save_cpu_state(ctx, 1);
1075 78723684 ths
        gen_load_gpr(t1, rt);
1076 d9bea114 aurel32
        gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1077 78723684 ths
        gen_store_gpr(t1, rt);
1078 6af0bf9c bellard
        opn = "ldl";
1079 6af0bf9c bellard
        break;
1080 6af0bf9c bellard
    case OPC_LDR:
1081 c8c2227e ths
        save_cpu_state(ctx, 1);
1082 78723684 ths
        gen_load_gpr(t1, rt);
1083 d9bea114 aurel32
        gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1084 78723684 ths
        gen_store_gpr(t1, rt);
1085 6af0bf9c bellard
        opn = "ldr";
1086 6af0bf9c bellard
        break;
1087 364d4831 Nathan Froyd
    case OPC_LDPC:
1088 b835e919 Aurelien Jarno
        save_cpu_state(ctx, 0);
1089 364d4831 Nathan Froyd
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1090 364d4831 Nathan Froyd
        gen_op_addr_add(ctx, t0, t0, t1);
1091 5c13fdfd Aurelien Jarno
        op_ld_ld(t0, t0, ctx);
1092 364d4831 Nathan Froyd
        gen_store_gpr(t0, rt);
1093 5c13fdfd Aurelien Jarno
        opn = "ldpc";
1094 364d4831 Nathan Froyd
        break;
1095 6af0bf9c bellard
#endif
1096 364d4831 Nathan Froyd
    case OPC_LWPC:
1097 b835e919 Aurelien Jarno
        save_cpu_state(ctx, 0);
1098 364d4831 Nathan Froyd
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1099 364d4831 Nathan Froyd
        gen_op_addr_add(ctx, t0, t0, t1);
1100 5c13fdfd Aurelien Jarno
        op_ld_lw(t0, t0, ctx);
1101 364d4831 Nathan Froyd
        gen_store_gpr(t0, rt);
1102 5c13fdfd Aurelien Jarno
        opn = "lwpc";
1103 364d4831 Nathan Froyd
        break;
1104 6af0bf9c bellard
    case OPC_LW:
1105 d66c7132 aurel32
        save_cpu_state(ctx, 0);
1106 5c13fdfd Aurelien Jarno
        op_ld_lw(t0, t0, ctx);
1107 78723684 ths
        gen_store_gpr(t0, rt);
1108 6af0bf9c bellard
        opn = "lw";
1109 6af0bf9c bellard
        break;
1110 6af0bf9c bellard
    case OPC_LH:
1111 d66c7132 aurel32
        save_cpu_state(ctx, 0);
1112 5c13fdfd Aurelien Jarno
        op_ld_lh(t0, t0, ctx);
1113 78723684 ths
        gen_store_gpr(t0, rt);
1114 6af0bf9c bellard
        opn = "lh";
1115 6af0bf9c bellard
        break;
1116 6af0bf9c bellard
    case OPC_LHU:
1117 d66c7132 aurel32
        save_cpu_state(ctx, 0);
1118 5c13fdfd Aurelien Jarno
        op_ld_lhu(t0, t0, ctx);
1119 78723684 ths
        gen_store_gpr(t0, rt);
1120 6af0bf9c bellard
        opn = "lhu";
1121 6af0bf9c bellard
        break;
1122 6af0bf9c bellard
    case OPC_LB:
1123 d66c7132 aurel32
        save_cpu_state(ctx, 0);
1124 5c13fdfd Aurelien Jarno
        op_ld_lb(t0, t0, ctx);
1125 78723684 ths
        gen_store_gpr(t0, rt);
1126 6af0bf9c bellard
        opn = "lb";
1127 6af0bf9c bellard
        break;
1128 6af0bf9c bellard
    case OPC_LBU:
1129 d66c7132 aurel32
        save_cpu_state(ctx, 0);
1130 5c13fdfd Aurelien Jarno
        op_ld_lbu(t0, t0, ctx);
1131 78723684 ths
        gen_store_gpr(t0, rt);
1132 6af0bf9c bellard
        opn = "lbu";
1133 6af0bf9c bellard
        break;
1134 6af0bf9c bellard
    case OPC_LWL:
1135 c8c2227e ths
        save_cpu_state(ctx, 1);
1136 6958549d aurel32
        gen_load_gpr(t1, rt);
1137 d9bea114 aurel32
        gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1138 78723684 ths
        gen_store_gpr(t1, rt);
1139 6af0bf9c bellard
        opn = "lwl";
1140 6af0bf9c bellard
        break;
1141 6af0bf9c bellard
    case OPC_LWR:
1142 c8c2227e ths
        save_cpu_state(ctx, 1);
1143 6958549d aurel32
        gen_load_gpr(t1, rt);
1144 d9bea114 aurel32
        gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1145 78723684 ths
        gen_store_gpr(t1, rt);
1146 6af0bf9c bellard
        opn = "lwr";
1147 6af0bf9c bellard
        break;
1148 6af0bf9c bellard
    case OPC_LL:
1149 e7139c44 Aurelien Jarno
        save_cpu_state(ctx, 1);
1150 5c13fdfd Aurelien Jarno
        op_ld_ll(t0, t0, ctx);
1151 78723684 ths
        gen_store_gpr(t0, rt);
1152 6af0bf9c bellard
        opn = "ll";
1153 6af0bf9c bellard
        break;
1154 d66c7132 aurel32
    }
1155 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1156 d66c7132 aurel32
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1157 d66c7132 aurel32
    tcg_temp_free(t0);
1158 d66c7132 aurel32
    tcg_temp_free(t1);
1159 d66c7132 aurel32
}
1160 d66c7132 aurel32
1161 5c13fdfd Aurelien Jarno
/* Store */
1162 5c13fdfd Aurelien Jarno
static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1163 5c13fdfd Aurelien Jarno
                    int base, int16_t offset)
1164 5c13fdfd Aurelien Jarno
{
1165 5c13fdfd Aurelien Jarno
    const char *opn = "st";
1166 5c13fdfd Aurelien Jarno
    TCGv t0 = tcg_temp_new();
1167 5c13fdfd Aurelien Jarno
    TCGv t1 = tcg_temp_new();
1168 5c13fdfd Aurelien Jarno
1169 5c13fdfd Aurelien Jarno
    gen_base_offset_addr(ctx, t0, base, offset);
1170 5c13fdfd Aurelien Jarno
    gen_load_gpr(t1, rt);
1171 5c13fdfd Aurelien Jarno
    switch (opc) {
1172 5c13fdfd Aurelien Jarno
#if defined(TARGET_MIPS64)
1173 5c13fdfd Aurelien Jarno
    case OPC_SD:
1174 5c13fdfd Aurelien Jarno
        save_cpu_state(ctx, 0);
1175 5c13fdfd Aurelien Jarno
        op_st_sd(t1, t0, ctx);
1176 5c13fdfd Aurelien Jarno
        opn = "sd";
1177 5c13fdfd Aurelien Jarno
        break;
1178 5c13fdfd Aurelien Jarno
    case OPC_SDL:
1179 5c13fdfd Aurelien Jarno
        save_cpu_state(ctx, 1);
1180 5c13fdfd Aurelien Jarno
        gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1181 5c13fdfd Aurelien Jarno
        opn = "sdl";
1182 5c13fdfd Aurelien Jarno
        break;
1183 5c13fdfd Aurelien Jarno
    case OPC_SDR:
1184 5c13fdfd Aurelien Jarno
        save_cpu_state(ctx, 1);
1185 5c13fdfd Aurelien Jarno
        gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1186 5c13fdfd Aurelien Jarno
        opn = "sdr";
1187 5c13fdfd Aurelien Jarno
        break;
1188 5c13fdfd Aurelien Jarno
#endif
1189 5c13fdfd Aurelien Jarno
    case OPC_SW:
1190 5c13fdfd Aurelien Jarno
        save_cpu_state(ctx, 0);
1191 5c13fdfd Aurelien Jarno
        op_st_sw(t1, t0, ctx);
1192 5c13fdfd Aurelien Jarno
        opn = "sw";
1193 5c13fdfd Aurelien Jarno
        break;
1194 5c13fdfd Aurelien Jarno
    case OPC_SH:
1195 5c13fdfd Aurelien Jarno
        save_cpu_state(ctx, 0);
1196 5c13fdfd Aurelien Jarno
        op_st_sh(t1, t0, ctx);
1197 5c13fdfd Aurelien Jarno
        opn = "sh";
1198 5c13fdfd Aurelien Jarno
        break;
1199 5c13fdfd Aurelien Jarno
    case OPC_SB:
1200 5c13fdfd Aurelien Jarno
        save_cpu_state(ctx, 0);
1201 5c13fdfd Aurelien Jarno
        op_st_sb(t1, t0, ctx);
1202 5c13fdfd Aurelien Jarno
        opn = "sb";
1203 5c13fdfd Aurelien Jarno
        break;
1204 5c13fdfd Aurelien Jarno
    case OPC_SWL:
1205 5c13fdfd Aurelien Jarno
        save_cpu_state(ctx, 1);
1206 5c13fdfd Aurelien Jarno
        gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1207 5c13fdfd Aurelien Jarno
        opn = "swl";
1208 5c13fdfd Aurelien Jarno
        break;
1209 5c13fdfd Aurelien Jarno
    case OPC_SWR:
1210 5c13fdfd Aurelien Jarno
        save_cpu_state(ctx, 1);
1211 5c13fdfd Aurelien Jarno
        gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1212 5c13fdfd Aurelien Jarno
        opn = "swr";
1213 5c13fdfd Aurelien Jarno
        break;
1214 5c13fdfd Aurelien Jarno
    }
1215 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1216 5c13fdfd Aurelien Jarno
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1217 5c13fdfd Aurelien Jarno
    tcg_temp_free(t0);
1218 5c13fdfd Aurelien Jarno
    tcg_temp_free(t1);
1219 5c13fdfd Aurelien Jarno
}
1220 5c13fdfd Aurelien Jarno
1221 5c13fdfd Aurelien Jarno
1222 d66c7132 aurel32
/* Store conditional */
1223 d66c7132 aurel32
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1224 d66c7132 aurel32
                         int base, int16_t offset)
1225 d66c7132 aurel32
{
1226 d66c7132 aurel32
    const char *opn = "st_cond";
1227 d66c7132 aurel32
    TCGv t0, t1;
1228 d66c7132 aurel32
1229 d66c7132 aurel32
    t0 = tcg_temp_local_new();
1230 d66c7132 aurel32
1231 662d7485 Nathan Froyd
    gen_base_offset_addr(ctx, t0, base, offset);
1232 d66c7132 aurel32
    /* Don't do NOP if destination is zero: we must perform the actual
1233 d66c7132 aurel32
       memory access. */
1234 d66c7132 aurel32
1235 d66c7132 aurel32
    t1 = tcg_temp_local_new();
1236 d66c7132 aurel32
    gen_load_gpr(t1, rt);
1237 d66c7132 aurel32
    switch (opc) {
1238 d66c7132 aurel32
#if defined(TARGET_MIPS64)
1239 d66c7132 aurel32
    case OPC_SCD:
1240 b835e919 Aurelien Jarno
        save_cpu_state(ctx, 1);
1241 5c13fdfd Aurelien Jarno
        op_st_scd(t1, t0, rt, ctx);
1242 d66c7132 aurel32
        opn = "scd";
1243 d66c7132 aurel32
        break;
1244 d66c7132 aurel32
#endif
1245 6af0bf9c bellard
    case OPC_SC:
1246 e7139c44 Aurelien Jarno
        save_cpu_state(ctx, 1);
1247 5c13fdfd Aurelien Jarno
        op_st_sc(t1, t0, rt, ctx);
1248 6af0bf9c bellard
        opn = "sc";
1249 6af0bf9c bellard
        break;
1250 6af0bf9c bellard
    }
1251 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1252 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1253 78723684 ths
    tcg_temp_free(t1);
1254 d66c7132 aurel32
    tcg_temp_free(t0);
1255 6af0bf9c bellard
}
1256 6af0bf9c bellard
1257 6ea83fed bellard
/* Load and store */
1258 7a387fff ths
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1259 356265ae ths
                          int base, int16_t offset)
1260 6ea83fed bellard
{
1261 923617a3 ths
    const char *opn = "flt_ldst";
1262 4e2474d6 aurel32
    TCGv t0 = tcg_temp_new();
1263 6ea83fed bellard
1264 662d7485 Nathan Froyd
    gen_base_offset_addr(ctx, t0, base, offset);
1265 6ea83fed bellard
    /* Don't do NOP if destination is zero: we must perform the actual
1266 ead9360e ths
       memory access. */
1267 6ea83fed bellard
    switch (opc) {
1268 6ea83fed bellard
    case OPC_LWC1:
1269 b6d96bed ths
        {
1270 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
1271 b6d96bed ths
1272 c407df81 aurel32
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1273 c407df81 aurel32
            tcg_gen_trunc_tl_i32(fp0, t0);
1274 b6d96bed ths
            gen_store_fpr32(fp0, ft);
1275 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
1276 b6d96bed ths
        }
1277 6ea83fed bellard
        opn = "lwc1";
1278 6ea83fed bellard
        break;
1279 6ea83fed bellard
    case OPC_SWC1:
1280 b6d96bed ths
        {
1281 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
1282 a7812ae4 pbrook
            TCGv t1 = tcg_temp_new();
1283 b6d96bed ths
1284 b6d96bed ths
            gen_load_fpr32(fp0, ft);
1285 a7812ae4 pbrook
            tcg_gen_extu_i32_tl(t1, fp0);
1286 a7812ae4 pbrook
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1287 a7812ae4 pbrook
            tcg_temp_free(t1);
1288 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
1289 b6d96bed ths
        }
1290 6ea83fed bellard
        opn = "swc1";
1291 6ea83fed bellard
        break;
1292 6ea83fed bellard
    case OPC_LDC1:
1293 b6d96bed ths
        {
1294 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
1295 b6d96bed ths
1296 b6d96bed ths
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1297 b6d96bed ths
            gen_store_fpr64(ctx, fp0, ft);
1298 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
1299 b6d96bed ths
        }
1300 6ea83fed bellard
        opn = "ldc1";
1301 6ea83fed bellard
        break;
1302 6ea83fed bellard
    case OPC_SDC1:
1303 b6d96bed ths
        {
1304 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
1305 b6d96bed ths
1306 b6d96bed ths
            gen_load_fpr64(ctx, fp0, ft);
1307 b6d96bed ths
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1308 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
1309 b6d96bed ths
        }
1310 6ea83fed bellard
        opn = "sdc1";
1311 6ea83fed bellard
        break;
1312 6ea83fed bellard
    default:
1313 923617a3 ths
        MIPS_INVAL(opn);
1314 e397ee33 ths
        generate_exception(ctx, EXCP_RI);
1315 78723684 ths
        goto out;
1316 6ea83fed bellard
    }
1317 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1318 6ea83fed bellard
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1319 78723684 ths
 out:
1320 78723684 ths
    tcg_temp_free(t0);
1321 6ea83fed bellard
}
1322 6ea83fed bellard
1323 26ebe468 Nathan Froyd
static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1324 26ebe468 Nathan Froyd
                          uint32_t op, int rt, int rs, int16_t imm)
1325 26ebe468 Nathan Froyd
{
1326 26ebe468 Nathan Froyd
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1327 26ebe468 Nathan Froyd
        check_cp1_enabled(ctx);
1328 26ebe468 Nathan Froyd
        gen_flt_ldst(ctx, op, rt, rs, imm);
1329 26ebe468 Nathan Froyd
    } else {
1330 26ebe468 Nathan Froyd
        generate_exception_err(ctx, EXCP_CpU, 1);
1331 26ebe468 Nathan Froyd
    }
1332 26ebe468 Nathan Froyd
}
1333 26ebe468 Nathan Froyd
1334 6af0bf9c bellard
/* Arithmetic with immediate operand */
1335 e189e748 ths
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1336 e189e748 ths
                           int rt, int rs, int16_t imm)
1337 6af0bf9c bellard
{
1338 324d9e32 aurel32
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1339 923617a3 ths
    const char *opn = "imm arith";
1340 6af0bf9c bellard
1341 7a387fff ths
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1342 ead9360e ths
        /* If no destination, treat it as a NOP.
1343 ead9360e ths
           For addi, we must generate the overflow exception when needed. */
1344 6af0bf9c bellard
        MIPS_DEBUG("NOP");
1345 324d9e32 aurel32
        return;
1346 6af0bf9c bellard
    }
1347 6af0bf9c bellard
    switch (opc) {
1348 6af0bf9c bellard
    case OPC_ADDI:
1349 48d38ca5 ths
        {
1350 324d9e32 aurel32
            TCGv t0 = tcg_temp_local_new();
1351 324d9e32 aurel32
            TCGv t1 = tcg_temp_new();
1352 324d9e32 aurel32
            TCGv t2 = tcg_temp_new();
1353 48d38ca5 ths
            int l1 = gen_new_label();
1354 48d38ca5 ths
1355 324d9e32 aurel32
            gen_load_gpr(t1, rs);
1356 324d9e32 aurel32
            tcg_gen_addi_tl(t0, t1, uimm);
1357 324d9e32 aurel32
            tcg_gen_ext32s_tl(t0, t0);
1358 48d38ca5 ths
1359 324d9e32 aurel32
            tcg_gen_xori_tl(t1, t1, ~uimm);
1360 324d9e32 aurel32
            tcg_gen_xori_tl(t2, t0, uimm);
1361 324d9e32 aurel32
            tcg_gen_and_tl(t1, t1, t2);
1362 324d9e32 aurel32
            tcg_temp_free(t2);
1363 324d9e32 aurel32
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1364 324d9e32 aurel32
            tcg_temp_free(t1);
1365 48d38ca5 ths
            /* operands of same sign, result different sign */
1366 48d38ca5 ths
            generate_exception(ctx, EXCP_OVERFLOW);
1367 48d38ca5 ths
            gen_set_label(l1);
1368 78723684 ths
            tcg_gen_ext32s_tl(t0, t0);
1369 324d9e32 aurel32
            gen_store_gpr(t0, rt);
1370 324d9e32 aurel32
            tcg_temp_free(t0);
1371 48d38ca5 ths
        }
1372 6af0bf9c bellard
        opn = "addi";
1373 6af0bf9c bellard
        break;
1374 6af0bf9c bellard
    case OPC_ADDIU:
1375 324d9e32 aurel32
        if (rs != 0) {
1376 324d9e32 aurel32
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1377 324d9e32 aurel32
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1378 324d9e32 aurel32
        } else {
1379 324d9e32 aurel32
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1380 324d9e32 aurel32
        }
1381 6af0bf9c bellard
        opn = "addiu";
1382 6af0bf9c bellard
        break;
1383 d26bc211 ths
#if defined(TARGET_MIPS64)
1384 7a387fff ths
    case OPC_DADDI:
1385 48d38ca5 ths
        {
1386 324d9e32 aurel32
            TCGv t0 = tcg_temp_local_new();
1387 324d9e32 aurel32
            TCGv t1 = tcg_temp_new();
1388 324d9e32 aurel32
            TCGv t2 = tcg_temp_new();
1389 48d38ca5 ths
            int l1 = gen_new_label();
1390 48d38ca5 ths
1391 324d9e32 aurel32
            gen_load_gpr(t1, rs);
1392 324d9e32 aurel32
            tcg_gen_addi_tl(t0, t1, uimm);
1393 48d38ca5 ths
1394 324d9e32 aurel32
            tcg_gen_xori_tl(t1, t1, ~uimm);
1395 324d9e32 aurel32
            tcg_gen_xori_tl(t2, t0, uimm);
1396 324d9e32 aurel32
            tcg_gen_and_tl(t1, t1, t2);
1397 324d9e32 aurel32
            tcg_temp_free(t2);
1398 324d9e32 aurel32
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1399 324d9e32 aurel32
            tcg_temp_free(t1);
1400 48d38ca5 ths
            /* operands of same sign, result different sign */
1401 48d38ca5 ths
            generate_exception(ctx, EXCP_OVERFLOW);
1402 48d38ca5 ths
            gen_set_label(l1);
1403 324d9e32 aurel32
            gen_store_gpr(t0, rt);
1404 324d9e32 aurel32
            tcg_temp_free(t0);
1405 48d38ca5 ths
        }
1406 7a387fff ths
        opn = "daddi";
1407 7a387fff ths
        break;
1408 7a387fff ths
    case OPC_DADDIU:
1409 324d9e32 aurel32
        if (rs != 0) {
1410 324d9e32 aurel32
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1411 324d9e32 aurel32
        } else {
1412 324d9e32 aurel32
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1413 324d9e32 aurel32
        }
1414 7a387fff ths
        opn = "daddiu";
1415 7a387fff ths
        break;
1416 7a387fff ths
#endif
1417 324d9e32 aurel32
    }
1418 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1419 324d9e32 aurel32
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1420 324d9e32 aurel32
}
1421 324d9e32 aurel32
1422 324d9e32 aurel32
/* Logic with immediate operand */
1423 324d9e32 aurel32
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1424 324d9e32 aurel32
{
1425 324d9e32 aurel32
    target_ulong uimm;
1426 324d9e32 aurel32
    const char *opn = "imm logic";
1427 324d9e32 aurel32
1428 324d9e32 aurel32
    if (rt == 0) {
1429 324d9e32 aurel32
        /* If no destination, treat it as a NOP. */
1430 324d9e32 aurel32
        MIPS_DEBUG("NOP");
1431 324d9e32 aurel32
        return;
1432 324d9e32 aurel32
    }
1433 324d9e32 aurel32
    uimm = (uint16_t)imm;
1434 324d9e32 aurel32
    switch (opc) {
1435 6af0bf9c bellard
    case OPC_ANDI:
1436 324d9e32 aurel32
        if (likely(rs != 0))
1437 324d9e32 aurel32
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1438 324d9e32 aurel32
        else
1439 324d9e32 aurel32
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1440 6af0bf9c bellard
        opn = "andi";
1441 6af0bf9c bellard
        break;
1442 6af0bf9c bellard
    case OPC_ORI:
1443 324d9e32 aurel32
        if (rs != 0)
1444 324d9e32 aurel32
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1445 324d9e32 aurel32
        else
1446 324d9e32 aurel32
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1447 6af0bf9c bellard
        opn = "ori";
1448 6af0bf9c bellard
        break;
1449 6af0bf9c bellard
    case OPC_XORI:
1450 324d9e32 aurel32
        if (likely(rs != 0))
1451 324d9e32 aurel32
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1452 324d9e32 aurel32
        else
1453 324d9e32 aurel32
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1454 6af0bf9c bellard
        opn = "xori";
1455 6af0bf9c bellard
        break;
1456 6af0bf9c bellard
    case OPC_LUI:
1457 324d9e32 aurel32
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1458 6af0bf9c bellard
        opn = "lui";
1459 6af0bf9c bellard
        break;
1460 324d9e32 aurel32
    }
1461 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1462 324d9e32 aurel32
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1463 324d9e32 aurel32
}
1464 324d9e32 aurel32
1465 324d9e32 aurel32
/* Set on less than with immediate operand */
1466 324d9e32 aurel32
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1467 324d9e32 aurel32
{
1468 324d9e32 aurel32
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1469 324d9e32 aurel32
    const char *opn = "imm arith";
1470 324d9e32 aurel32
    TCGv t0;
1471 324d9e32 aurel32
1472 324d9e32 aurel32
    if (rt == 0) {
1473 324d9e32 aurel32
        /* If no destination, treat it as a NOP. */
1474 324d9e32 aurel32
        MIPS_DEBUG("NOP");
1475 324d9e32 aurel32
        return;
1476 324d9e32 aurel32
    }
1477 324d9e32 aurel32
    t0 = tcg_temp_new();
1478 324d9e32 aurel32
    gen_load_gpr(t0, rs);
1479 324d9e32 aurel32
    switch (opc) {
1480 324d9e32 aurel32
    case OPC_SLTI:
1481 e68dd28f Aurelien Jarno
        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1482 324d9e32 aurel32
        opn = "slti";
1483 324d9e32 aurel32
        break;
1484 324d9e32 aurel32
    case OPC_SLTIU:
1485 e68dd28f Aurelien Jarno
        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1486 324d9e32 aurel32
        opn = "sltiu";
1487 324d9e32 aurel32
        break;
1488 324d9e32 aurel32
    }
1489 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1490 324d9e32 aurel32
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1491 324d9e32 aurel32
    tcg_temp_free(t0);
1492 324d9e32 aurel32
}
1493 324d9e32 aurel32
1494 324d9e32 aurel32
/* Shifts with immediate operand */
1495 324d9e32 aurel32
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1496 324d9e32 aurel32
                          int rt, int rs, int16_t imm)
1497 324d9e32 aurel32
{
1498 324d9e32 aurel32
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1499 324d9e32 aurel32
    const char *opn = "imm shift";
1500 324d9e32 aurel32
    TCGv t0;
1501 324d9e32 aurel32
1502 324d9e32 aurel32
    if (rt == 0) {
1503 324d9e32 aurel32
        /* If no destination, treat it as a NOP. */
1504 324d9e32 aurel32
        MIPS_DEBUG("NOP");
1505 324d9e32 aurel32
        return;
1506 324d9e32 aurel32
    }
1507 324d9e32 aurel32
1508 324d9e32 aurel32
    t0 = tcg_temp_new();
1509 324d9e32 aurel32
    gen_load_gpr(t0, rs);
1510 324d9e32 aurel32
    switch (opc) {
1511 6af0bf9c bellard
    case OPC_SLL:
1512 78723684 ths
        tcg_gen_shli_tl(t0, t0, uimm);
1513 324d9e32 aurel32
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1514 6af0bf9c bellard
        opn = "sll";
1515 6af0bf9c bellard
        break;
1516 6af0bf9c bellard
    case OPC_SRA:
1517 324d9e32 aurel32
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1518 6af0bf9c bellard
        opn = "sra";
1519 6af0bf9c bellard
        break;
1520 6af0bf9c bellard
    case OPC_SRL:
1521 ea63e2c3 Nathan Froyd
        if (uimm != 0) {
1522 ea63e2c3 Nathan Froyd
            tcg_gen_ext32u_tl(t0, t0);
1523 ea63e2c3 Nathan Froyd
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1524 ea63e2c3 Nathan Froyd
        } else {
1525 ea63e2c3 Nathan Froyd
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1526 5a63bcb2 ths
        }
1527 ea63e2c3 Nathan Froyd
        opn = "srl";
1528 ea63e2c3 Nathan Froyd
        break;
1529 ea63e2c3 Nathan Froyd
    case OPC_ROTR:
1530 ea63e2c3 Nathan Froyd
        if (uimm != 0) {
1531 ea63e2c3 Nathan Froyd
            TCGv_i32 t1 = tcg_temp_new_i32();
1532 ea63e2c3 Nathan Froyd
1533 ea63e2c3 Nathan Froyd
            tcg_gen_trunc_tl_i32(t1, t0);
1534 ea63e2c3 Nathan Froyd
            tcg_gen_rotri_i32(t1, t1, uimm);
1535 ea63e2c3 Nathan Froyd
            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1536 ea63e2c3 Nathan Froyd
            tcg_temp_free_i32(t1);
1537 3399e30f Nathan Froyd
        } else {
1538 3399e30f Nathan Froyd
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1539 ea63e2c3 Nathan Froyd
        }
1540 ea63e2c3 Nathan Froyd
        opn = "rotr";
1541 7a387fff ths
        break;
1542 d26bc211 ths
#if defined(TARGET_MIPS64)
1543 7a387fff ths
    case OPC_DSLL:
1544 324d9e32 aurel32
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1545 7a387fff ths
        opn = "dsll";
1546 7a387fff ths
        break;
1547 7a387fff ths
    case OPC_DSRA:
1548 324d9e32 aurel32
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1549 7a387fff ths
        opn = "dsra";
1550 7a387fff ths
        break;
1551 7a387fff ths
    case OPC_DSRL:
1552 ea63e2c3 Nathan Froyd
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1553 ea63e2c3 Nathan Froyd
        opn = "dsrl";
1554 ea63e2c3 Nathan Froyd
        break;
1555 ea63e2c3 Nathan Froyd
    case OPC_DROTR:
1556 ea63e2c3 Nathan Froyd
        if (uimm != 0) {
1557 ea63e2c3 Nathan Froyd
            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1558 3399e30f Nathan Froyd
        } else {
1559 3399e30f Nathan Froyd
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
1560 5a63bcb2 ths
        }
1561 ea63e2c3 Nathan Froyd
        opn = "drotr";
1562 7a387fff ths
        break;
1563 7a387fff ths
    case OPC_DSLL32:
1564 324d9e32 aurel32
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1565 7a387fff ths
        opn = "dsll32";
1566 7a387fff ths
        break;
1567 7a387fff ths
    case OPC_DSRA32:
1568 324d9e32 aurel32
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1569 7a387fff ths
        opn = "dsra32";
1570 7a387fff ths
        break;
1571 7a387fff ths
    case OPC_DSRL32:
1572 ea63e2c3 Nathan Froyd
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1573 ea63e2c3 Nathan Froyd
        opn = "dsrl32";
1574 ea63e2c3 Nathan Froyd
        break;
1575 ea63e2c3 Nathan Froyd
    case OPC_DROTR32:
1576 ea63e2c3 Nathan Froyd
        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1577 ea63e2c3 Nathan Froyd
        opn = "drotr32";
1578 6af0bf9c bellard
        break;
1579 7a387fff ths
#endif
1580 6af0bf9c bellard
    }
1581 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1582 93b12ccc ths
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1583 78723684 ths
    tcg_temp_free(t0);
1584 6af0bf9c bellard
}
1585 6af0bf9c bellard
1586 6af0bf9c bellard
/* Arithmetic */
1587 e189e748 ths
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1588 6af0bf9c bellard
                       int rd, int rs, int rt)
1589 6af0bf9c bellard
{
1590 923617a3 ths
    const char *opn = "arith";
1591 6af0bf9c bellard
1592 7a387fff ths
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1593 7a387fff ths
       && opc != OPC_DADD && opc != OPC_DSUB) {
1594 ead9360e ths
        /* If no destination, treat it as a NOP.
1595 ead9360e ths
           For add & sub, we must generate the overflow exception when needed. */
1596 6af0bf9c bellard
        MIPS_DEBUG("NOP");
1597 460f00c4 aurel32
        return;
1598 185f0762 ths
    }
1599 460f00c4 aurel32
1600 6af0bf9c bellard
    switch (opc) {
1601 6af0bf9c bellard
    case OPC_ADD:
1602 48d38ca5 ths
        {
1603 460f00c4 aurel32
            TCGv t0 = tcg_temp_local_new();
1604 460f00c4 aurel32
            TCGv t1 = tcg_temp_new();
1605 460f00c4 aurel32
            TCGv t2 = tcg_temp_new();
1606 48d38ca5 ths
            int l1 = gen_new_label();
1607 48d38ca5 ths
1608 460f00c4 aurel32
            gen_load_gpr(t1, rs);
1609 460f00c4 aurel32
            gen_load_gpr(t2, rt);
1610 460f00c4 aurel32
            tcg_gen_add_tl(t0, t1, t2);
1611 460f00c4 aurel32
            tcg_gen_ext32s_tl(t0, t0);
1612 460f00c4 aurel32
            tcg_gen_xor_tl(t1, t1, t2);
1613 460f00c4 aurel32
            tcg_gen_xor_tl(t2, t0, t2);
1614 deb4203d Aurelien Jarno
            tcg_gen_andc_tl(t1, t2, t1);
1615 460f00c4 aurel32
            tcg_temp_free(t2);
1616 460f00c4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1617 460f00c4 aurel32
            tcg_temp_free(t1);
1618 48d38ca5 ths
            /* operands of same sign, result different sign */
1619 48d38ca5 ths
            generate_exception(ctx, EXCP_OVERFLOW);
1620 48d38ca5 ths
            gen_set_label(l1);
1621 460f00c4 aurel32
            gen_store_gpr(t0, rd);
1622 460f00c4 aurel32
            tcg_temp_free(t0);
1623 48d38ca5 ths
        }
1624 6af0bf9c bellard
        opn = "add";
1625 6af0bf9c bellard
        break;
1626 6af0bf9c bellard
    case OPC_ADDU:
1627 460f00c4 aurel32
        if (rs != 0 && rt != 0) {
1628 460f00c4 aurel32
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1629 460f00c4 aurel32
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1630 460f00c4 aurel32
        } else if (rs == 0 && rt != 0) {
1631 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1632 460f00c4 aurel32
        } else if (rs != 0 && rt == 0) {
1633 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1634 460f00c4 aurel32
        } else {
1635 460f00c4 aurel32
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1636 460f00c4 aurel32
        }
1637 6af0bf9c bellard
        opn = "addu";
1638 6af0bf9c bellard
        break;
1639 6af0bf9c bellard
    case OPC_SUB:
1640 48d38ca5 ths
        {
1641 460f00c4 aurel32
            TCGv t0 = tcg_temp_local_new();
1642 460f00c4 aurel32
            TCGv t1 = tcg_temp_new();
1643 460f00c4 aurel32
            TCGv t2 = tcg_temp_new();
1644 48d38ca5 ths
            int l1 = gen_new_label();
1645 48d38ca5 ths
1646 460f00c4 aurel32
            gen_load_gpr(t1, rs);
1647 460f00c4 aurel32
            gen_load_gpr(t2, rt);
1648 460f00c4 aurel32
            tcg_gen_sub_tl(t0, t1, t2);
1649 460f00c4 aurel32
            tcg_gen_ext32s_tl(t0, t0);
1650 460f00c4 aurel32
            tcg_gen_xor_tl(t2, t1, t2);
1651 460f00c4 aurel32
            tcg_gen_xor_tl(t1, t0, t1);
1652 460f00c4 aurel32
            tcg_gen_and_tl(t1, t1, t2);
1653 460f00c4 aurel32
            tcg_temp_free(t2);
1654 460f00c4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1655 460f00c4 aurel32
            tcg_temp_free(t1);
1656 31e3104f Aurelien Jarno
            /* operands of different sign, first operand and result different sign */
1657 48d38ca5 ths
            generate_exception(ctx, EXCP_OVERFLOW);
1658 48d38ca5 ths
            gen_set_label(l1);
1659 460f00c4 aurel32
            gen_store_gpr(t0, rd);
1660 460f00c4 aurel32
            tcg_temp_free(t0);
1661 48d38ca5 ths
        }
1662 6af0bf9c bellard
        opn = "sub";
1663 6af0bf9c bellard
        break;
1664 6af0bf9c bellard
    case OPC_SUBU:
1665 460f00c4 aurel32
        if (rs != 0 && rt != 0) {
1666 460f00c4 aurel32
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1667 460f00c4 aurel32
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1668 460f00c4 aurel32
        } else if (rs == 0 && rt != 0) {
1669 460f00c4 aurel32
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1670 6bb72b18 Aurelien Jarno
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1671 460f00c4 aurel32
        } else if (rs != 0 && rt == 0) {
1672 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1673 460f00c4 aurel32
        } else {
1674 460f00c4 aurel32
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1675 460f00c4 aurel32
        }
1676 6af0bf9c bellard
        opn = "subu";
1677 6af0bf9c bellard
        break;
1678 d26bc211 ths
#if defined(TARGET_MIPS64)
1679 7a387fff ths
    case OPC_DADD:
1680 48d38ca5 ths
        {
1681 460f00c4 aurel32
            TCGv t0 = tcg_temp_local_new();
1682 460f00c4 aurel32
            TCGv t1 = tcg_temp_new();
1683 460f00c4 aurel32
            TCGv t2 = tcg_temp_new();
1684 48d38ca5 ths
            int l1 = gen_new_label();
1685 48d38ca5 ths
1686 460f00c4 aurel32
            gen_load_gpr(t1, rs);
1687 460f00c4 aurel32
            gen_load_gpr(t2, rt);
1688 460f00c4 aurel32
            tcg_gen_add_tl(t0, t1, t2);
1689 460f00c4 aurel32
            tcg_gen_xor_tl(t1, t1, t2);
1690 460f00c4 aurel32
            tcg_gen_xor_tl(t2, t0, t2);
1691 deb4203d Aurelien Jarno
            tcg_gen_andc_tl(t1, t2, t1);
1692 460f00c4 aurel32
            tcg_temp_free(t2);
1693 460f00c4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1694 460f00c4 aurel32
            tcg_temp_free(t1);
1695 48d38ca5 ths
            /* operands of same sign, result different sign */
1696 48d38ca5 ths
            generate_exception(ctx, EXCP_OVERFLOW);
1697 48d38ca5 ths
            gen_set_label(l1);
1698 460f00c4 aurel32
            gen_store_gpr(t0, rd);
1699 460f00c4 aurel32
            tcg_temp_free(t0);
1700 48d38ca5 ths
        }
1701 7a387fff ths
        opn = "dadd";
1702 7a387fff ths
        break;
1703 7a387fff ths
    case OPC_DADDU:
1704 460f00c4 aurel32
        if (rs != 0 && rt != 0) {
1705 460f00c4 aurel32
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1706 460f00c4 aurel32
        } else if (rs == 0 && rt != 0) {
1707 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1708 460f00c4 aurel32
        } else if (rs != 0 && rt == 0) {
1709 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1710 460f00c4 aurel32
        } else {
1711 460f00c4 aurel32
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1712 460f00c4 aurel32
        }
1713 7a387fff ths
        opn = "daddu";
1714 7a387fff ths
        break;
1715 7a387fff ths
    case OPC_DSUB:
1716 48d38ca5 ths
        {
1717 460f00c4 aurel32
            TCGv t0 = tcg_temp_local_new();
1718 460f00c4 aurel32
            TCGv t1 = tcg_temp_new();
1719 460f00c4 aurel32
            TCGv t2 = tcg_temp_new();
1720 48d38ca5 ths
            int l1 = gen_new_label();
1721 48d38ca5 ths
1722 460f00c4 aurel32
            gen_load_gpr(t1, rs);
1723 460f00c4 aurel32
            gen_load_gpr(t2, rt);
1724 460f00c4 aurel32
            tcg_gen_sub_tl(t0, t1, t2);
1725 460f00c4 aurel32
            tcg_gen_xor_tl(t2, t1, t2);
1726 460f00c4 aurel32
            tcg_gen_xor_tl(t1, t0, t1);
1727 460f00c4 aurel32
            tcg_gen_and_tl(t1, t1, t2);
1728 460f00c4 aurel32
            tcg_temp_free(t2);
1729 460f00c4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1730 460f00c4 aurel32
            tcg_temp_free(t1);
1731 31e3104f Aurelien Jarno
            /* operands of different sign, first operand and result different sign */
1732 48d38ca5 ths
            generate_exception(ctx, EXCP_OVERFLOW);
1733 48d38ca5 ths
            gen_set_label(l1);
1734 460f00c4 aurel32
            gen_store_gpr(t0, rd);
1735 460f00c4 aurel32
            tcg_temp_free(t0);
1736 48d38ca5 ths
        }
1737 7a387fff ths
        opn = "dsub";
1738 7a387fff ths
        break;
1739 7a387fff ths
    case OPC_DSUBU:
1740 460f00c4 aurel32
        if (rs != 0 && rt != 0) {
1741 460f00c4 aurel32
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1742 460f00c4 aurel32
        } else if (rs == 0 && rt != 0) {
1743 460f00c4 aurel32
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1744 460f00c4 aurel32
        } else if (rs != 0 && rt == 0) {
1745 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1746 460f00c4 aurel32
        } else {
1747 460f00c4 aurel32
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1748 460f00c4 aurel32
        }
1749 7a387fff ths
        opn = "dsubu";
1750 7a387fff ths
        break;
1751 7a387fff ths
#endif
1752 460f00c4 aurel32
    case OPC_MUL:
1753 460f00c4 aurel32
        if (likely(rs != 0 && rt != 0)) {
1754 460f00c4 aurel32
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1755 460f00c4 aurel32
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1756 460f00c4 aurel32
        } else {
1757 460f00c4 aurel32
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1758 460f00c4 aurel32
        }
1759 460f00c4 aurel32
        opn = "mul";
1760 6af0bf9c bellard
        break;
1761 460f00c4 aurel32
    }
1762 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1763 460f00c4 aurel32
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1764 460f00c4 aurel32
}
1765 460f00c4 aurel32
1766 460f00c4 aurel32
/* Conditional move */
1767 460f00c4 aurel32
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1768 460f00c4 aurel32
{
1769 460f00c4 aurel32
    const char *opn = "cond move";
1770 460f00c4 aurel32
    int l1;
1771 460f00c4 aurel32
1772 460f00c4 aurel32
    if (rd == 0) {
1773 460f00c4 aurel32
        /* If no destination, treat it as a NOP.
1774 460f00c4 aurel32
           For add & sub, we must generate the overflow exception when needed. */
1775 460f00c4 aurel32
        MIPS_DEBUG("NOP");
1776 460f00c4 aurel32
        return;
1777 460f00c4 aurel32
    }
1778 460f00c4 aurel32
1779 460f00c4 aurel32
    l1 = gen_new_label();
1780 460f00c4 aurel32
    switch (opc) {
1781 460f00c4 aurel32
    case OPC_MOVN:
1782 460f00c4 aurel32
        if (likely(rt != 0))
1783 460f00c4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1784 460f00c4 aurel32
        else
1785 460f00c4 aurel32
            tcg_gen_br(l1);
1786 460f00c4 aurel32
        opn = "movn";
1787 6af0bf9c bellard
        break;
1788 460f00c4 aurel32
    case OPC_MOVZ:
1789 460f00c4 aurel32
        if (likely(rt != 0))
1790 460f00c4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1791 460f00c4 aurel32
        opn = "movz";
1792 460f00c4 aurel32
        break;
1793 460f00c4 aurel32
    }
1794 460f00c4 aurel32
    if (rs != 0)
1795 460f00c4 aurel32
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1796 460f00c4 aurel32
    else
1797 460f00c4 aurel32
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1798 460f00c4 aurel32
    gen_set_label(l1);
1799 460f00c4 aurel32
1800 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1801 460f00c4 aurel32
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1802 460f00c4 aurel32
}
1803 460f00c4 aurel32
1804 460f00c4 aurel32
/* Logic */
1805 460f00c4 aurel32
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1806 460f00c4 aurel32
{
1807 460f00c4 aurel32
    const char *opn = "logic";
1808 460f00c4 aurel32
1809 460f00c4 aurel32
    if (rd == 0) {
1810 460f00c4 aurel32
        /* If no destination, treat it as a NOP. */
1811 460f00c4 aurel32
        MIPS_DEBUG("NOP");
1812 460f00c4 aurel32
        return;
1813 460f00c4 aurel32
    }
1814 460f00c4 aurel32
1815 460f00c4 aurel32
    switch (opc) {
1816 6af0bf9c bellard
    case OPC_AND:
1817 460f00c4 aurel32
        if (likely(rs != 0 && rt != 0)) {
1818 460f00c4 aurel32
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1819 460f00c4 aurel32
        } else {
1820 460f00c4 aurel32
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1821 460f00c4 aurel32
        }
1822 6af0bf9c bellard
        opn = "and";
1823 6af0bf9c bellard
        break;
1824 6af0bf9c bellard
    case OPC_NOR:
1825 460f00c4 aurel32
        if (rs != 0 && rt != 0) {
1826 460f00c4 aurel32
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1827 460f00c4 aurel32
        } else if (rs == 0 && rt != 0) {
1828 460f00c4 aurel32
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1829 460f00c4 aurel32
        } else if (rs != 0 && rt == 0) {
1830 460f00c4 aurel32
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1831 460f00c4 aurel32
        } else {
1832 460f00c4 aurel32
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1833 460f00c4 aurel32
        }
1834 6af0bf9c bellard
        opn = "nor";
1835 6af0bf9c bellard
        break;
1836 6af0bf9c bellard
    case OPC_OR:
1837 460f00c4 aurel32
        if (likely(rs != 0 && rt != 0)) {
1838 460f00c4 aurel32
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1839 460f00c4 aurel32
        } else if (rs == 0 && rt != 0) {
1840 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1841 460f00c4 aurel32
        } else if (rs != 0 && rt == 0) {
1842 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1843 460f00c4 aurel32
        } else {
1844 460f00c4 aurel32
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1845 460f00c4 aurel32
        }
1846 6af0bf9c bellard
        opn = "or";
1847 6af0bf9c bellard
        break;
1848 6af0bf9c bellard
    case OPC_XOR:
1849 460f00c4 aurel32
        if (likely(rs != 0 && rt != 0)) {
1850 460f00c4 aurel32
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1851 460f00c4 aurel32
        } else if (rs == 0 && rt != 0) {
1852 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1853 460f00c4 aurel32
        } else if (rs != 0 && rt == 0) {
1854 460f00c4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1855 460f00c4 aurel32
        } else {
1856 460f00c4 aurel32
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1857 460f00c4 aurel32
        }
1858 6af0bf9c bellard
        opn = "xor";
1859 6af0bf9c bellard
        break;
1860 460f00c4 aurel32
    }
1861 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1862 460f00c4 aurel32
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1863 460f00c4 aurel32
}
1864 460f00c4 aurel32
1865 460f00c4 aurel32
/* Set on lower than */
1866 460f00c4 aurel32
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1867 460f00c4 aurel32
{
1868 460f00c4 aurel32
    const char *opn = "slt";
1869 460f00c4 aurel32
    TCGv t0, t1;
1870 460f00c4 aurel32
1871 460f00c4 aurel32
    if (rd == 0) {
1872 460f00c4 aurel32
        /* If no destination, treat it as a NOP. */
1873 460f00c4 aurel32
        MIPS_DEBUG("NOP");
1874 460f00c4 aurel32
        return;
1875 460f00c4 aurel32
    }
1876 460f00c4 aurel32
1877 460f00c4 aurel32
    t0 = tcg_temp_new();
1878 460f00c4 aurel32
    t1 = tcg_temp_new();
1879 460f00c4 aurel32
    gen_load_gpr(t0, rs);
1880 460f00c4 aurel32
    gen_load_gpr(t1, rt);
1881 460f00c4 aurel32
    switch (opc) {
1882 460f00c4 aurel32
    case OPC_SLT:
1883 e68dd28f Aurelien Jarno
        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1884 460f00c4 aurel32
        opn = "slt";
1885 6af0bf9c bellard
        break;
1886 460f00c4 aurel32
    case OPC_SLTU:
1887 e68dd28f Aurelien Jarno
        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1888 460f00c4 aurel32
        opn = "sltu";
1889 460f00c4 aurel32
        break;
1890 460f00c4 aurel32
    }
1891 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1892 460f00c4 aurel32
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1893 460f00c4 aurel32
    tcg_temp_free(t0);
1894 460f00c4 aurel32
    tcg_temp_free(t1);
1895 460f00c4 aurel32
}
1896 20c4c97c ths
1897 460f00c4 aurel32
/* Shifts */
1898 460f00c4 aurel32
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1899 460f00c4 aurel32
                       int rd, int rs, int rt)
1900 460f00c4 aurel32
{
1901 460f00c4 aurel32
    const char *opn = "shifts";
1902 460f00c4 aurel32
    TCGv t0, t1;
1903 20c4c97c ths
1904 460f00c4 aurel32
    if (rd == 0) {
1905 460f00c4 aurel32
        /* If no destination, treat it as a NOP.
1906 460f00c4 aurel32
           For add & sub, we must generate the overflow exception when needed. */
1907 460f00c4 aurel32
        MIPS_DEBUG("NOP");
1908 460f00c4 aurel32
        return;
1909 460f00c4 aurel32
    }
1910 460f00c4 aurel32
1911 460f00c4 aurel32
    t0 = tcg_temp_new();
1912 460f00c4 aurel32
    t1 = tcg_temp_new();
1913 460f00c4 aurel32
    gen_load_gpr(t0, rs);
1914 460f00c4 aurel32
    gen_load_gpr(t1, rt);
1915 460f00c4 aurel32
    switch (opc) {
1916 6af0bf9c bellard
    case OPC_SLLV:
1917 78723684 ths
        tcg_gen_andi_tl(t0, t0, 0x1f);
1918 78723684 ths
        tcg_gen_shl_tl(t0, t1, t0);
1919 460f00c4 aurel32
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1920 6af0bf9c bellard
        opn = "sllv";
1921 6af0bf9c bellard
        break;
1922 6af0bf9c bellard
    case OPC_SRAV:
1923 78723684 ths
        tcg_gen_andi_tl(t0, t0, 0x1f);
1924 460f00c4 aurel32
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1925 6af0bf9c bellard
        opn = "srav";
1926 6af0bf9c bellard
        break;
1927 6af0bf9c bellard
    case OPC_SRLV:
1928 ea63e2c3 Nathan Froyd
        tcg_gen_ext32u_tl(t1, t1);
1929 ea63e2c3 Nathan Froyd
        tcg_gen_andi_tl(t0, t0, 0x1f);
1930 ea63e2c3 Nathan Froyd
        tcg_gen_shr_tl(t0, t1, t0);
1931 ea63e2c3 Nathan Froyd
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1932 ea63e2c3 Nathan Froyd
        opn = "srlv";
1933 ea63e2c3 Nathan Froyd
        break;
1934 ea63e2c3 Nathan Froyd
    case OPC_ROTRV:
1935 ea63e2c3 Nathan Froyd
        {
1936 ea63e2c3 Nathan Froyd
            TCGv_i32 t2 = tcg_temp_new_i32();
1937 ea63e2c3 Nathan Froyd
            TCGv_i32 t3 = tcg_temp_new_i32();
1938 ea63e2c3 Nathan Froyd
1939 ea63e2c3 Nathan Froyd
            tcg_gen_trunc_tl_i32(t2, t0);
1940 ea63e2c3 Nathan Froyd
            tcg_gen_trunc_tl_i32(t3, t1);
1941 ea63e2c3 Nathan Froyd
            tcg_gen_andi_i32(t2, t2, 0x1f);
1942 ea63e2c3 Nathan Froyd
            tcg_gen_rotr_i32(t2, t3, t2);
1943 ea63e2c3 Nathan Froyd
            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1944 ea63e2c3 Nathan Froyd
            tcg_temp_free_i32(t2);
1945 ea63e2c3 Nathan Froyd
            tcg_temp_free_i32(t3);
1946 ea63e2c3 Nathan Froyd
            opn = "rotrv";
1947 5a63bcb2 ths
        }
1948 7a387fff ths
        break;
1949 d26bc211 ths
#if defined(TARGET_MIPS64)
1950 7a387fff ths
    case OPC_DSLLV:
1951 78723684 ths
        tcg_gen_andi_tl(t0, t0, 0x3f);
1952 460f00c4 aurel32
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1953 7a387fff ths
        opn = "dsllv";
1954 7a387fff ths
        break;
1955 7a387fff ths
    case OPC_DSRAV:
1956 78723684 ths
        tcg_gen_andi_tl(t0, t0, 0x3f);
1957 460f00c4 aurel32
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1958 7a387fff ths
        opn = "dsrav";
1959 7a387fff ths
        break;
1960 7a387fff ths
    case OPC_DSRLV:
1961 ea63e2c3 Nathan Froyd
        tcg_gen_andi_tl(t0, t0, 0x3f);
1962 ea63e2c3 Nathan Froyd
        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1963 ea63e2c3 Nathan Froyd
        opn = "dsrlv";
1964 ea63e2c3 Nathan Froyd
        break;
1965 ea63e2c3 Nathan Froyd
    case OPC_DROTRV:
1966 ea63e2c3 Nathan Froyd
        tcg_gen_andi_tl(t0, t0, 0x3f);
1967 ea63e2c3 Nathan Froyd
        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1968 ea63e2c3 Nathan Froyd
        opn = "drotrv";
1969 6af0bf9c bellard
        break;
1970 7a387fff ths
#endif
1971 6af0bf9c bellard
    }
1972 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
1973 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1974 78723684 ths
    tcg_temp_free(t0);
1975 78723684 ths
    tcg_temp_free(t1);
1976 6af0bf9c bellard
}
1977 6af0bf9c bellard
1978 6af0bf9c bellard
/* Arithmetic on HI/LO registers */
1979 7a387fff ths
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1980 6af0bf9c bellard
{
1981 923617a3 ths
    const char *opn = "hilo";
1982 6af0bf9c bellard
1983 6af0bf9c bellard
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1984 ead9360e ths
        /* Treat as NOP. */
1985 6af0bf9c bellard
        MIPS_DEBUG("NOP");
1986 a1f6684d aurel32
        return;
1987 6af0bf9c bellard
    }
1988 6af0bf9c bellard
    switch (opc) {
1989 6af0bf9c bellard
    case OPC_MFHI:
1990 a1f6684d aurel32
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1991 6af0bf9c bellard
        opn = "mfhi";
1992 6af0bf9c bellard
        break;
1993 6af0bf9c bellard
    case OPC_MFLO:
1994 a1f6684d aurel32
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1995 6af0bf9c bellard
        opn = "mflo";
1996 6af0bf9c bellard
        break;
1997 6af0bf9c bellard
    case OPC_MTHI:
1998 a1f6684d aurel32
        if (reg != 0)
1999 a1f6684d aurel32
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
2000 a1f6684d aurel32
        else
2001 a1f6684d aurel32
            tcg_gen_movi_tl(cpu_HI[0], 0);
2002 6af0bf9c bellard
        opn = "mthi";
2003 6af0bf9c bellard
        break;
2004 6af0bf9c bellard
    case OPC_MTLO:
2005 a1f6684d aurel32
        if (reg != 0)
2006 a1f6684d aurel32
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2007 a1f6684d aurel32
        else
2008 a1f6684d aurel32
            tcg_gen_movi_tl(cpu_LO[0], 0);
2009 6af0bf9c bellard
        opn = "mtlo";
2010 6af0bf9c bellard
        break;
2011 6af0bf9c bellard
    }
2012 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
2013 6af0bf9c bellard
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
2014 6af0bf9c bellard
}
2015 6af0bf9c bellard
2016 7a387fff ths
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2017 6af0bf9c bellard
                        int rs, int rt)
2018 6af0bf9c bellard
{
2019 923617a3 ths
    const char *opn = "mul/div";
2020 d45f89f4 aurel32
    TCGv t0, t1;
2021 d45f89f4 aurel32
2022 d45f89f4 aurel32
    switch (opc) {
2023 d45f89f4 aurel32
    case OPC_DIV:
2024 d45f89f4 aurel32
    case OPC_DIVU:
2025 d45f89f4 aurel32
#if defined(TARGET_MIPS64)
2026 d45f89f4 aurel32
    case OPC_DDIV:
2027 d45f89f4 aurel32
    case OPC_DDIVU:
2028 d45f89f4 aurel32
#endif
2029 d45f89f4 aurel32
        t0 = tcg_temp_local_new();
2030 d45f89f4 aurel32
        t1 = tcg_temp_local_new();
2031 d45f89f4 aurel32
        break;
2032 d45f89f4 aurel32
    default:
2033 d45f89f4 aurel32
        t0 = tcg_temp_new();
2034 d45f89f4 aurel32
        t1 = tcg_temp_new();
2035 d45f89f4 aurel32
        break;
2036 d45f89f4 aurel32
    }
2037 6af0bf9c bellard
2038 78723684 ths
    gen_load_gpr(t0, rs);
2039 78723684 ths
    gen_load_gpr(t1, rt);
2040 6af0bf9c bellard
    switch (opc) {
2041 6af0bf9c bellard
    case OPC_DIV:
2042 48d38ca5 ths
        {
2043 48d38ca5 ths
            int l1 = gen_new_label();
2044 d45f89f4 aurel32
            int l2 = gen_new_label();
2045 48d38ca5 ths
2046 d45f89f4 aurel32
            tcg_gen_ext32s_tl(t0, t0);
2047 d45f89f4 aurel32
            tcg_gen_ext32s_tl(t1, t1);
2048 78723684 ths
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2049 d45f89f4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2050 d45f89f4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2051 d45f89f4 aurel32
2052 d45f89f4 aurel32
            tcg_gen_mov_tl(cpu_LO[0], t0);
2053 d45f89f4 aurel32
            tcg_gen_movi_tl(cpu_HI[0], 0);
2054 d45f89f4 aurel32
            tcg_gen_br(l1);
2055 d45f89f4 aurel32
            gen_set_label(l2);
2056 d45f89f4 aurel32
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2057 d45f89f4 aurel32
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2058 d45f89f4 aurel32
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2059 d45f89f4 aurel32
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2060 48d38ca5 ths
            gen_set_label(l1);
2061 48d38ca5 ths
        }
2062 6af0bf9c bellard
        opn = "div";
2063 6af0bf9c bellard
        break;
2064 6af0bf9c bellard
    case OPC_DIVU:
2065 48d38ca5 ths
        {
2066 48d38ca5 ths
            int l1 = gen_new_label();
2067 48d38ca5 ths
2068 0c0ed03b aurel32
            tcg_gen_ext32u_tl(t0, t0);
2069 0c0ed03b aurel32
            tcg_gen_ext32u_tl(t1, t1);
2070 78723684 ths
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2071 d45f89f4 aurel32
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2072 d45f89f4 aurel32
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2073 d45f89f4 aurel32
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2074 d45f89f4 aurel32
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2075 48d38ca5 ths
            gen_set_label(l1);
2076 48d38ca5 ths
        }
2077 6af0bf9c bellard
        opn = "divu";
2078 6af0bf9c bellard
        break;
2079 6af0bf9c bellard
    case OPC_MULT:
2080 214c465f ths
        {
2081 d45f89f4 aurel32
            TCGv_i64 t2 = tcg_temp_new_i64();
2082 d45f89f4 aurel32
            TCGv_i64 t3 = tcg_temp_new_i64();
2083 d45f89f4 aurel32
2084 d45f89f4 aurel32
            tcg_gen_ext_tl_i64(t2, t0);
2085 d45f89f4 aurel32
            tcg_gen_ext_tl_i64(t3, t1);
2086 d45f89f4 aurel32
            tcg_gen_mul_i64(t2, t2, t3);
2087 d45f89f4 aurel32
            tcg_temp_free_i64(t3);
2088 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t0, t2);
2089 d45f89f4 aurel32
            tcg_gen_shri_i64(t2, t2, 32);
2090 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t1, t2);
2091 d45f89f4 aurel32
            tcg_temp_free_i64(t2);
2092 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2093 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2094 214c465f ths
        }
2095 6af0bf9c bellard
        opn = "mult";
2096 6af0bf9c bellard
        break;
2097 6af0bf9c bellard
    case OPC_MULTU:
2098 214c465f ths
        {
2099 d45f89f4 aurel32
            TCGv_i64 t2 = tcg_temp_new_i64();
2100 d45f89f4 aurel32
            TCGv_i64 t3 = tcg_temp_new_i64();
2101 214c465f ths
2102 78723684 ths
            tcg_gen_ext32u_tl(t0, t0);
2103 78723684 ths
            tcg_gen_ext32u_tl(t1, t1);
2104 d45f89f4 aurel32
            tcg_gen_extu_tl_i64(t2, t0);
2105 d45f89f4 aurel32
            tcg_gen_extu_tl_i64(t3, t1);
2106 d45f89f4 aurel32
            tcg_gen_mul_i64(t2, t2, t3);
2107 d45f89f4 aurel32
            tcg_temp_free_i64(t3);
2108 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t0, t2);
2109 d45f89f4 aurel32
            tcg_gen_shri_i64(t2, t2, 32);
2110 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t1, t2);
2111 d45f89f4 aurel32
            tcg_temp_free_i64(t2);
2112 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2113 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2114 214c465f ths
        }
2115 6af0bf9c bellard
        opn = "multu";
2116 6af0bf9c bellard
        break;
2117 d26bc211 ths
#if defined(TARGET_MIPS64)
2118 7a387fff ths
    case OPC_DDIV:
2119 48d38ca5 ths
        {
2120 48d38ca5 ths
            int l1 = gen_new_label();
2121 d45f89f4 aurel32
            int l2 = gen_new_label();
2122 48d38ca5 ths
2123 78723684 ths
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2124 d45f89f4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2125 d45f89f4 aurel32
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2126 d45f89f4 aurel32
            tcg_gen_mov_tl(cpu_LO[0], t0);
2127 d45f89f4 aurel32
            tcg_gen_movi_tl(cpu_HI[0], 0);
2128 d45f89f4 aurel32
            tcg_gen_br(l1);
2129 d45f89f4 aurel32
            gen_set_label(l2);
2130 d45f89f4 aurel32
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2131 d45f89f4 aurel32
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2132 48d38ca5 ths
            gen_set_label(l1);
2133 48d38ca5 ths
        }
2134 7a387fff ths
        opn = "ddiv";
2135 7a387fff ths
        break;
2136 7a387fff ths
    case OPC_DDIVU:
2137 48d38ca5 ths
        {
2138 48d38ca5 ths
            int l1 = gen_new_label();
2139 48d38ca5 ths
2140 78723684 ths
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2141 b10fa3c9 aurel32
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2142 b10fa3c9 aurel32
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2143 48d38ca5 ths
            gen_set_label(l1);
2144 48d38ca5 ths
        }
2145 7a387fff ths
        opn = "ddivu";
2146 7a387fff ths
        break;
2147 7a387fff ths
    case OPC_DMULT:
2148 a7812ae4 pbrook
        gen_helper_dmult(t0, t1);
2149 7a387fff ths
        opn = "dmult";
2150 7a387fff ths
        break;
2151 7a387fff ths
    case OPC_DMULTU:
2152 a7812ae4 pbrook
        gen_helper_dmultu(t0, t1);
2153 7a387fff ths
        opn = "dmultu";
2154 7a387fff ths
        break;
2155 7a387fff ths
#endif
2156 6af0bf9c bellard
    case OPC_MADD:
2157 214c465f ths
        {
2158 d45f89f4 aurel32
            TCGv_i64 t2 = tcg_temp_new_i64();
2159 d45f89f4 aurel32
            TCGv_i64 t3 = tcg_temp_new_i64();
2160 d45f89f4 aurel32
2161 d45f89f4 aurel32
            tcg_gen_ext_tl_i64(t2, t0);
2162 d45f89f4 aurel32
            tcg_gen_ext_tl_i64(t3, t1);
2163 d45f89f4 aurel32
            tcg_gen_mul_i64(t2, t2, t3);
2164 d45f89f4 aurel32
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2165 d45f89f4 aurel32
            tcg_gen_add_i64(t2, t2, t3);
2166 d45f89f4 aurel32
            tcg_temp_free_i64(t3);
2167 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t0, t2);
2168 d45f89f4 aurel32
            tcg_gen_shri_i64(t2, t2, 32);
2169 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t1, t2);
2170 d45f89f4 aurel32
            tcg_temp_free_i64(t2);
2171 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2172 98070ce0 Nathan Froyd
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2173 214c465f ths
        }
2174 6af0bf9c bellard
        opn = "madd";
2175 6af0bf9c bellard
        break;
2176 6af0bf9c bellard
    case OPC_MADDU:
2177 214c465f ths
       {
2178 d45f89f4 aurel32
            TCGv_i64 t2 = tcg_temp_new_i64();
2179 d45f89f4 aurel32
            TCGv_i64 t3 = tcg_temp_new_i64();
2180 214c465f ths
2181 78723684 ths
            tcg_gen_ext32u_tl(t0, t0);
2182 78723684 ths
            tcg_gen_ext32u_tl(t1, t1);
2183 d45f89f4 aurel32
            tcg_gen_extu_tl_i64(t2, t0);
2184 d45f89f4 aurel32
            tcg_gen_extu_tl_i64(t3, t1);
2185 d45f89f4 aurel32
            tcg_gen_mul_i64(t2, t2, t3);
2186 d45f89f4 aurel32
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2187 d45f89f4 aurel32
            tcg_gen_add_i64(t2, t2, t3);
2188 d45f89f4 aurel32
            tcg_temp_free_i64(t3);
2189 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t0, t2);
2190 d45f89f4 aurel32
            tcg_gen_shri_i64(t2, t2, 32);
2191 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t1, t2);
2192 d45f89f4 aurel32
            tcg_temp_free_i64(t2);
2193 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2194 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2195 214c465f ths
        }
2196 6af0bf9c bellard
        opn = "maddu";
2197 6af0bf9c bellard
        break;
2198 6af0bf9c bellard
    case OPC_MSUB:
2199 214c465f ths
        {
2200 d45f89f4 aurel32
            TCGv_i64 t2 = tcg_temp_new_i64();
2201 d45f89f4 aurel32
            TCGv_i64 t3 = tcg_temp_new_i64();
2202 d45f89f4 aurel32
2203 d45f89f4 aurel32
            tcg_gen_ext_tl_i64(t2, t0);
2204 d45f89f4 aurel32
            tcg_gen_ext_tl_i64(t3, t1);
2205 d45f89f4 aurel32
            tcg_gen_mul_i64(t2, t2, t3);
2206 d45f89f4 aurel32
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2207 98070ce0 Nathan Froyd
            tcg_gen_sub_i64(t2, t3, t2);
2208 d45f89f4 aurel32
            tcg_temp_free_i64(t3);
2209 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t0, t2);
2210 d45f89f4 aurel32
            tcg_gen_shri_i64(t2, t2, 32);
2211 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t1, t2);
2212 d45f89f4 aurel32
            tcg_temp_free_i64(t2);
2213 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2214 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2215 214c465f ths
        }
2216 6af0bf9c bellard
        opn = "msub";
2217 6af0bf9c bellard
        break;
2218 6af0bf9c bellard
    case OPC_MSUBU:
2219 214c465f ths
        {
2220 d45f89f4 aurel32
            TCGv_i64 t2 = tcg_temp_new_i64();
2221 d45f89f4 aurel32
            TCGv_i64 t3 = tcg_temp_new_i64();
2222 214c465f ths
2223 78723684 ths
            tcg_gen_ext32u_tl(t0, t0);
2224 78723684 ths
            tcg_gen_ext32u_tl(t1, t1);
2225 d45f89f4 aurel32
            tcg_gen_extu_tl_i64(t2, t0);
2226 d45f89f4 aurel32
            tcg_gen_extu_tl_i64(t3, t1);
2227 d45f89f4 aurel32
            tcg_gen_mul_i64(t2, t2, t3);
2228 d45f89f4 aurel32
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2229 98070ce0 Nathan Froyd
            tcg_gen_sub_i64(t2, t3, t2);
2230 d45f89f4 aurel32
            tcg_temp_free_i64(t3);
2231 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t0, t2);
2232 d45f89f4 aurel32
            tcg_gen_shri_i64(t2, t2, 32);
2233 d45f89f4 aurel32
            tcg_gen_trunc_i64_tl(t1, t2);
2234 d45f89f4 aurel32
            tcg_temp_free_i64(t2);
2235 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2236 b10fa3c9 aurel32
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2237 214c465f ths
        }
2238 6af0bf9c bellard
        opn = "msubu";
2239 6af0bf9c bellard
        break;
2240 6af0bf9c bellard
    default:
2241 923617a3 ths
        MIPS_INVAL(opn);
2242 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
2243 78723684 ths
        goto out;
2244 6af0bf9c bellard
    }
2245 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
2246 6af0bf9c bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2247 78723684 ths
 out:
2248 78723684 ths
    tcg_temp_free(t0);
2249 78723684 ths
    tcg_temp_free(t1);
2250 6af0bf9c bellard
}
2251 6af0bf9c bellard
2252 e9c71dd1 ths
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2253 e9c71dd1 ths
                            int rd, int rs, int rt)
2254 e9c71dd1 ths
{
2255 e9c71dd1 ths
    const char *opn = "mul vr54xx";
2256 f157bfe1 aurel32
    TCGv t0 = tcg_temp_new();
2257 f157bfe1 aurel32
    TCGv t1 = tcg_temp_new();
2258 e9c71dd1 ths
2259 6c5c1e20 ths
    gen_load_gpr(t0, rs);
2260 6c5c1e20 ths
    gen_load_gpr(t1, rt);
2261 e9c71dd1 ths
2262 e9c71dd1 ths
    switch (opc) {
2263 e9c71dd1 ths
    case OPC_VR54XX_MULS:
2264 a7812ae4 pbrook
        gen_helper_muls(t0, t0, t1);
2265 e9c71dd1 ths
        opn = "muls";
2266 6958549d aurel32
        break;
2267 e9c71dd1 ths
    case OPC_VR54XX_MULSU:
2268 a7812ae4 pbrook
        gen_helper_mulsu(t0, t0, t1);
2269 e9c71dd1 ths
        opn = "mulsu";
2270 6958549d aurel32
        break;
2271 e9c71dd1 ths
    case OPC_VR54XX_MACC:
2272 a7812ae4 pbrook
        gen_helper_macc(t0, t0, t1);
2273 e9c71dd1 ths
        opn = "macc";
2274 6958549d aurel32
        break;
2275 e9c71dd1 ths
    case OPC_VR54XX_MACCU:
2276 a7812ae4 pbrook
        gen_helper_maccu(t0, t0, t1);
2277 e9c71dd1 ths
        opn = "maccu";
2278 6958549d aurel32
        break;
2279 e9c71dd1 ths
    case OPC_VR54XX_MSAC:
2280 a7812ae4 pbrook
        gen_helper_msac(t0, t0, t1);
2281 e9c71dd1 ths
        opn = "msac";
2282 6958549d aurel32
        break;
2283 e9c71dd1 ths
    case OPC_VR54XX_MSACU:
2284 a7812ae4 pbrook
        gen_helper_msacu(t0, t0, t1);
2285 e9c71dd1 ths
        opn = "msacu";
2286 6958549d aurel32
        break;
2287 e9c71dd1 ths
    case OPC_VR54XX_MULHI:
2288 a7812ae4 pbrook
        gen_helper_mulhi(t0, t0, t1);
2289 e9c71dd1 ths
        opn = "mulhi";
2290 6958549d aurel32
        break;
2291 e9c71dd1 ths
    case OPC_VR54XX_MULHIU:
2292 a7812ae4 pbrook
        gen_helper_mulhiu(t0, t0, t1);
2293 e9c71dd1 ths
        opn = "mulhiu";
2294 6958549d aurel32
        break;
2295 e9c71dd1 ths
    case OPC_VR54XX_MULSHI:
2296 a7812ae4 pbrook
        gen_helper_mulshi(t0, t0, t1);
2297 e9c71dd1 ths
        opn = "mulshi";
2298 6958549d aurel32
        break;
2299 e9c71dd1 ths
    case OPC_VR54XX_MULSHIU:
2300 a7812ae4 pbrook
        gen_helper_mulshiu(t0, t0, t1);
2301 e9c71dd1 ths
        opn = "mulshiu";
2302 6958549d aurel32
        break;
2303 e9c71dd1 ths
    case OPC_VR54XX_MACCHI:
2304 a7812ae4 pbrook
        gen_helper_macchi(t0, t0, t1);
2305 e9c71dd1 ths
        opn = "macchi";
2306 6958549d aurel32
        break;
2307 e9c71dd1 ths
    case OPC_VR54XX_MACCHIU:
2308 a7812ae4 pbrook
        gen_helper_macchiu(t0, t0, t1);
2309 e9c71dd1 ths
        opn = "macchiu";
2310 6958549d aurel32
        break;
2311 e9c71dd1 ths
    case OPC_VR54XX_MSACHI:
2312 a7812ae4 pbrook
        gen_helper_msachi(t0, t0, t1);
2313 e9c71dd1 ths
        opn = "msachi";
2314 6958549d aurel32
        break;
2315 e9c71dd1 ths
    case OPC_VR54XX_MSACHIU:
2316 a7812ae4 pbrook
        gen_helper_msachiu(t0, t0, t1);
2317 e9c71dd1 ths
        opn = "msachiu";
2318 6958549d aurel32
        break;
2319 e9c71dd1 ths
    default:
2320 e9c71dd1 ths
        MIPS_INVAL("mul vr54xx");
2321 e9c71dd1 ths
        generate_exception(ctx, EXCP_RI);
2322 6c5c1e20 ths
        goto out;
2323 e9c71dd1 ths
    }
2324 6c5c1e20 ths
    gen_store_gpr(t0, rd);
2325 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
2326 e9c71dd1 ths
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2327 6c5c1e20 ths
2328 6c5c1e20 ths
 out:
2329 6c5c1e20 ths
    tcg_temp_free(t0);
2330 6c5c1e20 ths
    tcg_temp_free(t1);
2331 e9c71dd1 ths
}
2332 e9c71dd1 ths
2333 7a387fff ths
static void gen_cl (DisasContext *ctx, uint32_t opc,
2334 6af0bf9c bellard
                    int rd, int rs)
2335 6af0bf9c bellard
{
2336 923617a3 ths
    const char *opn = "CLx";
2337 20e1fb52 aurel32
    TCGv t0;
2338 6c5c1e20 ths
2339 6af0bf9c bellard
    if (rd == 0) {
2340 ead9360e ths
        /* Treat as NOP. */
2341 6af0bf9c bellard
        MIPS_DEBUG("NOP");
2342 20e1fb52 aurel32
        return;
2343 6af0bf9c bellard
    }
2344 20e1fb52 aurel32
    t0 = tcg_temp_new();
2345 6c5c1e20 ths
    gen_load_gpr(t0, rs);
2346 6af0bf9c bellard
    switch (opc) {
2347 6af0bf9c bellard
    case OPC_CLO:
2348 20e1fb52 aurel32
        gen_helper_clo(cpu_gpr[rd], t0);
2349 6af0bf9c bellard
        opn = "clo";
2350 6af0bf9c bellard
        break;
2351 6af0bf9c bellard
    case OPC_CLZ:
2352 20e1fb52 aurel32
        gen_helper_clz(cpu_gpr[rd], t0);
2353 6af0bf9c bellard
        opn = "clz";
2354 6af0bf9c bellard
        break;
2355 d26bc211 ths
#if defined(TARGET_MIPS64)
2356 7a387fff ths
    case OPC_DCLO:
2357 20e1fb52 aurel32
        gen_helper_dclo(cpu_gpr[rd], t0);
2358 7a387fff ths
        opn = "dclo";
2359 7a387fff ths
        break;
2360 7a387fff ths
    case OPC_DCLZ:
2361 20e1fb52 aurel32
        gen_helper_dclz(cpu_gpr[rd], t0);
2362 7a387fff ths
        opn = "dclz";
2363 7a387fff ths
        break;
2364 7a387fff ths
#endif
2365 6af0bf9c bellard
    }
2366 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
2367 6af0bf9c bellard
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2368 6c5c1e20 ths
    tcg_temp_free(t0);
2369 6af0bf9c bellard
}
2370 6af0bf9c bellard
2371 161f85e6 Aurelien Jarno
/* Godson integer instructions */
2372 161f85e6 Aurelien Jarno
static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2373 161f85e6 Aurelien Jarno
                                int rd, int rs, int rt)
2374 161f85e6 Aurelien Jarno
{
2375 161f85e6 Aurelien Jarno
    const char *opn = "loongson";
2376 161f85e6 Aurelien Jarno
    TCGv t0, t1;
2377 161f85e6 Aurelien Jarno
2378 161f85e6 Aurelien Jarno
    if (rd == 0) {
2379 161f85e6 Aurelien Jarno
        /* Treat as NOP. */
2380 161f85e6 Aurelien Jarno
        MIPS_DEBUG("NOP");
2381 161f85e6 Aurelien Jarno
        return;
2382 161f85e6 Aurelien Jarno
    }
2383 161f85e6 Aurelien Jarno
2384 161f85e6 Aurelien Jarno
    switch (opc) {
2385 161f85e6 Aurelien Jarno
    case OPC_MULT_G_2E:
2386 161f85e6 Aurelien Jarno
    case OPC_MULT_G_2F:
2387 161f85e6 Aurelien Jarno
    case OPC_MULTU_G_2E:
2388 161f85e6 Aurelien Jarno
    case OPC_MULTU_G_2F:
2389 161f85e6 Aurelien Jarno
#if defined(TARGET_MIPS64)
2390 161f85e6 Aurelien Jarno
    case OPC_DMULT_G_2E:
2391 161f85e6 Aurelien Jarno
    case OPC_DMULT_G_2F:
2392 161f85e6 Aurelien Jarno
    case OPC_DMULTU_G_2E:
2393 161f85e6 Aurelien Jarno
    case OPC_DMULTU_G_2F:
2394 161f85e6 Aurelien Jarno
#endif
2395 161f85e6 Aurelien Jarno
        t0 = tcg_temp_new();
2396 161f85e6 Aurelien Jarno
        t1 = tcg_temp_new();
2397 161f85e6 Aurelien Jarno
        break;
2398 161f85e6 Aurelien Jarno
    default:
2399 161f85e6 Aurelien Jarno
        t0 = tcg_temp_local_new();
2400 161f85e6 Aurelien Jarno
        t1 = tcg_temp_local_new();
2401 161f85e6 Aurelien Jarno
        break;
2402 161f85e6 Aurelien Jarno
    }
2403 161f85e6 Aurelien Jarno
2404 161f85e6 Aurelien Jarno
    gen_load_gpr(t0, rs);
2405 161f85e6 Aurelien Jarno
    gen_load_gpr(t1, rt);
2406 161f85e6 Aurelien Jarno
2407 161f85e6 Aurelien Jarno
    switch (opc) {
2408 161f85e6 Aurelien Jarno
    case OPC_MULT_G_2E:
2409 161f85e6 Aurelien Jarno
    case OPC_MULT_G_2F:
2410 161f85e6 Aurelien Jarno
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2411 161f85e6 Aurelien Jarno
        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2412 161f85e6 Aurelien Jarno
        opn = "mult.g";
2413 161f85e6 Aurelien Jarno
        break;
2414 161f85e6 Aurelien Jarno
    case OPC_MULTU_G_2E:
2415 161f85e6 Aurelien Jarno
    case OPC_MULTU_G_2F:
2416 161f85e6 Aurelien Jarno
        tcg_gen_ext32u_tl(t0, t0);
2417 161f85e6 Aurelien Jarno
        tcg_gen_ext32u_tl(t1, t1);
2418 161f85e6 Aurelien Jarno
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2419 161f85e6 Aurelien Jarno
        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2420 161f85e6 Aurelien Jarno
        opn = "multu.g";
2421 161f85e6 Aurelien Jarno
        break;
2422 161f85e6 Aurelien Jarno
    case OPC_DIV_G_2E:
2423 161f85e6 Aurelien Jarno
    case OPC_DIV_G_2F:
2424 161f85e6 Aurelien Jarno
        {
2425 161f85e6 Aurelien Jarno
            int l1 = gen_new_label();
2426 161f85e6 Aurelien Jarno
            int l2 = gen_new_label();
2427 161f85e6 Aurelien Jarno
            int l3 = gen_new_label();
2428 161f85e6 Aurelien Jarno
            tcg_gen_ext32s_tl(t0, t0);
2429 161f85e6 Aurelien Jarno
            tcg_gen_ext32s_tl(t1, t1);
2430 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2431 161f85e6 Aurelien Jarno
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2432 161f85e6 Aurelien Jarno
            tcg_gen_br(l3);
2433 161f85e6 Aurelien Jarno
            gen_set_label(l1);
2434 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2435 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2436 161f85e6 Aurelien Jarno
            tcg_gen_mov_tl(cpu_gpr[rd], t0);
2437 161f85e6 Aurelien Jarno
            tcg_gen_br(l3);
2438 161f85e6 Aurelien Jarno
            gen_set_label(l2);
2439 161f85e6 Aurelien Jarno
            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2440 161f85e6 Aurelien Jarno
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2441 161f85e6 Aurelien Jarno
            gen_set_label(l3);
2442 161f85e6 Aurelien Jarno
        }
2443 161f85e6 Aurelien Jarno
        opn = "div.g";
2444 161f85e6 Aurelien Jarno
        break;
2445 161f85e6 Aurelien Jarno
    case OPC_DIVU_G_2E:
2446 161f85e6 Aurelien Jarno
    case OPC_DIVU_G_2F:
2447 161f85e6 Aurelien Jarno
        {
2448 161f85e6 Aurelien Jarno
            int l1 = gen_new_label();
2449 161f85e6 Aurelien Jarno
            int l2 = gen_new_label();
2450 161f85e6 Aurelien Jarno
            tcg_gen_ext32u_tl(t0, t0);
2451 161f85e6 Aurelien Jarno
            tcg_gen_ext32u_tl(t1, t1);
2452 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2453 161f85e6 Aurelien Jarno
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2454 161f85e6 Aurelien Jarno
            tcg_gen_br(l2);
2455 161f85e6 Aurelien Jarno
            gen_set_label(l1);
2456 161f85e6 Aurelien Jarno
            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2457 161f85e6 Aurelien Jarno
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2458 161f85e6 Aurelien Jarno
            gen_set_label(l2);
2459 161f85e6 Aurelien Jarno
        }
2460 161f85e6 Aurelien Jarno
        opn = "divu.g";
2461 161f85e6 Aurelien Jarno
        break;
2462 161f85e6 Aurelien Jarno
    case OPC_MOD_G_2E:
2463 161f85e6 Aurelien Jarno
    case OPC_MOD_G_2F:
2464 161f85e6 Aurelien Jarno
        {
2465 161f85e6 Aurelien Jarno
            int l1 = gen_new_label();
2466 161f85e6 Aurelien Jarno
            int l2 = gen_new_label();
2467 161f85e6 Aurelien Jarno
            int l3 = gen_new_label();
2468 161f85e6 Aurelien Jarno
            tcg_gen_ext32u_tl(t0, t0);
2469 161f85e6 Aurelien Jarno
            tcg_gen_ext32u_tl(t1, t1);
2470 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2471 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2472 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2473 161f85e6 Aurelien Jarno
            gen_set_label(l1);
2474 161f85e6 Aurelien Jarno
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2475 161f85e6 Aurelien Jarno
            tcg_gen_br(l3);
2476 161f85e6 Aurelien Jarno
            gen_set_label(l2);
2477 161f85e6 Aurelien Jarno
            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2478 161f85e6 Aurelien Jarno
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2479 161f85e6 Aurelien Jarno
            gen_set_label(l3);
2480 161f85e6 Aurelien Jarno
        }
2481 161f85e6 Aurelien Jarno
        opn = "mod.g";
2482 161f85e6 Aurelien Jarno
        break;
2483 161f85e6 Aurelien Jarno
    case OPC_MODU_G_2E:
2484 161f85e6 Aurelien Jarno
    case OPC_MODU_G_2F:
2485 161f85e6 Aurelien Jarno
        {
2486 161f85e6 Aurelien Jarno
            int l1 = gen_new_label();
2487 161f85e6 Aurelien Jarno
            int l2 = gen_new_label();
2488 161f85e6 Aurelien Jarno
            tcg_gen_ext32u_tl(t0, t0);
2489 161f85e6 Aurelien Jarno
            tcg_gen_ext32u_tl(t1, t1);
2490 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2491 161f85e6 Aurelien Jarno
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2492 161f85e6 Aurelien Jarno
            tcg_gen_br(l2);
2493 161f85e6 Aurelien Jarno
            gen_set_label(l1);
2494 161f85e6 Aurelien Jarno
            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2495 161f85e6 Aurelien Jarno
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2496 161f85e6 Aurelien Jarno
            gen_set_label(l2);
2497 161f85e6 Aurelien Jarno
        }
2498 161f85e6 Aurelien Jarno
        opn = "modu.g";
2499 161f85e6 Aurelien Jarno
        break;
2500 161f85e6 Aurelien Jarno
#if defined(TARGET_MIPS64)
2501 161f85e6 Aurelien Jarno
    case OPC_DMULT_G_2E:
2502 161f85e6 Aurelien Jarno
    case OPC_DMULT_G_2F:
2503 161f85e6 Aurelien Jarno
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2504 161f85e6 Aurelien Jarno
        opn = "dmult.g";
2505 161f85e6 Aurelien Jarno
        break;
2506 161f85e6 Aurelien Jarno
    case OPC_DMULTU_G_2E:
2507 161f85e6 Aurelien Jarno
    case OPC_DMULTU_G_2F:
2508 161f85e6 Aurelien Jarno
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2509 161f85e6 Aurelien Jarno
        opn = "dmultu.g";
2510 161f85e6 Aurelien Jarno
        break;
2511 161f85e6 Aurelien Jarno
    case OPC_DDIV_G_2E:
2512 161f85e6 Aurelien Jarno
    case OPC_DDIV_G_2F:
2513 161f85e6 Aurelien Jarno
        {
2514 161f85e6 Aurelien Jarno
            int l1 = gen_new_label();
2515 161f85e6 Aurelien Jarno
            int l2 = gen_new_label();
2516 161f85e6 Aurelien Jarno
            int l3 = gen_new_label();
2517 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2518 161f85e6 Aurelien Jarno
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2519 161f85e6 Aurelien Jarno
            tcg_gen_br(l3);
2520 161f85e6 Aurelien Jarno
            gen_set_label(l1);
2521 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2522 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2523 161f85e6 Aurelien Jarno
            tcg_gen_mov_tl(cpu_gpr[rd], t0);
2524 161f85e6 Aurelien Jarno
            tcg_gen_br(l3);
2525 161f85e6 Aurelien Jarno
            gen_set_label(l2);
2526 161f85e6 Aurelien Jarno
            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2527 161f85e6 Aurelien Jarno
            gen_set_label(l3);
2528 161f85e6 Aurelien Jarno
        }
2529 161f85e6 Aurelien Jarno
        opn = "ddiv.g";
2530 161f85e6 Aurelien Jarno
        break;
2531 161f85e6 Aurelien Jarno
    case OPC_DDIVU_G_2E:
2532 161f85e6 Aurelien Jarno
    case OPC_DDIVU_G_2F:
2533 161f85e6 Aurelien Jarno
        {
2534 161f85e6 Aurelien Jarno
            int l1 = gen_new_label();
2535 161f85e6 Aurelien Jarno
            int l2 = gen_new_label();
2536 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2537 161f85e6 Aurelien Jarno
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2538 161f85e6 Aurelien Jarno
            tcg_gen_br(l2);
2539 161f85e6 Aurelien Jarno
            gen_set_label(l1);
2540 161f85e6 Aurelien Jarno
            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2541 161f85e6 Aurelien Jarno
            gen_set_label(l2);
2542 161f85e6 Aurelien Jarno
        }
2543 161f85e6 Aurelien Jarno
        opn = "ddivu.g";
2544 161f85e6 Aurelien Jarno
        break;
2545 161f85e6 Aurelien Jarno
    case OPC_DMOD_G_2E:
2546 161f85e6 Aurelien Jarno
    case OPC_DMOD_G_2F:
2547 161f85e6 Aurelien Jarno
        {
2548 161f85e6 Aurelien Jarno
            int l1 = gen_new_label();
2549 161f85e6 Aurelien Jarno
            int l2 = gen_new_label();
2550 161f85e6 Aurelien Jarno
            int l3 = gen_new_label();
2551 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2552 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2553 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2554 161f85e6 Aurelien Jarno
            gen_set_label(l1);
2555 161f85e6 Aurelien Jarno
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2556 161f85e6 Aurelien Jarno
            tcg_gen_br(l3);
2557 161f85e6 Aurelien Jarno
            gen_set_label(l2);
2558 161f85e6 Aurelien Jarno
            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2559 161f85e6 Aurelien Jarno
            gen_set_label(l3);
2560 161f85e6 Aurelien Jarno
        }
2561 161f85e6 Aurelien Jarno
        opn = "dmod.g";
2562 161f85e6 Aurelien Jarno
        break;
2563 161f85e6 Aurelien Jarno
    case OPC_DMODU_G_2E:
2564 161f85e6 Aurelien Jarno
    case OPC_DMODU_G_2F:
2565 161f85e6 Aurelien Jarno
        {
2566 161f85e6 Aurelien Jarno
            int l1 = gen_new_label();
2567 161f85e6 Aurelien Jarno
            int l2 = gen_new_label();
2568 161f85e6 Aurelien Jarno
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2569 161f85e6 Aurelien Jarno
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2570 161f85e6 Aurelien Jarno
            tcg_gen_br(l2);
2571 161f85e6 Aurelien Jarno
            gen_set_label(l1);
2572 161f85e6 Aurelien Jarno
            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2573 161f85e6 Aurelien Jarno
            gen_set_label(l2);
2574 161f85e6 Aurelien Jarno
        }
2575 161f85e6 Aurelien Jarno
        opn = "dmodu.g";
2576 161f85e6 Aurelien Jarno
        break;
2577 161f85e6 Aurelien Jarno
#endif
2578 161f85e6 Aurelien Jarno
    }
2579 161f85e6 Aurelien Jarno
2580 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
2581 161f85e6 Aurelien Jarno
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2582 161f85e6 Aurelien Jarno
    tcg_temp_free(t0);
2583 161f85e6 Aurelien Jarno
    tcg_temp_free(t1);
2584 161f85e6 Aurelien Jarno
}
2585 161f85e6 Aurelien Jarno
2586 6af0bf9c bellard
/* Traps */
2587 7a387fff ths
static void gen_trap (DisasContext *ctx, uint32_t opc,
2588 6af0bf9c bellard
                      int rs, int rt, int16_t imm)
2589 6af0bf9c bellard
{
2590 6af0bf9c bellard
    int cond;
2591 cdc0faa6 aurel32
    TCGv t0 = tcg_temp_new();
2592 1ba74fb8 aurel32
    TCGv t1 = tcg_temp_new();
2593 6af0bf9c bellard
2594 6af0bf9c bellard
    cond = 0;
2595 6af0bf9c bellard
    /* Load needed operands */
2596 6af0bf9c bellard
    switch (opc) {
2597 6af0bf9c bellard
    case OPC_TEQ:
2598 6af0bf9c bellard
    case OPC_TGE:
2599 6af0bf9c bellard
    case OPC_TGEU:
2600 6af0bf9c bellard
    case OPC_TLT:
2601 6af0bf9c bellard
    case OPC_TLTU:
2602 6af0bf9c bellard
    case OPC_TNE:
2603 6af0bf9c bellard
        /* Compare two registers */
2604 6af0bf9c bellard
        if (rs != rt) {
2605 be24bb4f ths
            gen_load_gpr(t0, rs);
2606 be24bb4f ths
            gen_load_gpr(t1, rt);
2607 6af0bf9c bellard
            cond = 1;
2608 6af0bf9c bellard
        }
2609 179e32bb ths
        break;
2610 6af0bf9c bellard
    case OPC_TEQI:
2611 6af0bf9c bellard
    case OPC_TGEI:
2612 6af0bf9c bellard
    case OPC_TGEIU:
2613 6af0bf9c bellard
    case OPC_TLTI:
2614 6af0bf9c bellard
    case OPC_TLTIU:
2615 6af0bf9c bellard
    case OPC_TNEI:
2616 6af0bf9c bellard
        /* Compare register to immediate */
2617 6af0bf9c bellard
        if (rs != 0 || imm != 0) {
2618 be24bb4f ths
            gen_load_gpr(t0, rs);
2619 be24bb4f ths
            tcg_gen_movi_tl(t1, (int32_t)imm);
2620 6af0bf9c bellard
            cond = 1;
2621 6af0bf9c bellard
        }
2622 6af0bf9c bellard
        break;
2623 6af0bf9c bellard
    }
2624 6af0bf9c bellard
    if (cond == 0) {
2625 6af0bf9c bellard
        switch (opc) {
2626 6af0bf9c bellard
        case OPC_TEQ:   /* rs == rs */
2627 6af0bf9c bellard
        case OPC_TEQI:  /* r0 == 0  */
2628 6af0bf9c bellard
        case OPC_TGE:   /* rs >= rs */
2629 6af0bf9c bellard
        case OPC_TGEI:  /* r0 >= 0  */
2630 6af0bf9c bellard
        case OPC_TGEU:  /* rs >= rs unsigned */
2631 6af0bf9c bellard
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2632 6af0bf9c bellard
            /* Always trap */
2633 cdc0faa6 aurel32
            generate_exception(ctx, EXCP_TRAP);
2634 6af0bf9c bellard
            break;
2635 6af0bf9c bellard
        case OPC_TLT:   /* rs < rs           */
2636 6af0bf9c bellard
        case OPC_TLTI:  /* r0 < 0            */
2637 6af0bf9c bellard
        case OPC_TLTU:  /* rs < rs unsigned  */
2638 6af0bf9c bellard
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2639 6af0bf9c bellard
        case OPC_TNE:   /* rs != rs          */
2640 6af0bf9c bellard
        case OPC_TNEI:  /* r0 != 0           */
2641 ead9360e ths
            /* Never trap: treat as NOP. */
2642 cdc0faa6 aurel32
            break;
2643 6af0bf9c bellard
        }
2644 6af0bf9c bellard
    } else {
2645 cdc0faa6 aurel32
        int l1 = gen_new_label();
2646 cdc0faa6 aurel32
2647 6af0bf9c bellard
        switch (opc) {
2648 6af0bf9c bellard
        case OPC_TEQ:
2649 6af0bf9c bellard
        case OPC_TEQI:
2650 cdc0faa6 aurel32
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2651 6af0bf9c bellard
            break;
2652 6af0bf9c bellard
        case OPC_TGE:
2653 6af0bf9c bellard
        case OPC_TGEI:
2654 cdc0faa6 aurel32
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2655 6af0bf9c bellard
            break;
2656 6af0bf9c bellard
        case OPC_TGEU:
2657 6af0bf9c bellard
        case OPC_TGEIU:
2658 cdc0faa6 aurel32
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2659 6af0bf9c bellard
            break;
2660 6af0bf9c bellard
        case OPC_TLT:
2661 6af0bf9c bellard
        case OPC_TLTI:
2662 cdc0faa6 aurel32
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2663 6af0bf9c bellard
            break;
2664 6af0bf9c bellard
        case OPC_TLTU:
2665 6af0bf9c bellard
        case OPC_TLTIU:
2666 cdc0faa6 aurel32
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2667 6af0bf9c bellard
            break;
2668 6af0bf9c bellard
        case OPC_TNE:
2669 6af0bf9c bellard
        case OPC_TNEI:
2670 cdc0faa6 aurel32
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2671 6af0bf9c bellard
            break;
2672 6af0bf9c bellard
        }
2673 cdc0faa6 aurel32
        generate_exception(ctx, EXCP_TRAP);
2674 08ba7963 ths
        gen_set_label(l1);
2675 08ba7963 ths
    }
2676 be24bb4f ths
    tcg_temp_free(t0);
2677 be24bb4f ths
    tcg_temp_free(t1);
2678 6af0bf9c bellard
}
2679 6af0bf9c bellard
2680 356265ae ths
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2681 c53be334 bellard
{
2682 6e256c93 bellard
    TranslationBlock *tb;
2683 6e256c93 bellard
    tb = ctx->tb;
2684 7b270ef2 Nathan Froyd
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2685 7b270ef2 Nathan Froyd
        likely(!ctx->singlestep_enabled)) {
2686 57fec1fe bellard
        tcg_gen_goto_tb(n);
2687 9b9e4393 ths
        gen_save_pc(dest);
2688 4b4a72e5 Stefan Weil
        tcg_gen_exit_tb((tcg_target_long)tb + n);
2689 6e256c93 bellard
    } else {
2690 9b9e4393 ths
        gen_save_pc(dest);
2691 7b270ef2 Nathan Froyd
        if (ctx->singlestep_enabled) {
2692 7b270ef2 Nathan Froyd
            save_cpu_state(ctx, 0);
2693 7b270ef2 Nathan Froyd
            gen_helper_0i(raise_exception, EXCP_DEBUG);
2694 7b270ef2 Nathan Froyd
        }
2695 57fec1fe bellard
        tcg_gen_exit_tb(0);
2696 6e256c93 bellard
    }
2697 c53be334 bellard
}
2698 c53be334 bellard
2699 6af0bf9c bellard
/* Branches (before delay slot) */
2700 7a387fff ths
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2701 7dca4ad0 Nathan Froyd
                                int insn_bytes,
2702 6af0bf9c bellard
                                int rs, int rt, int32_t offset)
2703 6af0bf9c bellard
{
2704 d077b6f7 ths
    target_ulong btgt = -1;
2705 3ad4bb2d ths
    int blink = 0;
2706 2fdbad25 aurel32
    int bcond_compute = 0;
2707 1ba74fb8 aurel32
    TCGv t0 = tcg_temp_new();
2708 1ba74fb8 aurel32
    TCGv t1 = tcg_temp_new();
2709 3ad4bb2d ths
2710 3ad4bb2d ths
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2711 923617a3 ths
#ifdef MIPS_DEBUG_DISAS
2712 d12d51d5 aliguori
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2713 923617a3 ths
#endif
2714 3ad4bb2d ths
        generate_exception(ctx, EXCP_RI);
2715 6c5c1e20 ths
        goto out;
2716 3ad4bb2d ths
    }
2717 6af0bf9c bellard
2718 6af0bf9c bellard
    /* Load needed operands */
2719 6af0bf9c bellard
    switch (opc) {
2720 6af0bf9c bellard
    case OPC_BEQ:
2721 6af0bf9c bellard
    case OPC_BEQL:
2722 6af0bf9c bellard
    case OPC_BNE:
2723 6af0bf9c bellard
    case OPC_BNEL:
2724 6af0bf9c bellard
        /* Compare two registers */
2725 6af0bf9c bellard
        if (rs != rt) {
2726 6c5c1e20 ths
            gen_load_gpr(t0, rs);
2727 6c5c1e20 ths
            gen_load_gpr(t1, rt);
2728 2fdbad25 aurel32
            bcond_compute = 1;
2729 6af0bf9c bellard
        }
2730 7dca4ad0 Nathan Froyd
        btgt = ctx->pc + insn_bytes + offset;
2731 6af0bf9c bellard
        break;
2732 6af0bf9c bellard
    case OPC_BGEZ:
2733 6af0bf9c bellard
    case OPC_BGEZAL:
2734 3c824109 Nathan Froyd
    case OPC_BGEZALS:
2735 6af0bf9c bellard
    case OPC_BGEZALL:
2736 6af0bf9c bellard
    case OPC_BGEZL:
2737 6af0bf9c bellard
    case OPC_BGTZ:
2738 6af0bf9c bellard
    case OPC_BGTZL:
2739 6af0bf9c bellard
    case OPC_BLEZ:
2740 6af0bf9c bellard
    case OPC_BLEZL:
2741 6af0bf9c bellard
    case OPC_BLTZ:
2742 6af0bf9c bellard
    case OPC_BLTZAL:
2743 3c824109 Nathan Froyd
    case OPC_BLTZALS:
2744 6af0bf9c bellard
    case OPC_BLTZALL:
2745 6af0bf9c bellard
    case OPC_BLTZL:
2746 6af0bf9c bellard
        /* Compare to zero */
2747 6af0bf9c bellard
        if (rs != 0) {
2748 6c5c1e20 ths
            gen_load_gpr(t0, rs);
2749 2fdbad25 aurel32
            bcond_compute = 1;
2750 6af0bf9c bellard
        }
2751 7dca4ad0 Nathan Froyd
        btgt = ctx->pc + insn_bytes + offset;
2752 6af0bf9c bellard
        break;
2753 6af0bf9c bellard
    case OPC_J:
2754 6af0bf9c bellard
    case OPC_JAL:
2755 364d4831 Nathan Froyd
    case OPC_JALX:
2756 620e48f6 Nathan Froyd
    case OPC_JALS:
2757 620e48f6 Nathan Froyd
    case OPC_JALXS:
2758 6af0bf9c bellard
        /* Jump to immediate */
2759 7dca4ad0 Nathan Froyd
        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2760 6af0bf9c bellard
        break;
2761 6af0bf9c bellard
    case OPC_JR:
2762 6af0bf9c bellard
    case OPC_JALR:
2763 364d4831 Nathan Froyd
    case OPC_JALRC:
2764 620e48f6 Nathan Froyd
    case OPC_JALRS:
2765 6af0bf9c bellard
        /* Jump to register */
2766 7a387fff ths
        if (offset != 0 && offset != 16) {
2767 7a387fff ths
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2768 cbeb0857 ths
               others are reserved. */
2769 923617a3 ths
            MIPS_INVAL("jump hint");
2770 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
2771 6c5c1e20 ths
            goto out;
2772 6af0bf9c bellard
        }
2773 d077b6f7 ths
        gen_load_gpr(btarget, rs);
2774 6af0bf9c bellard
        break;
2775 6af0bf9c bellard
    default:
2776 6af0bf9c bellard
        MIPS_INVAL("branch/jump");
2777 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
2778 6c5c1e20 ths
        goto out;
2779 6af0bf9c bellard
    }
2780 2fdbad25 aurel32
    if (bcond_compute == 0) {
2781 6af0bf9c bellard
        /* No condition to be computed */
2782 6af0bf9c bellard
        switch (opc) {
2783 6af0bf9c bellard
        case OPC_BEQ:     /* rx == rx        */
2784 6af0bf9c bellard
        case OPC_BEQL:    /* rx == rx likely */
2785 6af0bf9c bellard
        case OPC_BGEZ:    /* 0 >= 0          */
2786 6af0bf9c bellard
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2787 6af0bf9c bellard
        case OPC_BLEZ:    /* 0 <= 0          */
2788 6af0bf9c bellard
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2789 6af0bf9c bellard
            /* Always take */
2790 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
2791 6af0bf9c bellard
            MIPS_DEBUG("balways");
2792 6af0bf9c bellard
            break;
2793 3c824109 Nathan Froyd
        case OPC_BGEZALS:
2794 6af0bf9c bellard
        case OPC_BGEZAL:  /* 0 >= 0          */
2795 6af0bf9c bellard
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2796 3c824109 Nathan Froyd
            ctx->hflags |= (opc == OPC_BGEZALS
2797 3c824109 Nathan Froyd
                            ? MIPS_HFLAG_BDS16
2798 3c824109 Nathan Froyd
                            : MIPS_HFLAG_BDS32);
2799 6af0bf9c bellard
            /* Always take and link */
2800 6af0bf9c bellard
            blink = 31;
2801 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
2802 6af0bf9c bellard
            MIPS_DEBUG("balways and link");
2803 6af0bf9c bellard
            break;
2804 6af0bf9c bellard
        case OPC_BNE:     /* rx != rx        */
2805 6af0bf9c bellard
        case OPC_BGTZ:    /* 0 > 0           */
2806 6af0bf9c bellard
        case OPC_BLTZ:    /* 0 < 0           */
2807 ead9360e ths
            /* Treat as NOP. */
2808 6af0bf9c bellard
            MIPS_DEBUG("bnever (NOP)");
2809 6c5c1e20 ths
            goto out;
2810 3c824109 Nathan Froyd
        case OPC_BLTZALS:
2811 eeef26cd bellard
        case OPC_BLTZAL:  /* 0 < 0           */
2812 3c824109 Nathan Froyd
            ctx->hflags |= (opc == OPC_BLTZALS
2813 3c824109 Nathan Froyd
                            ? MIPS_HFLAG_BDS16
2814 3c824109 Nathan Froyd
                            : MIPS_HFLAG_BDS32);
2815 3c824109 Nathan Froyd
            /* Handle as an unconditional branch to get correct delay
2816 3c824109 Nathan Froyd
               slot checking.  */
2817 3c824109 Nathan Froyd
            blink = 31;
2818 3c824109 Nathan Froyd
            btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2819 3c824109 Nathan Froyd
            ctx->hflags |= MIPS_HFLAG_B;
2820 9898128f ths
            MIPS_DEBUG("bnever and link");
2821 3c824109 Nathan Froyd
            break;
2822 eeef26cd bellard
        case OPC_BLTZALL: /* 0 < 0 likely */
2823 1ba74fb8 aurel32
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2824 9898128f ths
            /* Skip the instruction in the delay slot */
2825 9898128f ths
            MIPS_DEBUG("bnever, link and skip");
2826 9898128f ths
            ctx->pc += 4;
2827 6c5c1e20 ths
            goto out;
2828 6af0bf9c bellard
        case OPC_BNEL:    /* rx != rx likely */
2829 6af0bf9c bellard
        case OPC_BGTZL:   /* 0 > 0 likely */
2830 6af0bf9c bellard
        case OPC_BLTZL:   /* 0 < 0 likely */
2831 6af0bf9c bellard
            /* Skip the instruction in the delay slot */
2832 6af0bf9c bellard
            MIPS_DEBUG("bnever and skip");
2833 9898128f ths
            ctx->pc += 4;
2834 6c5c1e20 ths
            goto out;
2835 6af0bf9c bellard
        case OPC_J:
2836 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
2837 d077b6f7 ths
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2838 6af0bf9c bellard
            break;
2839 620e48f6 Nathan Froyd
        case OPC_JALXS:
2840 364d4831 Nathan Froyd
        case OPC_JALX:
2841 364d4831 Nathan Froyd
            ctx->hflags |= MIPS_HFLAG_BX;
2842 364d4831 Nathan Froyd
            /* Fallthrough */
2843 620e48f6 Nathan Froyd
        case OPC_JALS:
2844 6af0bf9c bellard
        case OPC_JAL:
2845 6af0bf9c bellard
            blink = 31;
2846 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_B;
2847 620e48f6 Nathan Froyd
            ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2848 364d4831 Nathan Froyd
                            ? MIPS_HFLAG_BDS16
2849 364d4831 Nathan Froyd
                            : MIPS_HFLAG_BDS32);
2850 d077b6f7 ths
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2851 6af0bf9c bellard
            break;
2852 6af0bf9c bellard
        case OPC_JR:
2853 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
2854 620e48f6 Nathan Froyd
            if (insn_bytes == 4)
2855 620e48f6 Nathan Froyd
                ctx->hflags |= MIPS_HFLAG_BDS32;
2856 6af0bf9c bellard
            MIPS_DEBUG("jr %s", regnames[rs]);
2857 6af0bf9c bellard
            break;
2858 620e48f6 Nathan Froyd
        case OPC_JALRS:
2859 6af0bf9c bellard
        case OPC_JALR:
2860 364d4831 Nathan Froyd
        case OPC_JALRC:
2861 6af0bf9c bellard
            blink = rt;
2862 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BR;
2863 620e48f6 Nathan Froyd
            ctx->hflags |= (opc == OPC_JALRS
2864 620e48f6 Nathan Froyd
                            ? MIPS_HFLAG_BDS16
2865 620e48f6 Nathan Froyd
                            : MIPS_HFLAG_BDS32);
2866 6af0bf9c bellard
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2867 6af0bf9c bellard
            break;
2868 6af0bf9c bellard
        default:
2869 6af0bf9c bellard
            MIPS_INVAL("branch/jump");
2870 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
2871 6c5c1e20 ths
            goto out;
2872 6af0bf9c bellard
        }
2873 6af0bf9c bellard
    } else {
2874 6af0bf9c bellard
        switch (opc) {
2875 6af0bf9c bellard
        case OPC_BEQ:
2876 e68dd28f Aurelien Jarno
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2877 923617a3 ths
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2878 d077b6f7 ths
                       regnames[rs], regnames[rt], btgt);
2879 6af0bf9c bellard
            goto not_likely;
2880 6af0bf9c bellard
        case OPC_BEQL:
2881 e68dd28f Aurelien Jarno
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2882 923617a3 ths
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2883 d077b6f7 ths
                       regnames[rs], regnames[rt], btgt);
2884 6af0bf9c bellard
            goto likely;
2885 6af0bf9c bellard
        case OPC_BNE:
2886 e68dd28f Aurelien Jarno
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2887 923617a3 ths
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2888 d077b6f7 ths
                       regnames[rs], regnames[rt], btgt);
2889 6af0bf9c bellard
            goto not_likely;
2890 6af0bf9c bellard
        case OPC_BNEL:
2891 e68dd28f Aurelien Jarno
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2892 923617a3 ths
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2893 d077b6f7 ths
                       regnames[rs], regnames[rt], btgt);
2894 6af0bf9c bellard
            goto likely;
2895 6af0bf9c bellard
        case OPC_BGEZ:
2896 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2897 d077b6f7 ths
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2898 6af0bf9c bellard
            goto not_likely;
2899 6af0bf9c bellard
        case OPC_BGEZL:
2900 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2901 d077b6f7 ths
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2902 6af0bf9c bellard
            goto likely;
2903 3c824109 Nathan Froyd
        case OPC_BGEZALS:
2904 6af0bf9c bellard
        case OPC_BGEZAL:
2905 3c824109 Nathan Froyd
            ctx->hflags |= (opc == OPC_BGEZALS
2906 3c824109 Nathan Froyd
                            ? MIPS_HFLAG_BDS16
2907 3c824109 Nathan Froyd
                            : MIPS_HFLAG_BDS32);
2908 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2909 d077b6f7 ths
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2910 6af0bf9c bellard
            blink = 31;
2911 6af0bf9c bellard
            goto not_likely;
2912 6af0bf9c bellard
        case OPC_BGEZALL:
2913 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2914 6af0bf9c bellard
            blink = 31;
2915 d077b6f7 ths
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2916 6af0bf9c bellard
            goto likely;
2917 6af0bf9c bellard
        case OPC_BGTZ:
2918 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2919 d077b6f7 ths
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2920 6af0bf9c bellard
            goto not_likely;
2921 6af0bf9c bellard
        case OPC_BGTZL:
2922 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2923 d077b6f7 ths
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2924 6af0bf9c bellard
            goto likely;
2925 6af0bf9c bellard
        case OPC_BLEZ:
2926 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2927 d077b6f7 ths
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2928 6af0bf9c bellard
            goto not_likely;
2929 6af0bf9c bellard
        case OPC_BLEZL:
2930 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2931 d077b6f7 ths
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2932 6af0bf9c bellard
            goto likely;
2933 6af0bf9c bellard
        case OPC_BLTZ:
2934 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2935 d077b6f7 ths
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2936 6af0bf9c bellard
            goto not_likely;
2937 6af0bf9c bellard
        case OPC_BLTZL:
2938 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2939 d077b6f7 ths
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2940 6af0bf9c bellard
            goto likely;
2941 3c824109 Nathan Froyd
        case OPC_BLTZALS:
2942 6af0bf9c bellard
        case OPC_BLTZAL:
2943 3c824109 Nathan Froyd
            ctx->hflags |= (opc == OPC_BLTZALS
2944 3c824109 Nathan Froyd
                            ? MIPS_HFLAG_BDS16
2945 3c824109 Nathan Froyd
                            : MIPS_HFLAG_BDS32);
2946 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2947 6af0bf9c bellard
            blink = 31;
2948 d077b6f7 ths
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2949 6af0bf9c bellard
        not_likely:
2950 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BC;
2951 6af0bf9c bellard
            break;
2952 6af0bf9c bellard
        case OPC_BLTZALL:
2953 e68dd28f Aurelien Jarno
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2954 6af0bf9c bellard
            blink = 31;
2955 d077b6f7 ths
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2956 6af0bf9c bellard
        likely:
2957 4ad40f36 bellard
            ctx->hflags |= MIPS_HFLAG_BL;
2958 6af0bf9c bellard
            break;
2959 c53f4a62 ths
        default:
2960 c53f4a62 ths
            MIPS_INVAL("conditional branch/jump");
2961 c53f4a62 ths
            generate_exception(ctx, EXCP_RI);
2962 6c5c1e20 ths
            goto out;
2963 6af0bf9c bellard
        }
2964 6af0bf9c bellard
    }
2965 923617a3 ths
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2966 d077b6f7 ths
               blink, ctx->hflags, btgt);
2967 9b9e4393 ths
2968 d077b6f7 ths
    ctx->btarget = btgt;
2969 6af0bf9c bellard
    if (blink > 0) {
2970 364d4831 Nathan Froyd
        int post_delay = insn_bytes;
2971 364d4831 Nathan Froyd
        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2972 364d4831 Nathan Froyd
2973 364d4831 Nathan Froyd
        if (opc != OPC_JALRC)
2974 364d4831 Nathan Froyd
            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2975 364d4831 Nathan Froyd
2976 364d4831 Nathan Froyd
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2977 6af0bf9c bellard
    }
2978 6c5c1e20 ths
2979 6c5c1e20 ths
 out:
2980 364d4831 Nathan Froyd
    if (insn_bytes == 2)
2981 364d4831 Nathan Froyd
        ctx->hflags |= MIPS_HFLAG_B16;
2982 6c5c1e20 ths
    tcg_temp_free(t0);
2983 6c5c1e20 ths
    tcg_temp_free(t1);
2984 6af0bf9c bellard
}
2985 6af0bf9c bellard
2986 7a387fff ths
/* special3 bitfield operations */
2987 7a387fff ths
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2988 356265ae ths
                        int rs, int lsb, int msb)
2989 7a387fff ths
{
2990 a7812ae4 pbrook
    TCGv t0 = tcg_temp_new();
2991 a7812ae4 pbrook
    TCGv t1 = tcg_temp_new();
2992 505ad7c2 aurel32
    target_ulong mask;
2993 6c5c1e20 ths
2994 6c5c1e20 ths
    gen_load_gpr(t1, rs);
2995 7a387fff ths
    switch (opc) {
2996 7a387fff ths
    case OPC_EXT:
2997 7a387fff ths
        if (lsb + msb > 31)
2998 7a387fff ths
            goto fail;
2999 505ad7c2 aurel32
        tcg_gen_shri_tl(t0, t1, lsb);
3000 505ad7c2 aurel32
        if (msb != 31) {
3001 505ad7c2 aurel32
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3002 505ad7c2 aurel32
        } else {
3003 505ad7c2 aurel32
            tcg_gen_ext32s_tl(t0, t0);
3004 505ad7c2 aurel32
        }
3005 7a387fff ths
        break;
3006 c6d6dd7c ths
#if defined(TARGET_MIPS64)
3007 7a387fff ths
    case OPC_DEXTM:
3008 505ad7c2 aurel32
        tcg_gen_shri_tl(t0, t1, lsb);
3009 505ad7c2 aurel32
        if (msb != 31) {
3010 505ad7c2 aurel32
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3011 505ad7c2 aurel32
        }
3012 7a387fff ths
        break;
3013 7a387fff ths
    case OPC_DEXTU:
3014 505ad7c2 aurel32
        tcg_gen_shri_tl(t0, t1, lsb + 32);
3015 505ad7c2 aurel32
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3016 7a387fff ths
        break;
3017 7a387fff ths
    case OPC_DEXT:
3018 505ad7c2 aurel32
        tcg_gen_shri_tl(t0, t1, lsb);
3019 505ad7c2 aurel32
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3020 7a387fff ths
        break;
3021 c6d6dd7c ths
#endif
3022 7a387fff ths
    case OPC_INS:
3023 7a387fff ths
        if (lsb > msb)
3024 7a387fff ths
            goto fail;
3025 505ad7c2 aurel32
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3026 6c5c1e20 ths
        gen_load_gpr(t0, rt);
3027 505ad7c2 aurel32
        tcg_gen_andi_tl(t0, t0, ~mask);
3028 505ad7c2 aurel32
        tcg_gen_shli_tl(t1, t1, lsb);
3029 505ad7c2 aurel32
        tcg_gen_andi_tl(t1, t1, mask);
3030 505ad7c2 aurel32
        tcg_gen_or_tl(t0, t0, t1);
3031 505ad7c2 aurel32
        tcg_gen_ext32s_tl(t0, t0);
3032 7a387fff ths
        break;
3033 c6d6dd7c ths
#if defined(TARGET_MIPS64)
3034 7a387fff ths
    case OPC_DINSM:
3035 7a387fff ths
        if (lsb > msb)
3036 7a387fff ths
            goto fail;
3037 505ad7c2 aurel32
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3038 6c5c1e20 ths
        gen_load_gpr(t0, rt);
3039 505ad7c2 aurel32
        tcg_gen_andi_tl(t0, t0, ~mask);
3040 505ad7c2 aurel32
        tcg_gen_shli_tl(t1, t1, lsb);
3041 505ad7c2 aurel32
        tcg_gen_andi_tl(t1, t1, mask);
3042 505ad7c2 aurel32
        tcg_gen_or_tl(t0, t0, t1);
3043 7a387fff ths
        break;
3044 7a387fff ths
    case OPC_DINSU:
3045 7a387fff ths
        if (lsb > msb)
3046 7a387fff ths
            goto fail;
3047 6fbab869 Aurelien Jarno
        mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3048 6c5c1e20 ths
        gen_load_gpr(t0, rt);
3049 505ad7c2 aurel32
        tcg_gen_andi_tl(t0, t0, ~mask);
3050 505ad7c2 aurel32
        tcg_gen_shli_tl(t1, t1, lsb + 32);
3051 505ad7c2 aurel32
        tcg_gen_andi_tl(t1, t1, mask);
3052 505ad7c2 aurel32
        tcg_gen_or_tl(t0, t0, t1);
3053 7a387fff ths
        break;
3054 7a387fff ths
    case OPC_DINS:
3055 7a387fff ths
        if (lsb > msb)
3056 7a387fff ths
            goto fail;
3057 6c5c1e20 ths
        gen_load_gpr(t0, rt);
3058 505ad7c2 aurel32
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3059 505ad7c2 aurel32
        gen_load_gpr(t0, rt);
3060 505ad7c2 aurel32
        tcg_gen_andi_tl(t0, t0, ~mask);
3061 505ad7c2 aurel32
        tcg_gen_shli_tl(t1, t1, lsb);
3062 505ad7c2 aurel32
        tcg_gen_andi_tl(t1, t1, mask);
3063 505ad7c2 aurel32
        tcg_gen_or_tl(t0, t0, t1);
3064 7a387fff ths
        break;
3065 c6d6dd7c ths
#endif
3066 7a387fff ths
    default:
3067 7a387fff ths
fail:
3068 7a387fff ths
        MIPS_INVAL("bitops");
3069 7a387fff ths
        generate_exception(ctx, EXCP_RI);
3070 6c5c1e20 ths
        tcg_temp_free(t0);
3071 6c5c1e20 ths
        tcg_temp_free(t1);
3072 7a387fff ths
        return;
3073 7a387fff ths
    }
3074 6c5c1e20 ths
    gen_store_gpr(t0, rt);
3075 6c5c1e20 ths
    tcg_temp_free(t0);
3076 6c5c1e20 ths
    tcg_temp_free(t1);
3077 7a387fff ths
}
3078 7a387fff ths
3079 49bcf33c aurel32
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3080 49bcf33c aurel32
{
3081 3a55fa47 aurel32
    TCGv t0;
3082 49bcf33c aurel32
3083 3a55fa47 aurel32
    if (rd == 0) {
3084 3a55fa47 aurel32
        /* If no destination, treat it as a NOP. */
3085 3a55fa47 aurel32
        MIPS_DEBUG("NOP");
3086 3a55fa47 aurel32
        return;
3087 3a55fa47 aurel32
    }
3088 3a55fa47 aurel32
3089 3a55fa47 aurel32
    t0 = tcg_temp_new();
3090 3a55fa47 aurel32
    gen_load_gpr(t0, rt);
3091 49bcf33c aurel32
    switch (op2) {
3092 49bcf33c aurel32
    case OPC_WSBH:
3093 3a55fa47 aurel32
        {
3094 3a55fa47 aurel32
            TCGv t1 = tcg_temp_new();
3095 3a55fa47 aurel32
3096 3a55fa47 aurel32
            tcg_gen_shri_tl(t1, t0, 8);
3097 3a55fa47 aurel32
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3098 3a55fa47 aurel32
            tcg_gen_shli_tl(t0, t0, 8);
3099 3a55fa47 aurel32
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3100 3a55fa47 aurel32
            tcg_gen_or_tl(t0, t0, t1);
3101 3a55fa47 aurel32
            tcg_temp_free(t1);
3102 3a55fa47 aurel32
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3103 3a55fa47 aurel32
        }
3104 49bcf33c aurel32
        break;
3105 49bcf33c aurel32
    case OPC_SEB:
3106 3a55fa47 aurel32
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3107 49bcf33c aurel32
        break;
3108 49bcf33c aurel32
    case OPC_SEH:
3109 3a55fa47 aurel32
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3110 49bcf33c aurel32
        break;
3111 49bcf33c aurel32
#if defined(TARGET_MIPS64)
3112 49bcf33c aurel32
    case OPC_DSBH:
3113 3a55fa47 aurel32
        {
3114 3a55fa47 aurel32
            TCGv t1 = tcg_temp_new();
3115 3a55fa47 aurel32
3116 3a55fa47 aurel32
            tcg_gen_shri_tl(t1, t0, 8);
3117 3a55fa47 aurel32
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
3118 3a55fa47 aurel32
            tcg_gen_shli_tl(t0, t0, 8);
3119 3a55fa47 aurel32
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
3120 3a55fa47 aurel32
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3121 3a55fa47 aurel32
            tcg_temp_free(t1);
3122 3a55fa47 aurel32
        }
3123 49bcf33c aurel32
        break;
3124 49bcf33c aurel32
    case OPC_DSHD:
3125 3a55fa47 aurel32
        {
3126 3a55fa47 aurel32
            TCGv t1 = tcg_temp_new();
3127 3a55fa47 aurel32
3128 3a55fa47 aurel32
            tcg_gen_shri_tl(t1, t0, 16);
3129 3a55fa47 aurel32
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
3130 3a55fa47 aurel32
            tcg_gen_shli_tl(t0, t0, 16);
3131 3a55fa47 aurel32
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
3132 3a55fa47 aurel32
            tcg_gen_or_tl(t0, t0, t1);
3133 3a55fa47 aurel32
            tcg_gen_shri_tl(t1, t0, 32);
3134 3a55fa47 aurel32
            tcg_gen_shli_tl(t0, t0, 32);
3135 3a55fa47 aurel32
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3136 3a55fa47 aurel32
            tcg_temp_free(t1);
3137 3a55fa47 aurel32
        }
3138 49bcf33c aurel32
        break;
3139 49bcf33c aurel32
#endif
3140 49bcf33c aurel32
    default:
3141 49bcf33c aurel32
        MIPS_INVAL("bsfhl");
3142 49bcf33c aurel32
        generate_exception(ctx, EXCP_RI);
3143 49bcf33c aurel32
        tcg_temp_free(t0);
3144 49bcf33c aurel32
        return;
3145 49bcf33c aurel32
    }
3146 49bcf33c aurel32
    tcg_temp_free(t0);
3147 49bcf33c aurel32
}
3148 49bcf33c aurel32
3149 f1aa6320 ths
#ifndef CONFIG_USER_ONLY
3150 0eaef5aa ths
/* CP0 (MMU and control) */
3151 d9bea114 aurel32
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
3152 4f57689a ths
{
3153 d9bea114 aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();
3154 4f57689a ths
3155 d9bea114 aurel32
    tcg_gen_ld_i32(t0, cpu_env, off);
3156 d9bea114 aurel32
    tcg_gen_ext_i32_tl(arg, t0);
3157 d9bea114 aurel32
    tcg_temp_free_i32(t0);
3158 4f57689a ths
}
3159 4f57689a ths
3160 d9bea114 aurel32
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
3161 4f57689a ths
{
3162 d9bea114 aurel32
    tcg_gen_ld_tl(arg, cpu_env, off);
3163 d9bea114 aurel32
    tcg_gen_ext32s_tl(arg, arg);
3164 4f57689a ths
}
3165 4f57689a ths
3166 d9bea114 aurel32
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
3167 f1aa6320 ths
{
3168 d9bea114 aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();
3169 f1aa6320 ths
3170 d9bea114 aurel32
    tcg_gen_trunc_tl_i32(t0, arg);
3171 d9bea114 aurel32
    tcg_gen_st_i32(t0, cpu_env, off);
3172 d9bea114 aurel32
    tcg_temp_free_i32(t0);
3173 f1aa6320 ths
}
3174 f1aa6320 ths
3175 d9bea114 aurel32
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
3176 f1aa6320 ths
{
3177 d9bea114 aurel32
    tcg_gen_ext32s_tl(arg, arg);
3178 d9bea114 aurel32
    tcg_gen_st_tl(arg, cpu_env, off);
3179 f1aa6320 ths
}
3180 f1aa6320 ths
3181 d9bea114 aurel32
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3182 873eb012 ths
{
3183 7a387fff ths
    const char *rn = "invalid";
3184 873eb012 ths
3185 e189e748 ths
    if (sel != 0)
3186 e189e748 ths
        check_insn(env, ctx, ISA_MIPS32);
3187 e189e748 ths
3188 873eb012 ths
    switch (reg) {
3189 873eb012 ths
    case 0:
3190 7a387fff ths
        switch (sel) {
3191 7a387fff ths
        case 0:
3192 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
3193 7a387fff ths
            rn = "Index";
3194 7a387fff ths
            break;
3195 7a387fff ths
        case 1:
3196 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3197 d9bea114 aurel32
            gen_helper_mfc0_mvpcontrol(arg);
3198 7a387fff ths
            rn = "MVPControl";
3199 ead9360e ths
            break;
3200 7a387fff ths
        case 2:
3201 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3202 d9bea114 aurel32
            gen_helper_mfc0_mvpconf0(arg);
3203 7a387fff ths
            rn = "MVPConf0";
3204 ead9360e ths
            break;
3205 7a387fff ths
        case 3:
3206 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3207 d9bea114 aurel32
            gen_helper_mfc0_mvpconf1(arg);
3208 7a387fff ths
            rn = "MVPConf1";
3209 ead9360e ths
            break;
3210 7a387fff ths
        default:
3211 7a387fff ths
            goto die;
3212 7a387fff ths
        }
3213 873eb012 ths
        break;
3214 873eb012 ths
    case 1:
3215 7a387fff ths
        switch (sel) {
3216 7a387fff ths
        case 0:
3217 d9bea114 aurel32
            gen_helper_mfc0_random(arg);
3218 7a387fff ths
            rn = "Random";
3219 2423f660 ths
            break;
3220 7a387fff ths
        case 1:
3221 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3222 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
3223 7a387fff ths
            rn = "VPEControl";
3224 ead9360e ths
            break;
3225 7a387fff ths
        case 2:
3226 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3227 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
3228 7a387fff ths
            rn = "VPEConf0";
3229 ead9360e ths
            break;
3230 7a387fff ths
        case 3:
3231 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3232 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
3233 7a387fff ths
            rn = "VPEConf1";
3234 ead9360e ths
            break;
3235 7a387fff ths
        case 4:
3236 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3237 d9bea114 aurel32
            gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
3238 7a387fff ths
            rn = "YQMask";
3239 ead9360e ths
            break;
3240 7a387fff ths
        case 5:
3241 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3242 d9bea114 aurel32
            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
3243 7a387fff ths
            rn = "VPESchedule";
3244 ead9360e ths
            break;
3245 7a387fff ths
        case 6:
3246 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3247 d9bea114 aurel32
            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3248 7a387fff ths
            rn = "VPEScheFBack";
3249 ead9360e ths
            break;
3250 7a387fff ths
        case 7:
3251 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3252 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
3253 7a387fff ths
            rn = "VPEOpt";
3254 ead9360e ths
            break;
3255 7a387fff ths
        default:
3256 7a387fff ths
            goto die;
3257 7a387fff ths
        }
3258 873eb012 ths
        break;
3259 873eb012 ths
    case 2:
3260 7a387fff ths
        switch (sel) {
3261 7a387fff ths
        case 0:
3262 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
3263 d9bea114 aurel32
            tcg_gen_ext32s_tl(arg, arg);
3264 2423f660 ths
            rn = "EntryLo0";
3265 2423f660 ths
            break;
3266 7a387fff ths
        case 1:
3267 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3268 d9bea114 aurel32
            gen_helper_mfc0_tcstatus(arg);
3269 2423f660 ths
            rn = "TCStatus";
3270 ead9360e ths
            break;
3271 7a387fff ths
        case 2:
3272 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3273 d9bea114 aurel32
            gen_helper_mfc0_tcbind(arg);
3274 2423f660 ths
            rn = "TCBind";
3275 ead9360e ths
            break;
3276 7a387fff ths
        case 3:
3277 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3278 d9bea114 aurel32
            gen_helper_mfc0_tcrestart(arg);
3279 2423f660 ths
            rn = "TCRestart";
3280 ead9360e ths
            break;
3281 7a387fff ths
        case 4:
3282 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3283 d9bea114 aurel32
            gen_helper_mfc0_tchalt(arg);
3284 2423f660 ths
            rn = "TCHalt";
3285 ead9360e ths
            break;
3286 7a387fff ths
        case 5:
3287 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3288 d9bea114 aurel32
            gen_helper_mfc0_tccontext(arg);
3289 2423f660 ths
            rn = "TCContext";
3290 ead9360e ths
            break;
3291 7a387fff ths
        case 6:
3292 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3293 d9bea114 aurel32
            gen_helper_mfc0_tcschedule(arg);
3294 2423f660 ths
            rn = "TCSchedule";
3295 ead9360e ths
            break;
3296 7a387fff ths
        case 7:
3297 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3298 d9bea114 aurel32
            gen_helper_mfc0_tcschefback(arg);
3299 2423f660 ths
            rn = "TCScheFBack";
3300 ead9360e ths
            break;
3301 7a387fff ths
        default:
3302 7a387fff ths
            goto die;
3303 7a387fff ths
        }
3304 873eb012 ths
        break;
3305 873eb012 ths
    case 3:
3306 7a387fff ths
        switch (sel) {
3307 7a387fff ths
        case 0:
3308 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3309 d9bea114 aurel32
            tcg_gen_ext32s_tl(arg, arg);
3310 2423f660 ths
            rn = "EntryLo1";
3311 2423f660 ths
            break;
3312 7a387fff ths
        default:
3313 7a387fff ths
            goto die;
3314 1579a72e ths
        }
3315 873eb012 ths
        break;
3316 873eb012 ths
    case 4:
3317 7a387fff ths
        switch (sel) {
3318 7a387fff ths
        case 0:
3319 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3320 d9bea114 aurel32
            tcg_gen_ext32s_tl(arg, arg);
3321 2423f660 ths
            rn = "Context";
3322 2423f660 ths
            break;
3323 7a387fff ths
        case 1:
3324 d9bea114 aurel32
//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3325 2423f660 ths
            rn = "ContextConfig";
3326 2423f660 ths
//            break;
3327 7a387fff ths
        default:
3328 7a387fff ths
            goto die;
3329 1579a72e ths
        }
3330 873eb012 ths
        break;
3331 873eb012 ths
    case 5:
3332 7a387fff ths
        switch (sel) {
3333 7a387fff ths
        case 0:
3334 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3335 2423f660 ths
            rn = "PageMask";
3336 2423f660 ths
            break;
3337 7a387fff ths
        case 1:
3338 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3339 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3340 2423f660 ths
            rn = "PageGrain";
3341 2423f660 ths
            break;
3342 7a387fff ths
        default:
3343 7a387fff ths
            goto die;
3344 1579a72e ths
        }
3345 873eb012 ths
        break;
3346 873eb012 ths
    case 6:
3347 7a387fff ths
        switch (sel) {
3348 7a387fff ths
        case 0:
3349 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3350 2423f660 ths
            rn = "Wired";
3351 2423f660 ths
            break;
3352 7a387fff ths
        case 1:
3353 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3354 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3355 2423f660 ths
            rn = "SRSConf0";
3356 ead9360e ths
            break;
3357 7a387fff ths
        case 2:
3358 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3359 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3360 2423f660 ths
            rn = "SRSConf1";
3361 ead9360e ths
            break;
3362 7a387fff ths
        case 3:
3363 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3364 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3365 2423f660 ths
            rn = "SRSConf2";
3366 ead9360e ths
            break;
3367 7a387fff ths
        case 4:
3368 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3369 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3370 2423f660 ths
            rn = "SRSConf3";
3371 ead9360e ths
            break;
3372 7a387fff ths
        case 5:
3373 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3374 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3375 2423f660 ths
            rn = "SRSConf4";
3376 ead9360e ths
            break;
3377 7a387fff ths
        default:
3378 7a387fff ths
            goto die;
3379 1579a72e ths
        }
3380 873eb012 ths
        break;
3381 8c0fdd85 ths
    case 7:
3382 7a387fff ths
        switch (sel) {
3383 7a387fff ths
        case 0:
3384 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3385 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3386 2423f660 ths
            rn = "HWREna";
3387 2423f660 ths
            break;
3388 7a387fff ths
        default:
3389 7a387fff ths
            goto die;
3390 1579a72e ths
        }
3391 8c0fdd85 ths
        break;
3392 873eb012 ths
    case 8:
3393 7a387fff ths
        switch (sel) {
3394 7a387fff ths
        case 0:
3395 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3396 d9bea114 aurel32
            tcg_gen_ext32s_tl(arg, arg);
3397 f0b3f3ae ths
            rn = "BadVAddr";
3398 2423f660 ths
            break;
3399 7a387fff ths
        default:
3400 7a387fff ths
            goto die;
3401 7a387fff ths
       }
3402 873eb012 ths
        break;
3403 873eb012 ths
    case 9:
3404 7a387fff ths
        switch (sel) {
3405 7a387fff ths
        case 0:
3406 2e70f6ef pbrook
            /* Mark as an IO operation because we read the time.  */
3407 2e70f6ef pbrook
            if (use_icount)
3408 2e70f6ef pbrook
                gen_io_start();
3409 d9bea114 aurel32
            gen_helper_mfc0_count(arg);
3410 2e70f6ef pbrook
            if (use_icount) {
3411 2e70f6ef pbrook
                gen_io_end();
3412 2e70f6ef pbrook
            }
3413 55807224 Edgar E. Iglesias
            /* Break the TB to be able to take timer interrupts immediately
3414 55807224 Edgar E. Iglesias
               after reading count.  */
3415 55807224 Edgar E. Iglesias
            ctx->bstate = BS_STOP;
3416 2423f660 ths
            rn = "Count";
3417 2423f660 ths
            break;
3418 2423f660 ths
        /* 6,7 are implementation dependent */
3419 7a387fff ths
        default:
3420 7a387fff ths
            goto die;
3421 2423f660 ths
        }
3422 873eb012 ths
        break;
3423 873eb012 ths
    case 10:
3424 7a387fff ths
        switch (sel) {
3425 7a387fff ths
        case 0:
3426 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3427 d9bea114 aurel32
            tcg_gen_ext32s_tl(arg, arg);
3428 2423f660 ths
            rn = "EntryHi";
3429 2423f660 ths
            break;
3430 7a387fff ths
        default:
3431 7a387fff ths
            goto die;
3432 1579a72e ths
        }
3433 873eb012 ths
        break;
3434 873eb012 ths
    case 11:
3435 7a387fff ths
        switch (sel) {
3436 7a387fff ths
        case 0:
3437 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3438 2423f660 ths
            rn = "Compare";
3439 2423f660 ths
            break;
3440 2423f660 ths
        /* 6,7 are implementation dependent */
3441 7a387fff ths
        default:
3442 7a387fff ths
            goto die;
3443 2423f660 ths
        }
3444 873eb012 ths
        break;
3445 873eb012 ths
    case 12:
3446 7a387fff ths
        switch (sel) {
3447 7a387fff ths
        case 0:
3448 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3449 2423f660 ths
            rn = "Status";
3450 2423f660 ths
            break;
3451 7a387fff ths
        case 1:
3452 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3453 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3454 2423f660 ths
            rn = "IntCtl";
3455 2423f660 ths
            break;
3456 7a387fff ths
        case 2:
3457 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3458 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3459 2423f660 ths
            rn = "SRSCtl";
3460 2423f660 ths
            break;
3461 7a387fff ths
        case 3:
3462 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3463 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3464 2423f660 ths
            rn = "SRSMap";
3465 fd88b6ab ths
            break;
3466 7a387fff ths
        default:
3467 7a387fff ths
            goto die;
3468 7a387fff ths
       }
3469 873eb012 ths
        break;
3470 873eb012 ths
    case 13:
3471 7a387fff ths
        switch (sel) {
3472 7a387fff ths
        case 0:
3473 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3474 2423f660 ths
            rn = "Cause";
3475 2423f660 ths
            break;
3476 7a387fff ths
        default:
3477 7a387fff ths
            goto die;
3478 7a387fff ths
       }
3479 873eb012 ths
        break;
3480 873eb012 ths
    case 14:
3481 7a387fff ths
        switch (sel) {
3482 7a387fff ths
        case 0:
3483 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3484 d9bea114 aurel32
            tcg_gen_ext32s_tl(arg, arg);
3485 2423f660 ths
            rn = "EPC";
3486 2423f660 ths
            break;
3487 7a387fff ths
        default:
3488 7a387fff ths
            goto die;
3489 1579a72e ths
        }
3490 873eb012 ths
        break;
3491 873eb012 ths
    case 15:
3492 7a387fff ths
        switch (sel) {
3493 7a387fff ths
        case 0:
3494 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3495 2423f660 ths
            rn = "PRid";
3496 2423f660 ths
            break;
3497 7a387fff ths
        case 1:
3498 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3499 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3500 2423f660 ths
            rn = "EBase";
3501 2423f660 ths
            break;
3502 7a387fff ths
        default:
3503 7a387fff ths
            goto die;
3504 7a387fff ths
       }
3505 873eb012 ths
        break;
3506 873eb012 ths
    case 16:
3507 873eb012 ths
        switch (sel) {
3508 873eb012 ths
        case 0:
3509 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3510 873eb012 ths
            rn = "Config";
3511 873eb012 ths
            break;
3512 873eb012 ths
        case 1:
3513 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3514 873eb012 ths
            rn = "Config1";
3515 873eb012 ths
            break;
3516 7a387fff ths
        case 2:
3517 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3518 7a387fff ths
            rn = "Config2";
3519 7a387fff ths
            break;
3520 7a387fff ths
        case 3:
3521 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3522 7a387fff ths
            rn = "Config3";
3523 7a387fff ths
            break;
3524 e397ee33 ths
        /* 4,5 are reserved */
3525 e397ee33 ths
        /* 6,7 are implementation dependent */
3526 e397ee33 ths
        case 6:
3527 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3528 e397ee33 ths
            rn = "Config6";
3529 e397ee33 ths
            break;
3530 e397ee33 ths
        case 7:
3531 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3532 e397ee33 ths
            rn = "Config7";
3533 e397ee33 ths
            break;
3534 873eb012 ths
        default:
3535 873eb012 ths
            goto die;
3536 873eb012 ths
        }
3537 873eb012 ths
        break;
3538 873eb012 ths
    case 17:
3539 7a387fff ths
        switch (sel) {
3540 7a387fff ths
        case 0:
3541 d9bea114 aurel32
            gen_helper_mfc0_lladdr(arg);
3542 2423f660 ths
            rn = "LLAddr";
3543 2423f660 ths
            break;
3544 7a387fff ths
        default:
3545 7a387fff ths
            goto die;
3546 7a387fff ths
        }
3547 873eb012 ths
        break;
3548 873eb012 ths
    case 18:
3549 7a387fff ths
        switch (sel) {
3550 fd88b6ab ths
        case 0 ... 7:
3551 d9bea114 aurel32
            gen_helper_1i(mfc0_watchlo, arg, sel);
3552 2423f660 ths
            rn = "WatchLo";
3553 2423f660 ths
            break;
3554 7a387fff ths
        default:
3555 7a387fff ths
            goto die;
3556 7a387fff ths
        }
3557 873eb012 ths
        break;
3558 873eb012 ths
    case 19:
3559 7a387fff ths
        switch (sel) {
3560 fd88b6ab ths
        case 0 ...7:
3561 d9bea114 aurel32
            gen_helper_1i(mfc0_watchhi, arg, sel);
3562 2423f660 ths
            rn = "WatchHi";
3563 2423f660 ths
            break;
3564 7a387fff ths
        default:
3565 7a387fff ths
            goto die;
3566 7a387fff ths
        }
3567 873eb012 ths
        break;
3568 8c0fdd85 ths
    case 20:
3569 7a387fff ths
        switch (sel) {
3570 7a387fff ths
        case 0:
3571 d26bc211 ths
#if defined(TARGET_MIPS64)
3572 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
3573 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3574 d9bea114 aurel32
            tcg_gen_ext32s_tl(arg, arg);
3575 2423f660 ths
            rn = "XContext";
3576 2423f660 ths
            break;
3577 703eaf37 ths
#endif
3578 7a387fff ths
        default:
3579 7a387fff ths
            goto die;
3580 7a387fff ths
        }
3581 8c0fdd85 ths
        break;
3582 8c0fdd85 ths
    case 21:
3583 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3584 7a387fff ths
        switch (sel) {
3585 7a387fff ths
        case 0:
3586 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3587 2423f660 ths
            rn = "Framemask";
3588 2423f660 ths
            break;
3589 7a387fff ths
        default:
3590 7a387fff ths
            goto die;
3591 7a387fff ths
        }
3592 8c0fdd85 ths
        break;
3593 8c0fdd85 ths
    case 22:
3594 d9bea114 aurel32
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3595 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
3596 2423f660 ths
        break;
3597 873eb012 ths
    case 23:
3598 7a387fff ths
        switch (sel) {
3599 7a387fff ths
        case 0:
3600 d9bea114 aurel32
            gen_helper_mfc0_debug(arg); /* EJTAG support */
3601 2423f660 ths
            rn = "Debug";
3602 2423f660 ths
            break;
3603 7a387fff ths
        case 1:
3604 d9bea114 aurel32
//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3605 2423f660 ths
            rn = "TraceControl";
3606 2423f660 ths
//            break;
3607 7a387fff ths
        case 2:
3608 d9bea114 aurel32
//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3609 2423f660 ths
            rn = "TraceControl2";
3610 2423f660 ths
//            break;
3611 7a387fff ths
        case 3:
3612 d9bea114 aurel32
//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3613 2423f660 ths
            rn = "UserTraceData";
3614 2423f660 ths
//            break;
3615 7a387fff ths
        case 4:
3616 d9bea114 aurel32
//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3617 2423f660 ths
            rn = "TraceBPC";
3618 2423f660 ths
//            break;
3619 7a387fff ths
        default:
3620 7a387fff ths
            goto die;
3621 7a387fff ths
        }
3622 873eb012 ths
        break;
3623 873eb012 ths
    case 24:
3624 7a387fff ths
        switch (sel) {
3625 7a387fff ths
        case 0:
3626 f0b3f3ae ths
            /* EJTAG support */
3627 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3628 d9bea114 aurel32
            tcg_gen_ext32s_tl(arg, arg);
3629 2423f660 ths
            rn = "DEPC";
3630 2423f660 ths
            break;
3631 7a387fff ths
        default:
3632 7a387fff ths
            goto die;
3633 7a387fff ths
        }
3634 873eb012 ths
        break;
3635 8c0fdd85 ths
    case 25:
3636 7a387fff ths
        switch (sel) {
3637 7a387fff ths
        case 0:
3638 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3639 2423f660 ths
            rn = "Performance0";
3640 7a387fff ths
            break;
3641 7a387fff ths
        case 1:
3642 d9bea114 aurel32
//            gen_helper_mfc0_performance1(arg);
3643 2423f660 ths
            rn = "Performance1";
3644 2423f660 ths
//            break;
3645 7a387fff ths
        case 2:
3646 d9bea114 aurel32
//            gen_helper_mfc0_performance2(arg);
3647 2423f660 ths
            rn = "Performance2";
3648 2423f660 ths
//            break;
3649 7a387fff ths
        case 3:
3650 d9bea114 aurel32
//            gen_helper_mfc0_performance3(arg);
3651 2423f660 ths
            rn = "Performance3";
3652 2423f660 ths
//            break;
3653 7a387fff ths
        case 4:
3654 d9bea114 aurel32
//            gen_helper_mfc0_performance4(arg);
3655 2423f660 ths
            rn = "Performance4";
3656 2423f660 ths
//            break;
3657 7a387fff ths
        case 5:
3658 d9bea114 aurel32
//            gen_helper_mfc0_performance5(arg);
3659 2423f660 ths
            rn = "Performance5";
3660 2423f660 ths
//            break;
3661 7a387fff ths
        case 6:
3662 d9bea114 aurel32
//            gen_helper_mfc0_performance6(arg);
3663 2423f660 ths
            rn = "Performance6";
3664 2423f660 ths
//            break;
3665 7a387fff ths
        case 7:
3666 d9bea114 aurel32
//            gen_helper_mfc0_performance7(arg);
3667 2423f660 ths
            rn = "Performance7";
3668 2423f660 ths
//            break;
3669 7a387fff ths
        default:
3670 7a387fff ths
            goto die;
3671 7a387fff ths
        }
3672 8c0fdd85 ths
        break;
3673 8c0fdd85 ths
    case 26:
3674 d9bea114 aurel32
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3675 da80682b aurel32
        rn = "ECC";
3676 da80682b aurel32
        break;
3677 8c0fdd85 ths
    case 27:
3678 7a387fff ths
        switch (sel) {
3679 7a387fff ths
        case 0 ... 3:
3680 d9bea114 aurel32
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
3681 2423f660 ths
            rn = "CacheErr";
3682 2423f660 ths
            break;
3683 7a387fff ths
        default:
3684 7a387fff ths
            goto die;
3685 7a387fff ths
        }
3686 8c0fdd85 ths
        break;
3687 873eb012 ths
    case 28:
3688 873eb012 ths
        switch (sel) {
3689 873eb012 ths
        case 0:
3690 7a387fff ths
        case 2:
3691 7a387fff ths
        case 4:
3692 7a387fff ths
        case 6:
3693 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3694 873eb012 ths
            rn = "TagLo";
3695 873eb012 ths
            break;
3696 873eb012 ths
        case 1:
3697 7a387fff ths
        case 3:
3698 7a387fff ths
        case 5:
3699 7a387fff ths
        case 7:
3700 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3701 873eb012 ths
            rn = "DataLo";
3702 873eb012 ths
            break;
3703 873eb012 ths
        default:
3704 873eb012 ths
            goto die;
3705 873eb012 ths
        }
3706 873eb012 ths
        break;
3707 8c0fdd85 ths
    case 29:
3708 7a387fff ths
        switch (sel) {
3709 7a387fff ths
        case 0:
3710 7a387fff ths
        case 2:
3711 7a387fff ths
        case 4:
3712 7a387fff ths
        case 6:
3713 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3714 7a387fff ths
            rn = "TagHi";
3715 7a387fff ths
            break;
3716 7a387fff ths
        case 1:
3717 7a387fff ths
        case 3:
3718 7a387fff ths
        case 5:
3719 7a387fff ths
        case 7:
3720 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3721 7a387fff ths
            rn = "DataHi";
3722 7a387fff ths
            break;
3723 7a387fff ths
        default:
3724 7a387fff ths
            goto die;
3725 7a387fff ths
        }
3726 8c0fdd85 ths
        break;
3727 873eb012 ths
    case 30:
3728 7a387fff ths
        switch (sel) {
3729 7a387fff ths
        case 0:
3730 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3731 d9bea114 aurel32
            tcg_gen_ext32s_tl(arg, arg);
3732 2423f660 ths
            rn = "ErrorEPC";
3733 2423f660 ths
            break;
3734 7a387fff ths
        default:
3735 7a387fff ths
            goto die;
3736 7a387fff ths
        }
3737 873eb012 ths
        break;
3738 873eb012 ths
    case 31:
3739 7a387fff ths
        switch (sel) {
3740 7a387fff ths
        case 0:
3741 f0b3f3ae ths
            /* EJTAG support */
3742 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3743 2423f660 ths
            rn = "DESAVE";
3744 2423f660 ths
            break;
3745 7a387fff ths
        default:
3746 7a387fff ths
            goto die;
3747 7a387fff ths
        }
3748 873eb012 ths
        break;
3749 873eb012 ths
    default:
3750 873eb012 ths
       goto die;
3751 873eb012 ths
    }
3752 2abf314d Blue Swirl
    (void)rn; /* avoid a compiler warning */
3753 d12d51d5 aliguori
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3754 873eb012 ths
    return;
3755 873eb012 ths
3756 873eb012 ths
die:
3757 d12d51d5 aliguori
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3758 873eb012 ths
    generate_exception(ctx, EXCP_RI);
3759 873eb012 ths
}
3760 873eb012 ths
3761 d9bea114 aurel32
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3762 8c0fdd85 ths
{
3763 7a387fff ths
    const char *rn = "invalid";
3764 7a387fff ths
3765 e189e748 ths
    if (sel != 0)
3766 e189e748 ths
        check_insn(env, ctx, ISA_MIPS32);
3767 e189e748 ths
3768 2e70f6ef pbrook
    if (use_icount)
3769 2e70f6ef pbrook
        gen_io_start();
3770 2e70f6ef pbrook
3771 8c0fdd85 ths
    switch (reg) {
3772 8c0fdd85 ths
    case 0:
3773 7a387fff ths
        switch (sel) {
3774 7a387fff ths
        case 0:
3775 d9bea114 aurel32
            gen_helper_mtc0_index(arg);
3776 7a387fff ths
            rn = "Index";
3777 7a387fff ths
            break;
3778 7a387fff ths
        case 1:
3779 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3780 d9bea114 aurel32
            gen_helper_mtc0_mvpcontrol(arg);
3781 7a387fff ths
            rn = "MVPControl";
3782 ead9360e ths
            break;
3783 7a387fff ths
        case 2:
3784 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3785 ead9360e ths
            /* ignored */
3786 7a387fff ths
            rn = "MVPConf0";
3787 ead9360e ths
            break;
3788 7a387fff ths
        case 3:
3789 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3790 ead9360e ths
            /* ignored */
3791 7a387fff ths
            rn = "MVPConf1";
3792 ead9360e ths
            break;
3793 7a387fff ths
        default:
3794 7a387fff ths
            goto die;
3795 7a387fff ths
        }
3796 8c0fdd85 ths
        break;
3797 8c0fdd85 ths
    case 1:
3798 7a387fff ths
        switch (sel) {
3799 7a387fff ths
        case 0:
3800 2423f660 ths
            /* ignored */
3801 7a387fff ths
            rn = "Random";
3802 2423f660 ths
            break;
3803 7a387fff ths
        case 1:
3804 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3805 d9bea114 aurel32
            gen_helper_mtc0_vpecontrol(arg);
3806 7a387fff ths
            rn = "VPEControl";
3807 ead9360e ths
            break;
3808 7a387fff ths
        case 2:
3809 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3810 d9bea114 aurel32
            gen_helper_mtc0_vpeconf0(arg);
3811 7a387fff ths
            rn = "VPEConf0";
3812 ead9360e ths
            break;
3813 7a387fff ths
        case 3:
3814 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3815 d9bea114 aurel32
            gen_helper_mtc0_vpeconf1(arg);
3816 7a387fff ths
            rn = "VPEConf1";
3817 ead9360e ths
            break;
3818 7a387fff ths
        case 4:
3819 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3820 d9bea114 aurel32
            gen_helper_mtc0_yqmask(arg);
3821 7a387fff ths
            rn = "YQMask";
3822 ead9360e ths
            break;
3823 7a387fff ths
        case 5:
3824 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3825 d9bea114 aurel32
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3826 7a387fff ths
            rn = "VPESchedule";
3827 ead9360e ths
            break;
3828 7a387fff ths
        case 6:
3829 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3830 d9bea114 aurel32
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3831 7a387fff ths
            rn = "VPEScheFBack";
3832 ead9360e ths
            break;
3833 7a387fff ths
        case 7:
3834 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3835 d9bea114 aurel32
            gen_helper_mtc0_vpeopt(arg);
3836 7a387fff ths
            rn = "VPEOpt";
3837 ead9360e ths
            break;
3838 7a387fff ths
        default:
3839 7a387fff ths
            goto die;
3840 7a387fff ths
        }
3841 8c0fdd85 ths
        break;
3842 8c0fdd85 ths
    case 2:
3843 7a387fff ths
        switch (sel) {
3844 7a387fff ths
        case 0:
3845 d9bea114 aurel32
            gen_helper_mtc0_entrylo0(arg);
3846 2423f660 ths
            rn = "EntryLo0";
3847 2423f660 ths
            break;
3848 7a387fff ths
        case 1:
3849 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3850 d9bea114 aurel32
            gen_helper_mtc0_tcstatus(arg);
3851 2423f660 ths
            rn = "TCStatus";
3852 ead9360e ths
            break;
3853 7a387fff ths
        case 2:
3854 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3855 d9bea114 aurel32
            gen_helper_mtc0_tcbind(arg);
3856 2423f660 ths
            rn = "TCBind";
3857 ead9360e ths
            break;
3858 7a387fff ths
        case 3:
3859 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3860 d9bea114 aurel32
            gen_helper_mtc0_tcrestart(arg);
3861 2423f660 ths
            rn = "TCRestart";
3862 ead9360e ths
            break;
3863 7a387fff ths
        case 4:
3864 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3865 d9bea114 aurel32
            gen_helper_mtc0_tchalt(arg);
3866 2423f660 ths
            rn = "TCHalt";
3867 ead9360e ths
            break;
3868 7a387fff ths
        case 5:
3869 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3870 d9bea114 aurel32
            gen_helper_mtc0_tccontext(arg);
3871 2423f660 ths
            rn = "TCContext";
3872 ead9360e ths
            break;
3873 7a387fff ths
        case 6:
3874 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3875 d9bea114 aurel32
            gen_helper_mtc0_tcschedule(arg);
3876 2423f660 ths
            rn = "TCSchedule";
3877 ead9360e ths
            break;
3878 7a387fff ths
        case 7:
3879 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
3880 d9bea114 aurel32
            gen_helper_mtc0_tcschefback(arg);
3881 2423f660 ths
            rn = "TCScheFBack";
3882 ead9360e ths
            break;
3883 7a387fff ths
        default:
3884 7a387fff ths
            goto die;
3885 7a387fff ths
        }
3886 8c0fdd85 ths
        break;
3887 8c0fdd85 ths
    case 3:
3888 7a387fff ths
        switch (sel) {
3889 7a387fff ths
        case 0:
3890 d9bea114 aurel32
            gen_helper_mtc0_entrylo1(arg);
3891 2423f660 ths
            rn = "EntryLo1";
3892 2423f660 ths
            break;
3893 7a387fff ths
        default:
3894 7a387fff ths
            goto die;
3895 876d4b07 ths
        }
3896 8c0fdd85 ths
        break;
3897 8c0fdd85 ths
    case 4:
3898 7a387fff ths
        switch (sel) {
3899 7a387fff ths
        case 0:
3900 d9bea114 aurel32
            gen_helper_mtc0_context(arg);
3901 2423f660 ths
            rn = "Context";
3902 2423f660 ths
            break;
3903 7a387fff ths
        case 1:
3904 d9bea114 aurel32
//            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3905 2423f660 ths
            rn = "ContextConfig";
3906 2423f660 ths
//            break;
3907 7a387fff ths
        default:
3908 7a387fff ths
            goto die;
3909 876d4b07 ths
        }
3910 8c0fdd85 ths
        break;
3911 8c0fdd85 ths
    case 5:
3912 7a387fff ths
        switch (sel) {
3913 7a387fff ths
        case 0:
3914 d9bea114 aurel32
            gen_helper_mtc0_pagemask(arg);
3915 2423f660 ths
            rn = "PageMask";
3916 2423f660 ths
            break;
3917 7a387fff ths
        case 1:
3918 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3919 d9bea114 aurel32
            gen_helper_mtc0_pagegrain(arg);
3920 2423f660 ths
            rn = "PageGrain";
3921 2423f660 ths
            break;
3922 7a387fff ths
        default:
3923 7a387fff ths
            goto die;
3924 876d4b07 ths
        }
3925 8c0fdd85 ths
        break;
3926 8c0fdd85 ths
    case 6:
3927 7a387fff ths
        switch (sel) {
3928 7a387fff ths
        case 0:
3929 d9bea114 aurel32
            gen_helper_mtc0_wired(arg);
3930 2423f660 ths
            rn = "Wired";
3931 2423f660 ths
            break;
3932 7a387fff ths
        case 1:
3933 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3934 d9bea114 aurel32
            gen_helper_mtc0_srsconf0(arg);
3935 2423f660 ths
            rn = "SRSConf0";
3936 ead9360e ths
            break;
3937 7a387fff ths
        case 2:
3938 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3939 d9bea114 aurel32
            gen_helper_mtc0_srsconf1(arg);
3940 2423f660 ths
            rn = "SRSConf1";
3941 ead9360e ths
            break;
3942 7a387fff ths
        case 3:
3943 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3944 d9bea114 aurel32
            gen_helper_mtc0_srsconf2(arg);
3945 2423f660 ths
            rn = "SRSConf2";
3946 ead9360e ths
            break;
3947 7a387fff ths
        case 4:
3948 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3949 d9bea114 aurel32
            gen_helper_mtc0_srsconf3(arg);
3950 2423f660 ths
            rn = "SRSConf3";
3951 ead9360e ths
            break;
3952 7a387fff ths
        case 5:
3953 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3954 d9bea114 aurel32
            gen_helper_mtc0_srsconf4(arg);
3955 2423f660 ths
            rn = "SRSConf4";
3956 ead9360e ths
            break;
3957 7a387fff ths
        default:
3958 7a387fff ths
            goto die;
3959 876d4b07 ths
        }
3960 8c0fdd85 ths
        break;
3961 8c0fdd85 ths
    case 7:
3962 7a387fff ths
        switch (sel) {
3963 7a387fff ths
        case 0:
3964 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
3965 d9bea114 aurel32
            gen_helper_mtc0_hwrena(arg);
3966 2423f660 ths
            rn = "HWREna";
3967 2423f660 ths
            break;
3968 7a387fff ths
        default:
3969 7a387fff ths
            goto die;
3970 876d4b07 ths
        }
3971 8c0fdd85 ths
        break;
3972 8c0fdd85 ths
    case 8:
3973 7a387fff ths
        /* ignored */
3974 f0b3f3ae ths
        rn = "BadVAddr";
3975 8c0fdd85 ths
        break;
3976 8c0fdd85 ths
    case 9:
3977 7a387fff ths
        switch (sel) {
3978 7a387fff ths
        case 0:
3979 d9bea114 aurel32
            gen_helper_mtc0_count(arg);
3980 2423f660 ths
            rn = "Count";
3981 2423f660 ths
            break;
3982 876d4b07 ths
        /* 6,7 are implementation dependent */
3983 7a387fff ths
        default:
3984 7a387fff ths
            goto die;
3985 876d4b07 ths
        }
3986 8c0fdd85 ths
        break;
3987 8c0fdd85 ths
    case 10:
3988 7a387fff ths
        switch (sel) {
3989 7a387fff ths
        case 0:
3990 d9bea114 aurel32
            gen_helper_mtc0_entryhi(arg);
3991 2423f660 ths
            rn = "EntryHi";
3992 2423f660 ths
            break;
3993 7a387fff ths
        default:
3994 7a387fff ths
            goto die;
3995 876d4b07 ths
        }
3996 8c0fdd85 ths
        break;
3997 8c0fdd85 ths
    case 11:
3998 7a387fff ths
        switch (sel) {
3999 7a387fff ths
        case 0:
4000 d9bea114 aurel32
            gen_helper_mtc0_compare(arg);
4001 2423f660 ths
            rn = "Compare";
4002 2423f660 ths
            break;
4003 2423f660 ths
        /* 6,7 are implementation dependent */
4004 7a387fff ths
        default:
4005 7a387fff ths
            goto die;
4006 876d4b07 ths
        }
4007 8c0fdd85 ths
        break;
4008 8c0fdd85 ths
    case 12:
4009 7a387fff ths
        switch (sel) {
4010 7a387fff ths
        case 0:
4011 867abc7e aurel32
            save_cpu_state(ctx, 1);
4012 d9bea114 aurel32
            gen_helper_mtc0_status(arg);
4013 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
4014 8487327a ths
            gen_save_pc(ctx->pc + 4);
4015 8487327a ths
            ctx->bstate = BS_EXCP;
4016 2423f660 ths
            rn = "Status";
4017 2423f660 ths
            break;
4018 7a387fff ths
        case 1:
4019 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4020 d9bea114 aurel32
            gen_helper_mtc0_intctl(arg);
4021 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4022 8487327a ths
            ctx->bstate = BS_STOP;
4023 2423f660 ths
            rn = "IntCtl";
4024 2423f660 ths
            break;
4025 7a387fff ths
        case 2:
4026 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4027 d9bea114 aurel32
            gen_helper_mtc0_srsctl(arg);
4028 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4029 8487327a ths
            ctx->bstate = BS_STOP;
4030 2423f660 ths
            rn = "SRSCtl";
4031 2423f660 ths
            break;
4032 7a387fff ths
        case 3:
4033 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4034 d9bea114 aurel32
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4035 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4036 8487327a ths
            ctx->bstate = BS_STOP;
4037 2423f660 ths
            rn = "SRSMap";
4038 fd88b6ab ths
            break;
4039 7a387fff ths
        default:
4040 7a387fff ths
            goto die;
4041 876d4b07 ths
        }
4042 8c0fdd85 ths
        break;
4043 8c0fdd85 ths
    case 13:
4044 7a387fff ths
        switch (sel) {
4045 7a387fff ths
        case 0:
4046 867abc7e aurel32
            save_cpu_state(ctx, 1);
4047 d9bea114 aurel32
            gen_helper_mtc0_cause(arg);
4048 2423f660 ths
            rn = "Cause";
4049 2423f660 ths
            break;
4050 7a387fff ths
        default:
4051 7a387fff ths
            goto die;
4052 876d4b07 ths
        }
4053 8c0fdd85 ths
        break;
4054 8c0fdd85 ths
    case 14:
4055 7a387fff ths
        switch (sel) {
4056 7a387fff ths
        case 0:
4057 d9bea114 aurel32
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
4058 2423f660 ths
            rn = "EPC";
4059 2423f660 ths
            break;
4060 7a387fff ths
        default:
4061 7a387fff ths
            goto die;
4062 876d4b07 ths
        }
4063 8c0fdd85 ths
        break;
4064 8c0fdd85 ths
    case 15:
4065 7a387fff ths
        switch (sel) {
4066 7a387fff ths
        case 0:
4067 2423f660 ths
            /* ignored */
4068 2423f660 ths
            rn = "PRid";
4069 2423f660 ths
            break;
4070 7a387fff ths
        case 1:
4071 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4072 d9bea114 aurel32
            gen_helper_mtc0_ebase(arg);
4073 2423f660 ths
            rn = "EBase";
4074 2423f660 ths
            break;
4075 7a387fff ths
        default:
4076 7a387fff ths
            goto die;
4077 1579a72e ths
        }
4078 8c0fdd85 ths
        break;
4079 8c0fdd85 ths
    case 16:
4080 8c0fdd85 ths
        switch (sel) {
4081 8c0fdd85 ths
        case 0:
4082 d9bea114 aurel32
            gen_helper_mtc0_config0(arg);
4083 7a387fff ths
            rn = "Config";
4084 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
4085 2423f660 ths
            ctx->bstate = BS_STOP;
4086 7a387fff ths
            break;
4087 7a387fff ths
        case 1:
4088 e397ee33 ths
            /* ignored, read only */
4089 7a387fff ths
            rn = "Config1";
4090 7a387fff ths
            break;
4091 7a387fff ths
        case 2:
4092 d9bea114 aurel32
            gen_helper_mtc0_config2(arg);
4093 7a387fff ths
            rn = "Config2";
4094 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
4095 2423f660 ths
            ctx->bstate = BS_STOP;
4096 8c0fdd85 ths
            break;
4097 7a387fff ths
        case 3:
4098 e397ee33 ths
            /* ignored, read only */
4099 7a387fff ths
            rn = "Config3";
4100 7a387fff ths
            break;
4101 e397ee33 ths
        /* 4,5 are reserved */
4102 e397ee33 ths
        /* 6,7 are implementation dependent */
4103 e397ee33 ths
        case 6:
4104 e397ee33 ths
            /* ignored */
4105 e397ee33 ths
            rn = "Config6";
4106 e397ee33 ths
            break;
4107 e397ee33 ths
        case 7:
4108 e397ee33 ths
            /* ignored */
4109 e397ee33 ths
            rn = "Config7";
4110 e397ee33 ths
            break;
4111 8c0fdd85 ths
        default:
4112 8c0fdd85 ths
            rn = "Invalid config selector";
4113 8c0fdd85 ths
            goto die;
4114 8c0fdd85 ths
        }
4115 8c0fdd85 ths
        break;
4116 8c0fdd85 ths
    case 17:
4117 7a387fff ths
        switch (sel) {
4118 7a387fff ths
        case 0:
4119 2a6e32dd Aurelien Jarno
            gen_helper_mtc0_lladdr(arg);
4120 2423f660 ths
            rn = "LLAddr";
4121 2423f660 ths
            break;
4122 7a387fff ths
        default:
4123 7a387fff ths
            goto die;
4124 7a387fff ths
        }
4125 8c0fdd85 ths
        break;
4126 8c0fdd85 ths
    case 18:
4127 7a387fff ths
        switch (sel) {
4128 fd88b6ab ths
        case 0 ... 7:
4129 d9bea114 aurel32
            gen_helper_1i(mtc0_watchlo, arg, sel);
4130 2423f660 ths
            rn = "WatchLo";
4131 2423f660 ths
            break;
4132 7a387fff ths
        default:
4133 7a387fff ths
            goto die;
4134 7a387fff ths
        }
4135 8c0fdd85 ths
        break;
4136 8c0fdd85 ths
    case 19:
4137 7a387fff ths
        switch (sel) {
4138 fd88b6ab ths
        case 0 ... 7:
4139 d9bea114 aurel32
            gen_helper_1i(mtc0_watchhi, arg, sel);
4140 2423f660 ths
            rn = "WatchHi";
4141 2423f660 ths
            break;
4142 7a387fff ths
        default:
4143 7a387fff ths
            goto die;
4144 7a387fff ths
        }
4145 8c0fdd85 ths
        break;
4146 8c0fdd85 ths
    case 20:
4147 7a387fff ths
        switch (sel) {
4148 7a387fff ths
        case 0:
4149 d26bc211 ths
#if defined(TARGET_MIPS64)
4150 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
4151 d9bea114 aurel32
            gen_helper_mtc0_xcontext(arg);
4152 2423f660 ths
            rn = "XContext";
4153 2423f660 ths
            break;
4154 703eaf37 ths
#endif
4155 7a387fff ths
        default:
4156 7a387fff ths
            goto die;
4157 7a387fff ths
        }
4158 8c0fdd85 ths
        break;
4159 8c0fdd85 ths
    case 21:
4160 7a387fff ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4161 7a387fff ths
        switch (sel) {
4162 7a387fff ths
        case 0:
4163 d9bea114 aurel32
            gen_helper_mtc0_framemask(arg);
4164 2423f660 ths
            rn = "Framemask";
4165 2423f660 ths
            break;
4166 7a387fff ths
        default:
4167 7a387fff ths
            goto die;
4168 7a387fff ths
        }
4169 7a387fff ths
        break;
4170 8c0fdd85 ths
    case 22:
4171 7a387fff ths
        /* ignored */
4172 7a387fff ths
        rn = "Diagnostic"; /* implementation dependent */
4173 2423f660 ths
        break;
4174 8c0fdd85 ths
    case 23:
4175 7a387fff ths
        switch (sel) {
4176 7a387fff ths
        case 0:
4177 d9bea114 aurel32
            gen_helper_mtc0_debug(arg); /* EJTAG support */
4178 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
4179 8487327a ths
            gen_save_pc(ctx->pc + 4);
4180 8487327a ths
            ctx->bstate = BS_EXCP;
4181 2423f660 ths
            rn = "Debug";
4182 2423f660 ths
            break;
4183 7a387fff ths
        case 1:
4184 d9bea114 aurel32
//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
4185 2423f660 ths
            rn = "TraceControl";
4186 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4187 8487327a ths
            ctx->bstate = BS_STOP;
4188 2423f660 ths
//            break;
4189 7a387fff ths
        case 2:
4190 d9bea114 aurel32
//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
4191 2423f660 ths
            rn = "TraceControl2";
4192 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4193 8487327a ths
            ctx->bstate = BS_STOP;
4194 2423f660 ths
//            break;
4195 7a387fff ths
        case 3:
4196 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4197 8487327a ths
            ctx->bstate = BS_STOP;
4198 d9bea114 aurel32
//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
4199 2423f660 ths
            rn = "UserTraceData";
4200 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4201 8487327a ths
            ctx->bstate = BS_STOP;
4202 2423f660 ths
//            break;
4203 7a387fff ths
        case 4:
4204 d9bea114 aurel32
//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
4205 8487327a ths
            /* Stop translation as we may have switched the execution mode */
4206 8487327a ths
            ctx->bstate = BS_STOP;
4207 2423f660 ths
            rn = "TraceBPC";
4208 2423f660 ths
//            break;
4209 7a387fff ths
        default:
4210 7a387fff ths
            goto die;
4211 7a387fff ths
        }
4212 8c0fdd85 ths
        break;
4213 8c0fdd85 ths
    case 24:
4214 7a387fff ths
        switch (sel) {
4215 7a387fff ths
        case 0:
4216 f1aa6320 ths
            /* EJTAG support */
4217 d9bea114 aurel32
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
4218 2423f660 ths
            rn = "DEPC";
4219 2423f660 ths
            break;
4220 7a387fff ths
        default:
4221 7a387fff ths
            goto die;
4222 7a387fff ths
        }
4223 8c0fdd85 ths
        break;
4224 8c0fdd85 ths
    case 25:
4225 7a387fff ths
        switch (sel) {
4226 7a387fff ths
        case 0:
4227 d9bea114 aurel32
            gen_helper_mtc0_performance0(arg);
4228 2423f660 ths
            rn = "Performance0";
4229 2423f660 ths
            break;
4230 7a387fff ths
        case 1:
4231 d9bea114 aurel32
//            gen_helper_mtc0_performance1(arg);
4232 2423f660 ths
            rn = "Performance1";
4233 2423f660 ths
//            break;
4234 7a387fff ths
        case 2:
4235 d9bea114 aurel32
//            gen_helper_mtc0_performance2(arg);
4236 2423f660 ths
            rn = "Performance2";
4237 2423f660 ths
//            break;
4238 7a387fff ths
        case 3:
4239 d9bea114 aurel32
//            gen_helper_mtc0_performance3(arg);
4240 2423f660 ths
            rn = "Performance3";
4241 2423f660 ths
//            break;
4242 7a387fff ths
        case 4:
4243 d9bea114 aurel32
//            gen_helper_mtc0_performance4(arg);
4244 2423f660 ths
            rn = "Performance4";
4245 2423f660 ths
//            break;
4246 7a387fff ths
        case 5:
4247 d9bea114 aurel32
//            gen_helper_mtc0_performance5(arg);
4248 2423f660 ths
            rn = "Performance5";
4249 2423f660 ths
//            break;
4250 7a387fff ths
        case 6:
4251 d9bea114 aurel32
//            gen_helper_mtc0_performance6(arg);
4252 2423f660 ths
            rn = "Performance6";
4253 2423f660 ths
//            break;
4254 7a387fff ths
        case 7:
4255 d9bea114 aurel32
//            gen_helper_mtc0_performance7(arg);
4256 2423f660 ths
            rn = "Performance7";
4257 2423f660 ths
//            break;
4258 7a387fff ths
        default:
4259 7a387fff ths
            goto die;
4260 7a387fff ths
        }
4261 8c0fdd85 ths
       break;
4262 8c0fdd85 ths
    case 26:
4263 2423f660 ths
        /* ignored */
4264 8c0fdd85 ths
        rn = "ECC";
4265 2423f660 ths
        break;
4266 8c0fdd85 ths
    case 27:
4267 7a387fff ths
        switch (sel) {
4268 7a387fff ths
        case 0 ... 3:
4269 2423f660 ths
            /* ignored */
4270 2423f660 ths
            rn = "CacheErr";
4271 2423f660 ths
            break;
4272 7a387fff ths
        default:
4273 7a387fff ths
            goto die;
4274 7a387fff ths
        }
4275 8c0fdd85 ths
       break;
4276 8c0fdd85 ths
    case 28:
4277 8c0fdd85 ths
        switch (sel) {
4278 8c0fdd85 ths
        case 0:
4279 7a387fff ths
        case 2:
4280 7a387fff ths
        case 4:
4281 7a387fff ths
        case 6:
4282 d9bea114 aurel32
            gen_helper_mtc0_taglo(arg);
4283 8c0fdd85 ths
            rn = "TagLo";
4284 8c0fdd85 ths
            break;
4285 7a387fff ths
        case 1:
4286 7a387fff ths
        case 3:
4287 7a387fff ths
        case 5:
4288 7a387fff ths
        case 7:
4289 d9bea114 aurel32
            gen_helper_mtc0_datalo(arg);
4290 7a387fff ths
            rn = "DataLo";
4291 7a387fff ths
            break;
4292 8c0fdd85 ths
        default:
4293 8c0fdd85 ths
            goto die;
4294 8c0fdd85 ths
        }
4295 8c0fdd85 ths
        break;
4296 8c0fdd85 ths
    case 29:
4297 7a387fff ths
        switch (sel) {
4298 7a387fff ths
        case 0:
4299 7a387fff ths
        case 2:
4300 7a387fff ths
        case 4:
4301 7a387fff ths
        case 6:
4302 d9bea114 aurel32
            gen_helper_mtc0_taghi(arg);
4303 7a387fff ths
            rn = "TagHi";
4304 7a387fff ths
            break;
4305 7a387fff ths
        case 1:
4306 7a387fff ths
        case 3:
4307 7a387fff ths
        case 5:
4308 7a387fff ths
        case 7:
4309 d9bea114 aurel32
            gen_helper_mtc0_datahi(arg);
4310 7a387fff ths
            rn = "DataHi";
4311 7a387fff ths
            break;
4312 7a387fff ths
        default:
4313 7a387fff ths
            rn = "invalid sel";
4314 7a387fff ths
            goto die;
4315 7a387fff ths
        }
4316 8c0fdd85 ths
       break;
4317 8c0fdd85 ths
    case 30:
4318 7a387fff ths
        switch (sel) {
4319 7a387fff ths
        case 0:
4320 d9bea114 aurel32
            gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4321 2423f660 ths
            rn = "ErrorEPC";
4322 2423f660 ths
            break;
4323 7a387fff ths
        default:
4324 7a387fff ths
            goto die;
4325 7a387fff ths
        }
4326 8c0fdd85 ths
        break;
4327 8c0fdd85 ths
    case 31:
4328 7a387fff ths
        switch (sel) {
4329 7a387fff ths
        case 0:
4330 f1aa6320 ths
            /* EJTAG support */
4331 d9bea114 aurel32
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4332 2423f660 ths
            rn = "DESAVE";
4333 2423f660 ths
            break;
4334 7a387fff ths
        default:
4335 7a387fff ths
            goto die;
4336 7a387fff ths
        }
4337 2423f660 ths
        /* Stop translation as we may have switched the execution mode */
4338 2423f660 ths
        ctx->bstate = BS_STOP;
4339 8c0fdd85 ths
        break;
4340 8c0fdd85 ths
    default:
4341 8c0fdd85 ths
       goto die;
4342 8c0fdd85 ths
    }
4343 2abf314d Blue Swirl
    (void)rn; /* avoid a compiler warning */
4344 d12d51d5 aliguori
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4345 bf20dc07 ths
    /* For simplicity assume that all writes can cause interrupts.  */
4346 2e70f6ef pbrook
    if (use_icount) {
4347 2e70f6ef pbrook
        gen_io_end();
4348 2e70f6ef pbrook
        ctx->bstate = BS_STOP;
4349 2e70f6ef pbrook
    }
4350 8c0fdd85 ths
    return;
4351 8c0fdd85 ths
4352 8c0fdd85 ths
die:
4353 d12d51d5 aliguori
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4354 8c0fdd85 ths
    generate_exception(ctx, EXCP_RI);
4355 8c0fdd85 ths
}
4356 8c0fdd85 ths
4357 d26bc211 ths
#if defined(TARGET_MIPS64)
4358 d9bea114 aurel32
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4359 9c2149c8 ths
{
4360 9c2149c8 ths
    const char *rn = "invalid";
4361 9c2149c8 ths
4362 e189e748 ths
    if (sel != 0)
4363 e189e748 ths
        check_insn(env, ctx, ISA_MIPS64);
4364 e189e748 ths
4365 9c2149c8 ths
    switch (reg) {
4366 9c2149c8 ths
    case 0:
4367 9c2149c8 ths
        switch (sel) {
4368 9c2149c8 ths
        case 0:
4369 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4370 9c2149c8 ths
            rn = "Index";
4371 9c2149c8 ths
            break;
4372 9c2149c8 ths
        case 1:
4373 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4374 d9bea114 aurel32
            gen_helper_mfc0_mvpcontrol(arg);
4375 9c2149c8 ths
            rn = "MVPControl";
4376 ead9360e ths
            break;
4377 9c2149c8 ths
        case 2:
4378 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4379 d9bea114 aurel32
            gen_helper_mfc0_mvpconf0(arg);
4380 9c2149c8 ths
            rn = "MVPConf0";
4381 ead9360e ths
            break;
4382 9c2149c8 ths
        case 3:
4383 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4384 d9bea114 aurel32
            gen_helper_mfc0_mvpconf1(arg);
4385 9c2149c8 ths
            rn = "MVPConf1";
4386 ead9360e ths
            break;
4387 9c2149c8 ths
        default:
4388 9c2149c8 ths
            goto die;
4389 9c2149c8 ths
        }
4390 9c2149c8 ths
        break;
4391 9c2149c8 ths
    case 1:
4392 9c2149c8 ths
        switch (sel) {
4393 9c2149c8 ths
        case 0:
4394 d9bea114 aurel32
            gen_helper_mfc0_random(arg);
4395 9c2149c8 ths
            rn = "Random";
4396 2423f660 ths
            break;
4397 9c2149c8 ths
        case 1:
4398 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4399 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4400 9c2149c8 ths
            rn = "VPEControl";
4401 ead9360e ths
            break;
4402 9c2149c8 ths
        case 2:
4403 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4404 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4405 9c2149c8 ths
            rn = "VPEConf0";
4406 ead9360e ths
            break;
4407 9c2149c8 ths
        case 3:
4408 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4409 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4410 9c2149c8 ths
            rn = "VPEConf1";
4411 ead9360e ths
            break;
4412 9c2149c8 ths
        case 4:
4413 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4414 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4415 9c2149c8 ths
            rn = "YQMask";
4416 ead9360e ths
            break;
4417 9c2149c8 ths
        case 5:
4418 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4419 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4420 9c2149c8 ths
            rn = "VPESchedule";
4421 ead9360e ths
            break;
4422 9c2149c8 ths
        case 6:
4423 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4424 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4425 9c2149c8 ths
            rn = "VPEScheFBack";
4426 ead9360e ths
            break;
4427 9c2149c8 ths
        case 7:
4428 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4429 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4430 9c2149c8 ths
            rn = "VPEOpt";
4431 ead9360e ths
            break;
4432 9c2149c8 ths
        default:
4433 9c2149c8 ths
            goto die;
4434 9c2149c8 ths
        }
4435 9c2149c8 ths
        break;
4436 9c2149c8 ths
    case 2:
4437 9c2149c8 ths
        switch (sel) {
4438 9c2149c8 ths
        case 0:
4439 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4440 2423f660 ths
            rn = "EntryLo0";
4441 2423f660 ths
            break;
4442 9c2149c8 ths
        case 1:
4443 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4444 d9bea114 aurel32
            gen_helper_mfc0_tcstatus(arg);
4445 2423f660 ths
            rn = "TCStatus";
4446 ead9360e ths
            break;
4447 9c2149c8 ths
        case 2:
4448 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4449 d9bea114 aurel32
            gen_helper_mfc0_tcbind(arg);
4450 2423f660 ths
            rn = "TCBind";
4451 ead9360e ths
            break;
4452 9c2149c8 ths
        case 3:
4453 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4454 d9bea114 aurel32
            gen_helper_dmfc0_tcrestart(arg);
4455 2423f660 ths
            rn = "TCRestart";
4456 ead9360e ths
            break;
4457 9c2149c8 ths
        case 4:
4458 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4459 d9bea114 aurel32
            gen_helper_dmfc0_tchalt(arg);
4460 2423f660 ths
            rn = "TCHalt";
4461 ead9360e ths
            break;
4462 9c2149c8 ths
        case 5:
4463 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4464 d9bea114 aurel32
            gen_helper_dmfc0_tccontext(arg);
4465 2423f660 ths
            rn = "TCContext";
4466 ead9360e ths
            break;
4467 9c2149c8 ths
        case 6:
4468 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4469 d9bea114 aurel32
            gen_helper_dmfc0_tcschedule(arg);
4470 2423f660 ths
            rn = "TCSchedule";
4471 ead9360e ths
            break;
4472 9c2149c8 ths
        case 7:
4473 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4474 d9bea114 aurel32
            gen_helper_dmfc0_tcschefback(arg);
4475 2423f660 ths
            rn = "TCScheFBack";
4476 ead9360e ths
            break;
4477 9c2149c8 ths
        default:
4478 9c2149c8 ths
            goto die;
4479 9c2149c8 ths
        }
4480 9c2149c8 ths
        break;
4481 9c2149c8 ths
    case 3:
4482 9c2149c8 ths
        switch (sel) {
4483 9c2149c8 ths
        case 0:
4484 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4485 2423f660 ths
            rn = "EntryLo1";
4486 2423f660 ths
            break;
4487 9c2149c8 ths
        default:
4488 9c2149c8 ths
            goto die;
4489 1579a72e ths
        }
4490 9c2149c8 ths
        break;
4491 9c2149c8 ths
    case 4:
4492 9c2149c8 ths
        switch (sel) {
4493 9c2149c8 ths
        case 0:
4494 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4495 2423f660 ths
            rn = "Context";
4496 2423f660 ths
            break;
4497 9c2149c8 ths
        case 1:
4498 d9bea114 aurel32
//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4499 2423f660 ths
            rn = "ContextConfig";
4500 2423f660 ths
//            break;
4501 9c2149c8 ths
        default:
4502 9c2149c8 ths
            goto die;
4503 876d4b07 ths
        }
4504 9c2149c8 ths
        break;
4505 9c2149c8 ths
    case 5:
4506 9c2149c8 ths
        switch (sel) {
4507 9c2149c8 ths
        case 0:
4508 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4509 2423f660 ths
            rn = "PageMask";
4510 2423f660 ths
            break;
4511 9c2149c8 ths
        case 1:
4512 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4513 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4514 2423f660 ths
            rn = "PageGrain";
4515 2423f660 ths
            break;
4516 9c2149c8 ths
        default:
4517 9c2149c8 ths
            goto die;
4518 876d4b07 ths
        }
4519 9c2149c8 ths
        break;
4520 9c2149c8 ths
    case 6:
4521 9c2149c8 ths
        switch (sel) {
4522 9c2149c8 ths
        case 0:
4523 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4524 2423f660 ths
            rn = "Wired";
4525 2423f660 ths
            break;
4526 9c2149c8 ths
        case 1:
4527 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4528 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4529 2423f660 ths
            rn = "SRSConf0";
4530 ead9360e ths
            break;
4531 9c2149c8 ths
        case 2:
4532 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4533 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4534 2423f660 ths
            rn = "SRSConf1";
4535 ead9360e ths
            break;
4536 9c2149c8 ths
        case 3:
4537 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4538 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4539 2423f660 ths
            rn = "SRSConf2";
4540 ead9360e ths
            break;
4541 9c2149c8 ths
        case 4:
4542 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4543 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4544 2423f660 ths
            rn = "SRSConf3";
4545 ead9360e ths
            break;
4546 9c2149c8 ths
        case 5:
4547 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4548 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4549 2423f660 ths
            rn = "SRSConf4";
4550 ead9360e ths
            break;
4551 9c2149c8 ths
        default:
4552 9c2149c8 ths
            goto die;
4553 876d4b07 ths
        }
4554 9c2149c8 ths
        break;
4555 9c2149c8 ths
    case 7:
4556 9c2149c8 ths
        switch (sel) {
4557 9c2149c8 ths
        case 0:
4558 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4559 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4560 2423f660 ths
            rn = "HWREna";
4561 2423f660 ths
            break;
4562 9c2149c8 ths
        default:
4563 9c2149c8 ths
            goto die;
4564 876d4b07 ths
        }
4565 9c2149c8 ths
        break;
4566 9c2149c8 ths
    case 8:
4567 9c2149c8 ths
        switch (sel) {
4568 9c2149c8 ths
        case 0:
4569 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4570 f0b3f3ae ths
            rn = "BadVAddr";
4571 2423f660 ths
            break;
4572 9c2149c8 ths
        default:
4573 9c2149c8 ths
            goto die;
4574 876d4b07 ths
        }
4575 9c2149c8 ths
        break;
4576 9c2149c8 ths
    case 9:
4577 9c2149c8 ths
        switch (sel) {
4578 9c2149c8 ths
        case 0:
4579 2e70f6ef pbrook
            /* Mark as an IO operation because we read the time.  */
4580 2e70f6ef pbrook
            if (use_icount)
4581 2e70f6ef pbrook
                gen_io_start();
4582 d9bea114 aurel32
            gen_helper_mfc0_count(arg);
4583 2e70f6ef pbrook
            if (use_icount) {
4584 2e70f6ef pbrook
                gen_io_end();
4585 2e70f6ef pbrook
            }
4586 55807224 Edgar E. Iglesias
            /* Break the TB to be able to take timer interrupts immediately
4587 55807224 Edgar E. Iglesias
               after reading count.  */
4588 55807224 Edgar E. Iglesias
            ctx->bstate = BS_STOP;
4589 2423f660 ths
            rn = "Count";
4590 2423f660 ths
            break;
4591 2423f660 ths
        /* 6,7 are implementation dependent */
4592 9c2149c8 ths
        default:
4593 9c2149c8 ths
            goto die;
4594 876d4b07 ths
        }
4595 9c2149c8 ths
        break;
4596 9c2149c8 ths
    case 10:
4597 9c2149c8 ths
        switch (sel) {
4598 9c2149c8 ths
        case 0:
4599 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4600 2423f660 ths
            rn = "EntryHi";
4601 2423f660 ths
            break;
4602 9c2149c8 ths
        default:
4603 9c2149c8 ths
            goto die;
4604 876d4b07 ths
        }
4605 9c2149c8 ths
        break;
4606 9c2149c8 ths
    case 11:
4607 9c2149c8 ths
        switch (sel) {
4608 9c2149c8 ths
        case 0:
4609 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4610 2423f660 ths
            rn = "Compare";
4611 2423f660 ths
            break;
4612 876d4b07 ths
        /* 6,7 are implementation dependent */
4613 9c2149c8 ths
        default:
4614 9c2149c8 ths
            goto die;
4615 876d4b07 ths
        }
4616 9c2149c8 ths
        break;
4617 9c2149c8 ths
    case 12:
4618 9c2149c8 ths
        switch (sel) {
4619 9c2149c8 ths
        case 0:
4620 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4621 2423f660 ths
            rn = "Status";
4622 2423f660 ths
            break;
4623 9c2149c8 ths
        case 1:
4624 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4625 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4626 2423f660 ths
            rn = "IntCtl";
4627 2423f660 ths
            break;
4628 9c2149c8 ths
        case 2:
4629 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4630 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4631 2423f660 ths
            rn = "SRSCtl";
4632 2423f660 ths
            break;
4633 9c2149c8 ths
        case 3:
4634 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4635 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4636 2423f660 ths
            rn = "SRSMap";
4637 2423f660 ths
            break;
4638 9c2149c8 ths
        default:
4639 9c2149c8 ths
            goto die;
4640 876d4b07 ths
        }
4641 9c2149c8 ths
        break;
4642 9c2149c8 ths
    case 13:
4643 9c2149c8 ths
        switch (sel) {
4644 9c2149c8 ths
        case 0:
4645 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4646 2423f660 ths
            rn = "Cause";
4647 2423f660 ths
            break;
4648 9c2149c8 ths
        default:
4649 9c2149c8 ths
            goto die;
4650 876d4b07 ths
        }
4651 9c2149c8 ths
        break;
4652 9c2149c8 ths
    case 14:
4653 9c2149c8 ths
        switch (sel) {
4654 9c2149c8 ths
        case 0:
4655 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4656 2423f660 ths
            rn = "EPC";
4657 2423f660 ths
            break;
4658 9c2149c8 ths
        default:
4659 9c2149c8 ths
            goto die;
4660 876d4b07 ths
        }
4661 9c2149c8 ths
        break;
4662 9c2149c8 ths
    case 15:
4663 9c2149c8 ths
        switch (sel) {
4664 9c2149c8 ths
        case 0:
4665 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4666 2423f660 ths
            rn = "PRid";
4667 2423f660 ths
            break;
4668 9c2149c8 ths
        case 1:
4669 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
4670 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4671 2423f660 ths
            rn = "EBase";
4672 2423f660 ths
            break;
4673 9c2149c8 ths
        default:
4674 9c2149c8 ths
            goto die;
4675 876d4b07 ths
        }
4676 9c2149c8 ths
        break;
4677 9c2149c8 ths
    case 16:
4678 9c2149c8 ths
        switch (sel) {
4679 9c2149c8 ths
        case 0:
4680 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4681 9c2149c8 ths
            rn = "Config";
4682 9c2149c8 ths
            break;
4683 9c2149c8 ths
        case 1:
4684 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4685 9c2149c8 ths
            rn = "Config1";
4686 9c2149c8 ths
            break;
4687 9c2149c8 ths
        case 2:
4688 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4689 9c2149c8 ths
            rn = "Config2";
4690 9c2149c8 ths
            break;
4691 9c2149c8 ths
        case 3:
4692 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4693 9c2149c8 ths
            rn = "Config3";
4694 9c2149c8 ths
            break;
4695 9c2149c8 ths
       /* 6,7 are implementation dependent */
4696 f0b3f3ae ths
        case 6:
4697 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4698 f0b3f3ae ths
            rn = "Config6";
4699 f0b3f3ae ths
            break;
4700 f0b3f3ae ths
        case 7:
4701 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4702 f0b3f3ae ths
            rn = "Config7";
4703 f0b3f3ae ths
            break;
4704 9c2149c8 ths
        default:
4705 9c2149c8 ths
            goto die;
4706 9c2149c8 ths
        }
4707 9c2149c8 ths
        break;
4708 9c2149c8 ths
    case 17:
4709 9c2149c8 ths
        switch (sel) {
4710 9c2149c8 ths
        case 0:
4711 d9bea114 aurel32
            gen_helper_dmfc0_lladdr(arg);
4712 2423f660 ths
            rn = "LLAddr";
4713 2423f660 ths
            break;
4714 9c2149c8 ths
        default:
4715 9c2149c8 ths
            goto die;
4716 9c2149c8 ths
        }
4717 9c2149c8 ths
        break;
4718 9c2149c8 ths
    case 18:
4719 9c2149c8 ths
        switch (sel) {
4720 fd88b6ab ths
        case 0 ... 7:
4721 d9bea114 aurel32
            gen_helper_1i(dmfc0_watchlo, arg, sel);
4722 2423f660 ths
            rn = "WatchLo";
4723 2423f660 ths
            break;
4724 9c2149c8 ths
        default:
4725 9c2149c8 ths
            goto die;
4726 9c2149c8 ths
        }
4727 9c2149c8 ths
        break;
4728 9c2149c8 ths
    case 19:
4729 9c2149c8 ths
        switch (sel) {
4730 fd88b6ab ths
        case 0 ... 7:
4731 d9bea114 aurel32
            gen_helper_1i(mfc0_watchhi, arg, sel);
4732 2423f660 ths
            rn = "WatchHi";
4733 2423f660 ths
            break;
4734 9c2149c8 ths
        default:
4735 9c2149c8 ths
            goto die;
4736 9c2149c8 ths
        }
4737 9c2149c8 ths
        break;
4738 9c2149c8 ths
    case 20:
4739 9c2149c8 ths
        switch (sel) {
4740 9c2149c8 ths
        case 0:
4741 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
4742 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4743 2423f660 ths
            rn = "XContext";
4744 2423f660 ths
            break;
4745 9c2149c8 ths
        default:
4746 9c2149c8 ths
            goto die;
4747 9c2149c8 ths
        }
4748 9c2149c8 ths
        break;
4749 9c2149c8 ths
    case 21:
4750 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4751 9c2149c8 ths
        switch (sel) {
4752 9c2149c8 ths
        case 0:
4753 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4754 2423f660 ths
            rn = "Framemask";
4755 2423f660 ths
            break;
4756 9c2149c8 ths
        default:
4757 9c2149c8 ths
            goto die;
4758 9c2149c8 ths
        }
4759 9c2149c8 ths
        break;
4760 9c2149c8 ths
    case 22:
4761 d9bea114 aurel32
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4762 2423f660 ths
        rn = "'Diagnostic"; /* implementation dependent */
4763 2423f660 ths
        break;
4764 9c2149c8 ths
    case 23:
4765 9c2149c8 ths
        switch (sel) {
4766 9c2149c8 ths
        case 0:
4767 d9bea114 aurel32
            gen_helper_mfc0_debug(arg); /* EJTAG support */
4768 2423f660 ths
            rn = "Debug";
4769 2423f660 ths
            break;
4770 9c2149c8 ths
        case 1:
4771 d9bea114 aurel32
//            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4772 2423f660 ths
            rn = "TraceControl";
4773 2423f660 ths
//            break;
4774 9c2149c8 ths
        case 2:
4775 d9bea114 aurel32
//            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4776 2423f660 ths
            rn = "TraceControl2";
4777 2423f660 ths
//            break;
4778 9c2149c8 ths
        case 3:
4779 d9bea114 aurel32
//            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4780 2423f660 ths
            rn = "UserTraceData";
4781 2423f660 ths
//            break;
4782 9c2149c8 ths
        case 4:
4783 d9bea114 aurel32
//            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4784 2423f660 ths
            rn = "TraceBPC";
4785 2423f660 ths
//            break;
4786 9c2149c8 ths
        default:
4787 9c2149c8 ths
            goto die;
4788 9c2149c8 ths
        }
4789 9c2149c8 ths
        break;
4790 9c2149c8 ths
    case 24:
4791 9c2149c8 ths
        switch (sel) {
4792 9c2149c8 ths
        case 0:
4793 f0b3f3ae ths
            /* EJTAG support */
4794 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4795 2423f660 ths
            rn = "DEPC";
4796 2423f660 ths
            break;
4797 9c2149c8 ths
        default:
4798 9c2149c8 ths
            goto die;
4799 9c2149c8 ths
        }
4800 9c2149c8 ths
        break;
4801 9c2149c8 ths
    case 25:
4802 9c2149c8 ths
        switch (sel) {
4803 9c2149c8 ths
        case 0:
4804 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4805 2423f660 ths
            rn = "Performance0";
4806 9c2149c8 ths
            break;
4807 9c2149c8 ths
        case 1:
4808 d9bea114 aurel32
//            gen_helper_dmfc0_performance1(arg);
4809 2423f660 ths
            rn = "Performance1";
4810 2423f660 ths
//            break;
4811 9c2149c8 ths
        case 2:
4812 d9bea114 aurel32
//            gen_helper_dmfc0_performance2(arg);
4813 2423f660 ths
            rn = "Performance2";
4814 2423f660 ths
//            break;
4815 9c2149c8 ths
        case 3:
4816 d9bea114 aurel32
//            gen_helper_dmfc0_performance3(arg);
4817 2423f660 ths
            rn = "Performance3";
4818 2423f660 ths
//            break;
4819 9c2149c8 ths
        case 4:
4820 d9bea114 aurel32
//            gen_helper_dmfc0_performance4(arg);
4821 2423f660 ths
            rn = "Performance4";
4822 2423f660 ths
//            break;
4823 9c2149c8 ths
        case 5:
4824 d9bea114 aurel32
//            gen_helper_dmfc0_performance5(arg);
4825 2423f660 ths
            rn = "Performance5";
4826 2423f660 ths
//            break;
4827 9c2149c8 ths
        case 6:
4828 d9bea114 aurel32
//            gen_helper_dmfc0_performance6(arg);
4829 2423f660 ths
            rn = "Performance6";
4830 2423f660 ths
//            break;
4831 9c2149c8 ths
        case 7:
4832 d9bea114 aurel32
//            gen_helper_dmfc0_performance7(arg);
4833 2423f660 ths
            rn = "Performance7";
4834 2423f660 ths
//            break;
4835 9c2149c8 ths
        default:
4836 9c2149c8 ths
            goto die;
4837 9c2149c8 ths
        }
4838 9c2149c8 ths
        break;
4839 9c2149c8 ths
    case 26:
4840 d9bea114 aurel32
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4841 da80682b aurel32
        rn = "ECC";
4842 da80682b aurel32
        break;
4843 9c2149c8 ths
    case 27:
4844 9c2149c8 ths
        switch (sel) {
4845 9c2149c8 ths
        /* ignored */
4846 9c2149c8 ths
        case 0 ... 3:
4847 d9bea114 aurel32
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
4848 2423f660 ths
            rn = "CacheErr";
4849 2423f660 ths
            break;
4850 9c2149c8 ths
        default:
4851 9c2149c8 ths
            goto die;
4852 9c2149c8 ths
        }
4853 9c2149c8 ths
        break;
4854 9c2149c8 ths
    case 28:
4855 9c2149c8 ths
        switch (sel) {
4856 9c2149c8 ths
        case 0:
4857 9c2149c8 ths
        case 2:
4858 9c2149c8 ths
        case 4:
4859 9c2149c8 ths
        case 6:
4860 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4861 9c2149c8 ths
            rn = "TagLo";
4862 9c2149c8 ths
            break;
4863 9c2149c8 ths
        case 1:
4864 9c2149c8 ths
        case 3:
4865 9c2149c8 ths
        case 5:
4866 9c2149c8 ths
        case 7:
4867 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4868 9c2149c8 ths
            rn = "DataLo";
4869 9c2149c8 ths
            break;
4870 9c2149c8 ths
        default:
4871 9c2149c8 ths
            goto die;
4872 9c2149c8 ths
        }
4873 9c2149c8 ths
        break;
4874 9c2149c8 ths
    case 29:
4875 9c2149c8 ths
        switch (sel) {
4876 9c2149c8 ths
        case 0:
4877 9c2149c8 ths
        case 2:
4878 9c2149c8 ths
        case 4:
4879 9c2149c8 ths
        case 6:
4880 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4881 9c2149c8 ths
            rn = "TagHi";
4882 9c2149c8 ths
            break;
4883 9c2149c8 ths
        case 1:
4884 9c2149c8 ths
        case 3:
4885 9c2149c8 ths
        case 5:
4886 9c2149c8 ths
        case 7:
4887 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4888 9c2149c8 ths
            rn = "DataHi";
4889 9c2149c8 ths
            break;
4890 9c2149c8 ths
        default:
4891 9c2149c8 ths
            goto die;
4892 9c2149c8 ths
        }
4893 9c2149c8 ths
        break;
4894 9c2149c8 ths
    case 30:
4895 9c2149c8 ths
        switch (sel) {
4896 9c2149c8 ths
        case 0:
4897 d9bea114 aurel32
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4898 2423f660 ths
            rn = "ErrorEPC";
4899 2423f660 ths
            break;
4900 9c2149c8 ths
        default:
4901 9c2149c8 ths
            goto die;
4902 9c2149c8 ths
        }
4903 9c2149c8 ths
        break;
4904 9c2149c8 ths
    case 31:
4905 9c2149c8 ths
        switch (sel) {
4906 9c2149c8 ths
        case 0:
4907 f0b3f3ae ths
            /* EJTAG support */
4908 d9bea114 aurel32
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4909 2423f660 ths
            rn = "DESAVE";
4910 2423f660 ths
            break;
4911 9c2149c8 ths
        default:
4912 9c2149c8 ths
            goto die;
4913 9c2149c8 ths
        }
4914 9c2149c8 ths
        break;
4915 9c2149c8 ths
    default:
4916 876d4b07 ths
        goto die;
4917 9c2149c8 ths
    }
4918 2abf314d Blue Swirl
    (void)rn; /* avoid a compiler warning */
4919 d12d51d5 aliguori
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4920 9c2149c8 ths
    return;
4921 9c2149c8 ths
4922 9c2149c8 ths
die:
4923 d12d51d5 aliguori
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4924 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
4925 9c2149c8 ths
}
4926 9c2149c8 ths
4927 d9bea114 aurel32
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4928 9c2149c8 ths
{
4929 9c2149c8 ths
    const char *rn = "invalid";
4930 9c2149c8 ths
4931 e189e748 ths
    if (sel != 0)
4932 e189e748 ths
        check_insn(env, ctx, ISA_MIPS64);
4933 e189e748 ths
4934 2e70f6ef pbrook
    if (use_icount)
4935 2e70f6ef pbrook
        gen_io_start();
4936 2e70f6ef pbrook
4937 9c2149c8 ths
    switch (reg) {
4938 9c2149c8 ths
    case 0:
4939 9c2149c8 ths
        switch (sel) {
4940 9c2149c8 ths
        case 0:
4941 d9bea114 aurel32
            gen_helper_mtc0_index(arg);
4942 9c2149c8 ths
            rn = "Index";
4943 9c2149c8 ths
            break;
4944 9c2149c8 ths
        case 1:
4945 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4946 d9bea114 aurel32
            gen_helper_mtc0_mvpcontrol(arg);
4947 9c2149c8 ths
            rn = "MVPControl";
4948 ead9360e ths
            break;
4949 9c2149c8 ths
        case 2:
4950 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4951 ead9360e ths
            /* ignored */
4952 9c2149c8 ths
            rn = "MVPConf0";
4953 ead9360e ths
            break;
4954 9c2149c8 ths
        case 3:
4955 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4956 ead9360e ths
            /* ignored */
4957 9c2149c8 ths
            rn = "MVPConf1";
4958 ead9360e ths
            break;
4959 9c2149c8 ths
        default:
4960 9c2149c8 ths
            goto die;
4961 9c2149c8 ths
        }
4962 9c2149c8 ths
        break;
4963 9c2149c8 ths
    case 1:
4964 9c2149c8 ths
        switch (sel) {
4965 9c2149c8 ths
        case 0:
4966 2423f660 ths
            /* ignored */
4967 9c2149c8 ths
            rn = "Random";
4968 2423f660 ths
            break;
4969 9c2149c8 ths
        case 1:
4970 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4971 d9bea114 aurel32
            gen_helper_mtc0_vpecontrol(arg);
4972 9c2149c8 ths
            rn = "VPEControl";
4973 ead9360e ths
            break;
4974 9c2149c8 ths
        case 2:
4975 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4976 d9bea114 aurel32
            gen_helper_mtc0_vpeconf0(arg);
4977 9c2149c8 ths
            rn = "VPEConf0";
4978 ead9360e ths
            break;
4979 9c2149c8 ths
        case 3:
4980 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4981 d9bea114 aurel32
            gen_helper_mtc0_vpeconf1(arg);
4982 9c2149c8 ths
            rn = "VPEConf1";
4983 ead9360e ths
            break;
4984 9c2149c8 ths
        case 4:
4985 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4986 d9bea114 aurel32
            gen_helper_mtc0_yqmask(arg);
4987 9c2149c8 ths
            rn = "YQMask";
4988 ead9360e ths
            break;
4989 9c2149c8 ths
        case 5:
4990 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4991 d9bea114 aurel32
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4992 9c2149c8 ths
            rn = "VPESchedule";
4993 ead9360e ths
            break;
4994 9c2149c8 ths
        case 6:
4995 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
4996 d9bea114 aurel32
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4997 9c2149c8 ths
            rn = "VPEScheFBack";
4998 ead9360e ths
            break;
4999 9c2149c8 ths
        case 7:
5000 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
5001 d9bea114 aurel32
            gen_helper_mtc0_vpeopt(arg);
5002 9c2149c8 ths
            rn = "VPEOpt";
5003 ead9360e ths
            break;
5004 9c2149c8 ths
        default:
5005 9c2149c8 ths
            goto die;
5006 9c2149c8 ths
        }
5007 9c2149c8 ths
        break;
5008 9c2149c8 ths
    case 2:
5009 9c2149c8 ths
        switch (sel) {
5010 9c2149c8 ths
        case 0:
5011 d9bea114 aurel32
            gen_helper_mtc0_entrylo0(arg);
5012 2423f660 ths
            rn = "EntryLo0";
5013 2423f660 ths
            break;
5014 9c2149c8 ths
        case 1:
5015 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
5016 d9bea114 aurel32
            gen_helper_mtc0_tcstatus(arg);
5017 2423f660 ths
            rn = "TCStatus";
5018 ead9360e ths
            break;
5019 9c2149c8 ths
        case 2:
5020 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
5021 d9bea114 aurel32
            gen_helper_mtc0_tcbind(arg);
5022 2423f660 ths
            rn = "TCBind";
5023 ead9360e ths
            break;
5024 9c2149c8 ths
        case 3:
5025 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
5026 d9bea114 aurel32
            gen_helper_mtc0_tcrestart(arg);
5027 2423f660 ths
            rn = "TCRestart";
5028 ead9360e ths
            break;
5029 9c2149c8 ths
        case 4:
5030 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
5031 d9bea114 aurel32
            gen_helper_mtc0_tchalt(arg);
5032 2423f660 ths
            rn = "TCHalt";
5033 ead9360e ths
            break;
5034 9c2149c8 ths
        case 5:
5035 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
5036 d9bea114 aurel32
            gen_helper_mtc0_tccontext(arg);
5037 2423f660 ths
            rn = "TCContext";
5038 ead9360e ths
            break;
5039 9c2149c8 ths
        case 6:
5040 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
5041 d9bea114 aurel32
            gen_helper_mtc0_tcschedule(arg);
5042 2423f660 ths
            rn = "TCSchedule";
5043 ead9360e ths
            break;
5044 9c2149c8 ths
        case 7:
5045 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
5046 d9bea114 aurel32
            gen_helper_mtc0_tcschefback(arg);
5047 2423f660 ths
            rn = "TCScheFBack";
5048 ead9360e ths
            break;
5049 9c2149c8 ths
        default:
5050 9c2149c8 ths
            goto die;
5051 9c2149c8 ths
        }
5052 9c2149c8 ths
        break;
5053 9c2149c8 ths
    case 3:
5054 9c2149c8 ths
        switch (sel) {
5055 9c2149c8 ths
        case 0:
5056 d9bea114 aurel32
            gen_helper_mtc0_entrylo1(arg);
5057 2423f660 ths
            rn = "EntryLo1";
5058 2423f660 ths
            break;
5059 9c2149c8 ths
        default:
5060 9c2149c8 ths
            goto die;
5061 876d4b07 ths
        }
5062 9c2149c8 ths
        break;
5063 9c2149c8 ths
    case 4:
5064 9c2149c8 ths
        switch (sel) {
5065 9c2149c8 ths
        case 0:
5066 d9bea114 aurel32
            gen_helper_mtc0_context(arg);
5067 2423f660 ths
            rn = "Context";
5068 2423f660 ths
            break;
5069 9c2149c8 ths
        case 1:
5070 d9bea114 aurel32
//           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
5071 2423f660 ths
            rn = "ContextConfig";
5072 2423f660 ths
//           break;
5073 9c2149c8 ths
        default:
5074 9c2149c8 ths
            goto die;
5075 876d4b07 ths
        }
5076 9c2149c8 ths
        break;
5077 9c2149c8 ths
    case 5:
5078 9c2149c8 ths
        switch (sel) {
5079 9c2149c8 ths
        case 0:
5080 d9bea114 aurel32
            gen_helper_mtc0_pagemask(arg);
5081 2423f660 ths
            rn = "PageMask";
5082 2423f660 ths
            break;
5083 9c2149c8 ths
        case 1:
5084 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5085 d9bea114 aurel32
            gen_helper_mtc0_pagegrain(arg);
5086 2423f660 ths
            rn = "PageGrain";
5087 2423f660 ths
            break;
5088 9c2149c8 ths
        default:
5089 9c2149c8 ths
            goto die;
5090 876d4b07 ths
        }
5091 9c2149c8 ths
        break;
5092 9c2149c8 ths
    case 6:
5093 9c2149c8 ths
        switch (sel) {
5094 9c2149c8 ths
        case 0:
5095 d9bea114 aurel32
            gen_helper_mtc0_wired(arg);
5096 2423f660 ths
            rn = "Wired";
5097 2423f660 ths
            break;
5098 9c2149c8 ths
        case 1:
5099 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5100 d9bea114 aurel32
            gen_helper_mtc0_srsconf0(arg);
5101 2423f660 ths
            rn = "SRSConf0";
5102 ead9360e ths
            break;
5103 9c2149c8 ths
        case 2:
5104 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5105 d9bea114 aurel32
            gen_helper_mtc0_srsconf1(arg);
5106 2423f660 ths
            rn = "SRSConf1";
5107 ead9360e ths
            break;
5108 9c2149c8 ths
        case 3:
5109 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5110 d9bea114 aurel32
            gen_helper_mtc0_srsconf2(arg);
5111 2423f660 ths
            rn = "SRSConf2";
5112 ead9360e ths
            break;
5113 9c2149c8 ths
        case 4:
5114 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5115 d9bea114 aurel32
            gen_helper_mtc0_srsconf3(arg);
5116 2423f660 ths
            rn = "SRSConf3";
5117 ead9360e ths
            break;
5118 9c2149c8 ths
        case 5:
5119 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5120 d9bea114 aurel32
            gen_helper_mtc0_srsconf4(arg);
5121 2423f660 ths
            rn = "SRSConf4";
5122 ead9360e ths
            break;
5123 9c2149c8 ths
        default:
5124 9c2149c8 ths
            goto die;
5125 876d4b07 ths
        }
5126 9c2149c8 ths
        break;
5127 9c2149c8 ths
    case 7:
5128 9c2149c8 ths
        switch (sel) {
5129 9c2149c8 ths
        case 0:
5130 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5131 d9bea114 aurel32
            gen_helper_mtc0_hwrena(arg);
5132 2423f660 ths
            rn = "HWREna";
5133 2423f660 ths
            break;
5134 9c2149c8 ths
        default:
5135 9c2149c8 ths
            goto die;
5136 876d4b07 ths
        }
5137 9c2149c8 ths
        break;
5138 9c2149c8 ths
    case 8:
5139 9c2149c8 ths
        /* ignored */
5140 f0b3f3ae ths
        rn = "BadVAddr";
5141 9c2149c8 ths
        break;
5142 9c2149c8 ths
    case 9:
5143 9c2149c8 ths
        switch (sel) {
5144 9c2149c8 ths
        case 0:
5145 d9bea114 aurel32
            gen_helper_mtc0_count(arg);
5146 2423f660 ths
            rn = "Count";
5147 2423f660 ths
            break;
5148 876d4b07 ths
        /* 6,7 are implementation dependent */
5149 9c2149c8 ths
        default:
5150 9c2149c8 ths
            goto die;
5151 876d4b07 ths
        }
5152 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
5153 876d4b07 ths
        ctx->bstate = BS_STOP;
5154 9c2149c8 ths
        break;
5155 9c2149c8 ths
    case 10:
5156 9c2149c8 ths
        switch (sel) {
5157 9c2149c8 ths
        case 0:
5158 d9bea114 aurel32
            gen_helper_mtc0_entryhi(arg);
5159 2423f660 ths
            rn = "EntryHi";
5160 2423f660 ths
            break;
5161 9c2149c8 ths
        default:
5162 9c2149c8 ths
            goto die;
5163 876d4b07 ths
        }
5164 9c2149c8 ths
        break;
5165 9c2149c8 ths
    case 11:
5166 9c2149c8 ths
        switch (sel) {
5167 9c2149c8 ths
        case 0:
5168 d9bea114 aurel32
            gen_helper_mtc0_compare(arg);
5169 2423f660 ths
            rn = "Compare";
5170 2423f660 ths
            break;
5171 876d4b07 ths
        /* 6,7 are implementation dependent */
5172 9c2149c8 ths
        default:
5173 9c2149c8 ths
            goto die;
5174 876d4b07 ths
        }
5175 de9a95f0 aurel32
        /* Stop translation as we may have switched the execution mode */
5176 de9a95f0 aurel32
        ctx->bstate = BS_STOP;
5177 9c2149c8 ths
        break;
5178 9c2149c8 ths
    case 12:
5179 9c2149c8 ths
        switch (sel) {
5180 9c2149c8 ths
        case 0:
5181 867abc7e aurel32
            save_cpu_state(ctx, 1);
5182 d9bea114 aurel32
            gen_helper_mtc0_status(arg);
5183 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
5184 8487327a ths
            gen_save_pc(ctx->pc + 4);
5185 8487327a ths
            ctx->bstate = BS_EXCP;
5186 2423f660 ths
            rn = "Status";
5187 2423f660 ths
            break;
5188 9c2149c8 ths
        case 1:
5189 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5190 d9bea114 aurel32
            gen_helper_mtc0_intctl(arg);
5191 8487327a ths
            /* Stop translation as we may have switched the execution mode */
5192 8487327a ths
            ctx->bstate = BS_STOP;
5193 2423f660 ths
            rn = "IntCtl";
5194 2423f660 ths
            break;
5195 9c2149c8 ths
        case 2:
5196 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5197 d9bea114 aurel32
            gen_helper_mtc0_srsctl(arg);
5198 8487327a ths
            /* Stop translation as we may have switched the execution mode */
5199 8487327a ths
            ctx->bstate = BS_STOP;
5200 2423f660 ths
            rn = "SRSCtl";
5201 2423f660 ths
            break;
5202 9c2149c8 ths
        case 3:
5203 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5204 d9bea114 aurel32
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
5205 8487327a ths
            /* Stop translation as we may have switched the execution mode */
5206 8487327a ths
            ctx->bstate = BS_STOP;
5207 2423f660 ths
            rn = "SRSMap";
5208 2423f660 ths
            break;
5209 2423f660 ths
        default:
5210 9c2149c8 ths
            goto die;
5211 876d4b07 ths
        }
5212 9c2149c8 ths
        break;
5213 9c2149c8 ths
    case 13:
5214 9c2149c8 ths
        switch (sel) {
5215 9c2149c8 ths
        case 0:
5216 867abc7e aurel32
            save_cpu_state(ctx, 1);
5217 5dc5d9f0 Aurelien Jarno
            /* Mark as an IO operation because we may trigger a software
5218 5dc5d9f0 Aurelien Jarno
               interrupt.  */
5219 5dc5d9f0 Aurelien Jarno
            if (use_icount) {
5220 5dc5d9f0 Aurelien Jarno
                gen_io_start();
5221 5dc5d9f0 Aurelien Jarno
            }
5222 d9bea114 aurel32
            gen_helper_mtc0_cause(arg);
5223 5dc5d9f0 Aurelien Jarno
            if (use_icount) {
5224 5dc5d9f0 Aurelien Jarno
                gen_io_end();
5225 5dc5d9f0 Aurelien Jarno
            }
5226 5dc5d9f0 Aurelien Jarno
            /* Stop translation as we may have triggered an intetrupt */
5227 5dc5d9f0 Aurelien Jarno
            ctx->bstate = BS_STOP;
5228 2423f660 ths
            rn = "Cause";
5229 2423f660 ths
            break;
5230 9c2149c8 ths
        default:
5231 9c2149c8 ths
            goto die;
5232 876d4b07 ths
        }
5233 9c2149c8 ths
        break;
5234 9c2149c8 ths
    case 14:
5235 9c2149c8 ths
        switch (sel) {
5236 9c2149c8 ths
        case 0:
5237 d9bea114 aurel32
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
5238 2423f660 ths
            rn = "EPC";
5239 2423f660 ths
            break;
5240 9c2149c8 ths
        default:
5241 9c2149c8 ths
            goto die;
5242 876d4b07 ths
        }
5243 9c2149c8 ths
        break;
5244 9c2149c8 ths
    case 15:
5245 9c2149c8 ths
        switch (sel) {
5246 9c2149c8 ths
        case 0:
5247 2423f660 ths
            /* ignored */
5248 2423f660 ths
            rn = "PRid";
5249 2423f660 ths
            break;
5250 9c2149c8 ths
        case 1:
5251 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
5252 d9bea114 aurel32
            gen_helper_mtc0_ebase(arg);
5253 2423f660 ths
            rn = "EBase";
5254 2423f660 ths
            break;
5255 9c2149c8 ths
        default:
5256 9c2149c8 ths
            goto die;
5257 876d4b07 ths
        }
5258 9c2149c8 ths
        break;
5259 9c2149c8 ths
    case 16:
5260 9c2149c8 ths
        switch (sel) {
5261 9c2149c8 ths
        case 0:
5262 d9bea114 aurel32
            gen_helper_mtc0_config0(arg);
5263 9c2149c8 ths
            rn = "Config";
5264 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
5265 2423f660 ths
            ctx->bstate = BS_STOP;
5266 9c2149c8 ths
            break;
5267 9c2149c8 ths
        case 1:
5268 1fc7bf6e aurel32
            /* ignored, read only */
5269 9c2149c8 ths
            rn = "Config1";
5270 9c2149c8 ths
            break;
5271 9c2149c8 ths
        case 2:
5272 d9bea114 aurel32
            gen_helper_mtc0_config2(arg);
5273 9c2149c8 ths
            rn = "Config2";
5274 2423f660 ths
            /* Stop translation as we may have switched the execution mode */
5275 2423f660 ths
            ctx->bstate = BS_STOP;
5276 9c2149c8 ths
            break;
5277 9c2149c8 ths
        case 3:
5278 2423f660 ths
            /* ignored */
5279 9c2149c8 ths
            rn = "Config3";
5280 9c2149c8 ths
            break;
5281 9c2149c8 ths
        /* 6,7 are implementation dependent */
5282 9c2149c8 ths
        default:
5283 9c2149c8 ths
            rn = "Invalid config selector";
5284 9c2149c8 ths
            goto die;
5285 9c2149c8 ths
        }
5286 9c2149c8 ths
        break;
5287 9c2149c8 ths
    case 17:
5288 9c2149c8 ths
        switch (sel) {
5289 9c2149c8 ths
        case 0:
5290 2a6e32dd Aurelien Jarno
            gen_helper_mtc0_lladdr(arg);
5291 2423f660 ths
            rn = "LLAddr";
5292 2423f660 ths
            break;
5293 9c2149c8 ths
        default:
5294 9c2149c8 ths
            goto die;
5295 9c2149c8 ths
        }
5296 9c2149c8 ths
        break;
5297 9c2149c8 ths
    case 18:
5298 9c2149c8 ths
        switch (sel) {
5299 fd88b6ab ths
        case 0 ... 7:
5300 d9bea114 aurel32
            gen_helper_1i(mtc0_watchlo, arg, sel);
5301 2423f660 ths
            rn = "WatchLo";
5302 2423f660 ths
            break;
5303 9c2149c8 ths
        default:
5304 9c2149c8 ths
            goto die;
5305 9c2149c8 ths
        }
5306 9c2149c8 ths
        break;
5307 9c2149c8 ths
    case 19:
5308 9c2149c8 ths
        switch (sel) {
5309 fd88b6ab ths
        case 0 ... 7:
5310 d9bea114 aurel32
            gen_helper_1i(mtc0_watchhi, arg, sel);
5311 2423f660 ths
            rn = "WatchHi";
5312 2423f660 ths
            break;
5313 9c2149c8 ths
        default:
5314 9c2149c8 ths
            goto die;
5315 9c2149c8 ths
        }
5316 9c2149c8 ths
        break;
5317 9c2149c8 ths
    case 20:
5318 9c2149c8 ths
        switch (sel) {
5319 9c2149c8 ths
        case 0:
5320 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
5321 d9bea114 aurel32
            gen_helper_mtc0_xcontext(arg);
5322 2423f660 ths
            rn = "XContext";
5323 2423f660 ths
            break;
5324 9c2149c8 ths
        default:
5325 9c2149c8 ths
            goto die;
5326 9c2149c8 ths
        }
5327 9c2149c8 ths
        break;
5328 9c2149c8 ths
    case 21:
5329 9c2149c8 ths
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5330 9c2149c8 ths
        switch (sel) {
5331 9c2149c8 ths
        case 0:
5332 d9bea114 aurel32
            gen_helper_mtc0_framemask(arg);
5333 2423f660 ths
            rn = "Framemask";
5334 2423f660 ths
            break;
5335 9c2149c8 ths
        default:
5336 9c2149c8 ths
            goto die;
5337 9c2149c8 ths
        }
5338 9c2149c8 ths
        break;
5339 9c2149c8 ths
    case 22:
5340 9c2149c8 ths
        /* ignored */
5341 9c2149c8 ths
        rn = "Diagnostic"; /* implementation dependent */
5342 876d4b07 ths
        break;
5343 9c2149c8 ths
    case 23:
5344 9c2149c8 ths
        switch (sel) {
5345 9c2149c8 ths
        case 0:
5346 d9bea114 aurel32
            gen_helper_mtc0_debug(arg); /* EJTAG support */
5347 8487327a ths
            /* BS_STOP isn't good enough here, hflags may have changed. */
5348 8487327a ths
            gen_save_pc(ctx->pc + 4);
5349 8487327a ths
            ctx->bstate = BS_EXCP;
5350 2423f660 ths
            rn = "Debug";
5351 2423f660 ths
            break;
5352 9c2149c8 ths
        case 1:
5353 d9bea114 aurel32
//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5354 8487327a ths
            /* Stop translation as we may have switched the execution mode */
5355 8487327a ths
            ctx->bstate = BS_STOP;
5356 2423f660 ths
            rn = "TraceControl";
5357 2423f660 ths
//            break;
5358 9c2149c8 ths
        case 2:
5359 d9bea114 aurel32
//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5360 8487327a ths
            /* Stop translation as we may have switched the execution mode */
5361 8487327a ths
            ctx->bstate = BS_STOP;
5362 2423f660 ths
            rn = "TraceControl2";
5363 2423f660 ths
//            break;
5364 9c2149c8 ths
        case 3:
5365 d9bea114 aurel32
//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5366 8487327a ths
            /* Stop translation as we may have switched the execution mode */
5367 8487327a ths
            ctx->bstate = BS_STOP;
5368 2423f660 ths
            rn = "UserTraceData";
5369 2423f660 ths
//            break;
5370 9c2149c8 ths
        case 4:
5371 d9bea114 aurel32
//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5372 8487327a ths
            /* Stop translation as we may have switched the execution mode */
5373 8487327a ths
            ctx->bstate = BS_STOP;
5374 2423f660 ths
            rn = "TraceBPC";
5375 2423f660 ths
//            break;
5376 9c2149c8 ths
        default:
5377 9c2149c8 ths
            goto die;
5378 9c2149c8 ths
        }
5379 9c2149c8 ths
        break;
5380 9c2149c8 ths
    case 24:
5381 9c2149c8 ths
        switch (sel) {
5382 9c2149c8 ths
        case 0:
5383 f1aa6320 ths
            /* EJTAG support */
5384 d9bea114 aurel32
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5385 2423f660 ths
            rn = "DEPC";
5386 2423f660 ths
            break;
5387 9c2149c8 ths
        default:
5388 9c2149c8 ths
            goto die;
5389 9c2149c8 ths
        }
5390 9c2149c8 ths
        break;
5391 9c2149c8 ths
    case 25:
5392 9c2149c8 ths
        switch (sel) {
5393 9c2149c8 ths
        case 0:
5394 d9bea114 aurel32
            gen_helper_mtc0_performance0(arg);
5395 2423f660 ths
            rn = "Performance0";
5396 2423f660 ths
            break;
5397 9c2149c8 ths
        case 1:
5398 d9bea114 aurel32
//            gen_helper_mtc0_performance1(arg);
5399 2423f660 ths
            rn = "Performance1";
5400 2423f660 ths
//            break;
5401 9c2149c8 ths
        case 2:
5402 d9bea114 aurel32
//            gen_helper_mtc0_performance2(arg);
5403 2423f660 ths
            rn = "Performance2";
5404 2423f660 ths
//            break;
5405 9c2149c8 ths
        case 3:
5406 d9bea114 aurel32
//            gen_helper_mtc0_performance3(arg);
5407 2423f660 ths
            rn = "Performance3";
5408 2423f660 ths
//            break;
5409 9c2149c8 ths
        case 4:
5410 d9bea114 aurel32
//            gen_helper_mtc0_performance4(arg);
5411 2423f660 ths
            rn = "Performance4";
5412 2423f660 ths
//            break;
5413 9c2149c8 ths
        case 5:
5414 d9bea114 aurel32
//            gen_helper_mtc0_performance5(arg);
5415 2423f660 ths
            rn = "Performance5";
5416 2423f660 ths
//            break;
5417 9c2149c8 ths
        case 6:
5418 d9bea114 aurel32
//            gen_helper_mtc0_performance6(arg);
5419 2423f660 ths
            rn = "Performance6";
5420 2423f660 ths
//            break;
5421 9c2149c8 ths
        case 7:
5422 d9bea114 aurel32
//            gen_helper_mtc0_performance7(arg);
5423 2423f660 ths
            rn = "Performance7";
5424 2423f660 ths
//            break;
5425 9c2149c8 ths
        default:
5426 9c2149c8 ths
            goto die;
5427 9c2149c8 ths
        }
5428 876d4b07 ths
        break;
5429 9c2149c8 ths
    case 26:
5430 876d4b07 ths
        /* ignored */
5431 9c2149c8 ths
        rn = "ECC";
5432 876d4b07 ths
        break;
5433 9c2149c8 ths
    case 27:
5434 9c2149c8 ths
        switch (sel) {
5435 9c2149c8 ths
        case 0 ... 3:
5436 2423f660 ths
            /* ignored */
5437 2423f660 ths
            rn = "CacheErr";
5438 2423f660 ths
            break;
5439 9c2149c8 ths
        default:
5440 9c2149c8 ths
            goto die;
5441 9c2149c8 ths
        }
5442 876d4b07 ths
        break;
5443 9c2149c8 ths
    case 28:
5444 9c2149c8 ths
        switch (sel) {
5445 9c2149c8 ths
        case 0:
5446 9c2149c8 ths
        case 2:
5447 9c2149c8 ths
        case 4:
5448 9c2149c8 ths
        case 6:
5449 d9bea114 aurel32
            gen_helper_mtc0_taglo(arg);
5450 9c2149c8 ths
            rn = "TagLo";
5451 9c2149c8 ths
            break;
5452 9c2149c8 ths
        case 1:
5453 9c2149c8 ths
        case 3:
5454 9c2149c8 ths
        case 5:
5455 9c2149c8 ths
        case 7:
5456 d9bea114 aurel32
            gen_helper_mtc0_datalo(arg);
5457 9c2149c8 ths
            rn = "DataLo";
5458 9c2149c8 ths
            break;
5459 9c2149c8 ths
        default:
5460 9c2149c8 ths
            goto die;
5461 9c2149c8 ths
        }
5462 9c2149c8 ths
        break;
5463 9c2149c8 ths
    case 29:
5464 9c2149c8 ths
        switch (sel) {
5465 9c2149c8 ths
        case 0:
5466 9c2149c8 ths
        case 2:
5467 9c2149c8 ths
        case 4:
5468 9c2149c8 ths
        case 6:
5469 d9bea114 aurel32
            gen_helper_mtc0_taghi(arg);
5470 9c2149c8 ths
            rn = "TagHi";
5471 9c2149c8 ths
            break;
5472 9c2149c8 ths
        case 1:
5473 9c2149c8 ths
        case 3:
5474 9c2149c8 ths
        case 5:
5475 9c2149c8 ths
        case 7:
5476 d9bea114 aurel32
            gen_helper_mtc0_datahi(arg);
5477 9c2149c8 ths
            rn = "DataHi";
5478 9c2149c8 ths
            break;
5479 9c2149c8 ths
        default:
5480 9c2149c8 ths
            rn = "invalid sel";
5481 9c2149c8 ths
            goto die;
5482 9c2149c8 ths
        }
5483 876d4b07 ths
        break;
5484 9c2149c8 ths
    case 30:
5485 9c2149c8 ths
        switch (sel) {
5486 9c2149c8 ths
        case 0:
5487 d9bea114 aurel32
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5488 2423f660 ths
            rn = "ErrorEPC";
5489 2423f660 ths
            break;
5490 9c2149c8 ths
        default:
5491 9c2149c8 ths
            goto die;
5492 9c2149c8 ths
        }
5493 9c2149c8 ths
        break;
5494 9c2149c8 ths
    case 31:
5495 9c2149c8 ths
        switch (sel) {
5496 9c2149c8 ths
        case 0:
5497 f1aa6320 ths
            /* EJTAG support */
5498 d9bea114 aurel32
            gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5499 2423f660 ths
            rn = "DESAVE";
5500 2423f660 ths
            break;
5501 9c2149c8 ths
        default:
5502 9c2149c8 ths
            goto die;
5503 9c2149c8 ths
        }
5504 876d4b07 ths
        /* Stop translation as we may have switched the execution mode */
5505 876d4b07 ths
        ctx->bstate = BS_STOP;
5506 9c2149c8 ths
        break;
5507 9c2149c8 ths
    default:
5508 876d4b07 ths
        goto die;
5509 9c2149c8 ths
    }
5510 2abf314d Blue Swirl
    (void)rn; /* avoid a compiler warning */
5511 d12d51d5 aliguori
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5512 bf20dc07 ths
    /* For simplicity assume that all writes can cause interrupts.  */
5513 2e70f6ef pbrook
    if (use_icount) {
5514 2e70f6ef pbrook
        gen_io_end();
5515 2e70f6ef pbrook
        ctx->bstate = BS_STOP;
5516 2e70f6ef pbrook
    }
5517 9c2149c8 ths
    return;
5518 9c2149c8 ths
5519 9c2149c8 ths
die:
5520 d12d51d5 aliguori
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5521 9c2149c8 ths
    generate_exception(ctx, EXCP_RI);
5522 9c2149c8 ths
}
5523 d26bc211 ths
#endif /* TARGET_MIPS64 */
5524 9c2149c8 ths
5525 6c5c1e20 ths
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5526 ead9360e ths
                     int u, int sel, int h)
5527 ead9360e ths
{
5528 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5529 a7812ae4 pbrook
    TCGv t0 = tcg_temp_local_new();
5530 ead9360e ths
5531 ead9360e ths
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5532 b5dc7732 ths
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5533 b5dc7732 ths
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5534 1a3fd9c3 ths
        tcg_gen_movi_tl(t0, -1);
5535 ead9360e ths
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5536 ead9360e ths
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5537 1a3fd9c3 ths
        tcg_gen_movi_tl(t0, -1);
5538 ead9360e ths
    else if (u == 0) {
5539 ead9360e ths
        switch (rt) {
5540 5a25ce94 Edgar E. Iglesias
        case 1:
5541 5a25ce94 Edgar E. Iglesias
            switch (sel) {
5542 5a25ce94 Edgar E. Iglesias
            case 1:
5543 5a25ce94 Edgar E. Iglesias
                gen_helper_mftc0_vpecontrol(t0);
5544 5a25ce94 Edgar E. Iglesias
                break;
5545 5a25ce94 Edgar E. Iglesias
            case 2:
5546 5a25ce94 Edgar E. Iglesias
                gen_helper_mftc0_vpeconf0(t0);
5547 5a25ce94 Edgar E. Iglesias
                break;
5548 5a25ce94 Edgar E. Iglesias
            default:
5549 5a25ce94 Edgar E. Iglesias
                goto die;
5550 5a25ce94 Edgar E. Iglesias
                break;
5551 5a25ce94 Edgar E. Iglesias
            }
5552 5a25ce94 Edgar E. Iglesias
            break;
5553 ead9360e ths
        case 2:
5554 ead9360e ths
            switch (sel) {
5555 ead9360e ths
            case 1:
5556 a7812ae4 pbrook
                gen_helper_mftc0_tcstatus(t0);
5557 ead9360e ths
                break;
5558 ead9360e ths
            case 2:
5559 a7812ae4 pbrook
                gen_helper_mftc0_tcbind(t0);
5560 ead9360e ths
                break;
5561 ead9360e ths
            case 3:
5562 a7812ae4 pbrook
                gen_helper_mftc0_tcrestart(t0);
5563 ead9360e ths
                break;
5564 ead9360e ths
            case 4:
5565 a7812ae4 pbrook
                gen_helper_mftc0_tchalt(t0);
5566 ead9360e ths
                break;
5567 ead9360e ths
            case 5:
5568 a7812ae4 pbrook
                gen_helper_mftc0_tccontext(t0);
5569 ead9360e ths
                break;
5570 ead9360e ths
            case 6:
5571 a7812ae4 pbrook
                gen_helper_mftc0_tcschedule(t0);
5572 ead9360e ths
                break;
5573 ead9360e ths
            case 7:
5574 a7812ae4 pbrook
                gen_helper_mftc0_tcschefback(t0);
5575 ead9360e ths
                break;
5576 ead9360e ths
            default:
5577 1a3fd9c3 ths
                gen_mfc0(env, ctx, t0, rt, sel);
5578 ead9360e ths
                break;
5579 ead9360e ths
            }
5580 ead9360e ths
            break;
5581 ead9360e ths
        case 10:
5582 ead9360e ths
            switch (sel) {
5583 ead9360e ths
            case 0:
5584 a7812ae4 pbrook
                gen_helper_mftc0_entryhi(t0);
5585 ead9360e ths
                break;
5586 ead9360e ths
            default:
5587 1a3fd9c3 ths
                gen_mfc0(env, ctx, t0, rt, sel);
5588 ead9360e ths
                break;
5589 ead9360e ths
            }
5590 ead9360e ths
        case 12:
5591 ead9360e ths
            switch (sel) {
5592 ead9360e ths
            case 0:
5593 a7812ae4 pbrook
                gen_helper_mftc0_status(t0);
5594 ead9360e ths
                break;
5595 ead9360e ths
            default:
5596 1a3fd9c3 ths
                gen_mfc0(env, ctx, t0, rt, sel);
5597 ead9360e ths
                break;
5598 ead9360e ths
            }
5599 5a25ce94 Edgar E. Iglesias
        case 13:
5600 5a25ce94 Edgar E. Iglesias
            switch (sel) {
5601 5a25ce94 Edgar E. Iglesias
            case 0:
5602 5a25ce94 Edgar E. Iglesias
                gen_helper_mftc0_cause(t0);
5603 5a25ce94 Edgar E. Iglesias
                break;
5604 5a25ce94 Edgar E. Iglesias
            default:
5605 5a25ce94 Edgar E. Iglesias
                goto die;
5606 5a25ce94 Edgar E. Iglesias
                break;
5607 5a25ce94 Edgar E. Iglesias
            }
5608 5a25ce94 Edgar E. Iglesias
            break;
5609 5a25ce94 Edgar E. Iglesias
        case 14:
5610 5a25ce94 Edgar E. Iglesias
            switch (sel) {
5611 5a25ce94 Edgar E. Iglesias
            case 0:
5612 5a25ce94 Edgar E. Iglesias
                gen_helper_mftc0_epc(t0);
5613 5a25ce94 Edgar E. Iglesias
                break;
5614 5a25ce94 Edgar E. Iglesias
            default:
5615 5a25ce94 Edgar E. Iglesias
                goto die;
5616 5a25ce94 Edgar E. Iglesias
                break;
5617 5a25ce94 Edgar E. Iglesias
            }
5618 5a25ce94 Edgar E. Iglesias
            break;
5619 5a25ce94 Edgar E. Iglesias
        case 15:
5620 5a25ce94 Edgar E. Iglesias
            switch (sel) {
5621 5a25ce94 Edgar E. Iglesias
            case 1:
5622 5a25ce94 Edgar E. Iglesias
                gen_helper_mftc0_ebase(t0);
5623 5a25ce94 Edgar E. Iglesias
                break;
5624 5a25ce94 Edgar E. Iglesias
            default:
5625 5a25ce94 Edgar E. Iglesias
                goto die;
5626 5a25ce94 Edgar E. Iglesias
                break;
5627 5a25ce94 Edgar E. Iglesias
            }
5628 5a25ce94 Edgar E. Iglesias
            break;
5629 5a25ce94 Edgar E. Iglesias
        case 16:
5630 5a25ce94 Edgar E. Iglesias
            switch (sel) {
5631 5a25ce94 Edgar E. Iglesias
            case 0 ... 7:
5632 5a25ce94 Edgar E. Iglesias
                gen_helper_mftc0_configx(t0, tcg_const_tl(sel));
5633 5a25ce94 Edgar E. Iglesias
                break;
5634 5a25ce94 Edgar E. Iglesias
            default:
5635 5a25ce94 Edgar E. Iglesias
                goto die;
5636 5a25ce94 Edgar E. Iglesias
                break;
5637 5a25ce94 Edgar E. Iglesias
            }
5638 5a25ce94 Edgar E. Iglesias
            break;
5639 ead9360e ths
        case 23:
5640 ead9360e ths
            switch (sel) {
5641 ead9360e ths
            case 0:
5642 a7812ae4 pbrook
                gen_helper_mftc0_debug(t0);
5643 ead9360e ths
                break;
5644 ead9360e ths
            default:
5645 1a3fd9c3 ths
                gen_mfc0(env, ctx, t0, rt, sel);
5646 ead9360e ths
                break;
5647 ead9360e ths
            }
5648 ead9360e ths
            break;
5649 ead9360e ths
        default:
5650 1a3fd9c3 ths
            gen_mfc0(env, ctx, t0, rt, sel);
5651 ead9360e ths
        }
5652 ead9360e ths
    } else switch (sel) {
5653 ead9360e ths
    /* GPR registers. */
5654 ead9360e ths
    case 0:
5655 a7812ae4 pbrook
        gen_helper_1i(mftgpr, t0, rt);
5656 ead9360e ths
        break;
5657 ead9360e ths
    /* Auxiliary CPU registers */
5658 ead9360e ths
    case 1:
5659 ead9360e ths
        switch (rt) {
5660 ead9360e ths
        case 0:
5661 a7812ae4 pbrook
            gen_helper_1i(mftlo, t0, 0);
5662 ead9360e ths
            break;
5663 ead9360e ths
        case 1:
5664 a7812ae4 pbrook
            gen_helper_1i(mfthi, t0, 0);
5665 ead9360e ths
            break;
5666 ead9360e ths
        case 2:
5667 a7812ae4 pbrook
            gen_helper_1i(mftacx, t0, 0);
5668 ead9360e ths
            break;
5669 ead9360e ths
        case 4:
5670 a7812ae4 pbrook
            gen_helper_1i(mftlo, t0, 1);
5671 ead9360e ths
            break;
5672 ead9360e ths
        case 5:
5673 a7812ae4 pbrook
            gen_helper_1i(mfthi, t0, 1);
5674 ead9360e ths
            break;
5675 ead9360e ths
        case 6:
5676 a7812ae4 pbrook
            gen_helper_1i(mftacx, t0, 1);
5677 ead9360e ths
            break;
5678 ead9360e ths
        case 8:
5679 a7812ae4 pbrook
            gen_helper_1i(mftlo, t0, 2);
5680 ead9360e ths
            break;
5681 ead9360e ths
        case 9:
5682 a7812ae4 pbrook
            gen_helper_1i(mfthi, t0, 2);
5683 ead9360e ths
            break;
5684 ead9360e ths
        case 10:
5685 a7812ae4 pbrook
            gen_helper_1i(mftacx, t0, 2);
5686 ead9360e ths
            break;
5687 ead9360e ths
        case 12:
5688 a7812ae4 pbrook
            gen_helper_1i(mftlo, t0, 3);
5689 ead9360e ths
            break;
5690 ead9360e ths
        case 13:
5691 a7812ae4 pbrook
            gen_helper_1i(mfthi, t0, 3);
5692 ead9360e ths
            break;
5693 ead9360e ths
        case 14:
5694 a7812ae4 pbrook
            gen_helper_1i(mftacx, t0, 3);
5695 ead9360e ths
            break;
5696 ead9360e ths
        case 16:
5697 a7812ae4 pbrook
            gen_helper_mftdsp(t0);
5698 ead9360e ths
            break;
5699 ead9360e ths
        default:
5700 ead9360e ths
            goto die;
5701 ead9360e ths
        }
5702 ead9360e ths
        break;
5703 ead9360e ths
    /* Floating point (COP1). */
5704 ead9360e ths
    case 2:
5705 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5706 ead9360e ths
        if (h == 0) {
5707 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
5708 b6d96bed ths
5709 b6d96bed ths
            gen_load_fpr32(fp0, rt);
5710 b6d96bed ths
            tcg_gen_ext_i32_tl(t0, fp0);
5711 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
5712 ead9360e ths
        } else {
5713 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
5714 b6d96bed ths
5715 b6d96bed ths
            gen_load_fpr32h(fp0, rt);
5716 b6d96bed ths
            tcg_gen_ext_i32_tl(t0, fp0);
5717 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
5718 ead9360e ths
        }
5719 ead9360e ths
        break;
5720 ead9360e ths
    case 3:
5721 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5722 a7812ae4 pbrook
        gen_helper_1i(cfc1, t0, rt);
5723 ead9360e ths
        break;
5724 ead9360e ths
    /* COP2: Not implemented. */
5725 ead9360e ths
    case 4:
5726 ead9360e ths
    case 5:
5727 ead9360e ths
        /* fall through */
5728 ead9360e ths
    default:
5729 ead9360e ths
        goto die;
5730 ead9360e ths
    }
5731 d12d51d5 aliguori
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5732 1a3fd9c3 ths
    gen_store_gpr(t0, rd);
5733 1a3fd9c3 ths
    tcg_temp_free(t0);
5734 ead9360e ths
    return;
5735 ead9360e ths
5736 ead9360e ths
die:
5737 1a3fd9c3 ths
    tcg_temp_free(t0);
5738 d12d51d5 aliguori
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5739 ead9360e ths
    generate_exception(ctx, EXCP_RI);
5740 ead9360e ths
}
5741 ead9360e ths
5742 6c5c1e20 ths
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5743 ead9360e ths
                     int u, int sel, int h)
5744 ead9360e ths
{
5745 ead9360e ths
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5746 a7812ae4 pbrook
    TCGv t0 = tcg_temp_local_new();
5747 ead9360e ths
5748 1a3fd9c3 ths
    gen_load_gpr(t0, rt);
5749 ead9360e ths
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5750 b5dc7732 ths
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5751 b5dc7732 ths
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5752 ead9360e ths
        /* NOP */ ;
5753 ead9360e ths
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5754 ead9360e ths
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5755 ead9360e ths
        /* NOP */ ;
5756 ead9360e ths
    else if (u == 0) {
5757 ead9360e ths
        switch (rd) {
5758 5a25ce94 Edgar E. Iglesias
        case 1:
5759 5a25ce94 Edgar E. Iglesias
            switch (sel) {
5760 5a25ce94 Edgar E. Iglesias
            case 1:
5761 5a25ce94 Edgar E. Iglesias
                gen_helper_mttc0_vpecontrol(t0);
5762 5a25ce94 Edgar E. Iglesias
                break;
5763 5a25ce94 Edgar E. Iglesias
            case 2:
5764 5a25ce94 Edgar E. Iglesias
                gen_helper_mttc0_vpeconf0(t0);
5765 5a25ce94 Edgar E. Iglesias
                break;
5766 5a25ce94 Edgar E. Iglesias
            default:
5767 5a25ce94 Edgar E. Iglesias
                goto die;
5768 5a25ce94 Edgar E. Iglesias
                break;
5769 5a25ce94 Edgar E. Iglesias
            }
5770 5a25ce94 Edgar E. Iglesias
            break;
5771 ead9360e ths
        case 2:
5772 ead9360e ths
            switch (sel) {
5773 ead9360e ths
            case 1:
5774 a7812ae4 pbrook
                gen_helper_mttc0_tcstatus(t0);
5775 ead9360e ths
                break;
5776 ead9360e ths
            case 2:
5777 a7812ae4 pbrook
                gen_helper_mttc0_tcbind(t0);
5778 ead9360e ths
                break;
5779 ead9360e ths
            case 3:
5780 a7812ae4 pbrook
                gen_helper_mttc0_tcrestart(t0);
5781 ead9360e ths
                break;
5782 ead9360e ths
            case 4:
5783 a7812ae4 pbrook
                gen_helper_mttc0_tchalt(t0);
5784 ead9360e ths
                break;
5785 ead9360e ths
            case 5:
5786 a7812ae4 pbrook
                gen_helper_mttc0_tccontext(t0);
5787 ead9360e ths
                break;
5788 ead9360e ths
            case 6:
5789 a7812ae4 pbrook
                gen_helper_mttc0_tcschedule(t0);
5790 ead9360e ths
                break;
5791 ead9360e ths
            case 7:
5792 a7812ae4 pbrook
                gen_helper_mttc0_tcschefback(t0);
5793 ead9360e ths
                break;
5794 ead9360e ths
            default:
5795 1a3fd9c3 ths
                gen_mtc0(env, ctx, t0, rd, sel);
5796 ead9360e ths
                break;
5797 ead9360e ths
            }
5798 ead9360e ths
            break;
5799 ead9360e ths
        case 10:
5800 ead9360e ths
            switch (sel) {
5801 ead9360e ths
            case 0:
5802 a7812ae4 pbrook
                gen_helper_mttc0_entryhi(t0);
5803 ead9360e ths
                break;
5804 ead9360e ths
            default:
5805 1a3fd9c3 ths
                gen_mtc0(env, ctx, t0, rd, sel);
5806 ead9360e ths
                break;
5807 ead9360e ths
            }
5808 ead9360e ths
        case 12:
5809 ead9360e ths
            switch (sel) {
5810 ead9360e ths
            case 0:
5811 a7812ae4 pbrook
                gen_helper_mttc0_status(t0);
5812 ead9360e ths
                break;
5813 ead9360e ths
            default:
5814 1a3fd9c3 ths
                gen_mtc0(env, ctx, t0, rd, sel);
5815 ead9360e ths
                break;
5816 ead9360e ths
            }
5817 5a25ce94 Edgar E. Iglesias
        case 13:
5818 5a25ce94 Edgar E. Iglesias
            switch (sel) {
5819 5a25ce94 Edgar E. Iglesias
            case 0:
5820 5a25ce94 Edgar E. Iglesias
                gen_helper_mttc0_cause(t0);
5821 5a25ce94 Edgar E. Iglesias
                break;
5822 5a25ce94 Edgar E. Iglesias
            default:
5823 5a25ce94 Edgar E. Iglesias
                goto die;
5824 5a25ce94 Edgar E. Iglesias
                break;
5825 5a25ce94 Edgar E. Iglesias
            }
5826 5a25ce94 Edgar E. Iglesias
            break;
5827 5a25ce94 Edgar E. Iglesias
        case 15:
5828 5a25ce94 Edgar E. Iglesias
            switch (sel) {
5829 5a25ce94 Edgar E. Iglesias
            case 1:
5830 5a25ce94 Edgar E. Iglesias
                gen_helper_mttc0_ebase(t0);
5831 5a25ce94 Edgar E. Iglesias
                break;
5832 5a25ce94 Edgar E. Iglesias
            default:
5833 5a25ce94 Edgar E. Iglesias
                goto die;
5834 5a25ce94 Edgar E. Iglesias
                break;
5835 5a25ce94 Edgar E. Iglesias
            }
5836 5a25ce94 Edgar E. Iglesias
            break;
5837 ead9360e ths
        case 23:
5838 ead9360e ths
            switch (sel) {
5839 ead9360e ths
            case 0:
5840 a7812ae4 pbrook
                gen_helper_mttc0_debug(t0);
5841 ead9360e ths
                break;
5842 ead9360e ths
            default:
5843 1a3fd9c3 ths
                gen_mtc0(env, ctx, t0, rd, sel);
5844 ead9360e ths
                break;
5845 ead9360e ths
            }
5846 ead9360e ths
            break;
5847 ead9360e ths
        default:
5848 1a3fd9c3 ths
            gen_mtc0(env, ctx, t0, rd, sel);
5849 ead9360e ths
        }
5850 ead9360e ths
    } else switch (sel) {
5851 ead9360e ths
    /* GPR registers. */
5852 ead9360e ths
    case 0:
5853 a7812ae4 pbrook
        gen_helper_1i(mttgpr, t0, rd);
5854 ead9360e ths
        break;
5855 ead9360e ths
    /* Auxiliary CPU registers */
5856 ead9360e ths
    case 1:
5857 ead9360e ths
        switch (rd) {
5858 ead9360e ths
        case 0:
5859 a7812ae4 pbrook
            gen_helper_1i(mttlo, t0, 0);
5860 ead9360e ths
            break;
5861 ead9360e ths
        case 1:
5862 a7812ae4 pbrook
            gen_helper_1i(mtthi, t0, 0);
5863 ead9360e ths
            break;
5864 ead9360e ths
        case 2:
5865 a7812ae4 pbrook
            gen_helper_1i(mttacx, t0, 0);
5866 ead9360e ths
            break;
5867 ead9360e ths
        case 4:
5868 a7812ae4 pbrook
            gen_helper_1i(mttlo, t0, 1);
5869 ead9360e ths
            break;
5870 ead9360e ths
        case 5:
5871 a7812ae4 pbrook
            gen_helper_1i(mtthi, t0, 1);
5872 ead9360e ths
            break;
5873 ead9360e ths
        case 6:
5874 a7812ae4 pbrook
            gen_helper_1i(mttacx, t0, 1);
5875 ead9360e ths
            break;
5876 ead9360e ths
        case 8:
5877 a7812ae4 pbrook
            gen_helper_1i(mttlo, t0, 2);
5878 ead9360e ths
            break;
5879 ead9360e ths
        case 9:
5880 a7812ae4 pbrook
            gen_helper_1i(mtthi, t0, 2);
5881 ead9360e ths
            break;
5882 ead9360e ths
        case 10:
5883 a7812ae4 pbrook
            gen_helper_1i(mttacx, t0, 2);
5884 ead9360e ths
            break;
5885 ead9360e ths
        case 12:
5886 a7812ae4 pbrook
            gen_helper_1i(mttlo, t0, 3);
5887 ead9360e ths
            break;
5888 ead9360e ths
        case 13:
5889 a7812ae4 pbrook
            gen_helper_1i(mtthi, t0, 3);
5890 ead9360e ths
            break;
5891 ead9360e ths
        case 14:
5892 a7812ae4 pbrook
            gen_helper_1i(mttacx, t0, 3);
5893 ead9360e ths
            break;
5894 ead9360e ths
        case 16:
5895 a7812ae4 pbrook
            gen_helper_mttdsp(t0);
5896 ead9360e ths
            break;
5897 ead9360e ths
        default:
5898 ead9360e ths
            goto die;
5899 ead9360e ths
        }
5900 ead9360e ths
        break;
5901 ead9360e ths
    /* Floating point (COP1). */
5902 ead9360e ths
    case 2:
5903 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5904 ead9360e ths
        if (h == 0) {
5905 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
5906 b6d96bed ths
5907 b6d96bed ths
            tcg_gen_trunc_tl_i32(fp0, t0);
5908 b6d96bed ths
            gen_store_fpr32(fp0, rd);
5909 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
5910 ead9360e ths
        } else {
5911 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
5912 b6d96bed ths
5913 b6d96bed ths
            tcg_gen_trunc_tl_i32(fp0, t0);
5914 b6d96bed ths
            gen_store_fpr32h(fp0, rd);
5915 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
5916 ead9360e ths
        }
5917 ead9360e ths
        break;
5918 ead9360e ths
    case 3:
5919 ead9360e ths
        /* XXX: For now we support only a single FPU context. */
5920 a7812ae4 pbrook
        gen_helper_1i(ctc1, t0, rd);
5921 ead9360e ths
        break;
5922 ead9360e ths
    /* COP2: Not implemented. */
5923 ead9360e ths
    case 4:
5924 ead9360e ths
    case 5:
5925 ead9360e ths
        /* fall through */
5926 ead9360e ths
    default:
5927 ead9360e ths
        goto die;
5928 ead9360e ths
    }
5929 d12d51d5 aliguori
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5930 1a3fd9c3 ths
    tcg_temp_free(t0);
5931 ead9360e ths
    return;
5932 ead9360e ths
5933 ead9360e ths
die:
5934 1a3fd9c3 ths
    tcg_temp_free(t0);
5935 d12d51d5 aliguori
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5936 ead9360e ths
    generate_exception(ctx, EXCP_RI);
5937 ead9360e ths
}
5938 ead9360e ths
5939 29929e34 ths
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5940 6af0bf9c bellard
{
5941 287c4b84 ths
    const char *opn = "ldst";
5942 6af0bf9c bellard
5943 6af0bf9c bellard
    switch (opc) {
5944 6af0bf9c bellard
    case OPC_MFC0:
5945 6af0bf9c bellard
        if (rt == 0) {
5946 ead9360e ths
            /* Treat as NOP. */
5947 6af0bf9c bellard
            return;
5948 6af0bf9c bellard
        }
5949 1fc7bf6e aurel32
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5950 6af0bf9c bellard
        opn = "mfc0";
5951 6af0bf9c bellard
        break;
5952 6af0bf9c bellard
    case OPC_MTC0:
5953 1a3fd9c3 ths
        {
5954 1fc7bf6e aurel32
            TCGv t0 = tcg_temp_new();
5955 1a3fd9c3 ths
5956 1a3fd9c3 ths
            gen_load_gpr(t0, rt);
5957 1a3fd9c3 ths
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5958 1a3fd9c3 ths
            tcg_temp_free(t0);
5959 1a3fd9c3 ths
        }
5960 6af0bf9c bellard
        opn = "mtc0";
5961 6af0bf9c bellard
        break;
5962 d26bc211 ths
#if defined(TARGET_MIPS64)
5963 9c2149c8 ths
    case OPC_DMFC0:
5964 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
5965 9c2149c8 ths
        if (rt == 0) {
5966 ead9360e ths
            /* Treat as NOP. */
5967 9c2149c8 ths
            return;
5968 9c2149c8 ths
        }
5969 1fc7bf6e aurel32
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5970 9c2149c8 ths
        opn = "dmfc0";
5971 9c2149c8 ths
        break;
5972 9c2149c8 ths
    case OPC_DMTC0:
5973 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
5974 1a3fd9c3 ths
        {
5975 1fc7bf6e aurel32
            TCGv t0 = tcg_temp_new();
5976 1a3fd9c3 ths
5977 1a3fd9c3 ths
            gen_load_gpr(t0, rt);
5978 1a3fd9c3 ths
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5979 1a3fd9c3 ths
            tcg_temp_free(t0);
5980 1a3fd9c3 ths
        }
5981 9c2149c8 ths
        opn = "dmtc0";
5982 9c2149c8 ths
        break;
5983 534ce69f ths
#endif
5984 ead9360e ths
    case OPC_MFTR:
5985 7385ac0b ths
        check_insn(env, ctx, ASE_MT);
5986 ead9360e ths
        if (rd == 0) {
5987 ead9360e ths
            /* Treat as NOP. */
5988 ead9360e ths
            return;
5989 ead9360e ths
        }
5990 6c5c1e20 ths
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5991 ead9360e ths
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5992 ead9360e ths
        opn = "mftr";
5993 ead9360e ths
        break;
5994 ead9360e ths
    case OPC_MTTR:
5995 7385ac0b ths
        check_insn(env, ctx, ASE_MT);
5996 6c5c1e20 ths
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5997 ead9360e ths
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5998 ead9360e ths
        opn = "mttr";
5999 ead9360e ths
        break;
6000 6af0bf9c bellard
    case OPC_TLBWI:
6001 6af0bf9c bellard
        opn = "tlbwi";
6002 c01fccd2 aurel32
        if (!env->tlb->helper_tlbwi)
6003 29929e34 ths
            goto die;
6004 a7812ae4 pbrook
        gen_helper_tlbwi();
6005 6af0bf9c bellard
        break;
6006 6af0bf9c bellard
    case OPC_TLBWR:
6007 6af0bf9c bellard
        opn = "tlbwr";
6008 c01fccd2 aurel32
        if (!env->tlb->helper_tlbwr)
6009 29929e34 ths
            goto die;
6010 a7812ae4 pbrook
        gen_helper_tlbwr();
6011 6af0bf9c bellard
        break;
6012 6af0bf9c bellard
    case OPC_TLBP:
6013 6af0bf9c bellard
        opn = "tlbp";
6014 c01fccd2 aurel32
        if (!env->tlb->helper_tlbp)
6015 29929e34 ths
            goto die;
6016 a7812ae4 pbrook
        gen_helper_tlbp();
6017 6af0bf9c bellard
        break;
6018 6af0bf9c bellard
    case OPC_TLBR:
6019 6af0bf9c bellard
        opn = "tlbr";
6020 c01fccd2 aurel32
        if (!env->tlb->helper_tlbr)
6021 29929e34 ths
            goto die;
6022 a7812ae4 pbrook
        gen_helper_tlbr();
6023 6af0bf9c bellard
        break;
6024 6af0bf9c bellard
    case OPC_ERET:
6025 6af0bf9c bellard
        opn = "eret";
6026 e189e748 ths
        check_insn(env, ctx, ISA_MIPS2);
6027 a7812ae4 pbrook
        gen_helper_eret();
6028 6af0bf9c bellard
        ctx->bstate = BS_EXCP;
6029 6af0bf9c bellard
        break;
6030 6af0bf9c bellard
    case OPC_DERET:
6031 6af0bf9c bellard
        opn = "deret";
6032 e189e748 ths
        check_insn(env, ctx, ISA_MIPS32);
6033 6af0bf9c bellard
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6034 923617a3 ths
            MIPS_INVAL(opn);
6035 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
6036 6af0bf9c bellard
        } else {
6037 a7812ae4 pbrook
            gen_helper_deret();
6038 6af0bf9c bellard
            ctx->bstate = BS_EXCP;
6039 6af0bf9c bellard
        }
6040 6af0bf9c bellard
        break;
6041 4ad40f36 bellard
    case OPC_WAIT:
6042 4ad40f36 bellard
        opn = "wait";
6043 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6044 4ad40f36 bellard
        /* If we get an exception, we want to restart at next instruction */
6045 4ad40f36 bellard
        ctx->pc += 4;
6046 4ad40f36 bellard
        save_cpu_state(ctx, 1);
6047 4ad40f36 bellard
        ctx->pc -= 4;
6048 a7812ae4 pbrook
        gen_helper_wait();
6049 4ad40f36 bellard
        ctx->bstate = BS_EXCP;
6050 4ad40f36 bellard
        break;
6051 6af0bf9c bellard
    default:
6052 29929e34 ths
 die:
6053 923617a3 ths
        MIPS_INVAL(opn);
6054 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
6055 6af0bf9c bellard
        return;
6056 6af0bf9c bellard
    }
6057 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
6058 6af0bf9c bellard
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6059 6af0bf9c bellard
}
6060 f1aa6320 ths
#endif /* !CONFIG_USER_ONLY */
6061 6af0bf9c bellard
6062 6ea83fed bellard
/* CP1 Branches (before delay slot) */
6063 e189e748 ths
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
6064 5a5012ec ths
                                 int32_t cc, int32_t offset)
6065 6ea83fed bellard
{
6066 6ea83fed bellard
    target_ulong btarget;
6067 923617a3 ths
    const char *opn = "cp1 cond branch";
6068 a7812ae4 pbrook
    TCGv_i32 t0 = tcg_temp_new_i32();
6069 6ea83fed bellard
6070 e189e748 ths
    if (cc != 0)
6071 e189e748 ths
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6072 e189e748 ths
6073 6ea83fed bellard
    btarget = ctx->pc + 4 + offset;
6074 6ea83fed bellard
6075 7a387fff ths
    switch (op) {
6076 7a387fff ths
    case OPC_BC1F:
6077 d94536f4 aurel32
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6078 d94536f4 aurel32
        tcg_gen_not_i32(t0, t0);
6079 d94536f4 aurel32
        tcg_gen_andi_i32(t0, t0, 1);
6080 d94536f4 aurel32
        tcg_gen_extu_i32_tl(bcond, t0);
6081 923617a3 ths
        opn = "bc1f";
6082 6ea83fed bellard
        goto not_likely;
6083 7a387fff ths
    case OPC_BC1FL:
6084 d94536f4 aurel32
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6085 d94536f4 aurel32
        tcg_gen_not_i32(t0, t0);
6086 d94536f4 aurel32
        tcg_gen_andi_i32(t0, t0, 1);
6087 d94536f4 aurel32
        tcg_gen_extu_i32_tl(bcond, t0);
6088 923617a3 ths
        opn = "bc1fl";
6089 6ea83fed bellard
        goto likely;
6090 7a387fff ths
    case OPC_BC1T:
6091 d94536f4 aurel32
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6092 d94536f4 aurel32
        tcg_gen_andi_i32(t0, t0, 1);
6093 d94536f4 aurel32
        tcg_gen_extu_i32_tl(bcond, t0);
6094 923617a3 ths
        opn = "bc1t";
6095 5a5012ec ths
        goto not_likely;
6096 7a387fff ths
    case OPC_BC1TL:
6097 d94536f4 aurel32
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6098 d94536f4 aurel32
        tcg_gen_andi_i32(t0, t0, 1);
6099 d94536f4 aurel32
        tcg_gen_extu_i32_tl(bcond, t0);
6100 923617a3 ths
        opn = "bc1tl";
6101 6ea83fed bellard
    likely:
6102 6ea83fed bellard
        ctx->hflags |= MIPS_HFLAG_BL;
6103 6ea83fed bellard
        break;
6104 5a5012ec ths
    case OPC_BC1FANY2:
6105 a16336e4 ths
        {
6106 d94536f4 aurel32
            TCGv_i32 t1 = tcg_temp_new_i32();
6107 d94536f4 aurel32
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6108 d94536f4 aurel32
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6109 deb4203d Aurelien Jarno
            tcg_gen_nor_i32(t0, t0, t1);
6110 d94536f4 aurel32
            tcg_temp_free_i32(t1);
6111 d94536f4 aurel32
            tcg_gen_andi_i32(t0, t0, 1);
6112 d94536f4 aurel32
            tcg_gen_extu_i32_tl(bcond, t0);
6113 a16336e4 ths
        }
6114 fd4a04eb ths
        opn = "bc1any2f";
6115 5a5012ec ths
        goto not_likely;
6116 5a5012ec ths
    case OPC_BC1TANY2:
6117 a16336e4 ths
        {
6118 d94536f4 aurel32
            TCGv_i32 t1 = tcg_temp_new_i32();
6119 d94536f4 aurel32
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6120 d94536f4 aurel32
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6121 d94536f4 aurel32
            tcg_gen_or_i32(t0, t0, t1);
6122 d94536f4 aurel32
            tcg_temp_free_i32(t1);
6123 d94536f4 aurel32
            tcg_gen_andi_i32(t0, t0, 1);
6124 d94536f4 aurel32
            tcg_gen_extu_i32_tl(bcond, t0);
6125 a16336e4 ths
        }
6126 fd4a04eb ths
        opn = "bc1any2t";
6127 5a5012ec ths
        goto not_likely;
6128 5a5012ec ths
    case OPC_BC1FANY4:
6129 a16336e4 ths
        {
6130 d94536f4 aurel32
            TCGv_i32 t1 = tcg_temp_new_i32();
6131 d94536f4 aurel32
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6132 d94536f4 aurel32
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6133 d94536f4 aurel32
            tcg_gen_or_i32(t0, t0, t1);
6134 d94536f4 aurel32
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6135 d94536f4 aurel32
            tcg_gen_or_i32(t0, t0, t1);
6136 d94536f4 aurel32
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6137 deb4203d Aurelien Jarno
            tcg_gen_nor_i32(t0, t0, t1);
6138 d94536f4 aurel32
            tcg_temp_free_i32(t1);
6139 d94536f4 aurel32
            tcg_gen_andi_i32(t0, t0, 1);
6140 d94536f4 aurel32
            tcg_gen_extu_i32_tl(bcond, t0);
6141 a16336e4 ths
        }
6142 fd4a04eb ths
        opn = "bc1any4f";
6143 5a5012ec ths
        goto not_likely;
6144 5a5012ec ths
    case OPC_BC1TANY4:
6145 a16336e4 ths
        {
6146 d94536f4 aurel32
            TCGv_i32 t1 = tcg_temp_new_i32();
6147 d94536f4 aurel32
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6148 d94536f4 aurel32
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6149 d94536f4 aurel32
            tcg_gen_or_i32(t0, t0, t1);
6150 d94536f4 aurel32
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6151 d94536f4 aurel32
            tcg_gen_or_i32(t0, t0, t1);
6152 d94536f4 aurel32
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6153 d94536f4 aurel32
            tcg_gen_or_i32(t0, t0, t1);
6154 d94536f4 aurel32
            tcg_temp_free_i32(t1);
6155 d94536f4 aurel32
            tcg_gen_andi_i32(t0, t0, 1);
6156 d94536f4 aurel32
            tcg_gen_extu_i32_tl(bcond, t0);
6157 a16336e4 ths
        }
6158 fd4a04eb ths
        opn = "bc1any4t";
6159 5a5012ec ths
    not_likely:
6160 5a5012ec ths
        ctx->hflags |= MIPS_HFLAG_BC;
6161 5a5012ec ths
        break;
6162 5a5012ec ths
    default:
6163 923617a3 ths
        MIPS_INVAL(opn);
6164 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
6165 6c5c1e20 ths
        goto out;
6166 6ea83fed bellard
    }
6167 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
6168 923617a3 ths
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6169 6ea83fed bellard
               ctx->hflags, btarget);
6170 6ea83fed bellard
    ctx->btarget = btarget;
6171 6c5c1e20 ths
6172 6c5c1e20 ths
 out:
6173 a7812ae4 pbrook
    tcg_temp_free_i32(t0);
6174 6ea83fed bellard
}
6175 6ea83fed bellard
6176 6af0bf9c bellard
/* Coprocessor 1 (FPU) */
6177 5a5012ec ths
6178 5a5012ec ths
#define FOP(func, fmt) (((fmt) << 21) | (func))
6179 5a5012ec ths
6180 bf4120ad Nathan Froyd
enum fopcode {
6181 bf4120ad Nathan Froyd
    OPC_ADD_S = FOP(0, FMT_S),
6182 bf4120ad Nathan Froyd
    OPC_SUB_S = FOP(1, FMT_S),
6183 bf4120ad Nathan Froyd
    OPC_MUL_S = FOP(2, FMT_S),
6184 bf4120ad Nathan Froyd
    OPC_DIV_S = FOP(3, FMT_S),
6185 bf4120ad Nathan Froyd
    OPC_SQRT_S = FOP(4, FMT_S),
6186 bf4120ad Nathan Froyd
    OPC_ABS_S = FOP(5, FMT_S),
6187 bf4120ad Nathan Froyd
    OPC_MOV_S = FOP(6, FMT_S),
6188 bf4120ad Nathan Froyd
    OPC_NEG_S = FOP(7, FMT_S),
6189 bf4120ad Nathan Froyd
    OPC_ROUND_L_S = FOP(8, FMT_S),
6190 bf4120ad Nathan Froyd
    OPC_TRUNC_L_S = FOP(9, FMT_S),
6191 bf4120ad Nathan Froyd
    OPC_CEIL_L_S = FOP(10, FMT_S),
6192 bf4120ad Nathan Froyd
    OPC_FLOOR_L_S = FOP(11, FMT_S),
6193 bf4120ad Nathan Froyd
    OPC_ROUND_W_S = FOP(12, FMT_S),
6194 bf4120ad Nathan Froyd
    OPC_TRUNC_W_S = FOP(13, FMT_S),
6195 bf4120ad Nathan Froyd
    OPC_CEIL_W_S = FOP(14, FMT_S),
6196 bf4120ad Nathan Froyd
    OPC_FLOOR_W_S = FOP(15, FMT_S),
6197 bf4120ad Nathan Froyd
    OPC_MOVCF_S = FOP(17, FMT_S),
6198 bf4120ad Nathan Froyd
    OPC_MOVZ_S = FOP(18, FMT_S),
6199 bf4120ad Nathan Froyd
    OPC_MOVN_S = FOP(19, FMT_S),
6200 bf4120ad Nathan Froyd
    OPC_RECIP_S = FOP(21, FMT_S),
6201 bf4120ad Nathan Froyd
    OPC_RSQRT_S = FOP(22, FMT_S),
6202 bf4120ad Nathan Froyd
    OPC_RECIP2_S = FOP(28, FMT_S),
6203 bf4120ad Nathan Froyd
    OPC_RECIP1_S = FOP(29, FMT_S),
6204 bf4120ad Nathan Froyd
    OPC_RSQRT1_S = FOP(30, FMT_S),
6205 bf4120ad Nathan Froyd
    OPC_RSQRT2_S = FOP(31, FMT_S),
6206 bf4120ad Nathan Froyd
    OPC_CVT_D_S = FOP(33, FMT_S),
6207 bf4120ad Nathan Froyd
    OPC_CVT_W_S = FOP(36, FMT_S),
6208 bf4120ad Nathan Froyd
    OPC_CVT_L_S = FOP(37, FMT_S),
6209 bf4120ad Nathan Froyd
    OPC_CVT_PS_S = FOP(38, FMT_S),
6210 bf4120ad Nathan Froyd
    OPC_CMP_F_S = FOP (48, FMT_S),
6211 bf4120ad Nathan Froyd
    OPC_CMP_UN_S = FOP (49, FMT_S),
6212 bf4120ad Nathan Froyd
    OPC_CMP_EQ_S = FOP (50, FMT_S),
6213 bf4120ad Nathan Froyd
    OPC_CMP_UEQ_S = FOP (51, FMT_S),
6214 bf4120ad Nathan Froyd
    OPC_CMP_OLT_S = FOP (52, FMT_S),
6215 bf4120ad Nathan Froyd
    OPC_CMP_ULT_S = FOP (53, FMT_S),
6216 bf4120ad Nathan Froyd
    OPC_CMP_OLE_S = FOP (54, FMT_S),
6217 bf4120ad Nathan Froyd
    OPC_CMP_ULE_S = FOP (55, FMT_S),
6218 bf4120ad Nathan Froyd
    OPC_CMP_SF_S = FOP (56, FMT_S),
6219 bf4120ad Nathan Froyd
    OPC_CMP_NGLE_S = FOP (57, FMT_S),
6220 bf4120ad Nathan Froyd
    OPC_CMP_SEQ_S = FOP (58, FMT_S),
6221 bf4120ad Nathan Froyd
    OPC_CMP_NGL_S = FOP (59, FMT_S),
6222 bf4120ad Nathan Froyd
    OPC_CMP_LT_S = FOP (60, FMT_S),
6223 bf4120ad Nathan Froyd
    OPC_CMP_NGE_S = FOP (61, FMT_S),
6224 bf4120ad Nathan Froyd
    OPC_CMP_LE_S = FOP (62, FMT_S),
6225 bf4120ad Nathan Froyd
    OPC_CMP_NGT_S = FOP (63, FMT_S),
6226 bf4120ad Nathan Froyd
6227 bf4120ad Nathan Froyd
    OPC_ADD_D = FOP(0, FMT_D),
6228 bf4120ad Nathan Froyd
    OPC_SUB_D = FOP(1, FMT_D),
6229 bf4120ad Nathan Froyd
    OPC_MUL_D = FOP(2, FMT_D),
6230 bf4120ad Nathan Froyd
    OPC_DIV_D = FOP(3, FMT_D),
6231 bf4120ad Nathan Froyd
    OPC_SQRT_D = FOP(4, FMT_D),
6232 bf4120ad Nathan Froyd
    OPC_ABS_D = FOP(5, FMT_D),
6233 bf4120ad Nathan Froyd
    OPC_MOV_D = FOP(6, FMT_D),
6234 bf4120ad Nathan Froyd
    OPC_NEG_D = FOP(7, FMT_D),
6235 bf4120ad Nathan Froyd
    OPC_ROUND_L_D = FOP(8, FMT_D),
6236 bf4120ad Nathan Froyd
    OPC_TRUNC_L_D = FOP(9, FMT_D),
6237 bf4120ad Nathan Froyd
    OPC_CEIL_L_D = FOP(10, FMT_D),
6238 bf4120ad Nathan Froyd
    OPC_FLOOR_L_D = FOP(11, FMT_D),
6239 bf4120ad Nathan Froyd
    OPC_ROUND_W_D = FOP(12, FMT_D),
6240 bf4120ad Nathan Froyd
    OPC_TRUNC_W_D = FOP(13, FMT_D),
6241 bf4120ad Nathan Froyd
    OPC_CEIL_W_D = FOP(14, FMT_D),
6242 bf4120ad Nathan Froyd
    OPC_FLOOR_W_D = FOP(15, FMT_D),
6243 bf4120ad Nathan Froyd
    OPC_MOVCF_D = FOP(17, FMT_D),
6244 bf4120ad Nathan Froyd
    OPC_MOVZ_D = FOP(18, FMT_D),
6245 bf4120ad Nathan Froyd
    OPC_MOVN_D = FOP(19, FMT_D),
6246 bf4120ad Nathan Froyd
    OPC_RECIP_D = FOP(21, FMT_D),
6247 bf4120ad Nathan Froyd
    OPC_RSQRT_D = FOP(22, FMT_D),
6248 bf4120ad Nathan Froyd
    OPC_RECIP2_D = FOP(28, FMT_D),
6249 bf4120ad Nathan Froyd
    OPC_RECIP1_D = FOP(29, FMT_D),
6250 bf4120ad Nathan Froyd
    OPC_RSQRT1_D = FOP(30, FMT_D),
6251 bf4120ad Nathan Froyd
    OPC_RSQRT2_D = FOP(31, FMT_D),
6252 bf4120ad Nathan Froyd
    OPC_CVT_S_D = FOP(32, FMT_D),
6253 bf4120ad Nathan Froyd
    OPC_CVT_W_D = FOP(36, FMT_D),
6254 bf4120ad Nathan Froyd
    OPC_CVT_L_D = FOP(37, FMT_D),
6255 bf4120ad Nathan Froyd
    OPC_CMP_F_D = FOP (48, FMT_D),
6256 bf4120ad Nathan Froyd
    OPC_CMP_UN_D = FOP (49, FMT_D),
6257 bf4120ad Nathan Froyd
    OPC_CMP_EQ_D = FOP (50, FMT_D),
6258 bf4120ad Nathan Froyd
    OPC_CMP_UEQ_D = FOP (51, FMT_D),
6259 bf4120ad Nathan Froyd
    OPC_CMP_OLT_D = FOP (52, FMT_D),
6260 bf4120ad Nathan Froyd
    OPC_CMP_ULT_D = FOP (53, FMT_D),
6261 bf4120ad Nathan Froyd
    OPC_CMP_OLE_D = FOP (54, FMT_D),
6262 bf4120ad Nathan Froyd
    OPC_CMP_ULE_D = FOP (55, FMT_D),
6263 bf4120ad Nathan Froyd
    OPC_CMP_SF_D = FOP (56, FMT_D),
6264 bf4120ad Nathan Froyd
    OPC_CMP_NGLE_D = FOP (57, FMT_D),
6265 bf4120ad Nathan Froyd
    OPC_CMP_SEQ_D = FOP (58, FMT_D),
6266 bf4120ad Nathan Froyd
    OPC_CMP_NGL_D = FOP (59, FMT_D),
6267 bf4120ad Nathan Froyd
    OPC_CMP_LT_D = FOP (60, FMT_D),
6268 bf4120ad Nathan Froyd
    OPC_CMP_NGE_D = FOP (61, FMT_D),
6269 bf4120ad Nathan Froyd
    OPC_CMP_LE_D = FOP (62, FMT_D),
6270 bf4120ad Nathan Froyd
    OPC_CMP_NGT_D = FOP (63, FMT_D),
6271 bf4120ad Nathan Froyd
6272 bf4120ad Nathan Froyd
    OPC_CVT_S_W = FOP(32, FMT_W),
6273 bf4120ad Nathan Froyd
    OPC_CVT_D_W = FOP(33, FMT_W),
6274 bf4120ad Nathan Froyd
    OPC_CVT_S_L = FOP(32, FMT_L),
6275 bf4120ad Nathan Froyd
    OPC_CVT_D_L = FOP(33, FMT_L),
6276 bf4120ad Nathan Froyd
    OPC_CVT_PS_PW = FOP(38, FMT_W),
6277 bf4120ad Nathan Froyd
6278 bf4120ad Nathan Froyd
    OPC_ADD_PS = FOP(0, FMT_PS),
6279 bf4120ad Nathan Froyd
    OPC_SUB_PS = FOP(1, FMT_PS),
6280 bf4120ad Nathan Froyd
    OPC_MUL_PS = FOP(2, FMT_PS),
6281 bf4120ad Nathan Froyd
    OPC_DIV_PS = FOP(3, FMT_PS),
6282 bf4120ad Nathan Froyd
    OPC_ABS_PS = FOP(5, FMT_PS),
6283 bf4120ad Nathan Froyd
    OPC_MOV_PS = FOP(6, FMT_PS),
6284 bf4120ad Nathan Froyd
    OPC_NEG_PS = FOP(7, FMT_PS),
6285 bf4120ad Nathan Froyd
    OPC_MOVCF_PS = FOP(17, FMT_PS),
6286 bf4120ad Nathan Froyd
    OPC_MOVZ_PS = FOP(18, FMT_PS),
6287 bf4120ad Nathan Froyd
    OPC_MOVN_PS = FOP(19, FMT_PS),
6288 bf4120ad Nathan Froyd
    OPC_ADDR_PS = FOP(24, FMT_PS),
6289 bf4120ad Nathan Froyd
    OPC_MULR_PS = FOP(26, FMT_PS),
6290 bf4120ad Nathan Froyd
    OPC_RECIP2_PS = FOP(28, FMT_PS),
6291 bf4120ad Nathan Froyd
    OPC_RECIP1_PS = FOP(29, FMT_PS),
6292 bf4120ad Nathan Froyd
    OPC_RSQRT1_PS = FOP(30, FMT_PS),
6293 bf4120ad Nathan Froyd
    OPC_RSQRT2_PS = FOP(31, FMT_PS),
6294 bf4120ad Nathan Froyd
6295 bf4120ad Nathan Froyd
    OPC_CVT_S_PU = FOP(32, FMT_PS),
6296 bf4120ad Nathan Froyd
    OPC_CVT_PW_PS = FOP(36, FMT_PS),
6297 bf4120ad Nathan Froyd
    OPC_CVT_S_PL = FOP(40, FMT_PS),
6298 bf4120ad Nathan Froyd
    OPC_PLL_PS = FOP(44, FMT_PS),
6299 bf4120ad Nathan Froyd
    OPC_PLU_PS = FOP(45, FMT_PS),
6300 bf4120ad Nathan Froyd
    OPC_PUL_PS = FOP(46, FMT_PS),
6301 bf4120ad Nathan Froyd
    OPC_PUU_PS = FOP(47, FMT_PS),
6302 bf4120ad Nathan Froyd
    OPC_CMP_F_PS = FOP (48, FMT_PS),
6303 bf4120ad Nathan Froyd
    OPC_CMP_UN_PS = FOP (49, FMT_PS),
6304 bf4120ad Nathan Froyd
    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
6305 bf4120ad Nathan Froyd
    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
6306 bf4120ad Nathan Froyd
    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
6307 bf4120ad Nathan Froyd
    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
6308 bf4120ad Nathan Froyd
    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
6309 bf4120ad Nathan Froyd
    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
6310 bf4120ad Nathan Froyd
    OPC_CMP_SF_PS = FOP (56, FMT_PS),
6311 bf4120ad Nathan Froyd
    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
6312 bf4120ad Nathan Froyd
    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
6313 bf4120ad Nathan Froyd
    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
6314 bf4120ad Nathan Froyd
    OPC_CMP_LT_PS = FOP (60, FMT_PS),
6315 bf4120ad Nathan Froyd
    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
6316 bf4120ad Nathan Froyd
    OPC_CMP_LE_PS = FOP (62, FMT_PS),
6317 bf4120ad Nathan Froyd
    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
6318 bf4120ad Nathan Froyd
};
6319 bf4120ad Nathan Froyd
6320 7a387fff ths
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6321 6ea83fed bellard
{
6322 923617a3 ths
    const char *opn = "cp1 move";
6323 72c3a3ee aurel32
    TCGv t0 = tcg_temp_new();
6324 6ea83fed bellard
6325 6ea83fed bellard
    switch (opc) {
6326 6ea83fed bellard
    case OPC_MFC1:
6327 b6d96bed ths
        {
6328 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6329 b6d96bed ths
6330 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6331 b6d96bed ths
            tcg_gen_ext_i32_tl(t0, fp0);
6332 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6333 6958549d aurel32
        }
6334 6c5c1e20 ths
        gen_store_gpr(t0, rt);
6335 6ea83fed bellard
        opn = "mfc1";
6336 6ea83fed bellard
        break;
6337 6ea83fed bellard
    case OPC_MTC1:
6338 6c5c1e20 ths
        gen_load_gpr(t0, rt);
6339 b6d96bed ths
        {
6340 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6341 b6d96bed ths
6342 b6d96bed ths
            tcg_gen_trunc_tl_i32(fp0, t0);
6343 b6d96bed ths
            gen_store_fpr32(fp0, fs);
6344 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6345 6958549d aurel32
        }
6346 6ea83fed bellard
        opn = "mtc1";
6347 6ea83fed bellard
        break;
6348 6ea83fed bellard
    case OPC_CFC1:
6349 a7812ae4 pbrook
        gen_helper_1i(cfc1, t0, fs);
6350 6c5c1e20 ths
        gen_store_gpr(t0, rt);
6351 6ea83fed bellard
        opn = "cfc1";
6352 6ea83fed bellard
        break;
6353 6ea83fed bellard
    case OPC_CTC1:
6354 6c5c1e20 ths
        gen_load_gpr(t0, rt);
6355 a7812ae4 pbrook
        gen_helper_1i(ctc1, t0, fs);
6356 6ea83fed bellard
        opn = "ctc1";
6357 6ea83fed bellard
        break;
6358 72c3a3ee aurel32
#if defined(TARGET_MIPS64)
6359 9c2149c8 ths
    case OPC_DMFC1:
6360 72c3a3ee aurel32
        gen_load_fpr64(ctx, t0, fs);
6361 6c5c1e20 ths
        gen_store_gpr(t0, rt);
6362 5a5012ec ths
        opn = "dmfc1";
6363 5a5012ec ths
        break;
6364 9c2149c8 ths
    case OPC_DMTC1:
6365 6c5c1e20 ths
        gen_load_gpr(t0, rt);
6366 72c3a3ee aurel32
        gen_store_fpr64(ctx, t0, fs);
6367 5a5012ec ths
        opn = "dmtc1";
6368 5a5012ec ths
        break;
6369 72c3a3ee aurel32
#endif
6370 5a5012ec ths
    case OPC_MFHC1:
6371 b6d96bed ths
        {
6372 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6373 b6d96bed ths
6374 b6d96bed ths
            gen_load_fpr32h(fp0, fs);
6375 b6d96bed ths
            tcg_gen_ext_i32_tl(t0, fp0);
6376 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6377 6958549d aurel32
        }
6378 6c5c1e20 ths
        gen_store_gpr(t0, rt);
6379 5a5012ec ths
        opn = "mfhc1";
6380 5a5012ec ths
        break;
6381 5a5012ec ths
    case OPC_MTHC1:
6382 6c5c1e20 ths
        gen_load_gpr(t0, rt);
6383 b6d96bed ths
        {
6384 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6385 b6d96bed ths
6386 b6d96bed ths
            tcg_gen_trunc_tl_i32(fp0, t0);
6387 b6d96bed ths
            gen_store_fpr32h(fp0, fs);
6388 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6389 6958549d aurel32
        }
6390 5a5012ec ths
        opn = "mthc1";
6391 5a5012ec ths
        break;
6392 6ea83fed bellard
    default:
6393 923617a3 ths
        MIPS_INVAL(opn);
6394 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
6395 6c5c1e20 ths
        goto out;
6396 6ea83fed bellard
    }
6397 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
6398 6ea83fed bellard
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6399 6c5c1e20 ths
6400 6c5c1e20 ths
 out:
6401 6c5c1e20 ths
    tcg_temp_free(t0);
6402 6ea83fed bellard
}
6403 6ea83fed bellard
6404 5a5012ec ths
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6405 5a5012ec ths
{
6406 af58f9ca aurel32
    int l1;
6407 e214b9bb ths
    TCGCond cond;
6408 af58f9ca aurel32
    TCGv_i32 t0;
6409 af58f9ca aurel32
6410 af58f9ca aurel32
    if (rd == 0) {
6411 af58f9ca aurel32
        /* Treat as NOP. */
6412 af58f9ca aurel32
        return;
6413 af58f9ca aurel32
    }
6414 6ea83fed bellard
6415 e214b9bb ths
    if (tf)
6416 e214b9bb ths
        cond = TCG_COND_EQ;
6417 27848470 ths
    else
6418 27848470 ths
        cond = TCG_COND_NE;
6419 27848470 ths
6420 af58f9ca aurel32
    l1 = gen_new_label();
6421 af58f9ca aurel32
    t0 = tcg_temp_new_i32();
6422 fa31af0e Nathan Froyd
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6423 af58f9ca aurel32
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6424 a4e8338d aurel32
    tcg_temp_free_i32(t0);
6425 af58f9ca aurel32
    if (rs == 0) {
6426 af58f9ca aurel32
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
6427 af58f9ca aurel32
    } else {
6428 af58f9ca aurel32
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6429 af58f9ca aurel32
    }
6430 e214b9bb ths
    gen_set_label(l1);
6431 5a5012ec ths
}
6432 5a5012ec ths
6433 b6d96bed ths
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6434 a16336e4 ths
{
6435 a16336e4 ths
    int cond;
6436 cbc37b28 aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();
6437 a16336e4 ths
    int l1 = gen_new_label();
6438 a16336e4 ths
6439 a16336e4 ths
    if (tf)
6440 a16336e4 ths
        cond = TCG_COND_EQ;
6441 a16336e4 ths
    else
6442 a16336e4 ths
        cond = TCG_COND_NE;
6443 a16336e4 ths
6444 fa31af0e Nathan Froyd
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6445 cbc37b28 aurel32
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6446 cbc37b28 aurel32
    gen_load_fpr32(t0, fs);
6447 cbc37b28 aurel32
    gen_store_fpr32(t0, fd);
6448 a16336e4 ths
    gen_set_label(l1);
6449 cbc37b28 aurel32
    tcg_temp_free_i32(t0);
6450 5a5012ec ths
}
6451 a16336e4 ths
6452 b6d96bed ths
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6453 a16336e4 ths
{
6454 a16336e4 ths
    int cond;
6455 cbc37b28 aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();
6456 cbc37b28 aurel32
    TCGv_i64 fp0;
6457 a16336e4 ths
    int l1 = gen_new_label();
6458 a16336e4 ths
6459 a16336e4 ths
    if (tf)
6460 a16336e4 ths
        cond = TCG_COND_EQ;
6461 a16336e4 ths
    else
6462 a16336e4 ths
        cond = TCG_COND_NE;
6463 a16336e4 ths
6464 fa31af0e Nathan Froyd
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6465 cbc37b28 aurel32
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6466 a4e8338d aurel32
    tcg_temp_free_i32(t0);
6467 11f94258 aurel32
    fp0 = tcg_temp_new_i64();
6468 9bf3eb2c aurel32
    gen_load_fpr64(ctx, fp0, fs);
6469 9bf3eb2c aurel32
    gen_store_fpr64(ctx, fp0, fd);
6470 a7812ae4 pbrook
    tcg_temp_free_i64(fp0);
6471 cbc37b28 aurel32
    gen_set_label(l1);
6472 a16336e4 ths
}
6473 a16336e4 ths
6474 b6d96bed ths
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6475 a16336e4 ths
{
6476 a16336e4 ths
    int cond;
6477 cbc37b28 aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();
6478 a16336e4 ths
    int l1 = gen_new_label();
6479 a16336e4 ths
    int l2 = gen_new_label();
6480 a16336e4 ths
6481 a16336e4 ths
    if (tf)
6482 a16336e4 ths
        cond = TCG_COND_EQ;
6483 a16336e4 ths
    else
6484 a16336e4 ths
        cond = TCG_COND_NE;
6485 a16336e4 ths
6486 fa31af0e Nathan Froyd
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6487 cbc37b28 aurel32
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6488 cbc37b28 aurel32
    gen_load_fpr32(t0, fs);
6489 cbc37b28 aurel32
    gen_store_fpr32(t0, fd);
6490 a16336e4 ths
    gen_set_label(l1);
6491 9bf3eb2c aurel32
6492 fa31af0e Nathan Froyd
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6493 cbc37b28 aurel32
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
6494 cbc37b28 aurel32
    gen_load_fpr32h(t0, fs);
6495 cbc37b28 aurel32
    gen_store_fpr32h(t0, fd);
6496 52a0e9eb aurel32
    tcg_temp_free_i32(t0);
6497 a16336e4 ths
    gen_set_label(l2);
6498 a16336e4 ths
}
6499 a16336e4 ths
6500 6ea83fed bellard
6501 bf4120ad Nathan Froyd
static void gen_farith (DisasContext *ctx, enum fopcode op1,
6502 5e755519 ths
                        int ft, int fs, int fd, int cc)
6503 6ea83fed bellard
{
6504 923617a3 ths
    const char *opn = "farith";
6505 6ea83fed bellard
    const char *condnames[] = {
6506 6ea83fed bellard
            "c.f",
6507 6ea83fed bellard
            "c.un",
6508 6ea83fed bellard
            "c.eq",
6509 6ea83fed bellard
            "c.ueq",
6510 6ea83fed bellard
            "c.olt",
6511 6ea83fed bellard
            "c.ult",
6512 6ea83fed bellard
            "c.ole",
6513 6ea83fed bellard
            "c.ule",
6514 6ea83fed bellard
            "c.sf",
6515 6ea83fed bellard
            "c.ngle",
6516 6ea83fed bellard
            "c.seq",
6517 6ea83fed bellard
            "c.ngl",
6518 6ea83fed bellard
            "c.lt",
6519 6ea83fed bellard
            "c.nge",
6520 6ea83fed bellard
            "c.le",
6521 6ea83fed bellard
            "c.ngt",
6522 6ea83fed bellard
    };
6523 5a1e8ffb ths
    const char *condnames_abs[] = {
6524 5a1e8ffb ths
            "cabs.f",
6525 5a1e8ffb ths
            "cabs.un",
6526 5a1e8ffb ths
            "cabs.eq",
6527 5a1e8ffb ths
            "cabs.ueq",
6528 5a1e8ffb ths
            "cabs.olt",
6529 5a1e8ffb ths
            "cabs.ult",
6530 5a1e8ffb ths
            "cabs.ole",
6531 5a1e8ffb ths
            "cabs.ule",
6532 5a1e8ffb ths
            "cabs.sf",
6533 5a1e8ffb ths
            "cabs.ngle",
6534 5a1e8ffb ths
            "cabs.seq",
6535 5a1e8ffb ths
            "cabs.ngl",
6536 5a1e8ffb ths
            "cabs.lt",
6537 5a1e8ffb ths
            "cabs.nge",
6538 5a1e8ffb ths
            "cabs.le",
6539 5a1e8ffb ths
            "cabs.ngt",
6540 5a1e8ffb ths
    };
6541 5a1e8ffb ths
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6542 7a387fff ths
    uint32_t func = ctx->opcode & 0x3f;
6543 7a387fff ths
6544 bf4120ad Nathan Froyd
    switch (op1) {
6545 bf4120ad Nathan Froyd
    case OPC_ADD_S:
6546 b6d96bed ths
        {
6547 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6548 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
6549 b6d96bed ths
6550 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6551 b6d96bed ths
            gen_load_fpr32(fp1, ft);
6552 a7812ae4 pbrook
            gen_helper_float_add_s(fp0, fp0, fp1);
6553 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
6554 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6555 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6556 b6d96bed ths
        }
6557 5a5012ec ths
        opn = "add.s";
6558 5a1e8ffb ths
        optype = BINOP;
6559 5a5012ec ths
        break;
6560 bf4120ad Nathan Froyd
    case OPC_SUB_S:
6561 b6d96bed ths
        {
6562 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6563 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
6564 b6d96bed ths
6565 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6566 b6d96bed ths
            gen_load_fpr32(fp1, ft);
6567 a7812ae4 pbrook
            gen_helper_float_sub_s(fp0, fp0, fp1);
6568 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
6569 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6570 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6571 b6d96bed ths
        }
6572 5a5012ec ths
        opn = "sub.s";
6573 5a1e8ffb ths
        optype = BINOP;
6574 5a5012ec ths
        break;
6575 bf4120ad Nathan Froyd
    case OPC_MUL_S:
6576 b6d96bed ths
        {
6577 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6578 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
6579 b6d96bed ths
6580 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6581 b6d96bed ths
            gen_load_fpr32(fp1, ft);
6582 a7812ae4 pbrook
            gen_helper_float_mul_s(fp0, fp0, fp1);
6583 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
6584 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6585 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6586 b6d96bed ths
        }
6587 5a5012ec ths
        opn = "mul.s";
6588 5a1e8ffb ths
        optype = BINOP;
6589 5a5012ec ths
        break;
6590 bf4120ad Nathan Froyd
    case OPC_DIV_S:
6591 b6d96bed ths
        {
6592 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6593 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
6594 b6d96bed ths
6595 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6596 b6d96bed ths
            gen_load_fpr32(fp1, ft);
6597 a7812ae4 pbrook
            gen_helper_float_div_s(fp0, fp0, fp1);
6598 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
6599 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6600 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6601 b6d96bed ths
        }
6602 5a5012ec ths
        opn = "div.s";
6603 5a1e8ffb ths
        optype = BINOP;
6604 5a5012ec ths
        break;
6605 bf4120ad Nathan Froyd
    case OPC_SQRT_S:
6606 b6d96bed ths
        {
6607 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6608 b6d96bed ths
6609 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6610 a7812ae4 pbrook
            gen_helper_float_sqrt_s(fp0, fp0);
6611 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6612 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6613 b6d96bed ths
        }
6614 5a5012ec ths
        opn = "sqrt.s";
6615 5a5012ec ths
        break;
6616 bf4120ad Nathan Froyd
    case OPC_ABS_S:
6617 b6d96bed ths
        {
6618 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6619 b6d96bed ths
6620 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6621 a7812ae4 pbrook
            gen_helper_float_abs_s(fp0, fp0);
6622 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6623 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6624 b6d96bed ths
        }
6625 5a5012ec ths
        opn = "abs.s";
6626 5a5012ec ths
        break;
6627 bf4120ad Nathan Froyd
    case OPC_MOV_S:
6628 b6d96bed ths
        {
6629 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6630 b6d96bed ths
6631 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6632 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6633 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6634 b6d96bed ths
        }
6635 5a5012ec ths
        opn = "mov.s";
6636 5a5012ec ths
        break;
6637 bf4120ad Nathan Froyd
    case OPC_NEG_S:
6638 b6d96bed ths
        {
6639 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6640 b6d96bed ths
6641 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6642 a7812ae4 pbrook
            gen_helper_float_chs_s(fp0, fp0);
6643 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6644 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6645 b6d96bed ths
        }
6646 5a5012ec ths
        opn = "neg.s";
6647 5a5012ec ths
        break;
6648 bf4120ad Nathan Froyd
    case OPC_ROUND_L_S:
6649 5e755519 ths
        check_cp1_64bitmode(ctx);
6650 b6d96bed ths
        {
6651 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6652 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6653 b6d96bed ths
6654 b6d96bed ths
            gen_load_fpr32(fp32, fs);
6655 a7812ae4 pbrook
            gen_helper_float_roundl_s(fp64, fp32);
6656 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6657 b6d96bed ths
            gen_store_fpr64(ctx, fp64, fd);
6658 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6659 b6d96bed ths
        }
6660 5a5012ec ths
        opn = "round.l.s";
6661 5a5012ec ths
        break;
6662 bf4120ad Nathan Froyd
    case OPC_TRUNC_L_S:
6663 5e755519 ths
        check_cp1_64bitmode(ctx);
6664 b6d96bed ths
        {
6665 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6666 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6667 b6d96bed ths
6668 b6d96bed ths
            gen_load_fpr32(fp32, fs);
6669 a7812ae4 pbrook
            gen_helper_float_truncl_s(fp64, fp32);
6670 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6671 b6d96bed ths
            gen_store_fpr64(ctx, fp64, fd);
6672 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6673 b6d96bed ths
        }
6674 5a5012ec ths
        opn = "trunc.l.s";
6675 5a5012ec ths
        break;
6676 bf4120ad Nathan Froyd
    case OPC_CEIL_L_S:
6677 5e755519 ths
        check_cp1_64bitmode(ctx);
6678 b6d96bed ths
        {
6679 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6680 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6681 b6d96bed ths
6682 b6d96bed ths
            gen_load_fpr32(fp32, fs);
6683 a7812ae4 pbrook
            gen_helper_float_ceill_s(fp64, fp32);
6684 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6685 b6d96bed ths
            gen_store_fpr64(ctx, fp64, fd);
6686 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6687 b6d96bed ths
        }
6688 5a5012ec ths
        opn = "ceil.l.s";
6689 5a5012ec ths
        break;
6690 bf4120ad Nathan Froyd
    case OPC_FLOOR_L_S:
6691 5e755519 ths
        check_cp1_64bitmode(ctx);
6692 b6d96bed ths
        {
6693 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6694 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6695 b6d96bed ths
6696 b6d96bed ths
            gen_load_fpr32(fp32, fs);
6697 a7812ae4 pbrook
            gen_helper_float_floorl_s(fp64, fp32);
6698 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6699 b6d96bed ths
            gen_store_fpr64(ctx, fp64, fd);
6700 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6701 b6d96bed ths
        }
6702 5a5012ec ths
        opn = "floor.l.s";
6703 5a5012ec ths
        break;
6704 bf4120ad Nathan Froyd
    case OPC_ROUND_W_S:
6705 b6d96bed ths
        {
6706 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6707 b6d96bed ths
6708 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6709 a7812ae4 pbrook
            gen_helper_float_roundw_s(fp0, fp0);
6710 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6711 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6712 b6d96bed ths
        }
6713 5a5012ec ths
        opn = "round.w.s";
6714 5a5012ec ths
        break;
6715 bf4120ad Nathan Froyd
    case OPC_TRUNC_W_S:
6716 b6d96bed ths
        {
6717 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6718 b6d96bed ths
6719 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6720 a7812ae4 pbrook
            gen_helper_float_truncw_s(fp0, fp0);
6721 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6722 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6723 b6d96bed ths
        }
6724 5a5012ec ths
        opn = "trunc.w.s";
6725 5a5012ec ths
        break;
6726 bf4120ad Nathan Froyd
    case OPC_CEIL_W_S:
6727 b6d96bed ths
        {
6728 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6729 b6d96bed ths
6730 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6731 a7812ae4 pbrook
            gen_helper_float_ceilw_s(fp0, fp0);
6732 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6733 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6734 b6d96bed ths
        }
6735 5a5012ec ths
        opn = "ceil.w.s";
6736 5a5012ec ths
        break;
6737 bf4120ad Nathan Froyd
    case OPC_FLOOR_W_S:
6738 b6d96bed ths
        {
6739 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6740 b6d96bed ths
6741 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6742 a7812ae4 pbrook
            gen_helper_float_floorw_s(fp0, fp0);
6743 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6744 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6745 b6d96bed ths
        }
6746 5a5012ec ths
        opn = "floor.w.s";
6747 5a5012ec ths
        break;
6748 bf4120ad Nathan Froyd
    case OPC_MOVCF_S:
6749 b6d96bed ths
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6750 5a5012ec ths
        opn = "movcf.s";
6751 5a5012ec ths
        break;
6752 bf4120ad Nathan Froyd
    case OPC_MOVZ_S:
6753 a16336e4 ths
        {
6754 a16336e4 ths
            int l1 = gen_new_label();
6755 c9297f4d aurel32
            TCGv_i32 fp0;
6756 a16336e4 ths
6757 c9297f4d aurel32
            if (ft != 0) {
6758 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6759 c9297f4d aurel32
            }
6760 c9297f4d aurel32
            fp0 = tcg_temp_new_i32();
6761 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6762 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6763 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6764 a16336e4 ths
            gen_set_label(l1);
6765 a16336e4 ths
        }
6766 5a5012ec ths
        opn = "movz.s";
6767 5a5012ec ths
        break;
6768 bf4120ad Nathan Froyd
    case OPC_MOVN_S:
6769 a16336e4 ths
        {
6770 a16336e4 ths
            int l1 = gen_new_label();
6771 c9297f4d aurel32
            TCGv_i32 fp0;
6772 c9297f4d aurel32
6773 c9297f4d aurel32
            if (ft != 0) {
6774 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6775 c9297f4d aurel32
                fp0 = tcg_temp_new_i32();
6776 c9297f4d aurel32
                gen_load_fpr32(fp0, fs);
6777 c9297f4d aurel32
                gen_store_fpr32(fp0, fd);
6778 c9297f4d aurel32
                tcg_temp_free_i32(fp0);
6779 c9297f4d aurel32
                gen_set_label(l1);
6780 c9297f4d aurel32
            }
6781 a16336e4 ths
        }
6782 5a5012ec ths
        opn = "movn.s";
6783 5a5012ec ths
        break;
6784 bf4120ad Nathan Froyd
    case OPC_RECIP_S:
6785 b8aa4598 ths
        check_cop1x(ctx);
6786 b6d96bed ths
        {
6787 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6788 b6d96bed ths
6789 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6790 a7812ae4 pbrook
            gen_helper_float_recip_s(fp0, fp0);
6791 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6792 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6793 b6d96bed ths
        }
6794 57fa1fb3 ths
        opn = "recip.s";
6795 57fa1fb3 ths
        break;
6796 bf4120ad Nathan Froyd
    case OPC_RSQRT_S:
6797 b8aa4598 ths
        check_cop1x(ctx);
6798 b6d96bed ths
        {
6799 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6800 b6d96bed ths
6801 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6802 a7812ae4 pbrook
            gen_helper_float_rsqrt_s(fp0, fp0);
6803 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6804 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6805 b6d96bed ths
        }
6806 57fa1fb3 ths
        opn = "rsqrt.s";
6807 57fa1fb3 ths
        break;
6808 bf4120ad Nathan Froyd
    case OPC_RECIP2_S:
6809 5e755519 ths
        check_cp1_64bitmode(ctx);
6810 b6d96bed ths
        {
6811 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6812 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
6813 b6d96bed ths
6814 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6815 b6d96bed ths
            gen_load_fpr32(fp1, fd);
6816 a7812ae4 pbrook
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6817 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
6818 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6819 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6820 b6d96bed ths
        }
6821 57fa1fb3 ths
        opn = "recip2.s";
6822 57fa1fb3 ths
        break;
6823 bf4120ad Nathan Froyd
    case OPC_RECIP1_S:
6824 5e755519 ths
        check_cp1_64bitmode(ctx);
6825 b6d96bed ths
        {
6826 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6827 b6d96bed ths
6828 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6829 a7812ae4 pbrook
            gen_helper_float_recip1_s(fp0, fp0);
6830 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6831 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6832 b6d96bed ths
        }
6833 57fa1fb3 ths
        opn = "recip1.s";
6834 57fa1fb3 ths
        break;
6835 bf4120ad Nathan Froyd
    case OPC_RSQRT1_S:
6836 5e755519 ths
        check_cp1_64bitmode(ctx);
6837 b6d96bed ths
        {
6838 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6839 b6d96bed ths
6840 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6841 a7812ae4 pbrook
            gen_helper_float_rsqrt1_s(fp0, fp0);
6842 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6843 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6844 b6d96bed ths
        }
6845 57fa1fb3 ths
        opn = "rsqrt1.s";
6846 57fa1fb3 ths
        break;
6847 bf4120ad Nathan Froyd
    case OPC_RSQRT2_S:
6848 5e755519 ths
        check_cp1_64bitmode(ctx);
6849 b6d96bed ths
        {
6850 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6851 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
6852 b6d96bed ths
6853 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6854 b6d96bed ths
            gen_load_fpr32(fp1, ft);
6855 a7812ae4 pbrook
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6856 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
6857 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6858 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6859 b6d96bed ths
        }
6860 57fa1fb3 ths
        opn = "rsqrt2.s";
6861 57fa1fb3 ths
        break;
6862 bf4120ad Nathan Froyd
    case OPC_CVT_D_S:
6863 5e755519 ths
        check_cp1_registers(ctx, fd);
6864 b6d96bed ths
        {
6865 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6866 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6867 b6d96bed ths
6868 b6d96bed ths
            gen_load_fpr32(fp32, fs);
6869 a7812ae4 pbrook
            gen_helper_float_cvtd_s(fp64, fp32);
6870 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6871 b6d96bed ths
            gen_store_fpr64(ctx, fp64, fd);
6872 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6873 b6d96bed ths
        }
6874 5a5012ec ths
        opn = "cvt.d.s";
6875 5a5012ec ths
        break;
6876 bf4120ad Nathan Froyd
    case OPC_CVT_W_S:
6877 b6d96bed ths
        {
6878 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
6879 b6d96bed ths
6880 b6d96bed ths
            gen_load_fpr32(fp0, fs);
6881 a7812ae4 pbrook
            gen_helper_float_cvtw_s(fp0, fp0);
6882 b6d96bed ths
            gen_store_fpr32(fp0, fd);
6883 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
6884 b6d96bed ths
        }
6885 5a5012ec ths
        opn = "cvt.w.s";
6886 5a5012ec ths
        break;
6887 bf4120ad Nathan Froyd
    case OPC_CVT_L_S:
6888 5e755519 ths
        check_cp1_64bitmode(ctx);
6889 b6d96bed ths
        {
6890 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
6891 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6892 b6d96bed ths
6893 b6d96bed ths
            gen_load_fpr32(fp32, fs);
6894 a7812ae4 pbrook
            gen_helper_float_cvtl_s(fp64, fp32);
6895 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
6896 b6d96bed ths
            gen_store_fpr64(ctx, fp64, fd);
6897 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6898 b6d96bed ths
        }
6899 5a5012ec ths
        opn = "cvt.l.s";
6900 5a5012ec ths
        break;
6901 bf4120ad Nathan Froyd
    case OPC_CVT_PS_S:
6902 5e755519 ths
        check_cp1_64bitmode(ctx);
6903 b6d96bed ths
        {
6904 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
6905 a7812ae4 pbrook
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6906 a7812ae4 pbrook
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6907 b6d96bed ths
6908 b6d96bed ths
            gen_load_fpr32(fp32_0, fs);
6909 b6d96bed ths
            gen_load_fpr32(fp32_1, ft);
6910 36aa55dc pbrook
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6911 a7812ae4 pbrook
            tcg_temp_free_i32(fp32_1);
6912 a7812ae4 pbrook
            tcg_temp_free_i32(fp32_0);
6913 36aa55dc pbrook
            gen_store_fpr64(ctx, fp64, fd);
6914 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
6915 b6d96bed ths
        }
6916 5a5012ec ths
        opn = "cvt.ps.s";
6917 5a5012ec ths
        break;
6918 bf4120ad Nathan Froyd
    case OPC_CMP_F_S:
6919 bf4120ad Nathan Froyd
    case OPC_CMP_UN_S:
6920 bf4120ad Nathan Froyd
    case OPC_CMP_EQ_S:
6921 bf4120ad Nathan Froyd
    case OPC_CMP_UEQ_S:
6922 bf4120ad Nathan Froyd
    case OPC_CMP_OLT_S:
6923 bf4120ad Nathan Froyd
    case OPC_CMP_ULT_S:
6924 bf4120ad Nathan Froyd
    case OPC_CMP_OLE_S:
6925 bf4120ad Nathan Froyd
    case OPC_CMP_ULE_S:
6926 bf4120ad Nathan Froyd
    case OPC_CMP_SF_S:
6927 bf4120ad Nathan Froyd
    case OPC_CMP_NGLE_S:
6928 bf4120ad Nathan Froyd
    case OPC_CMP_SEQ_S:
6929 bf4120ad Nathan Froyd
    case OPC_CMP_NGL_S:
6930 bf4120ad Nathan Froyd
    case OPC_CMP_LT_S:
6931 bf4120ad Nathan Froyd
    case OPC_CMP_NGE_S:
6932 bf4120ad Nathan Froyd
    case OPC_CMP_LE_S:
6933 bf4120ad Nathan Froyd
    case OPC_CMP_NGT_S:
6934 8153667c Nathan Froyd
        if (ctx->opcode & (1 << 6)) {
6935 8153667c Nathan Froyd
            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6936 8153667c Nathan Froyd
            opn = condnames_abs[func-48];
6937 8153667c Nathan Froyd
        } else {
6938 8153667c Nathan Froyd
            gen_cmp_s(ctx, func-48, ft, fs, cc);
6939 8153667c Nathan Froyd
            opn = condnames[func-48];
6940 5a1e8ffb ths
        }
6941 5a5012ec ths
        break;
6942 bf4120ad Nathan Froyd
    case OPC_ADD_D:
6943 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
6944 b6d96bed ths
        {
6945 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6946 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6947 b6d96bed ths
6948 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6949 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6950 a7812ae4 pbrook
            gen_helper_float_add_d(fp0, fp0, fp1);
6951 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6952 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6953 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6954 b6d96bed ths
        }
6955 6ea83fed bellard
        opn = "add.d";
6956 5a1e8ffb ths
        optype = BINOP;
6957 6ea83fed bellard
        break;
6958 bf4120ad Nathan Froyd
    case OPC_SUB_D:
6959 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
6960 b6d96bed ths
        {
6961 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6962 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6963 b6d96bed ths
6964 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6965 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6966 a7812ae4 pbrook
            gen_helper_float_sub_d(fp0, fp0, fp1);
6967 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6968 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6969 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6970 b6d96bed ths
        }
6971 6ea83fed bellard
        opn = "sub.d";
6972 5a1e8ffb ths
        optype = BINOP;
6973 6ea83fed bellard
        break;
6974 bf4120ad Nathan Froyd
    case OPC_MUL_D:
6975 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
6976 b6d96bed ths
        {
6977 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6978 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6979 b6d96bed ths
6980 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6981 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6982 a7812ae4 pbrook
            gen_helper_float_mul_d(fp0, fp0, fp1);
6983 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
6984 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
6985 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
6986 b6d96bed ths
        }
6987 6ea83fed bellard
        opn = "mul.d";
6988 5a1e8ffb ths
        optype = BINOP;
6989 6ea83fed bellard
        break;
6990 bf4120ad Nathan Froyd
    case OPC_DIV_D:
6991 5e755519 ths
        check_cp1_registers(ctx, fs | ft | fd);
6992 b6d96bed ths
        {
6993 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
6994 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
6995 b6d96bed ths
6996 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
6997 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
6998 a7812ae4 pbrook
            gen_helper_float_div_d(fp0, fp0, fp1);
6999 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7000 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7001 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7002 b6d96bed ths
        }
7003 6ea83fed bellard
        opn = "div.d";
7004 5a1e8ffb ths
        optype = BINOP;
7005 6ea83fed bellard
        break;
7006 bf4120ad Nathan Froyd
    case OPC_SQRT_D:
7007 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
7008 b6d96bed ths
        {
7009 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7010 b6d96bed ths
7011 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7012 a7812ae4 pbrook
            gen_helper_float_sqrt_d(fp0, fp0);
7013 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7014 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7015 b6d96bed ths
        }
7016 6ea83fed bellard
        opn = "sqrt.d";
7017 6ea83fed bellard
        break;
7018 bf4120ad Nathan Froyd
    case OPC_ABS_D:
7019 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
7020 b6d96bed ths
        {
7021 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7022 b6d96bed ths
7023 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7024 a7812ae4 pbrook
            gen_helper_float_abs_d(fp0, fp0);
7025 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7026 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7027 b6d96bed ths
        }
7028 6ea83fed bellard
        opn = "abs.d";
7029 6ea83fed bellard
        break;
7030 bf4120ad Nathan Froyd
    case OPC_MOV_D:
7031 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
7032 b6d96bed ths
        {
7033 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7034 b6d96bed ths
7035 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7036 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7037 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7038 b6d96bed ths
        }
7039 6ea83fed bellard
        opn = "mov.d";
7040 6ea83fed bellard
        break;
7041 bf4120ad Nathan Froyd
    case OPC_NEG_D:
7042 5e755519 ths
        check_cp1_registers(ctx, fs | fd);
7043 b6d96bed ths
        {
7044 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7045 b6d96bed ths
7046 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7047 a7812ae4 pbrook
            gen_helper_float_chs_d(fp0, fp0);
7048 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7049 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7050 b6d96bed ths
        }
7051 6ea83fed bellard
        opn = "neg.d";
7052 6ea83fed bellard
        break;
7053 bf4120ad Nathan Froyd
    case OPC_ROUND_L_D:
7054 5e755519 ths
        check_cp1_64bitmode(ctx);
7055 b6d96bed ths
        {
7056 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7057 b6d96bed ths
7058 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7059 a7812ae4 pbrook
            gen_helper_float_roundl_d(fp0, fp0);
7060 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7061 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7062 b6d96bed ths
        }
7063 5a5012ec ths
        opn = "round.l.d";
7064 5a5012ec ths
        break;
7065 bf4120ad Nathan Froyd
    case OPC_TRUNC_L_D:
7066 5e755519 ths
        check_cp1_64bitmode(ctx);
7067 b6d96bed ths
        {
7068 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7069 b6d96bed ths
7070 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7071 a7812ae4 pbrook
            gen_helper_float_truncl_d(fp0, fp0);
7072 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7073 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7074 b6d96bed ths
        }
7075 5a5012ec ths
        opn = "trunc.l.d";
7076 5a5012ec ths
        break;
7077 bf4120ad Nathan Froyd
    case OPC_CEIL_L_D:
7078 5e755519 ths
        check_cp1_64bitmode(ctx);
7079 b6d96bed ths
        {
7080 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7081 b6d96bed ths
7082 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7083 a7812ae4 pbrook
            gen_helper_float_ceill_d(fp0, fp0);
7084 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7085 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7086 b6d96bed ths
        }
7087 5a5012ec ths
        opn = "ceil.l.d";
7088 5a5012ec ths
        break;
7089 bf4120ad Nathan Froyd
    case OPC_FLOOR_L_D:
7090 5e755519 ths
        check_cp1_64bitmode(ctx);
7091 b6d96bed ths
        {
7092 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7093 b6d96bed ths
7094 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7095 a7812ae4 pbrook
            gen_helper_float_floorl_d(fp0, fp0);
7096 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7097 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7098 b6d96bed ths
        }
7099 5a5012ec ths
        opn = "floor.l.d";
7100 5a5012ec ths
        break;
7101 bf4120ad Nathan Froyd
    case OPC_ROUND_W_D:
7102 5e755519 ths
        check_cp1_registers(ctx, fs);
7103 b6d96bed ths
        {
7104 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
7105 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
7106 b6d96bed ths
7107 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
7108 a7812ae4 pbrook
            gen_helper_float_roundw_d(fp32, fp64);
7109 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
7110 b6d96bed ths
            gen_store_fpr32(fp32, fd);
7111 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
7112 b6d96bed ths
        }
7113 6ea83fed bellard
        opn = "round.w.d";
7114 6ea83fed bellard
        break;
7115 bf4120ad Nathan Froyd
    case OPC_TRUNC_W_D:
7116 5e755519 ths
        check_cp1_registers(ctx, fs);
7117 b6d96bed ths
        {
7118 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
7119 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
7120 b6d96bed ths
7121 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
7122 a7812ae4 pbrook
            gen_helper_float_truncw_d(fp32, fp64);
7123 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
7124 b6d96bed ths
            gen_store_fpr32(fp32, fd);
7125 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
7126 b6d96bed ths
        }
7127 6ea83fed bellard
        opn = "trunc.w.d";
7128 6ea83fed bellard
        break;
7129 bf4120ad Nathan Froyd
    case OPC_CEIL_W_D:
7130 5e755519 ths
        check_cp1_registers(ctx, fs);
7131 b6d96bed ths
        {
7132 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
7133 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
7134 b6d96bed ths
7135 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
7136 a7812ae4 pbrook
            gen_helper_float_ceilw_d(fp32, fp64);
7137 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
7138 b6d96bed ths
            gen_store_fpr32(fp32, fd);
7139 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
7140 b6d96bed ths
        }
7141 6ea83fed bellard
        opn = "ceil.w.d";
7142 6ea83fed bellard
        break;
7143 bf4120ad Nathan Froyd
    case OPC_FLOOR_W_D:
7144 5e755519 ths
        check_cp1_registers(ctx, fs);
7145 b6d96bed ths
        {
7146 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
7147 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
7148 b6d96bed ths
7149 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
7150 a7812ae4 pbrook
            gen_helper_float_floorw_d(fp32, fp64);
7151 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
7152 b6d96bed ths
            gen_store_fpr32(fp32, fd);
7153 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
7154 b6d96bed ths
        }
7155 7a387fff ths
        opn = "floor.w.d";
7156 6ea83fed bellard
        break;
7157 bf4120ad Nathan Froyd
    case OPC_MOVCF_D:
7158 b6d96bed ths
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7159 5a5012ec ths
        opn = "movcf.d";
7160 dd016883 bellard
        break;
7161 bf4120ad Nathan Froyd
    case OPC_MOVZ_D:
7162 a16336e4 ths
        {
7163 a16336e4 ths
            int l1 = gen_new_label();
7164 c9297f4d aurel32
            TCGv_i64 fp0;
7165 a16336e4 ths
7166 c9297f4d aurel32
            if (ft != 0) {
7167 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7168 c9297f4d aurel32
            }
7169 c9297f4d aurel32
            fp0 = tcg_temp_new_i64();
7170 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7171 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7172 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7173 a16336e4 ths
            gen_set_label(l1);
7174 a16336e4 ths
        }
7175 5a5012ec ths
        opn = "movz.d";
7176 5a5012ec ths
        break;
7177 bf4120ad Nathan Froyd
    case OPC_MOVN_D:
7178 a16336e4 ths
        {
7179 a16336e4 ths
            int l1 = gen_new_label();
7180 c9297f4d aurel32
            TCGv_i64 fp0;
7181 c9297f4d aurel32
7182 c9297f4d aurel32
            if (ft != 0) {
7183 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7184 c9297f4d aurel32
                fp0 = tcg_temp_new_i64();
7185 c9297f4d aurel32
                gen_load_fpr64(ctx, fp0, fs);
7186 c9297f4d aurel32
                gen_store_fpr64(ctx, fp0, fd);
7187 c9297f4d aurel32
                tcg_temp_free_i64(fp0);
7188 c9297f4d aurel32
                gen_set_label(l1);
7189 c9297f4d aurel32
            }
7190 a16336e4 ths
        }
7191 5a5012ec ths
        opn = "movn.d";
7192 6ea83fed bellard
        break;
7193 bf4120ad Nathan Froyd
    case OPC_RECIP_D:
7194 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7195 b6d96bed ths
        {
7196 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7197 b6d96bed ths
7198 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7199 a7812ae4 pbrook
            gen_helper_float_recip_d(fp0, fp0);
7200 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7201 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7202 b6d96bed ths
        }
7203 57fa1fb3 ths
        opn = "recip.d";
7204 57fa1fb3 ths
        break;
7205 bf4120ad Nathan Froyd
    case OPC_RSQRT_D:
7206 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7207 b6d96bed ths
        {
7208 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7209 b6d96bed ths
7210 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7211 a7812ae4 pbrook
            gen_helper_float_rsqrt_d(fp0, fp0);
7212 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7213 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7214 b6d96bed ths
        }
7215 57fa1fb3 ths
        opn = "rsqrt.d";
7216 57fa1fb3 ths
        break;
7217 bf4120ad Nathan Froyd
    case OPC_RECIP2_D:
7218 5e755519 ths
        check_cp1_64bitmode(ctx);
7219 b6d96bed ths
        {
7220 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7221 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7222 b6d96bed ths
7223 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7224 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7225 a7812ae4 pbrook
            gen_helper_float_recip2_d(fp0, fp0, fp1);
7226 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7227 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7228 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7229 b6d96bed ths
        }
7230 57fa1fb3 ths
        opn = "recip2.d";
7231 57fa1fb3 ths
        break;
7232 bf4120ad Nathan Froyd
    case OPC_RECIP1_D:
7233 5e755519 ths
        check_cp1_64bitmode(ctx);
7234 b6d96bed ths
        {
7235 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7236 b6d96bed ths
7237 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7238 a7812ae4 pbrook
            gen_helper_float_recip1_d(fp0, fp0);
7239 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7240 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7241 b6d96bed ths
        }
7242 57fa1fb3 ths
        opn = "recip1.d";
7243 57fa1fb3 ths
        break;
7244 bf4120ad Nathan Froyd
    case OPC_RSQRT1_D:
7245 5e755519 ths
        check_cp1_64bitmode(ctx);
7246 b6d96bed ths
        {
7247 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7248 b6d96bed ths
7249 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7250 a7812ae4 pbrook
            gen_helper_float_rsqrt1_d(fp0, fp0);
7251 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7252 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7253 b6d96bed ths
        }
7254 57fa1fb3 ths
        opn = "rsqrt1.d";
7255 57fa1fb3 ths
        break;
7256 bf4120ad Nathan Froyd
    case OPC_RSQRT2_D:
7257 5e755519 ths
        check_cp1_64bitmode(ctx);
7258 b6d96bed ths
        {
7259 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7260 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7261 b6d96bed ths
7262 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7263 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7264 a7812ae4 pbrook
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
7265 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7266 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7267 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7268 b6d96bed ths
        }
7269 57fa1fb3 ths
        opn = "rsqrt2.d";
7270 57fa1fb3 ths
        break;
7271 bf4120ad Nathan Froyd
    case OPC_CMP_F_D:
7272 bf4120ad Nathan Froyd
    case OPC_CMP_UN_D:
7273 bf4120ad Nathan Froyd
    case OPC_CMP_EQ_D:
7274 bf4120ad Nathan Froyd
    case OPC_CMP_UEQ_D:
7275 bf4120ad Nathan Froyd
    case OPC_CMP_OLT_D:
7276 bf4120ad Nathan Froyd
    case OPC_CMP_ULT_D:
7277 bf4120ad Nathan Froyd
    case OPC_CMP_OLE_D:
7278 bf4120ad Nathan Froyd
    case OPC_CMP_ULE_D:
7279 bf4120ad Nathan Froyd
    case OPC_CMP_SF_D:
7280 bf4120ad Nathan Froyd
    case OPC_CMP_NGLE_D:
7281 bf4120ad Nathan Froyd
    case OPC_CMP_SEQ_D:
7282 bf4120ad Nathan Froyd
    case OPC_CMP_NGL_D:
7283 bf4120ad Nathan Froyd
    case OPC_CMP_LT_D:
7284 bf4120ad Nathan Froyd
    case OPC_CMP_NGE_D:
7285 bf4120ad Nathan Froyd
    case OPC_CMP_LE_D:
7286 bf4120ad Nathan Froyd
    case OPC_CMP_NGT_D:
7287 8153667c Nathan Froyd
        if (ctx->opcode & (1 << 6)) {
7288 8153667c Nathan Froyd
            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7289 8153667c Nathan Froyd
            opn = condnames_abs[func-48];
7290 8153667c Nathan Froyd
        } else {
7291 8153667c Nathan Froyd
            gen_cmp_d(ctx, func-48, ft, fs, cc);
7292 8153667c Nathan Froyd
            opn = condnames[func-48];
7293 5a1e8ffb ths
        }
7294 6ea83fed bellard
        break;
7295 bf4120ad Nathan Froyd
    case OPC_CVT_S_D:
7296 5e755519 ths
        check_cp1_registers(ctx, fs);
7297 b6d96bed ths
        {
7298 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
7299 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
7300 b6d96bed ths
7301 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
7302 a7812ae4 pbrook
            gen_helper_float_cvts_d(fp32, fp64);
7303 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
7304 b6d96bed ths
            gen_store_fpr32(fp32, fd);
7305 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
7306 b6d96bed ths
        }
7307 5a5012ec ths
        opn = "cvt.s.d";
7308 5a5012ec ths
        break;
7309 bf4120ad Nathan Froyd
    case OPC_CVT_W_D:
7310 5e755519 ths
        check_cp1_registers(ctx, fs);
7311 b6d96bed ths
        {
7312 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
7313 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
7314 b6d96bed ths
7315 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
7316 a7812ae4 pbrook
            gen_helper_float_cvtw_d(fp32, fp64);
7317 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
7318 b6d96bed ths
            gen_store_fpr32(fp32, fd);
7319 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
7320 b6d96bed ths
        }
7321 5a5012ec ths
        opn = "cvt.w.d";
7322 5a5012ec ths
        break;
7323 bf4120ad Nathan Froyd
    case OPC_CVT_L_D:
7324 5e755519 ths
        check_cp1_64bitmode(ctx);
7325 b6d96bed ths
        {
7326 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7327 b6d96bed ths
7328 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7329 a7812ae4 pbrook
            gen_helper_float_cvtl_d(fp0, fp0);
7330 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7331 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7332 b6d96bed ths
        }
7333 5a5012ec ths
        opn = "cvt.l.d";
7334 5a5012ec ths
        break;
7335 bf4120ad Nathan Froyd
    case OPC_CVT_S_W:
7336 b6d96bed ths
        {
7337 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7338 b6d96bed ths
7339 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7340 a7812ae4 pbrook
            gen_helper_float_cvts_w(fp0, fp0);
7341 b6d96bed ths
            gen_store_fpr32(fp0, fd);
7342 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7343 b6d96bed ths
        }
7344 5a5012ec ths
        opn = "cvt.s.w";
7345 6ea83fed bellard
        break;
7346 bf4120ad Nathan Froyd
    case OPC_CVT_D_W:
7347 5e755519 ths
        check_cp1_registers(ctx, fd);
7348 b6d96bed ths
        {
7349 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
7350 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
7351 b6d96bed ths
7352 b6d96bed ths
            gen_load_fpr32(fp32, fs);
7353 a7812ae4 pbrook
            gen_helper_float_cvtd_w(fp64, fp32);
7354 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
7355 b6d96bed ths
            gen_store_fpr64(ctx, fp64, fd);
7356 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
7357 b6d96bed ths
        }
7358 5a5012ec ths
        opn = "cvt.d.w";
7359 5a5012ec ths
        break;
7360 bf4120ad Nathan Froyd
    case OPC_CVT_S_L:
7361 5e755519 ths
        check_cp1_64bitmode(ctx);
7362 b6d96bed ths
        {
7363 a7812ae4 pbrook
            TCGv_i32 fp32 = tcg_temp_new_i32();
7364 a7812ae4 pbrook
            TCGv_i64 fp64 = tcg_temp_new_i64();
7365 b6d96bed ths
7366 b6d96bed ths
            gen_load_fpr64(ctx, fp64, fs);
7367 a7812ae4 pbrook
            gen_helper_float_cvts_l(fp32, fp64);
7368 a7812ae4 pbrook
            tcg_temp_free_i64(fp64);
7369 b6d96bed ths
            gen_store_fpr32(fp32, fd);
7370 a7812ae4 pbrook
            tcg_temp_free_i32(fp32);
7371 b6d96bed ths
        }
7372 5a5012ec ths
        opn = "cvt.s.l";
7373 5a5012ec ths
        break;
7374 bf4120ad Nathan Froyd
    case OPC_CVT_D_L:
7375 5e755519 ths
        check_cp1_64bitmode(ctx);
7376 b6d96bed ths
        {
7377 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7378 b6d96bed ths
7379 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7380 a7812ae4 pbrook
            gen_helper_float_cvtd_l(fp0, fp0);
7381 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7382 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7383 b6d96bed ths
        }
7384 5a5012ec ths
        opn = "cvt.d.l";
7385 5a5012ec ths
        break;
7386 bf4120ad Nathan Froyd
    case OPC_CVT_PS_PW:
7387 5e755519 ths
        check_cp1_64bitmode(ctx);
7388 b6d96bed ths
        {
7389 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7390 b6d96bed ths
7391 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7392 a7812ae4 pbrook
            gen_helper_float_cvtps_pw(fp0, fp0);
7393 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7394 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7395 b6d96bed ths
        }
7396 5a5012ec ths
        opn = "cvt.ps.pw";
7397 5a5012ec ths
        break;
7398 bf4120ad Nathan Froyd
    case OPC_ADD_PS:
7399 5e755519 ths
        check_cp1_64bitmode(ctx);
7400 b6d96bed ths
        {
7401 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7402 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7403 b6d96bed ths
7404 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7405 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7406 a7812ae4 pbrook
            gen_helper_float_add_ps(fp0, fp0, fp1);
7407 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7408 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7409 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7410 b6d96bed ths
        }
7411 5a5012ec ths
        opn = "add.ps";
7412 6ea83fed bellard
        break;
7413 bf4120ad Nathan Froyd
    case OPC_SUB_PS:
7414 5e755519 ths
        check_cp1_64bitmode(ctx);
7415 b6d96bed ths
        {
7416 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7417 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7418 b6d96bed ths
7419 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7420 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7421 a7812ae4 pbrook
            gen_helper_float_sub_ps(fp0, fp0, fp1);
7422 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7423 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7424 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7425 b6d96bed ths
        }
7426 5a5012ec ths
        opn = "sub.ps";
7427 6ea83fed bellard
        break;
7428 bf4120ad Nathan Froyd
    case OPC_MUL_PS:
7429 5e755519 ths
        check_cp1_64bitmode(ctx);
7430 b6d96bed ths
        {
7431 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7432 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7433 b6d96bed ths
7434 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7435 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7436 a7812ae4 pbrook
            gen_helper_float_mul_ps(fp0, fp0, fp1);
7437 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7438 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7439 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7440 b6d96bed ths
        }
7441 5a5012ec ths
        opn = "mul.ps";
7442 6ea83fed bellard
        break;
7443 bf4120ad Nathan Froyd
    case OPC_ABS_PS:
7444 5e755519 ths
        check_cp1_64bitmode(ctx);
7445 b6d96bed ths
        {
7446 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7447 b6d96bed ths
7448 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7449 a7812ae4 pbrook
            gen_helper_float_abs_ps(fp0, fp0);
7450 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7451 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7452 b6d96bed ths
        }
7453 5a5012ec ths
        opn = "abs.ps";
7454 6ea83fed bellard
        break;
7455 bf4120ad Nathan Froyd
    case OPC_MOV_PS:
7456 5e755519 ths
        check_cp1_64bitmode(ctx);
7457 b6d96bed ths
        {
7458 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7459 b6d96bed ths
7460 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7461 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7462 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7463 b6d96bed ths
        }
7464 5a5012ec ths
        opn = "mov.ps";
7465 6ea83fed bellard
        break;
7466 bf4120ad Nathan Froyd
    case OPC_NEG_PS:
7467 5e755519 ths
        check_cp1_64bitmode(ctx);
7468 b6d96bed ths
        {
7469 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7470 b6d96bed ths
7471 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7472 a7812ae4 pbrook
            gen_helper_float_chs_ps(fp0, fp0);
7473 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7474 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7475 b6d96bed ths
        }
7476 5a5012ec ths
        opn = "neg.ps";
7477 6ea83fed bellard
        break;
7478 bf4120ad Nathan Froyd
    case OPC_MOVCF_PS:
7479 5e755519 ths
        check_cp1_64bitmode(ctx);
7480 b6d96bed ths
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7481 5a5012ec ths
        opn = "movcf.ps";
7482 6ea83fed bellard
        break;
7483 bf4120ad Nathan Froyd
    case OPC_MOVZ_PS:
7484 5e755519 ths
        check_cp1_64bitmode(ctx);
7485 a16336e4 ths
        {
7486 a16336e4 ths
            int l1 = gen_new_label();
7487 30a3848b aurel32
            TCGv_i64 fp0;
7488 a16336e4 ths
7489 c9297f4d aurel32
            if (ft != 0)
7490 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7491 c9297f4d aurel32
            fp0 = tcg_temp_new_i64();
7492 c9297f4d aurel32
            gen_load_fpr64(ctx, fp0, fs);
7493 c9297f4d aurel32
            gen_store_fpr64(ctx, fp0, fd);
7494 c9297f4d aurel32
            tcg_temp_free_i64(fp0);
7495 a16336e4 ths
            gen_set_label(l1);
7496 a16336e4 ths
        }
7497 5a5012ec ths
        opn = "movz.ps";
7498 6ea83fed bellard
        break;
7499 bf4120ad Nathan Froyd
    case OPC_MOVN_PS:
7500 5e755519 ths
        check_cp1_64bitmode(ctx);
7501 a16336e4 ths
        {
7502 a16336e4 ths
            int l1 = gen_new_label();
7503 30a3848b aurel32
            TCGv_i64 fp0;
7504 c9297f4d aurel32
7505 c9297f4d aurel32
            if (ft != 0) {
7506 c9297f4d aurel32
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7507 c9297f4d aurel32
                fp0 = tcg_temp_new_i64();
7508 c9297f4d aurel32
                gen_load_fpr64(ctx, fp0, fs);
7509 c9297f4d aurel32
                gen_store_fpr64(ctx, fp0, fd);
7510 c9297f4d aurel32
                tcg_temp_free_i64(fp0);
7511 c9297f4d aurel32
                gen_set_label(l1);
7512 c9297f4d aurel32
            }
7513 a16336e4 ths
        }
7514 5a5012ec ths
        opn = "movn.ps";
7515 6ea83fed bellard
        break;
7516 bf4120ad Nathan Froyd
    case OPC_ADDR_PS:
7517 5e755519 ths
        check_cp1_64bitmode(ctx);
7518 b6d96bed ths
        {
7519 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7520 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7521 b6d96bed ths
7522 b6d96bed ths
            gen_load_fpr64(ctx, fp0, ft);
7523 b6d96bed ths
            gen_load_fpr64(ctx, fp1, fs);
7524 a7812ae4 pbrook
            gen_helper_float_addr_ps(fp0, fp0, fp1);
7525 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7526 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7527 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7528 b6d96bed ths
        }
7529 fbcc6828 ths
        opn = "addr.ps";
7530 fbcc6828 ths
        break;
7531 bf4120ad Nathan Froyd
    case OPC_MULR_PS:
7532 5e755519 ths
        check_cp1_64bitmode(ctx);
7533 b6d96bed ths
        {
7534 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7535 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7536 b6d96bed ths
7537 b6d96bed ths
            gen_load_fpr64(ctx, fp0, ft);
7538 b6d96bed ths
            gen_load_fpr64(ctx, fp1, fs);
7539 a7812ae4 pbrook
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7540 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7541 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7542 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7543 b6d96bed ths
        }
7544 57fa1fb3 ths
        opn = "mulr.ps";
7545 57fa1fb3 ths
        break;
7546 bf4120ad Nathan Froyd
    case OPC_RECIP2_PS:
7547 5e755519 ths
        check_cp1_64bitmode(ctx);
7548 b6d96bed ths
        {
7549 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7550 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7551 b6d96bed ths
7552 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7553 b6d96bed ths
            gen_load_fpr64(ctx, fp1, fd);
7554 a7812ae4 pbrook
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7555 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7556 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7557 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7558 b6d96bed ths
        }
7559 57fa1fb3 ths
        opn = "recip2.ps";
7560 57fa1fb3 ths
        break;
7561 bf4120ad Nathan Froyd
    case OPC_RECIP1_PS:
7562 5e755519 ths
        check_cp1_64bitmode(ctx);
7563 b6d96bed ths
        {
7564 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7565 b6d96bed ths
7566 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7567 a7812ae4 pbrook
            gen_helper_float_recip1_ps(fp0, fp0);
7568 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7569 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7570 b6d96bed ths
        }
7571 57fa1fb3 ths
        opn = "recip1.ps";
7572 57fa1fb3 ths
        break;
7573 bf4120ad Nathan Froyd
    case OPC_RSQRT1_PS:
7574 5e755519 ths
        check_cp1_64bitmode(ctx);
7575 b6d96bed ths
        {
7576 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7577 b6d96bed ths
7578 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7579 a7812ae4 pbrook
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7580 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7581 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7582 b6d96bed ths
        }
7583 57fa1fb3 ths
        opn = "rsqrt1.ps";
7584 57fa1fb3 ths
        break;
7585 bf4120ad Nathan Froyd
    case OPC_RSQRT2_PS:
7586 5e755519 ths
        check_cp1_64bitmode(ctx);
7587 b6d96bed ths
        {
7588 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7589 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7590 b6d96bed ths
7591 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7592 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7593 a7812ae4 pbrook
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7594 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7595 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7596 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7597 b6d96bed ths
        }
7598 57fa1fb3 ths
        opn = "rsqrt2.ps";
7599 57fa1fb3 ths
        break;
7600 bf4120ad Nathan Froyd
    case OPC_CVT_S_PU:
7601 5e755519 ths
        check_cp1_64bitmode(ctx);
7602 b6d96bed ths
        {
7603 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7604 b6d96bed ths
7605 b6d96bed ths
            gen_load_fpr32h(fp0, fs);
7606 a7812ae4 pbrook
            gen_helper_float_cvts_pu(fp0, fp0);
7607 b6d96bed ths
            gen_store_fpr32(fp0, fd);
7608 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7609 b6d96bed ths
        }
7610 5a5012ec ths
        opn = "cvt.s.pu";
7611 dd016883 bellard
        break;
7612 bf4120ad Nathan Froyd
    case OPC_CVT_PW_PS:
7613 5e755519 ths
        check_cp1_64bitmode(ctx);
7614 b6d96bed ths
        {
7615 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7616 b6d96bed ths
7617 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7618 a7812ae4 pbrook
            gen_helper_float_cvtpw_ps(fp0, fp0);
7619 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7620 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7621 b6d96bed ths
        }
7622 5a5012ec ths
        opn = "cvt.pw.ps";
7623 6ea83fed bellard
        break;
7624 bf4120ad Nathan Froyd
    case OPC_CVT_S_PL:
7625 5e755519 ths
        check_cp1_64bitmode(ctx);
7626 b6d96bed ths
        {
7627 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7628 b6d96bed ths
7629 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7630 a7812ae4 pbrook
            gen_helper_float_cvts_pl(fp0, fp0);
7631 b6d96bed ths
            gen_store_fpr32(fp0, fd);
7632 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7633 b6d96bed ths
        }
7634 5a5012ec ths
        opn = "cvt.s.pl";
7635 6ea83fed bellard
        break;
7636 bf4120ad Nathan Froyd
    case OPC_PLL_PS:
7637 5e755519 ths
        check_cp1_64bitmode(ctx);
7638 b6d96bed ths
        {
7639 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7640 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7641 b6d96bed ths
7642 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7643 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7644 b6d96bed ths
            gen_store_fpr32h(fp0, fd);
7645 b6d96bed ths
            gen_store_fpr32(fp1, fd);
7646 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7647 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7648 b6d96bed ths
        }
7649 5a5012ec ths
        opn = "pll.ps";
7650 6ea83fed bellard
        break;
7651 bf4120ad Nathan Froyd
    case OPC_PLU_PS:
7652 5e755519 ths
        check_cp1_64bitmode(ctx);
7653 b6d96bed ths
        {
7654 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7655 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7656 b6d96bed ths
7657 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7658 b6d96bed ths
            gen_load_fpr32h(fp1, ft);
7659 b6d96bed ths
            gen_store_fpr32(fp1, fd);
7660 b6d96bed ths
            gen_store_fpr32h(fp0, fd);
7661 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7662 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7663 b6d96bed ths
        }
7664 5a5012ec ths
        opn = "plu.ps";
7665 5a5012ec ths
        break;
7666 bf4120ad Nathan Froyd
    case OPC_PUL_PS:
7667 5e755519 ths
        check_cp1_64bitmode(ctx);
7668 b6d96bed ths
        {
7669 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7670 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7671 b6d96bed ths
7672 b6d96bed ths
            gen_load_fpr32h(fp0, fs);
7673 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7674 b6d96bed ths
            gen_store_fpr32(fp1, fd);
7675 b6d96bed ths
            gen_store_fpr32h(fp0, fd);
7676 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7677 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7678 b6d96bed ths
        }
7679 5a5012ec ths
        opn = "pul.ps";
7680 5a5012ec ths
        break;
7681 bf4120ad Nathan Froyd
    case OPC_PUU_PS:
7682 5e755519 ths
        check_cp1_64bitmode(ctx);
7683 b6d96bed ths
        {
7684 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7685 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7686 b6d96bed ths
7687 b6d96bed ths
            gen_load_fpr32h(fp0, fs);
7688 b6d96bed ths
            gen_load_fpr32h(fp1, ft);
7689 b6d96bed ths
            gen_store_fpr32(fp1, fd);
7690 b6d96bed ths
            gen_store_fpr32h(fp0, fd);
7691 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7692 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7693 b6d96bed ths
        }
7694 5a5012ec ths
        opn = "puu.ps";
7695 5a5012ec ths
        break;
7696 bf4120ad Nathan Froyd
    case OPC_CMP_F_PS:
7697 bf4120ad Nathan Froyd
    case OPC_CMP_UN_PS:
7698 bf4120ad Nathan Froyd
    case OPC_CMP_EQ_PS:
7699 bf4120ad Nathan Froyd
    case OPC_CMP_UEQ_PS:
7700 bf4120ad Nathan Froyd
    case OPC_CMP_OLT_PS:
7701 bf4120ad Nathan Froyd
    case OPC_CMP_ULT_PS:
7702 bf4120ad Nathan Froyd
    case OPC_CMP_OLE_PS:
7703 bf4120ad Nathan Froyd
    case OPC_CMP_ULE_PS:
7704 bf4120ad Nathan Froyd
    case OPC_CMP_SF_PS:
7705 bf4120ad Nathan Froyd
    case OPC_CMP_NGLE_PS:
7706 bf4120ad Nathan Froyd
    case OPC_CMP_SEQ_PS:
7707 bf4120ad Nathan Froyd
    case OPC_CMP_NGL_PS:
7708 bf4120ad Nathan Froyd
    case OPC_CMP_LT_PS:
7709 bf4120ad Nathan Froyd
    case OPC_CMP_NGE_PS:
7710 bf4120ad Nathan Froyd
    case OPC_CMP_LE_PS:
7711 bf4120ad Nathan Froyd
    case OPC_CMP_NGT_PS:
7712 8153667c Nathan Froyd
        if (ctx->opcode & (1 << 6)) {
7713 8153667c Nathan Froyd
            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7714 8153667c Nathan Froyd
            opn = condnames_abs[func-48];
7715 8153667c Nathan Froyd
        } else {
7716 8153667c Nathan Froyd
            gen_cmp_ps(ctx, func-48, ft, fs, cc);
7717 8153667c Nathan Froyd
            opn = condnames[func-48];
7718 5a1e8ffb ths
        }
7719 6ea83fed bellard
        break;
7720 5a5012ec ths
    default:
7721 923617a3 ths
        MIPS_INVAL(opn);
7722 e397ee33 ths
        generate_exception (ctx, EXCP_RI);
7723 6ea83fed bellard
        return;
7724 6ea83fed bellard
    }
7725 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
7726 5a1e8ffb ths
    switch (optype) {
7727 5a1e8ffb ths
    case BINOP:
7728 6ea83fed bellard
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7729 5a1e8ffb ths
        break;
7730 5a1e8ffb ths
    case CMPOP:
7731 5a1e8ffb ths
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7732 5a1e8ffb ths
        break;
7733 5a1e8ffb ths
    default:
7734 6ea83fed bellard
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7735 5a1e8ffb ths
        break;
7736 5a1e8ffb ths
    }
7737 6ea83fed bellard
}
7738 6af0bf9c bellard
7739 5a5012ec ths
/* Coprocessor 3 (FPU) */
7740 5e755519 ths
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7741 5e755519 ths
                           int fd, int fs, int base, int index)
7742 7a387fff ths
{
7743 923617a3 ths
    const char *opn = "extended float load/store";
7744 93b12ccc ths
    int store = 0;
7745 4e2474d6 aurel32
    TCGv t0 = tcg_temp_new();
7746 7a387fff ths
7747 93b12ccc ths
    if (base == 0) {
7748 6c5c1e20 ths
        gen_load_gpr(t0, index);
7749 93b12ccc ths
    } else if (index == 0) {
7750 6c5c1e20 ths
        gen_load_gpr(t0, base);
7751 93b12ccc ths
    } else {
7752 e9203484 aurel32
        gen_load_gpr(t0, index);
7753 941694d0 Aurelien Jarno
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7754 93b12ccc ths
    }
7755 5a5012ec ths
    /* Don't do NOP if destination is zero: we must perform the actual
7756 ead9360e ths
       memory access. */
7757 4e2474d6 aurel32
    save_cpu_state(ctx, 0);
7758 5a5012ec ths
    switch (opc) {
7759 5a5012ec ths
    case OPC_LWXC1:
7760 8c0ab41f aurel32
        check_cop1x(ctx);
7761 b6d96bed ths
        {
7762 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7763 b6d96bed ths
7764 585c88d5 aurel32
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7765 585c88d5 aurel32
            tcg_gen_trunc_tl_i32(fp0, t0);
7766 b6d96bed ths
            gen_store_fpr32(fp0, fd);
7767 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7768 b6d96bed ths
        }
7769 5a5012ec ths
        opn = "lwxc1";
7770 5a5012ec ths
        break;
7771 5a5012ec ths
    case OPC_LDXC1:
7772 8c0ab41f aurel32
        check_cop1x(ctx);
7773 8c0ab41f aurel32
        check_cp1_registers(ctx, fd);
7774 b6d96bed ths
        {
7775 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7776 b6d96bed ths
7777 b6d96bed ths
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7778 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7779 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7780 b6d96bed ths
        }
7781 5a5012ec ths
        opn = "ldxc1";
7782 5a5012ec ths
        break;
7783 5a5012ec ths
    case OPC_LUXC1:
7784 8c0ab41f aurel32
        check_cp1_64bitmode(ctx);
7785 6c5c1e20 ths
        tcg_gen_andi_tl(t0, t0, ~0x7);
7786 b6d96bed ths
        {
7787 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7788 b6d96bed ths
7789 b6d96bed ths
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7790 b6d96bed ths
            gen_store_fpr64(ctx, fp0, fd);
7791 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7792 b6d96bed ths
        }
7793 5a5012ec ths
        opn = "luxc1";
7794 5a5012ec ths
        break;
7795 5a5012ec ths
    case OPC_SWXC1:
7796 8c0ab41f aurel32
        check_cop1x(ctx);
7797 b6d96bed ths
        {
7798 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7799 585c88d5 aurel32
            TCGv t1 = tcg_temp_new();
7800 b6d96bed ths
7801 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7802 a7812ae4 pbrook
            tcg_gen_extu_i32_tl(t1, fp0);
7803 a7812ae4 pbrook
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7804 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7805 a6035857 aurel32
            tcg_temp_free(t1);
7806 b6d96bed ths
        }
7807 5a5012ec ths
        opn = "swxc1";
7808 93b12ccc ths
        store = 1;
7809 5a5012ec ths
        break;
7810 5a5012ec ths
    case OPC_SDXC1:
7811 8c0ab41f aurel32
        check_cop1x(ctx);
7812 8c0ab41f aurel32
        check_cp1_registers(ctx, fs);
7813 b6d96bed ths
        {
7814 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7815 b6d96bed ths
7816 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7817 b6d96bed ths
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7818 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7819 b6d96bed ths
        }
7820 5a5012ec ths
        opn = "sdxc1";
7821 93b12ccc ths
        store = 1;
7822 5a5012ec ths
        break;
7823 5a5012ec ths
    case OPC_SUXC1:
7824 8c0ab41f aurel32
        check_cp1_64bitmode(ctx);
7825 6c5c1e20 ths
        tcg_gen_andi_tl(t0, t0, ~0x7);
7826 b6d96bed ths
        {
7827 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7828 b6d96bed ths
7829 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7830 b6d96bed ths
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7831 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7832 b6d96bed ths
        }
7833 5a5012ec ths
        opn = "suxc1";
7834 93b12ccc ths
        store = 1;
7835 5a5012ec ths
        break;
7836 5a5012ec ths
    }
7837 6c5c1e20 ths
    tcg_temp_free(t0);
7838 2abf314d Blue Swirl
    (void)opn; (void)store; /* avoid compiler warnings */
7839 93b12ccc ths
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7840 93b12ccc ths
               regnames[index], regnames[base]);
7841 5a5012ec ths
}
7842 5a5012ec ths
7843 5e755519 ths
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7844 5e755519 ths
                            int fd, int fr, int fs, int ft)
7845 5a5012ec ths
{
7846 923617a3 ths
    const char *opn = "flt3_arith";
7847 5a5012ec ths
7848 5a5012ec ths
    switch (opc) {
7849 5a5012ec ths
    case OPC_ALNV_PS:
7850 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7851 a16336e4 ths
        {
7852 a7812ae4 pbrook
            TCGv t0 = tcg_temp_local_new();
7853 c905fdac aurel32
            TCGv_i32 fp = tcg_temp_new_i32();
7854 c905fdac aurel32
            TCGv_i32 fph = tcg_temp_new_i32();
7855 a16336e4 ths
            int l1 = gen_new_label();
7856 a16336e4 ths
            int l2 = gen_new_label();
7857 a16336e4 ths
7858 6c5c1e20 ths
            gen_load_gpr(t0, fr);
7859 6c5c1e20 ths
            tcg_gen_andi_tl(t0, t0, 0x7);
7860 6c5c1e20 ths
7861 6c5c1e20 ths
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7862 c905fdac aurel32
            gen_load_fpr32(fp, fs);
7863 c905fdac aurel32
            gen_load_fpr32h(fph, fs);
7864 c905fdac aurel32
            gen_store_fpr32(fp, fd);
7865 c905fdac aurel32
            gen_store_fpr32h(fph, fd);
7866 a16336e4 ths
            tcg_gen_br(l2);
7867 a16336e4 ths
            gen_set_label(l1);
7868 6c5c1e20 ths
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7869 6c5c1e20 ths
            tcg_temp_free(t0);
7870 a16336e4 ths
#ifdef TARGET_WORDS_BIGENDIAN
7871 c905fdac aurel32
            gen_load_fpr32(fp, fs);
7872 c905fdac aurel32
            gen_load_fpr32h(fph, ft);
7873 c905fdac aurel32
            gen_store_fpr32h(fp, fd);
7874 c905fdac aurel32
            gen_store_fpr32(fph, fd);
7875 a16336e4 ths
#else
7876 c905fdac aurel32
            gen_load_fpr32h(fph, fs);
7877 c905fdac aurel32
            gen_load_fpr32(fp, ft);
7878 c905fdac aurel32
            gen_store_fpr32(fph, fd);
7879 c905fdac aurel32
            gen_store_fpr32h(fp, fd);
7880 a16336e4 ths
#endif
7881 a16336e4 ths
            gen_set_label(l2);
7882 c905fdac aurel32
            tcg_temp_free_i32(fp);
7883 c905fdac aurel32
            tcg_temp_free_i32(fph);
7884 a16336e4 ths
        }
7885 5a5012ec ths
        opn = "alnv.ps";
7886 5a5012ec ths
        break;
7887 5a5012ec ths
    case OPC_MADD_S:
7888 b8aa4598 ths
        check_cop1x(ctx);
7889 b6d96bed ths
        {
7890 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7891 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7892 a7812ae4 pbrook
            TCGv_i32 fp2 = tcg_temp_new_i32();
7893 b6d96bed ths
7894 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7895 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7896 b6d96bed ths
            gen_load_fpr32(fp2, fr);
7897 a7812ae4 pbrook
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7898 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7899 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7900 b6d96bed ths
            gen_store_fpr32(fp2, fd);
7901 a7812ae4 pbrook
            tcg_temp_free_i32(fp2);
7902 b6d96bed ths
        }
7903 5a5012ec ths
        opn = "madd.s";
7904 5a5012ec ths
        break;
7905 5a5012ec ths
    case OPC_MADD_D:
7906 b8aa4598 ths
        check_cop1x(ctx);
7907 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
7908 b6d96bed ths
        {
7909 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7910 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7911 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7912 b6d96bed ths
7913 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7914 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7915 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7916 a7812ae4 pbrook
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7917 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7918 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7919 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7920 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7921 b6d96bed ths
        }
7922 5a5012ec ths
        opn = "madd.d";
7923 5a5012ec ths
        break;
7924 5a5012ec ths
    case OPC_MADD_PS:
7925 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7926 b6d96bed ths
        {
7927 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7928 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7929 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7930 b6d96bed ths
7931 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7932 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7933 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7934 a7812ae4 pbrook
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7935 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7936 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7937 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7938 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7939 b6d96bed ths
        }
7940 5a5012ec ths
        opn = "madd.ps";
7941 5a5012ec ths
        break;
7942 5a5012ec ths
    case OPC_MSUB_S:
7943 b8aa4598 ths
        check_cop1x(ctx);
7944 b6d96bed ths
        {
7945 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
7946 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
7947 a7812ae4 pbrook
            TCGv_i32 fp2 = tcg_temp_new_i32();
7948 b6d96bed ths
7949 b6d96bed ths
            gen_load_fpr32(fp0, fs);
7950 b6d96bed ths
            gen_load_fpr32(fp1, ft);
7951 b6d96bed ths
            gen_load_fpr32(fp2, fr);
7952 a7812ae4 pbrook
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7953 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
7954 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
7955 b6d96bed ths
            gen_store_fpr32(fp2, fd);
7956 a7812ae4 pbrook
            tcg_temp_free_i32(fp2);
7957 b6d96bed ths
        }
7958 5a5012ec ths
        opn = "msub.s";
7959 5a5012ec ths
        break;
7960 5a5012ec ths
    case OPC_MSUB_D:
7961 b8aa4598 ths
        check_cop1x(ctx);
7962 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
7963 b6d96bed ths
        {
7964 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7965 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7966 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7967 b6d96bed ths
7968 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7969 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7970 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7971 a7812ae4 pbrook
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7972 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7973 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7974 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7975 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7976 b6d96bed ths
        }
7977 5a5012ec ths
        opn = "msub.d";
7978 5a5012ec ths
        break;
7979 5a5012ec ths
    case OPC_MSUB_PS:
7980 b8aa4598 ths
        check_cp1_64bitmode(ctx);
7981 b6d96bed ths
        {
7982 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
7983 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
7984 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
7985 b6d96bed ths
7986 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
7987 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
7988 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
7989 a7812ae4 pbrook
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7990 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
7991 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
7992 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
7993 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
7994 b6d96bed ths
        }
7995 5a5012ec ths
        opn = "msub.ps";
7996 5a5012ec ths
        break;
7997 5a5012ec ths
    case OPC_NMADD_S:
7998 b8aa4598 ths
        check_cop1x(ctx);
7999 b6d96bed ths
        {
8000 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
8001 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
8002 a7812ae4 pbrook
            TCGv_i32 fp2 = tcg_temp_new_i32();
8003 b6d96bed ths
8004 b6d96bed ths
            gen_load_fpr32(fp0, fs);
8005 b6d96bed ths
            gen_load_fpr32(fp1, ft);
8006 b6d96bed ths
            gen_load_fpr32(fp2, fr);
8007 a7812ae4 pbrook
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
8008 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
8009 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
8010 b6d96bed ths
            gen_store_fpr32(fp2, fd);
8011 a7812ae4 pbrook
            tcg_temp_free_i32(fp2);
8012 b6d96bed ths
        }
8013 5a5012ec ths
        opn = "nmadd.s";
8014 5a5012ec ths
        break;
8015 5a5012ec ths
    case OPC_NMADD_D:
8016 b8aa4598 ths
        check_cop1x(ctx);
8017 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
8018 b6d96bed ths
        {
8019 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
8020 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
8021 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
8022 b6d96bed ths
8023 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
8024 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
8025 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
8026 a7812ae4 pbrook
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
8027 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
8028 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
8029 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
8030 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
8031 b6d96bed ths
        }
8032 5a5012ec ths
        opn = "nmadd.d";
8033 5a5012ec ths
        break;
8034 5a5012ec ths
    case OPC_NMADD_PS:
8035 b8aa4598 ths
        check_cp1_64bitmode(ctx);
8036 b6d96bed ths
        {
8037 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
8038 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
8039 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
8040 b6d96bed ths
8041 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
8042 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
8043 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
8044 a7812ae4 pbrook
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
8045 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
8046 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
8047 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
8048 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
8049 b6d96bed ths
        }
8050 5a5012ec ths
        opn = "nmadd.ps";
8051 5a5012ec ths
        break;
8052 5a5012ec ths
    case OPC_NMSUB_S:
8053 b8aa4598 ths
        check_cop1x(ctx);
8054 b6d96bed ths
        {
8055 a7812ae4 pbrook
            TCGv_i32 fp0 = tcg_temp_new_i32();
8056 a7812ae4 pbrook
            TCGv_i32 fp1 = tcg_temp_new_i32();
8057 a7812ae4 pbrook
            TCGv_i32 fp2 = tcg_temp_new_i32();
8058 b6d96bed ths
8059 b6d96bed ths
            gen_load_fpr32(fp0, fs);
8060 b6d96bed ths
            gen_load_fpr32(fp1, ft);
8061 b6d96bed ths
            gen_load_fpr32(fp2, fr);
8062 a7812ae4 pbrook
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
8063 a7812ae4 pbrook
            tcg_temp_free_i32(fp0);
8064 a7812ae4 pbrook
            tcg_temp_free_i32(fp1);
8065 b6d96bed ths
            gen_store_fpr32(fp2, fd);
8066 a7812ae4 pbrook
            tcg_temp_free_i32(fp2);
8067 b6d96bed ths
        }
8068 5a5012ec ths
        opn = "nmsub.s";
8069 5a5012ec ths
        break;
8070 5a5012ec ths
    case OPC_NMSUB_D:
8071 b8aa4598 ths
        check_cop1x(ctx);
8072 b8aa4598 ths
        check_cp1_registers(ctx, fd | fs | ft | fr);
8073 b6d96bed ths
        {
8074 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
8075 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
8076 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
8077 b6d96bed ths
8078 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
8079 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
8080 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
8081 a7812ae4 pbrook
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
8082 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
8083 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
8084 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
8085 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
8086 b6d96bed ths
        }
8087 5a5012ec ths
        opn = "nmsub.d";
8088 5a5012ec ths
        break;
8089 5a5012ec ths
    case OPC_NMSUB_PS:
8090 b8aa4598 ths
        check_cp1_64bitmode(ctx);
8091 b6d96bed ths
        {
8092 a7812ae4 pbrook
            TCGv_i64 fp0 = tcg_temp_new_i64();
8093 a7812ae4 pbrook
            TCGv_i64 fp1 = tcg_temp_new_i64();
8094 a7812ae4 pbrook
            TCGv_i64 fp2 = tcg_temp_new_i64();
8095 b6d96bed ths
8096 b6d96bed ths
            gen_load_fpr64(ctx, fp0, fs);
8097 b6d96bed ths
            gen_load_fpr64(ctx, fp1, ft);
8098 b6d96bed ths
            gen_load_fpr64(ctx, fp2, fr);
8099 a7812ae4 pbrook
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
8100 a7812ae4 pbrook
            tcg_temp_free_i64(fp0);
8101 a7812ae4 pbrook
            tcg_temp_free_i64(fp1);
8102 b6d96bed ths
            gen_store_fpr64(ctx, fp2, fd);
8103 a7812ae4 pbrook
            tcg_temp_free_i64(fp2);
8104 b6d96bed ths
        }
8105 5a5012ec ths
        opn = "nmsub.ps";
8106 5a5012ec ths
        break;
8107 923617a3 ths
    default:
8108 923617a3 ths
        MIPS_INVAL(opn);
8109 5a5012ec ths
        generate_exception (ctx, EXCP_RI);
8110 5a5012ec ths
        return;
8111 5a5012ec ths
    }
8112 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
8113 5a5012ec ths
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
8114 5a5012ec ths
               fregnames[fs], fregnames[ft]);
8115 7a387fff ths
}
8116 7a387fff ths
8117 26ebe468 Nathan Froyd
static void
8118 26ebe468 Nathan Froyd
gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
8119 26ebe468 Nathan Froyd
{
8120 26ebe468 Nathan Froyd
    TCGv t0;
8121 26ebe468 Nathan Froyd
8122 26ebe468 Nathan Froyd
    check_insn(env, ctx, ISA_MIPS32R2);
8123 26ebe468 Nathan Froyd
    t0 = tcg_temp_new();
8124 26ebe468 Nathan Froyd
8125 26ebe468 Nathan Froyd
    switch (rd) {
8126 26ebe468 Nathan Froyd
    case 0:
8127 26ebe468 Nathan Froyd
        save_cpu_state(ctx, 1);
8128 26ebe468 Nathan Froyd
        gen_helper_rdhwr_cpunum(t0);
8129 26ebe468 Nathan Froyd
        gen_store_gpr(t0, rt);
8130 26ebe468 Nathan Froyd
        break;
8131 26ebe468 Nathan Froyd
    case 1:
8132 26ebe468 Nathan Froyd
        save_cpu_state(ctx, 1);
8133 26ebe468 Nathan Froyd
        gen_helper_rdhwr_synci_step(t0);
8134 26ebe468 Nathan Froyd
        gen_store_gpr(t0, rt);
8135 26ebe468 Nathan Froyd
        break;
8136 26ebe468 Nathan Froyd
    case 2:
8137 26ebe468 Nathan Froyd
        save_cpu_state(ctx, 1);
8138 26ebe468 Nathan Froyd
        gen_helper_rdhwr_cc(t0);
8139 26ebe468 Nathan Froyd
        gen_store_gpr(t0, rt);
8140 26ebe468 Nathan Froyd
        break;
8141 26ebe468 Nathan Froyd
    case 3:
8142 26ebe468 Nathan Froyd
        save_cpu_state(ctx, 1);
8143 26ebe468 Nathan Froyd
        gen_helper_rdhwr_ccres(t0);
8144 26ebe468 Nathan Froyd
        gen_store_gpr(t0, rt);
8145 26ebe468 Nathan Froyd
        break;
8146 26ebe468 Nathan Froyd
    case 29:
8147 26ebe468 Nathan Froyd
#if defined(CONFIG_USER_ONLY)
8148 26ebe468 Nathan Froyd
        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
8149 26ebe468 Nathan Froyd
        gen_store_gpr(t0, rt);
8150 26ebe468 Nathan Froyd
        break;
8151 26ebe468 Nathan Froyd
#else
8152 26ebe468 Nathan Froyd
        /* XXX: Some CPUs implement this in hardware.
8153 26ebe468 Nathan Froyd
           Not supported yet. */
8154 26ebe468 Nathan Froyd
#endif
8155 26ebe468 Nathan Froyd
    default:            /* Invalid */
8156 26ebe468 Nathan Froyd
        MIPS_INVAL("rdhwr");
8157 26ebe468 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
8158 26ebe468 Nathan Froyd
        break;
8159 26ebe468 Nathan Froyd
    }
8160 26ebe468 Nathan Froyd
    tcg_temp_free(t0);
8161 26ebe468 Nathan Froyd
}
8162 26ebe468 Nathan Froyd
8163 c9602061 Nathan Froyd
static void handle_delay_slot (CPUState *env, DisasContext *ctx,
8164 c9602061 Nathan Froyd
                               int insn_bytes)
8165 c9602061 Nathan Froyd
{
8166 c9602061 Nathan Froyd
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8167 364d4831 Nathan Froyd
        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8168 c9602061 Nathan Froyd
        /* Branches completion */
8169 c9602061 Nathan Froyd
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8170 c9602061 Nathan Froyd
        ctx->bstate = BS_BRANCH;
8171 c9602061 Nathan Froyd
        save_cpu_state(ctx, 0);
8172 c9602061 Nathan Froyd
        /* FIXME: Need to clear can_do_io.  */
8173 364d4831 Nathan Froyd
        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
8174 c9602061 Nathan Froyd
        case MIPS_HFLAG_B:
8175 c9602061 Nathan Froyd
            /* unconditional branch */
8176 c9602061 Nathan Froyd
            MIPS_DEBUG("unconditional branch");
8177 364d4831 Nathan Froyd
            if (proc_hflags & MIPS_HFLAG_BX) {
8178 364d4831 Nathan Froyd
                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
8179 364d4831 Nathan Froyd
            }
8180 c9602061 Nathan Froyd
            gen_goto_tb(ctx, 0, ctx->btarget);
8181 c9602061 Nathan Froyd
            break;
8182 c9602061 Nathan Froyd
        case MIPS_HFLAG_BL:
8183 c9602061 Nathan Froyd
            /* blikely taken case */
8184 c9602061 Nathan Froyd
            MIPS_DEBUG("blikely branch taken");
8185 c9602061 Nathan Froyd
            gen_goto_tb(ctx, 0, ctx->btarget);
8186 c9602061 Nathan Froyd
            break;
8187 c9602061 Nathan Froyd
        case MIPS_HFLAG_BC:
8188 c9602061 Nathan Froyd
            /* Conditional branch */
8189 c9602061 Nathan Froyd
            MIPS_DEBUG("conditional branch");
8190 c9602061 Nathan Froyd
            {
8191 c9602061 Nathan Froyd
                int l1 = gen_new_label();
8192 c9602061 Nathan Froyd
8193 c9602061 Nathan Froyd
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8194 c9602061 Nathan Froyd
                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
8195 c9602061 Nathan Froyd
                gen_set_label(l1);
8196 c9602061 Nathan Froyd
                gen_goto_tb(ctx, 0, ctx->btarget);
8197 c9602061 Nathan Froyd
            }
8198 c9602061 Nathan Froyd
            break;
8199 c9602061 Nathan Froyd
        case MIPS_HFLAG_BR:
8200 c9602061 Nathan Froyd
            /* unconditional branch to register */
8201 c9602061 Nathan Froyd
            MIPS_DEBUG("branch to register");
8202 3c824109 Nathan Froyd
            if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
8203 364d4831 Nathan Froyd
                TCGv t0 = tcg_temp_new();
8204 364d4831 Nathan Froyd
                TCGv_i32 t1 = tcg_temp_new_i32();
8205 364d4831 Nathan Froyd
8206 364d4831 Nathan Froyd
                tcg_gen_andi_tl(t0, btarget, 0x1);
8207 364d4831 Nathan Froyd
                tcg_gen_trunc_tl_i32(t1, t0);
8208 364d4831 Nathan Froyd
                tcg_temp_free(t0);
8209 364d4831 Nathan Froyd
                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
8210 364d4831 Nathan Froyd
                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
8211 364d4831 Nathan Froyd
                tcg_gen_or_i32(hflags, hflags, t1);
8212 364d4831 Nathan Froyd
                tcg_temp_free_i32(t1);
8213 364d4831 Nathan Froyd
8214 364d4831 Nathan Froyd
                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
8215 364d4831 Nathan Froyd
            } else {
8216 364d4831 Nathan Froyd
                tcg_gen_mov_tl(cpu_PC, btarget);
8217 364d4831 Nathan Froyd
            }
8218 c9602061 Nathan Froyd
            if (ctx->singlestep_enabled) {
8219 c9602061 Nathan Froyd
                save_cpu_state(ctx, 0);
8220 c9602061 Nathan Froyd
                gen_helper_0i(raise_exception, EXCP_DEBUG);
8221 c9602061 Nathan Froyd
            }
8222 c9602061 Nathan Froyd
            tcg_gen_exit_tb(0);
8223 c9602061 Nathan Froyd
            break;
8224 c9602061 Nathan Froyd
        default:
8225 c9602061 Nathan Froyd
            MIPS_DEBUG("unknown branch");
8226 c9602061 Nathan Froyd
            break;
8227 c9602061 Nathan Froyd
        }
8228 c9602061 Nathan Froyd
    }
8229 c9602061 Nathan Froyd
}
8230 c9602061 Nathan Froyd
8231 7a387fff ths
/* ISA extensions (ASEs) */
8232 6af0bf9c bellard
/* MIPS16 extension to MIPS32 */
8233 6ea219d0 Nathan Froyd
8234 6ea219d0 Nathan Froyd
/* MIPS16 major opcodes */
8235 6ea219d0 Nathan Froyd
enum {
8236 6ea219d0 Nathan Froyd
  M16_OPC_ADDIUSP = 0x00,
8237 6ea219d0 Nathan Froyd
  M16_OPC_ADDIUPC = 0x01,
8238 6ea219d0 Nathan Froyd
  M16_OPC_B = 0x02,
8239 6ea219d0 Nathan Froyd
  M16_OPC_JAL = 0x03,
8240 6ea219d0 Nathan Froyd
  M16_OPC_BEQZ = 0x04,
8241 6ea219d0 Nathan Froyd
  M16_OPC_BNEQZ = 0x05,
8242 6ea219d0 Nathan Froyd
  M16_OPC_SHIFT = 0x06,
8243 6ea219d0 Nathan Froyd
  M16_OPC_LD = 0x07,
8244 6ea219d0 Nathan Froyd
  M16_OPC_RRIA = 0x08,
8245 6ea219d0 Nathan Froyd
  M16_OPC_ADDIU8 = 0x09,
8246 6ea219d0 Nathan Froyd
  M16_OPC_SLTI = 0x0a,
8247 6ea219d0 Nathan Froyd
  M16_OPC_SLTIU = 0x0b,
8248 6ea219d0 Nathan Froyd
  M16_OPC_I8 = 0x0c,
8249 6ea219d0 Nathan Froyd
  M16_OPC_LI = 0x0d,
8250 6ea219d0 Nathan Froyd
  M16_OPC_CMPI = 0x0e,
8251 6ea219d0 Nathan Froyd
  M16_OPC_SD = 0x0f,
8252 6ea219d0 Nathan Froyd
  M16_OPC_LB = 0x10,
8253 6ea219d0 Nathan Froyd
  M16_OPC_LH = 0x11,
8254 6ea219d0 Nathan Froyd
  M16_OPC_LWSP = 0x12,
8255 6ea219d0 Nathan Froyd
  M16_OPC_LW = 0x13,
8256 6ea219d0 Nathan Froyd
  M16_OPC_LBU = 0x14,
8257 6ea219d0 Nathan Froyd
  M16_OPC_LHU = 0x15,
8258 6ea219d0 Nathan Froyd
  M16_OPC_LWPC = 0x16,
8259 6ea219d0 Nathan Froyd
  M16_OPC_LWU = 0x17,
8260 6ea219d0 Nathan Froyd
  M16_OPC_SB = 0x18,
8261 6ea219d0 Nathan Froyd
  M16_OPC_SH = 0x19,
8262 6ea219d0 Nathan Froyd
  M16_OPC_SWSP = 0x1a,
8263 6ea219d0 Nathan Froyd
  M16_OPC_SW = 0x1b,
8264 6ea219d0 Nathan Froyd
  M16_OPC_RRR = 0x1c,
8265 6ea219d0 Nathan Froyd
  M16_OPC_RR = 0x1d,
8266 6ea219d0 Nathan Froyd
  M16_OPC_EXTEND = 0x1e,
8267 6ea219d0 Nathan Froyd
  M16_OPC_I64 = 0x1f
8268 6ea219d0 Nathan Froyd
};
8269 6ea219d0 Nathan Froyd
8270 6ea219d0 Nathan Froyd
/* I8 funct field */
8271 6ea219d0 Nathan Froyd
enum {
8272 6ea219d0 Nathan Froyd
  I8_BTEQZ = 0x0,
8273 6ea219d0 Nathan Froyd
  I8_BTNEZ = 0x1,
8274 6ea219d0 Nathan Froyd
  I8_SWRASP = 0x2,
8275 6ea219d0 Nathan Froyd
  I8_ADJSP = 0x3,
8276 6ea219d0 Nathan Froyd
  I8_SVRS = 0x4,
8277 6ea219d0 Nathan Froyd
  I8_MOV32R = 0x5,
8278 6ea219d0 Nathan Froyd
  I8_MOVR32 = 0x7
8279 6ea219d0 Nathan Froyd
};
8280 6ea219d0 Nathan Froyd
8281 6ea219d0 Nathan Froyd
/* RRR f field */
8282 6ea219d0 Nathan Froyd
enum {
8283 6ea219d0 Nathan Froyd
  RRR_DADDU = 0x0,
8284 6ea219d0 Nathan Froyd
  RRR_ADDU = 0x1,
8285 6ea219d0 Nathan Froyd
  RRR_DSUBU = 0x2,
8286 6ea219d0 Nathan Froyd
  RRR_SUBU = 0x3
8287 6ea219d0 Nathan Froyd
};
8288 6ea219d0 Nathan Froyd
8289 6ea219d0 Nathan Froyd
/* RR funct field */
8290 6ea219d0 Nathan Froyd
enum {
8291 6ea219d0 Nathan Froyd
  RR_JR = 0x00,
8292 6ea219d0 Nathan Froyd
  RR_SDBBP = 0x01,
8293 6ea219d0 Nathan Froyd
  RR_SLT = 0x02,
8294 6ea219d0 Nathan Froyd
  RR_SLTU = 0x03,
8295 6ea219d0 Nathan Froyd
  RR_SLLV = 0x04,
8296 6ea219d0 Nathan Froyd
  RR_BREAK = 0x05,
8297 6ea219d0 Nathan Froyd
  RR_SRLV = 0x06,
8298 6ea219d0 Nathan Froyd
  RR_SRAV = 0x07,
8299 6ea219d0 Nathan Froyd
  RR_DSRL = 0x08,
8300 6ea219d0 Nathan Froyd
  RR_CMP = 0x0a,
8301 6ea219d0 Nathan Froyd
  RR_NEG = 0x0b,
8302 6ea219d0 Nathan Froyd
  RR_AND = 0x0c,
8303 6ea219d0 Nathan Froyd
  RR_OR = 0x0d,
8304 6ea219d0 Nathan Froyd
  RR_XOR = 0x0e,
8305 6ea219d0 Nathan Froyd
  RR_NOT = 0x0f,
8306 6ea219d0 Nathan Froyd
  RR_MFHI = 0x10,
8307 6ea219d0 Nathan Froyd
  RR_CNVT = 0x11,
8308 6ea219d0 Nathan Froyd
  RR_MFLO = 0x12,
8309 6ea219d0 Nathan Froyd
  RR_DSRA = 0x13,
8310 6ea219d0 Nathan Froyd
  RR_DSLLV = 0x14,
8311 6ea219d0 Nathan Froyd
  RR_DSRLV = 0x16,
8312 6ea219d0 Nathan Froyd
  RR_DSRAV = 0x17,
8313 6ea219d0 Nathan Froyd
  RR_MULT = 0x18,
8314 6ea219d0 Nathan Froyd
  RR_MULTU = 0x19,
8315 6ea219d0 Nathan Froyd
  RR_DIV = 0x1a,
8316 6ea219d0 Nathan Froyd
  RR_DIVU = 0x1b,
8317 6ea219d0 Nathan Froyd
  RR_DMULT = 0x1c,
8318 6ea219d0 Nathan Froyd
  RR_DMULTU = 0x1d,
8319 6ea219d0 Nathan Froyd
  RR_DDIV = 0x1e,
8320 6ea219d0 Nathan Froyd
  RR_DDIVU = 0x1f
8321 6ea219d0 Nathan Froyd
};
8322 6ea219d0 Nathan Froyd
8323 6ea219d0 Nathan Froyd
/* I64 funct field */
8324 6ea219d0 Nathan Froyd
enum {
8325 6ea219d0 Nathan Froyd
  I64_LDSP = 0x0,
8326 6ea219d0 Nathan Froyd
  I64_SDSP = 0x1,
8327 6ea219d0 Nathan Froyd
  I64_SDRASP = 0x2,
8328 6ea219d0 Nathan Froyd
  I64_DADJSP = 0x3,
8329 6ea219d0 Nathan Froyd
  I64_LDPC = 0x4,
8330 364d4831 Nathan Froyd
  I64_DADDIU5 = 0x5,
8331 6ea219d0 Nathan Froyd
  I64_DADDIUPC = 0x6,
8332 6ea219d0 Nathan Froyd
  I64_DADDIUSP = 0x7
8333 6ea219d0 Nathan Froyd
};
8334 6ea219d0 Nathan Froyd
8335 6ea219d0 Nathan Froyd
/* RR ry field for CNVT */
8336 6ea219d0 Nathan Froyd
enum {
8337 6ea219d0 Nathan Froyd
  RR_RY_CNVT_ZEB = 0x0,
8338 6ea219d0 Nathan Froyd
  RR_RY_CNVT_ZEH = 0x1,
8339 6ea219d0 Nathan Froyd
  RR_RY_CNVT_ZEW = 0x2,
8340 6ea219d0 Nathan Froyd
  RR_RY_CNVT_SEB = 0x4,
8341 6ea219d0 Nathan Froyd
  RR_RY_CNVT_SEH = 0x5,
8342 6ea219d0 Nathan Froyd
  RR_RY_CNVT_SEW = 0x6,
8343 6ea219d0 Nathan Froyd
};
8344 6ea219d0 Nathan Froyd
8345 364d4831 Nathan Froyd
static int xlat (int r)
8346 364d4831 Nathan Froyd
{
8347 364d4831 Nathan Froyd
  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8348 364d4831 Nathan Froyd
8349 364d4831 Nathan Froyd
  return map[r];
8350 364d4831 Nathan Froyd
}
8351 364d4831 Nathan Froyd
8352 364d4831 Nathan Froyd
static void gen_mips16_save (DisasContext *ctx,
8353 364d4831 Nathan Froyd
                             int xsregs, int aregs,
8354 364d4831 Nathan Froyd
                             int do_ra, int do_s0, int do_s1,
8355 364d4831 Nathan Froyd
                             int framesize)
8356 364d4831 Nathan Froyd
{
8357 364d4831 Nathan Froyd
    TCGv t0 = tcg_temp_new();
8358 364d4831 Nathan Froyd
    TCGv t1 = tcg_temp_new();
8359 364d4831 Nathan Froyd
    int args, astatic;
8360 364d4831 Nathan Froyd
8361 364d4831 Nathan Froyd
    switch (aregs) {
8362 364d4831 Nathan Froyd
    case 0:
8363 364d4831 Nathan Froyd
    case 1:
8364 364d4831 Nathan Froyd
    case 2:
8365 364d4831 Nathan Froyd
    case 3:
8366 364d4831 Nathan Froyd
    case 11:
8367 364d4831 Nathan Froyd
        args = 0;
8368 364d4831 Nathan Froyd
        break;
8369 364d4831 Nathan Froyd
    case 4:
8370 364d4831 Nathan Froyd
    case 5:
8371 364d4831 Nathan Froyd
    case 6:
8372 364d4831 Nathan Froyd
    case 7:
8373 364d4831 Nathan Froyd
        args = 1;
8374 364d4831 Nathan Froyd
        break;
8375 364d4831 Nathan Froyd
    case 8:
8376 364d4831 Nathan Froyd
    case 9:
8377 364d4831 Nathan Froyd
    case 10:
8378 364d4831 Nathan Froyd
        args = 2;
8379 364d4831 Nathan Froyd
        break;
8380 364d4831 Nathan Froyd
    case 12:
8381 364d4831 Nathan Froyd
    case 13:
8382 364d4831 Nathan Froyd
        args = 3;
8383 364d4831 Nathan Froyd
        break;
8384 364d4831 Nathan Froyd
    case 14:
8385 364d4831 Nathan Froyd
        args = 4;
8386 364d4831 Nathan Froyd
        break;
8387 364d4831 Nathan Froyd
    default:
8388 364d4831 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
8389 364d4831 Nathan Froyd
        return;
8390 364d4831 Nathan Froyd
    }
8391 364d4831 Nathan Froyd
8392 364d4831 Nathan Froyd
    switch (args) {
8393 364d4831 Nathan Froyd
    case 4:
8394 364d4831 Nathan Froyd
        gen_base_offset_addr(ctx, t0, 29, 12);
8395 364d4831 Nathan Froyd
        gen_load_gpr(t1, 7);
8396 5c13fdfd Aurelien Jarno
        op_st_sw(t1, t0, ctx);
8397 364d4831 Nathan Froyd
        /* Fall through */
8398 364d4831 Nathan Froyd
    case 3:
8399 364d4831 Nathan Froyd
        gen_base_offset_addr(ctx, t0, 29, 8);
8400 364d4831 Nathan Froyd
        gen_load_gpr(t1, 6);
8401 5c13fdfd Aurelien Jarno
        op_st_sw(t1, t0, ctx);
8402 364d4831 Nathan Froyd
        /* Fall through */
8403 364d4831 Nathan Froyd
    case 2:
8404 364d4831 Nathan Froyd
        gen_base_offset_addr(ctx, t0, 29, 4);
8405 364d4831 Nathan Froyd
        gen_load_gpr(t1, 5);
8406 5c13fdfd Aurelien Jarno
        op_st_sw(t1, t0, ctx);
8407 364d4831 Nathan Froyd
        /* Fall through */
8408 364d4831 Nathan Froyd
    case 1:
8409 364d4831 Nathan Froyd
        gen_base_offset_addr(ctx, t0, 29, 0);
8410 364d4831 Nathan Froyd
        gen_load_gpr(t1, 4);
8411 5c13fdfd Aurelien Jarno
        op_st_sw(t1, t0, ctx);
8412 364d4831 Nathan Froyd
    }
8413 364d4831 Nathan Froyd
8414 364d4831 Nathan Froyd
    gen_load_gpr(t0, 29);
8415 364d4831 Nathan Froyd
8416 364d4831 Nathan Froyd
#define DECR_AND_STORE(reg) do {                \
8417 364d4831 Nathan Froyd
        tcg_gen_subi_tl(t0, t0, 4);             \
8418 364d4831 Nathan Froyd
        gen_load_gpr(t1, reg);                  \
8419 5c13fdfd Aurelien Jarno
        op_st_sw(t1, t0, ctx);                  \
8420 364d4831 Nathan Froyd
    } while (0)
8421 364d4831 Nathan Froyd
8422 364d4831 Nathan Froyd
    if (do_ra) {
8423 364d4831 Nathan Froyd
        DECR_AND_STORE(31);
8424 364d4831 Nathan Froyd
    }
8425 364d4831 Nathan Froyd
8426 364d4831 Nathan Froyd
    switch (xsregs) {
8427 364d4831 Nathan Froyd
    case 7:
8428 364d4831 Nathan Froyd
        DECR_AND_STORE(30);
8429 364d4831 Nathan Froyd
        /* Fall through */
8430 364d4831 Nathan Froyd
    case 6:
8431 364d4831 Nathan Froyd
        DECR_AND_STORE(23);
8432 364d4831 Nathan Froyd
        /* Fall through */
8433 364d4831 Nathan Froyd
    case 5:
8434 364d4831 Nathan Froyd
        DECR_AND_STORE(22);
8435 364d4831 Nathan Froyd
        /* Fall through */
8436 364d4831 Nathan Froyd
    case 4:
8437 364d4831 Nathan Froyd
        DECR_AND_STORE(21);
8438 364d4831 Nathan Froyd
        /* Fall through */
8439 364d4831 Nathan Froyd
    case 3:
8440 364d4831 Nathan Froyd
        DECR_AND_STORE(20);
8441 364d4831 Nathan Froyd
        /* Fall through */
8442 364d4831 Nathan Froyd
    case 2:
8443 364d4831 Nathan Froyd
        DECR_AND_STORE(19);
8444 364d4831 Nathan Froyd
        /* Fall through */
8445 364d4831 Nathan Froyd
    case 1:
8446 364d4831 Nathan Froyd
        DECR_AND_STORE(18);
8447 364d4831 Nathan Froyd
    }
8448 364d4831 Nathan Froyd
8449 364d4831 Nathan Froyd
    if (do_s1) {
8450 364d4831 Nathan Froyd
        DECR_AND_STORE(17);
8451 364d4831 Nathan Froyd
    }
8452 364d4831 Nathan Froyd
    if (do_s0) {
8453 364d4831 Nathan Froyd
        DECR_AND_STORE(16);
8454 364d4831 Nathan Froyd
    }
8455 364d4831 Nathan Froyd
8456 364d4831 Nathan Froyd
    switch (aregs) {
8457 364d4831 Nathan Froyd
    case 0:
8458 364d4831 Nathan Froyd
    case 4:
8459 364d4831 Nathan Froyd
    case 8:
8460 364d4831 Nathan Froyd
    case 12:
8461 364d4831 Nathan Froyd
    case 14:
8462 364d4831 Nathan Froyd
        astatic = 0;
8463 364d4831 Nathan Froyd
        break;
8464 364d4831 Nathan Froyd
    case 1:
8465 364d4831 Nathan Froyd
    case 5:
8466 364d4831 Nathan Froyd
    case 9:
8467 364d4831 Nathan Froyd
    case 13:
8468 364d4831 Nathan Froyd
        astatic = 1;
8469 364d4831 Nathan Froyd
        break;
8470 364d4831 Nathan Froyd
    case 2:
8471 364d4831 Nathan Froyd
    case 6:
8472 364d4831 Nathan Froyd
    case 10:
8473 364d4831 Nathan Froyd
        astatic = 2;
8474 364d4831 Nathan Froyd
        break;
8475 364d4831 Nathan Froyd
    case 3:
8476 364d4831 Nathan Froyd
    case 7:
8477 364d4831 Nathan Froyd
        astatic = 3;
8478 364d4831 Nathan Froyd
        break;
8479 364d4831 Nathan Froyd
    case 11:
8480 364d4831 Nathan Froyd
        astatic = 4;
8481 364d4831 Nathan Froyd
        break;
8482 364d4831 Nathan Froyd
    default:
8483 364d4831 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
8484 364d4831 Nathan Froyd
        return;
8485 364d4831 Nathan Froyd
    }
8486 364d4831 Nathan Froyd
8487 364d4831 Nathan Froyd
    if (astatic > 0) {
8488 364d4831 Nathan Froyd
        DECR_AND_STORE(7);
8489 364d4831 Nathan Froyd
        if (astatic > 1) {
8490 364d4831 Nathan Froyd
            DECR_AND_STORE(6);
8491 364d4831 Nathan Froyd
            if (astatic > 2) {
8492 364d4831 Nathan Froyd
                DECR_AND_STORE(5);
8493 364d4831 Nathan Froyd
                if (astatic > 3) {
8494 364d4831 Nathan Froyd
                    DECR_AND_STORE(4);
8495 364d4831 Nathan Froyd
                }
8496 364d4831 Nathan Froyd
            }
8497 364d4831 Nathan Froyd
        }
8498 364d4831 Nathan Froyd
    }
8499 364d4831 Nathan Froyd
#undef DECR_AND_STORE
8500 364d4831 Nathan Froyd
8501 364d4831 Nathan Froyd
    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8502 364d4831 Nathan Froyd
    tcg_temp_free(t0);
8503 364d4831 Nathan Froyd
    tcg_temp_free(t1);
8504 364d4831 Nathan Froyd
}
8505 364d4831 Nathan Froyd
8506 364d4831 Nathan Froyd
static void gen_mips16_restore (DisasContext *ctx,
8507 364d4831 Nathan Froyd
                                int xsregs, int aregs,
8508 364d4831 Nathan Froyd
                                int do_ra, int do_s0, int do_s1,
8509 364d4831 Nathan Froyd
                                int framesize)
8510 364d4831 Nathan Froyd
{
8511 364d4831 Nathan Froyd
    int astatic;
8512 364d4831 Nathan Froyd
    TCGv t0 = tcg_temp_new();
8513 364d4831 Nathan Froyd
    TCGv t1 = tcg_temp_new();
8514 364d4831 Nathan Froyd
8515 364d4831 Nathan Froyd
    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8516 364d4831 Nathan Froyd
8517 364d4831 Nathan Froyd
#define DECR_AND_LOAD(reg) do {                 \
8518 364d4831 Nathan Froyd
        tcg_gen_subi_tl(t0, t0, 4);             \
8519 5c13fdfd Aurelien Jarno
        op_ld_lw(t1, t0, ctx);                  \
8520 364d4831 Nathan Froyd
        gen_store_gpr(t1, reg);                 \
8521 364d4831 Nathan Froyd
    } while (0)
8522 364d4831 Nathan Froyd
8523 364d4831 Nathan Froyd
    if (do_ra) {
8524 364d4831 Nathan Froyd
        DECR_AND_LOAD(31);
8525 364d4831 Nathan Froyd
    }
8526 364d4831 Nathan Froyd
8527 364d4831 Nathan Froyd
    switch (xsregs) {
8528 364d4831 Nathan Froyd
    case 7:
8529 364d4831 Nathan Froyd
        DECR_AND_LOAD(30);
8530 364d4831 Nathan Froyd
        /* Fall through */
8531 364d4831 Nathan Froyd
    case 6:
8532 364d4831 Nathan Froyd
        DECR_AND_LOAD(23);
8533 364d4831 Nathan Froyd
        /* Fall through */
8534 364d4831 Nathan Froyd
    case 5:
8535 364d4831 Nathan Froyd
        DECR_AND_LOAD(22);
8536 364d4831 Nathan Froyd
        /* Fall through */
8537 364d4831 Nathan Froyd
    case 4:
8538 364d4831 Nathan Froyd
        DECR_AND_LOAD(21);
8539 364d4831 Nathan Froyd
        /* Fall through */
8540 364d4831 Nathan Froyd
    case 3:
8541 364d4831 Nathan Froyd
        DECR_AND_LOAD(20);
8542 364d4831 Nathan Froyd
        /* Fall through */
8543 364d4831 Nathan Froyd
    case 2:
8544 364d4831 Nathan Froyd
        DECR_AND_LOAD(19);
8545 364d4831 Nathan Froyd
        /* Fall through */
8546 364d4831 Nathan Froyd
    case 1:
8547 364d4831 Nathan Froyd
        DECR_AND_LOAD(18);
8548 364d4831 Nathan Froyd
    }
8549 364d4831 Nathan Froyd
8550 364d4831 Nathan Froyd
    if (do_s1) {
8551 364d4831 Nathan Froyd
        DECR_AND_LOAD(17);
8552 364d4831 Nathan Froyd
    }
8553 364d4831 Nathan Froyd
    if (do_s0) {
8554 364d4831 Nathan Froyd
        DECR_AND_LOAD(16);
8555 364d4831 Nathan Froyd
    }
8556 364d4831 Nathan Froyd
8557 364d4831 Nathan Froyd
    switch (aregs) {
8558 364d4831 Nathan Froyd
    case 0:
8559 364d4831 Nathan Froyd
    case 4:
8560 364d4831 Nathan Froyd
    case 8:
8561 364d4831 Nathan Froyd
    case 12:
8562 364d4831 Nathan Froyd
    case 14:
8563 364d4831 Nathan Froyd
        astatic = 0;
8564 364d4831 Nathan Froyd
        break;
8565 364d4831 Nathan Froyd
    case 1:
8566 364d4831 Nathan Froyd
    case 5:
8567 364d4831 Nathan Froyd
    case 9:
8568 364d4831 Nathan Froyd
    case 13:
8569 364d4831 Nathan Froyd
        astatic = 1;
8570 364d4831 Nathan Froyd
        break;
8571 364d4831 Nathan Froyd
    case 2:
8572 364d4831 Nathan Froyd
    case 6:
8573 364d4831 Nathan Froyd
    case 10:
8574 364d4831 Nathan Froyd
        astatic = 2;
8575 364d4831 Nathan Froyd
        break;
8576 364d4831 Nathan Froyd
    case 3:
8577 364d4831 Nathan Froyd
    case 7:
8578 364d4831 Nathan Froyd
        astatic = 3;
8579 364d4831 Nathan Froyd
        break;
8580 364d4831 Nathan Froyd
    case 11:
8581 364d4831 Nathan Froyd
        astatic = 4;
8582 364d4831 Nathan Froyd
        break;
8583 364d4831 Nathan Froyd
    default:
8584 364d4831 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
8585 364d4831 Nathan Froyd
        return;
8586 364d4831 Nathan Froyd
    }
8587 364d4831 Nathan Froyd
8588 364d4831 Nathan Froyd
    if (astatic > 0) {
8589 364d4831 Nathan Froyd
        DECR_AND_LOAD(7);
8590 364d4831 Nathan Froyd
        if (astatic > 1) {
8591 364d4831 Nathan Froyd
            DECR_AND_LOAD(6);
8592 364d4831 Nathan Froyd
            if (astatic > 2) {
8593 364d4831 Nathan Froyd
                DECR_AND_LOAD(5);
8594 364d4831 Nathan Froyd
                if (astatic > 3) {
8595 364d4831 Nathan Froyd
                    DECR_AND_LOAD(4);
8596 364d4831 Nathan Froyd
                }
8597 364d4831 Nathan Froyd
            }
8598 364d4831 Nathan Froyd
        }
8599 364d4831 Nathan Froyd
    }
8600 364d4831 Nathan Froyd
#undef DECR_AND_LOAD
8601 364d4831 Nathan Froyd
8602 364d4831 Nathan Froyd
    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8603 364d4831 Nathan Froyd
    tcg_temp_free(t0);
8604 364d4831 Nathan Froyd
    tcg_temp_free(t1);
8605 364d4831 Nathan Froyd
}
8606 364d4831 Nathan Froyd
8607 364d4831 Nathan Froyd
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8608 364d4831 Nathan Froyd
                         int is_64_bit, int extended)
8609 364d4831 Nathan Froyd
{
8610 364d4831 Nathan Froyd
    TCGv t0;
8611 364d4831 Nathan Froyd
8612 364d4831 Nathan Froyd
    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8613 364d4831 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
8614 364d4831 Nathan Froyd
        return;
8615 364d4831 Nathan Froyd
    }
8616 364d4831 Nathan Froyd
8617 364d4831 Nathan Froyd
    t0 = tcg_temp_new();
8618 364d4831 Nathan Froyd
8619 364d4831 Nathan Froyd
    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8620 364d4831 Nathan Froyd
    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8621 364d4831 Nathan Froyd
    if (!is_64_bit) {
8622 364d4831 Nathan Froyd
        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8623 364d4831 Nathan Froyd
    }
8624 364d4831 Nathan Froyd
8625 364d4831 Nathan Froyd
    tcg_temp_free(t0);
8626 364d4831 Nathan Froyd
}
8627 364d4831 Nathan Froyd
8628 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8629 364d4831 Nathan Froyd
static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8630 364d4831 Nathan Froyd
                               int ry, int funct, int16_t offset,
8631 364d4831 Nathan Froyd
                               int extended)
8632 364d4831 Nathan Froyd
{
8633 364d4831 Nathan Froyd
    switch (funct) {
8634 364d4831 Nathan Froyd
    case I64_LDSP:
8635 364d4831 Nathan Froyd
        check_mips_64(ctx);
8636 364d4831 Nathan Froyd
        offset = extended ? offset : offset << 3;
8637 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LD, ry, 29, offset);
8638 364d4831 Nathan Froyd
        break;
8639 364d4831 Nathan Froyd
    case I64_SDSP:
8640 364d4831 Nathan Froyd
        check_mips_64(ctx);
8641 364d4831 Nathan Froyd
        offset = extended ? offset : offset << 3;
8642 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SD, ry, 29, offset);
8643 364d4831 Nathan Froyd
        break;
8644 364d4831 Nathan Froyd
    case I64_SDRASP:
8645 364d4831 Nathan Froyd
        check_mips_64(ctx);
8646 364d4831 Nathan Froyd
        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8647 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SD, 31, 29, offset);
8648 364d4831 Nathan Froyd
        break;
8649 364d4831 Nathan Froyd
    case I64_DADJSP:
8650 364d4831 Nathan Froyd
        check_mips_64(ctx);
8651 364d4831 Nathan Froyd
        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8652 364d4831 Nathan Froyd
        gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8653 364d4831 Nathan Froyd
        break;
8654 364d4831 Nathan Froyd
    case I64_LDPC:
8655 364d4831 Nathan Froyd
        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8656 364d4831 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
8657 364d4831 Nathan Froyd
        } else {
8658 364d4831 Nathan Froyd
            offset = extended ? offset : offset << 3;
8659 afa88c3a Aurelien Jarno
            gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
8660 364d4831 Nathan Froyd
        }
8661 364d4831 Nathan Froyd
        break;
8662 364d4831 Nathan Froyd
    case I64_DADDIU5:
8663 364d4831 Nathan Froyd
        check_mips_64(ctx);
8664 364d4831 Nathan Froyd
        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8665 364d4831 Nathan Froyd
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8666 364d4831 Nathan Froyd
        break;
8667 364d4831 Nathan Froyd
    case I64_DADDIUPC:
8668 364d4831 Nathan Froyd
        check_mips_64(ctx);
8669 364d4831 Nathan Froyd
        offset = extended ? offset : offset << 2;
8670 364d4831 Nathan Froyd
        gen_addiupc(ctx, ry, offset, 1, extended);
8671 364d4831 Nathan Froyd
        break;
8672 364d4831 Nathan Froyd
    case I64_DADDIUSP:
8673 364d4831 Nathan Froyd
        check_mips_64(ctx);
8674 364d4831 Nathan Froyd
        offset = extended ? offset : offset << 2;
8675 364d4831 Nathan Froyd
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8676 364d4831 Nathan Froyd
        break;
8677 364d4831 Nathan Froyd
    }
8678 364d4831 Nathan Froyd
}
8679 364d4831 Nathan Froyd
#endif
8680 364d4831 Nathan Froyd
8681 364d4831 Nathan Froyd
static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8682 364d4831 Nathan Froyd
                                       int *is_branch)
8683 364d4831 Nathan Froyd
{
8684 364d4831 Nathan Froyd
    int extend = lduw_code(ctx->pc + 2);
8685 364d4831 Nathan Froyd
    int op, rx, ry, funct, sa;
8686 364d4831 Nathan Froyd
    int16_t imm, offset;
8687 364d4831 Nathan Froyd
8688 364d4831 Nathan Froyd
    ctx->opcode = (ctx->opcode << 16) | extend;
8689 364d4831 Nathan Froyd
    op = (ctx->opcode >> 11) & 0x1f;
8690 364d4831 Nathan Froyd
    sa = (ctx->opcode >> 22) & 0x1f;
8691 364d4831 Nathan Froyd
    funct = (ctx->opcode >> 8) & 0x7;
8692 364d4831 Nathan Froyd
    rx = xlat((ctx->opcode >> 8) & 0x7);
8693 364d4831 Nathan Froyd
    ry = xlat((ctx->opcode >> 5) & 0x7);
8694 364d4831 Nathan Froyd
    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8695 364d4831 Nathan Froyd
                              | ((ctx->opcode >> 21) & 0x3f) << 5
8696 364d4831 Nathan Froyd
                              | (ctx->opcode & 0x1f));
8697 364d4831 Nathan Froyd
8698 364d4831 Nathan Froyd
    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8699 364d4831 Nathan Froyd
       counterparts.  */
8700 364d4831 Nathan Froyd
    switch (op) {
8701 364d4831 Nathan Froyd
    case M16_OPC_ADDIUSP:
8702 364d4831 Nathan Froyd
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8703 364d4831 Nathan Froyd
        break;
8704 364d4831 Nathan Froyd
    case M16_OPC_ADDIUPC:
8705 364d4831 Nathan Froyd
        gen_addiupc(ctx, rx, imm, 0, 1);
8706 364d4831 Nathan Froyd
        break;
8707 364d4831 Nathan Froyd
    case M16_OPC_B:
8708 364d4831 Nathan Froyd
        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8709 364d4831 Nathan Froyd
        /* No delay slot, so just process as a normal instruction */
8710 364d4831 Nathan Froyd
        break;
8711 364d4831 Nathan Froyd
    case M16_OPC_BEQZ:
8712 364d4831 Nathan Froyd
        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8713 364d4831 Nathan Froyd
        /* No delay slot, so just process as a normal instruction */
8714 364d4831 Nathan Froyd
        break;
8715 364d4831 Nathan Froyd
    case M16_OPC_BNEQZ:
8716 364d4831 Nathan Froyd
        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8717 364d4831 Nathan Froyd
        /* No delay slot, so just process as a normal instruction */
8718 364d4831 Nathan Froyd
        break;
8719 364d4831 Nathan Froyd
    case M16_OPC_SHIFT:
8720 364d4831 Nathan Froyd
        switch (ctx->opcode & 0x3) {
8721 364d4831 Nathan Froyd
        case 0x0:
8722 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8723 364d4831 Nathan Froyd
            break;
8724 364d4831 Nathan Froyd
        case 0x1:
8725 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8726 364d4831 Nathan Froyd
            check_mips_64(ctx);
8727 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8728 364d4831 Nathan Froyd
#else
8729 364d4831 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
8730 364d4831 Nathan Froyd
#endif
8731 364d4831 Nathan Froyd
            break;
8732 364d4831 Nathan Froyd
        case 0x2:
8733 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8734 364d4831 Nathan Froyd
            break;
8735 364d4831 Nathan Froyd
        case 0x3:
8736 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8737 364d4831 Nathan Froyd
            break;
8738 364d4831 Nathan Froyd
        }
8739 364d4831 Nathan Froyd
        break;
8740 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8741 364d4831 Nathan Froyd
    case M16_OPC_LD:
8742 364d4831 Nathan Froyd
            check_mips_64(ctx);
8743 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LD, ry, rx, offset);
8744 364d4831 Nathan Froyd
        break;
8745 364d4831 Nathan Froyd
#endif
8746 364d4831 Nathan Froyd
    case M16_OPC_RRIA:
8747 364d4831 Nathan Froyd
        imm = ctx->opcode & 0xf;
8748 364d4831 Nathan Froyd
        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8749 364d4831 Nathan Froyd
        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8750 364d4831 Nathan Froyd
        imm = (int16_t) (imm << 1) >> 1;
8751 364d4831 Nathan Froyd
        if ((ctx->opcode >> 4) & 0x1) {
8752 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8753 364d4831 Nathan Froyd
            check_mips_64(ctx);
8754 364d4831 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8755 364d4831 Nathan Froyd
#else
8756 364d4831 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
8757 364d4831 Nathan Froyd
#endif
8758 364d4831 Nathan Froyd
        } else {
8759 364d4831 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8760 364d4831 Nathan Froyd
        }
8761 364d4831 Nathan Froyd
        break;
8762 364d4831 Nathan Froyd
    case M16_OPC_ADDIU8:
8763 364d4831 Nathan Froyd
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8764 364d4831 Nathan Froyd
        break;
8765 364d4831 Nathan Froyd
    case M16_OPC_SLTI:
8766 364d4831 Nathan Froyd
        gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8767 364d4831 Nathan Froyd
        break;
8768 364d4831 Nathan Froyd
    case M16_OPC_SLTIU:
8769 364d4831 Nathan Froyd
        gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8770 364d4831 Nathan Froyd
        break;
8771 364d4831 Nathan Froyd
    case M16_OPC_I8:
8772 364d4831 Nathan Froyd
        switch (funct) {
8773 364d4831 Nathan Froyd
        case I8_BTEQZ:
8774 364d4831 Nathan Froyd
            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8775 364d4831 Nathan Froyd
            break;
8776 364d4831 Nathan Froyd
        case I8_BTNEZ:
8777 364d4831 Nathan Froyd
            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8778 364d4831 Nathan Froyd
            break;
8779 364d4831 Nathan Froyd
        case I8_SWRASP:
8780 5c13fdfd Aurelien Jarno
            gen_st(ctx, OPC_SW, 31, 29, imm);
8781 364d4831 Nathan Froyd
            break;
8782 364d4831 Nathan Froyd
        case I8_ADJSP:
8783 364d4831 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8784 364d4831 Nathan Froyd
            break;
8785 364d4831 Nathan Froyd
        case I8_SVRS:
8786 364d4831 Nathan Froyd
            {
8787 364d4831 Nathan Froyd
                int xsregs = (ctx->opcode >> 24) & 0x7;
8788 364d4831 Nathan Froyd
                int aregs = (ctx->opcode >> 16) & 0xf;
8789 364d4831 Nathan Froyd
                int do_ra = (ctx->opcode >> 6) & 0x1;
8790 364d4831 Nathan Froyd
                int do_s0 = (ctx->opcode >> 5) & 0x1;
8791 364d4831 Nathan Froyd
                int do_s1 = (ctx->opcode >> 4) & 0x1;
8792 364d4831 Nathan Froyd
                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8793 364d4831 Nathan Froyd
                                 | (ctx->opcode & 0xf)) << 3;
8794 364d4831 Nathan Froyd
8795 364d4831 Nathan Froyd
                if (ctx->opcode & (1 << 7)) {
8796 364d4831 Nathan Froyd
                    gen_mips16_save(ctx, xsregs, aregs,
8797 364d4831 Nathan Froyd
                                    do_ra, do_s0, do_s1,
8798 364d4831 Nathan Froyd
                                    framesize);
8799 364d4831 Nathan Froyd
                } else {
8800 364d4831 Nathan Froyd
                    gen_mips16_restore(ctx, xsregs, aregs,
8801 364d4831 Nathan Froyd
                                       do_ra, do_s0, do_s1,
8802 364d4831 Nathan Froyd
                                       framesize);
8803 364d4831 Nathan Froyd
                }
8804 364d4831 Nathan Froyd
            }
8805 364d4831 Nathan Froyd
            break;
8806 364d4831 Nathan Froyd
        default:
8807 364d4831 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
8808 364d4831 Nathan Froyd
            break;
8809 364d4831 Nathan Froyd
        }
8810 364d4831 Nathan Froyd
        break;
8811 364d4831 Nathan Froyd
    case M16_OPC_LI:
8812 364d4831 Nathan Froyd
        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8813 364d4831 Nathan Froyd
        break;
8814 364d4831 Nathan Froyd
    case M16_OPC_CMPI:
8815 364d4831 Nathan Froyd
        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8816 364d4831 Nathan Froyd
        break;
8817 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8818 364d4831 Nathan Froyd
    case M16_OPC_SD:
8819 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SD, ry, rx, offset);
8820 364d4831 Nathan Froyd
        break;
8821 364d4831 Nathan Froyd
#endif
8822 364d4831 Nathan Froyd
    case M16_OPC_LB:
8823 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8824 364d4831 Nathan Froyd
        break;
8825 364d4831 Nathan Froyd
    case M16_OPC_LH:
8826 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LH, ry, rx, offset);
8827 364d4831 Nathan Froyd
        break;
8828 364d4831 Nathan Froyd
    case M16_OPC_LWSP:
8829 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LW, rx, 29, offset);
8830 364d4831 Nathan Froyd
        break;
8831 364d4831 Nathan Froyd
    case M16_OPC_LW:
8832 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LW, ry, rx, offset);
8833 364d4831 Nathan Froyd
        break;
8834 364d4831 Nathan Froyd
    case M16_OPC_LBU:
8835 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8836 364d4831 Nathan Froyd
        break;
8837 364d4831 Nathan Froyd
    case M16_OPC_LHU:
8838 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
8839 364d4831 Nathan Froyd
        break;
8840 364d4831 Nathan Froyd
    case M16_OPC_LWPC:
8841 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
8842 364d4831 Nathan Froyd
        break;
8843 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8844 364d4831 Nathan Froyd
    case M16_OPC_LWU:
8845 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
8846 364d4831 Nathan Froyd
        break;
8847 364d4831 Nathan Froyd
#endif
8848 364d4831 Nathan Froyd
    case M16_OPC_SB:
8849 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SB, ry, rx, offset);
8850 364d4831 Nathan Froyd
        break;
8851 364d4831 Nathan Froyd
    case M16_OPC_SH:
8852 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SH, ry, rx, offset);
8853 364d4831 Nathan Froyd
        break;
8854 364d4831 Nathan Froyd
    case M16_OPC_SWSP:
8855 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SW, rx, 29, offset);
8856 364d4831 Nathan Froyd
        break;
8857 364d4831 Nathan Froyd
    case M16_OPC_SW:
8858 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SW, ry, rx, offset);
8859 364d4831 Nathan Froyd
        break;
8860 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8861 364d4831 Nathan Froyd
    case M16_OPC_I64:
8862 364d4831 Nathan Froyd
        decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8863 364d4831 Nathan Froyd
        break;
8864 364d4831 Nathan Froyd
#endif
8865 364d4831 Nathan Froyd
    default:
8866 364d4831 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
8867 364d4831 Nathan Froyd
        break;
8868 364d4831 Nathan Froyd
    }
8869 364d4831 Nathan Froyd
8870 364d4831 Nathan Froyd
    return 4;
8871 364d4831 Nathan Froyd
}
8872 364d4831 Nathan Froyd
8873 364d4831 Nathan Froyd
static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8874 364d4831 Nathan Froyd
                              int *is_branch)
8875 364d4831 Nathan Froyd
{
8876 364d4831 Nathan Froyd
    int rx, ry;
8877 364d4831 Nathan Froyd
    int sa;
8878 364d4831 Nathan Froyd
    int op, cnvt_op, op1, offset;
8879 364d4831 Nathan Froyd
    int funct;
8880 364d4831 Nathan Froyd
    int n_bytes;
8881 364d4831 Nathan Froyd
8882 364d4831 Nathan Froyd
    op = (ctx->opcode >> 11) & 0x1f;
8883 364d4831 Nathan Froyd
    sa = (ctx->opcode >> 2) & 0x7;
8884 364d4831 Nathan Froyd
    sa = sa == 0 ? 8 : sa;
8885 364d4831 Nathan Froyd
    rx = xlat((ctx->opcode >> 8) & 0x7);
8886 364d4831 Nathan Froyd
    cnvt_op = (ctx->opcode >> 5) & 0x7;
8887 364d4831 Nathan Froyd
    ry = xlat((ctx->opcode >> 5) & 0x7);
8888 364d4831 Nathan Froyd
    op1 = offset = ctx->opcode & 0x1f;
8889 364d4831 Nathan Froyd
8890 364d4831 Nathan Froyd
    n_bytes = 2;
8891 364d4831 Nathan Froyd
8892 364d4831 Nathan Froyd
    switch (op) {
8893 364d4831 Nathan Froyd
    case M16_OPC_ADDIUSP:
8894 364d4831 Nathan Froyd
        {
8895 364d4831 Nathan Froyd
            int16_t imm = ((uint8_t) ctx->opcode) << 2;
8896 364d4831 Nathan Froyd
8897 364d4831 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8898 364d4831 Nathan Froyd
        }
8899 364d4831 Nathan Froyd
        break;
8900 364d4831 Nathan Froyd
    case M16_OPC_ADDIUPC:
8901 364d4831 Nathan Froyd
        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8902 364d4831 Nathan Froyd
        break;
8903 364d4831 Nathan Froyd
    case M16_OPC_B:
8904 364d4831 Nathan Froyd
        offset = (ctx->opcode & 0x7ff) << 1;
8905 364d4831 Nathan Froyd
        offset = (int16_t)(offset << 4) >> 4;
8906 364d4831 Nathan Froyd
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8907 364d4831 Nathan Froyd
        /* No delay slot, so just process as a normal instruction */
8908 364d4831 Nathan Froyd
        break;
8909 364d4831 Nathan Froyd
    case M16_OPC_JAL:
8910 364d4831 Nathan Froyd
        offset = lduw_code(ctx->pc + 2);
8911 364d4831 Nathan Froyd
        offset = (((ctx->opcode & 0x1f) << 21)
8912 364d4831 Nathan Froyd
                  | ((ctx->opcode >> 5) & 0x1f) << 16
8913 364d4831 Nathan Froyd
                  | offset) << 2;
8914 620e48f6 Nathan Froyd
        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8915 364d4831 Nathan Froyd
        gen_compute_branch(ctx, op, 4, rx, ry, offset);
8916 364d4831 Nathan Froyd
        n_bytes = 4;
8917 364d4831 Nathan Froyd
        *is_branch = 1;
8918 364d4831 Nathan Froyd
        break;
8919 364d4831 Nathan Froyd
    case M16_OPC_BEQZ:
8920 364d4831 Nathan Froyd
        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8921 364d4831 Nathan Froyd
        /* No delay slot, so just process as a normal instruction */
8922 364d4831 Nathan Froyd
        break;
8923 364d4831 Nathan Froyd
    case M16_OPC_BNEQZ:
8924 364d4831 Nathan Froyd
        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8925 364d4831 Nathan Froyd
        /* No delay slot, so just process as a normal instruction */
8926 364d4831 Nathan Froyd
        break;
8927 364d4831 Nathan Froyd
    case M16_OPC_SHIFT:
8928 364d4831 Nathan Froyd
        switch (ctx->opcode & 0x3) {
8929 364d4831 Nathan Froyd
        case 0x0:
8930 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8931 364d4831 Nathan Froyd
            break;
8932 364d4831 Nathan Froyd
        case 0x1:
8933 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8934 364d4831 Nathan Froyd
            check_mips_64(ctx);
8935 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8936 364d4831 Nathan Froyd
#else
8937 364d4831 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
8938 364d4831 Nathan Froyd
#endif
8939 364d4831 Nathan Froyd
            break;
8940 364d4831 Nathan Froyd
        case 0x2:
8941 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8942 364d4831 Nathan Froyd
            break;
8943 364d4831 Nathan Froyd
        case 0x3:
8944 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8945 364d4831 Nathan Froyd
            break;
8946 364d4831 Nathan Froyd
        }
8947 364d4831 Nathan Froyd
        break;
8948 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8949 364d4831 Nathan Froyd
    case M16_OPC_LD:
8950 364d4831 Nathan Froyd
        check_mips_64(ctx);
8951 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
8952 364d4831 Nathan Froyd
        break;
8953 364d4831 Nathan Froyd
#endif
8954 364d4831 Nathan Froyd
    case M16_OPC_RRIA:
8955 364d4831 Nathan Froyd
        {
8956 364d4831 Nathan Froyd
            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8957 364d4831 Nathan Froyd
8958 364d4831 Nathan Froyd
            if ((ctx->opcode >> 4) & 1) {
8959 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
8960 364d4831 Nathan Froyd
                check_mips_64(ctx);
8961 364d4831 Nathan Froyd
                gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8962 364d4831 Nathan Froyd
#else
8963 364d4831 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
8964 364d4831 Nathan Froyd
#endif
8965 364d4831 Nathan Froyd
            } else {
8966 364d4831 Nathan Froyd
                gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8967 364d4831 Nathan Froyd
            }
8968 364d4831 Nathan Froyd
        }
8969 364d4831 Nathan Froyd
        break;
8970 364d4831 Nathan Froyd
    case M16_OPC_ADDIU8:
8971 364d4831 Nathan Froyd
        {
8972 364d4831 Nathan Froyd
            int16_t imm = (int8_t) ctx->opcode;
8973 364d4831 Nathan Froyd
8974 364d4831 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8975 364d4831 Nathan Froyd
        }
8976 364d4831 Nathan Froyd
        break;
8977 364d4831 Nathan Froyd
    case M16_OPC_SLTI:
8978 364d4831 Nathan Froyd
        {
8979 364d4831 Nathan Froyd
            int16_t imm = (uint8_t) ctx->opcode;
8980 364d4831 Nathan Froyd
8981 364d4831 Nathan Froyd
            gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8982 364d4831 Nathan Froyd
        }
8983 364d4831 Nathan Froyd
        break;
8984 364d4831 Nathan Froyd
    case M16_OPC_SLTIU:
8985 364d4831 Nathan Froyd
        {
8986 364d4831 Nathan Froyd
            int16_t imm = (uint8_t) ctx->opcode;
8987 364d4831 Nathan Froyd
8988 364d4831 Nathan Froyd
            gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8989 364d4831 Nathan Froyd
        }
8990 364d4831 Nathan Froyd
        break;
8991 364d4831 Nathan Froyd
    case M16_OPC_I8:
8992 364d4831 Nathan Froyd
        {
8993 364d4831 Nathan Froyd
            int reg32;
8994 364d4831 Nathan Froyd
8995 364d4831 Nathan Froyd
            funct = (ctx->opcode >> 8) & 0x7;
8996 364d4831 Nathan Froyd
            switch (funct) {
8997 364d4831 Nathan Froyd
            case I8_BTEQZ:
8998 364d4831 Nathan Froyd
                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8999 364d4831 Nathan Froyd
                                   ((int8_t)ctx->opcode) << 1);
9000 364d4831 Nathan Froyd
                break;
9001 364d4831 Nathan Froyd
            case I8_BTNEZ:
9002 364d4831 Nathan Froyd
                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9003 364d4831 Nathan Froyd
                                   ((int8_t)ctx->opcode) << 1);
9004 364d4831 Nathan Froyd
                break;
9005 364d4831 Nathan Froyd
            case I8_SWRASP:
9006 5c13fdfd Aurelien Jarno
                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9007 364d4831 Nathan Froyd
                break;
9008 364d4831 Nathan Froyd
            case I8_ADJSP:
9009 364d4831 Nathan Froyd
                gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9010 364d4831 Nathan Froyd
                              ((int8_t)ctx->opcode) << 3);
9011 364d4831 Nathan Froyd
                break;
9012 364d4831 Nathan Froyd
            case I8_SVRS:
9013 364d4831 Nathan Froyd
                {
9014 364d4831 Nathan Froyd
                    int do_ra = ctx->opcode & (1 << 6);
9015 364d4831 Nathan Froyd
                    int do_s0 = ctx->opcode & (1 << 5);
9016 364d4831 Nathan Froyd
                    int do_s1 = ctx->opcode & (1 << 4);
9017 364d4831 Nathan Froyd
                    int framesize = ctx->opcode & 0xf;
9018 364d4831 Nathan Froyd
9019 364d4831 Nathan Froyd
                    if (framesize == 0) {
9020 364d4831 Nathan Froyd
                        framesize = 128;
9021 364d4831 Nathan Froyd
                    } else {
9022 364d4831 Nathan Froyd
                        framesize = framesize << 3;
9023 364d4831 Nathan Froyd
                    }
9024 364d4831 Nathan Froyd
9025 364d4831 Nathan Froyd
                    if (ctx->opcode & (1 << 7)) {
9026 364d4831 Nathan Froyd
                        gen_mips16_save(ctx, 0, 0,
9027 364d4831 Nathan Froyd
                                        do_ra, do_s0, do_s1, framesize);
9028 364d4831 Nathan Froyd
                    } else {
9029 364d4831 Nathan Froyd
                        gen_mips16_restore(ctx, 0, 0,
9030 364d4831 Nathan Froyd
                                           do_ra, do_s0, do_s1, framesize);
9031 364d4831 Nathan Froyd
                    }
9032 364d4831 Nathan Froyd
                }
9033 364d4831 Nathan Froyd
                break;
9034 364d4831 Nathan Froyd
            case I8_MOV32R:
9035 364d4831 Nathan Froyd
                {
9036 364d4831 Nathan Froyd
                    int rz = xlat(ctx->opcode & 0x7);
9037 364d4831 Nathan Froyd
9038 364d4831 Nathan Froyd
                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9039 364d4831 Nathan Froyd
                        ((ctx->opcode >> 5) & 0x7);
9040 364d4831 Nathan Froyd
                    gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9041 364d4831 Nathan Froyd
                }
9042 364d4831 Nathan Froyd
                break;
9043 364d4831 Nathan Froyd
            case I8_MOVR32:
9044 364d4831 Nathan Froyd
                reg32 = ctx->opcode & 0x1f;
9045 364d4831 Nathan Froyd
                gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9046 364d4831 Nathan Froyd
                break;
9047 364d4831 Nathan Froyd
            default:
9048 364d4831 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
9049 364d4831 Nathan Froyd
                break;
9050 364d4831 Nathan Froyd
            }
9051 364d4831 Nathan Froyd
        }
9052 364d4831 Nathan Froyd
        break;
9053 364d4831 Nathan Froyd
    case M16_OPC_LI:
9054 364d4831 Nathan Froyd
        {
9055 364d4831 Nathan Froyd
            int16_t imm = (uint8_t) ctx->opcode;
9056 364d4831 Nathan Froyd
9057 364d4831 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9058 364d4831 Nathan Froyd
        }
9059 364d4831 Nathan Froyd
        break;
9060 364d4831 Nathan Froyd
    case M16_OPC_CMPI:
9061 364d4831 Nathan Froyd
        {
9062 364d4831 Nathan Froyd
            int16_t imm = (uint8_t) ctx->opcode;
9063 364d4831 Nathan Froyd
9064 364d4831 Nathan Froyd
            gen_logic_imm(env, OPC_XORI, 24, rx, imm);
9065 364d4831 Nathan Froyd
        }
9066 364d4831 Nathan Froyd
        break;
9067 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
9068 364d4831 Nathan Froyd
    case M16_OPC_SD:
9069 364d4831 Nathan Froyd
        check_mips_64(ctx);
9070 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9071 364d4831 Nathan Froyd
        break;
9072 364d4831 Nathan Froyd
#endif
9073 364d4831 Nathan Froyd
    case M16_OPC_LB:
9074 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9075 364d4831 Nathan Froyd
        break;
9076 364d4831 Nathan Froyd
    case M16_OPC_LH:
9077 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9078 364d4831 Nathan Froyd
        break;
9079 364d4831 Nathan Froyd
    case M16_OPC_LWSP:
9080 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9081 364d4831 Nathan Froyd
        break;
9082 364d4831 Nathan Froyd
    case M16_OPC_LW:
9083 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9084 364d4831 Nathan Froyd
        break;
9085 364d4831 Nathan Froyd
    case M16_OPC_LBU:
9086 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9087 364d4831 Nathan Froyd
        break;
9088 364d4831 Nathan Froyd
    case M16_OPC_LHU:
9089 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9090 364d4831 Nathan Froyd
        break;
9091 364d4831 Nathan Froyd
    case M16_OPC_LWPC:
9092 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9093 364d4831 Nathan Froyd
        break;
9094 364d4831 Nathan Froyd
#if defined (TARGET_MIPS64)
9095 364d4831 Nathan Froyd
    case M16_OPC_LWU:
9096 364d4831 Nathan Froyd
        check_mips_64(ctx);
9097 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9098 364d4831 Nathan Froyd
        break;
9099 364d4831 Nathan Froyd
#endif
9100 364d4831 Nathan Froyd
    case M16_OPC_SB:
9101 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SB, ry, rx, offset);
9102 364d4831 Nathan Froyd
        break;
9103 364d4831 Nathan Froyd
    case M16_OPC_SH:
9104 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9105 364d4831 Nathan Froyd
        break;
9106 364d4831 Nathan Froyd
    case M16_OPC_SWSP:
9107 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9108 364d4831 Nathan Froyd
        break;
9109 364d4831 Nathan Froyd
    case M16_OPC_SW:
9110 5c13fdfd Aurelien Jarno
        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9111 364d4831 Nathan Froyd
        break;
9112 364d4831 Nathan Froyd
    case M16_OPC_RRR:
9113 364d4831 Nathan Froyd
        {
9114 364d4831 Nathan Froyd
            int rz = xlat((ctx->opcode >> 2) & 0x7);
9115 364d4831 Nathan Froyd
            int mips32_op;
9116 364d4831 Nathan Froyd
9117 364d4831 Nathan Froyd
            switch (ctx->opcode & 0x3) {
9118 364d4831 Nathan Froyd
            case RRR_ADDU:
9119 364d4831 Nathan Froyd
                mips32_op = OPC_ADDU;
9120 364d4831 Nathan Froyd
                break;
9121 364d4831 Nathan Froyd
            case RRR_SUBU:
9122 364d4831 Nathan Froyd
                mips32_op = OPC_SUBU;
9123 364d4831 Nathan Froyd
                break;
9124 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
9125 364d4831 Nathan Froyd
            case RRR_DADDU:
9126 364d4831 Nathan Froyd
                mips32_op = OPC_DADDU;
9127 364d4831 Nathan Froyd
                check_mips_64(ctx);
9128 364d4831 Nathan Froyd
                break;
9129 364d4831 Nathan Froyd
            case RRR_DSUBU:
9130 364d4831 Nathan Froyd
                mips32_op = OPC_DSUBU;
9131 364d4831 Nathan Froyd
                check_mips_64(ctx);
9132 364d4831 Nathan Froyd
                break;
9133 364d4831 Nathan Froyd
#endif
9134 364d4831 Nathan Froyd
            default:
9135 364d4831 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
9136 364d4831 Nathan Froyd
                goto done;
9137 364d4831 Nathan Froyd
            }
9138 364d4831 Nathan Froyd
9139 364d4831 Nathan Froyd
            gen_arith(env, ctx, mips32_op, rz, rx, ry);
9140 364d4831 Nathan Froyd
        done:
9141 364d4831 Nathan Froyd
            ;
9142 364d4831 Nathan Froyd
        }
9143 364d4831 Nathan Froyd
        break;
9144 364d4831 Nathan Froyd
    case M16_OPC_RR:
9145 364d4831 Nathan Froyd
        switch (op1) {
9146 364d4831 Nathan Froyd
        case RR_JR:
9147 364d4831 Nathan Froyd
            {
9148 364d4831 Nathan Froyd
                int nd = (ctx->opcode >> 7) & 0x1;
9149 364d4831 Nathan Froyd
                int link = (ctx->opcode >> 6) & 0x1;
9150 364d4831 Nathan Froyd
                int ra = (ctx->opcode >> 5) & 0x1;
9151 364d4831 Nathan Froyd
9152 364d4831 Nathan Froyd
                if (link) {
9153 620e48f6 Nathan Froyd
                    op = nd ? OPC_JALRC : OPC_JALRS;
9154 364d4831 Nathan Froyd
                } else {
9155 364d4831 Nathan Froyd
                    op = OPC_JR;
9156 364d4831 Nathan Froyd
                }
9157 364d4831 Nathan Froyd
9158 364d4831 Nathan Froyd
                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9159 364d4831 Nathan Froyd
                if (!nd) {
9160 364d4831 Nathan Froyd
                    *is_branch = 1;
9161 364d4831 Nathan Froyd
                }
9162 364d4831 Nathan Froyd
            }
9163 364d4831 Nathan Froyd
            break;
9164 364d4831 Nathan Froyd
        case RR_SDBBP:
9165 364d4831 Nathan Froyd
            /* XXX: not clear which exception should be raised
9166 364d4831 Nathan Froyd
             *      when in debug mode...
9167 364d4831 Nathan Froyd
             */
9168 364d4831 Nathan Froyd
            check_insn(env, ctx, ISA_MIPS32);
9169 364d4831 Nathan Froyd
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9170 364d4831 Nathan Froyd
                generate_exception(ctx, EXCP_DBp);
9171 364d4831 Nathan Froyd
            } else {
9172 364d4831 Nathan Froyd
                generate_exception(ctx, EXCP_DBp);
9173 364d4831 Nathan Froyd
            }
9174 364d4831 Nathan Froyd
            break;
9175 364d4831 Nathan Froyd
        case RR_SLT:
9176 364d4831 Nathan Froyd
            gen_slt(env, OPC_SLT, 24, rx, ry);
9177 364d4831 Nathan Froyd
            break;
9178 364d4831 Nathan Froyd
        case RR_SLTU:
9179 364d4831 Nathan Froyd
            gen_slt(env, OPC_SLTU, 24, rx, ry);
9180 364d4831 Nathan Froyd
            break;
9181 364d4831 Nathan Froyd
        case RR_BREAK:
9182 364d4831 Nathan Froyd
            generate_exception(ctx, EXCP_BREAK);
9183 364d4831 Nathan Froyd
            break;
9184 364d4831 Nathan Froyd
        case RR_SLLV:
9185 364d4831 Nathan Froyd
            gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9186 364d4831 Nathan Froyd
            break;
9187 364d4831 Nathan Froyd
        case RR_SRLV:
9188 364d4831 Nathan Froyd
            gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9189 364d4831 Nathan Froyd
            break;
9190 364d4831 Nathan Froyd
        case RR_SRAV:
9191 364d4831 Nathan Froyd
            gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9192 364d4831 Nathan Froyd
            break;
9193 364d4831 Nathan Froyd
#if defined (TARGET_MIPS64)
9194 364d4831 Nathan Froyd
        case RR_DSRL:
9195 364d4831 Nathan Froyd
            check_mips_64(ctx);
9196 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9197 364d4831 Nathan Froyd
            break;
9198 364d4831 Nathan Froyd
#endif
9199 364d4831 Nathan Froyd
        case RR_CMP:
9200 364d4831 Nathan Froyd
            gen_logic(env, OPC_XOR, 24, rx, ry);
9201 364d4831 Nathan Froyd
            break;
9202 364d4831 Nathan Froyd
        case RR_NEG:
9203 364d4831 Nathan Froyd
            gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9204 364d4831 Nathan Froyd
            break;
9205 364d4831 Nathan Froyd
        case RR_AND:
9206 364d4831 Nathan Froyd
            gen_logic(env, OPC_AND, rx, rx, ry);
9207 364d4831 Nathan Froyd
            break;
9208 364d4831 Nathan Froyd
        case RR_OR:
9209 364d4831 Nathan Froyd
            gen_logic(env, OPC_OR, rx, rx, ry);
9210 364d4831 Nathan Froyd
            break;
9211 364d4831 Nathan Froyd
        case RR_XOR:
9212 364d4831 Nathan Froyd
            gen_logic(env, OPC_XOR, rx, rx, ry);
9213 364d4831 Nathan Froyd
            break;
9214 364d4831 Nathan Froyd
        case RR_NOT:
9215 364d4831 Nathan Froyd
            gen_logic(env, OPC_NOR, rx, ry, 0);
9216 364d4831 Nathan Froyd
            break;
9217 364d4831 Nathan Froyd
        case RR_MFHI:
9218 364d4831 Nathan Froyd
            gen_HILO(ctx, OPC_MFHI, rx);
9219 364d4831 Nathan Froyd
            break;
9220 364d4831 Nathan Froyd
        case RR_CNVT:
9221 364d4831 Nathan Froyd
            switch (cnvt_op) {
9222 364d4831 Nathan Froyd
            case RR_RY_CNVT_ZEB:
9223 364d4831 Nathan Froyd
                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9224 364d4831 Nathan Froyd
                break;
9225 364d4831 Nathan Froyd
            case RR_RY_CNVT_ZEH:
9226 364d4831 Nathan Froyd
                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9227 364d4831 Nathan Froyd
                break;
9228 364d4831 Nathan Froyd
            case RR_RY_CNVT_SEB:
9229 364d4831 Nathan Froyd
                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9230 364d4831 Nathan Froyd
                break;
9231 364d4831 Nathan Froyd
            case RR_RY_CNVT_SEH:
9232 364d4831 Nathan Froyd
                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9233 364d4831 Nathan Froyd
                break;
9234 364d4831 Nathan Froyd
#if defined (TARGET_MIPS64)
9235 364d4831 Nathan Froyd
            case RR_RY_CNVT_ZEW:
9236 364d4831 Nathan Froyd
                check_mips_64(ctx);
9237 364d4831 Nathan Froyd
                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9238 364d4831 Nathan Froyd
                break;
9239 364d4831 Nathan Froyd
            case RR_RY_CNVT_SEW:
9240 364d4831 Nathan Froyd
                check_mips_64(ctx);
9241 364d4831 Nathan Froyd
                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9242 364d4831 Nathan Froyd
                break;
9243 364d4831 Nathan Froyd
#endif
9244 364d4831 Nathan Froyd
            default:
9245 364d4831 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
9246 364d4831 Nathan Froyd
                break;
9247 364d4831 Nathan Froyd
            }
9248 364d4831 Nathan Froyd
            break;
9249 364d4831 Nathan Froyd
        case RR_MFLO:
9250 364d4831 Nathan Froyd
            gen_HILO(ctx, OPC_MFLO, rx);
9251 364d4831 Nathan Froyd
            break;
9252 364d4831 Nathan Froyd
#if defined (TARGET_MIPS64)
9253 364d4831 Nathan Froyd
        case RR_DSRA:
9254 364d4831 Nathan Froyd
            check_mips_64(ctx);
9255 364d4831 Nathan Froyd
            gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9256 364d4831 Nathan Froyd
            break;
9257 364d4831 Nathan Froyd
        case RR_DSLLV:
9258 364d4831 Nathan Froyd
            check_mips_64(ctx);
9259 364d4831 Nathan Froyd
            gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9260 364d4831 Nathan Froyd
            break;
9261 364d4831 Nathan Froyd
        case RR_DSRLV:
9262 364d4831 Nathan Froyd
            check_mips_64(ctx);
9263 364d4831 Nathan Froyd
            gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9264 364d4831 Nathan Froyd
            break;
9265 364d4831 Nathan Froyd
        case RR_DSRAV:
9266 364d4831 Nathan Froyd
            check_mips_64(ctx);
9267 364d4831 Nathan Froyd
            gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9268 364d4831 Nathan Froyd
            break;
9269 364d4831 Nathan Froyd
#endif
9270 364d4831 Nathan Froyd
        case RR_MULT:
9271 364d4831 Nathan Froyd
            gen_muldiv(ctx, OPC_MULT, rx, ry);
9272 364d4831 Nathan Froyd
            break;
9273 364d4831 Nathan Froyd
        case RR_MULTU:
9274 364d4831 Nathan Froyd
            gen_muldiv(ctx, OPC_MULTU, rx, ry);
9275 364d4831 Nathan Froyd
            break;
9276 364d4831 Nathan Froyd
        case RR_DIV:
9277 364d4831 Nathan Froyd
            gen_muldiv(ctx, OPC_DIV, rx, ry);
9278 364d4831 Nathan Froyd
            break;
9279 364d4831 Nathan Froyd
        case RR_DIVU:
9280 364d4831 Nathan Froyd
            gen_muldiv(ctx, OPC_DIVU, rx, ry);
9281 364d4831 Nathan Froyd
            break;
9282 364d4831 Nathan Froyd
#if defined (TARGET_MIPS64)
9283 364d4831 Nathan Froyd
        case RR_DMULT:
9284 364d4831 Nathan Froyd
            check_mips_64(ctx);
9285 364d4831 Nathan Froyd
            gen_muldiv(ctx, OPC_DMULT, rx, ry);
9286 364d4831 Nathan Froyd
            break;
9287 364d4831 Nathan Froyd
        case RR_DMULTU:
9288 364d4831 Nathan Froyd
            check_mips_64(ctx);
9289 364d4831 Nathan Froyd
            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9290 364d4831 Nathan Froyd
            break;
9291 364d4831 Nathan Froyd
        case RR_DDIV:
9292 364d4831 Nathan Froyd
            check_mips_64(ctx);
9293 364d4831 Nathan Froyd
            gen_muldiv(ctx, OPC_DDIV, rx, ry);
9294 364d4831 Nathan Froyd
            break;
9295 364d4831 Nathan Froyd
        case RR_DDIVU:
9296 364d4831 Nathan Froyd
            check_mips_64(ctx);
9297 364d4831 Nathan Froyd
            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9298 364d4831 Nathan Froyd
            break;
9299 364d4831 Nathan Froyd
#endif
9300 364d4831 Nathan Froyd
        default:
9301 364d4831 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
9302 364d4831 Nathan Froyd
            break;
9303 364d4831 Nathan Froyd
        }
9304 364d4831 Nathan Froyd
        break;
9305 364d4831 Nathan Froyd
    case M16_OPC_EXTEND:
9306 364d4831 Nathan Froyd
        decode_extended_mips16_opc(env, ctx, is_branch);
9307 364d4831 Nathan Froyd
        n_bytes = 4;
9308 364d4831 Nathan Froyd
        break;
9309 364d4831 Nathan Froyd
#if defined(TARGET_MIPS64)
9310 364d4831 Nathan Froyd
    case M16_OPC_I64:
9311 364d4831 Nathan Froyd
        funct = (ctx->opcode >> 8) & 0x7;
9312 364d4831 Nathan Froyd
        decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9313 364d4831 Nathan Froyd
        break;
9314 364d4831 Nathan Froyd
#endif
9315 364d4831 Nathan Froyd
    default:
9316 364d4831 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
9317 364d4831 Nathan Froyd
        break;
9318 364d4831 Nathan Froyd
    }
9319 364d4831 Nathan Froyd
9320 364d4831 Nathan Froyd
    return n_bytes;
9321 364d4831 Nathan Froyd
}
9322 364d4831 Nathan Froyd
9323 3c824109 Nathan Froyd
/* microMIPS extension to MIPS32 */
9324 6af0bf9c bellard
9325 3c824109 Nathan Froyd
/* microMIPS32 major opcodes */
9326 6af0bf9c bellard
9327 3c824109 Nathan Froyd
enum {
9328 3c824109 Nathan Froyd
    POOL32A = 0x00,
9329 3c824109 Nathan Froyd
    POOL16A = 0x01,
9330 3c824109 Nathan Froyd
    LBU16 = 0x02,
9331 3c824109 Nathan Froyd
    MOVE16 = 0x03,
9332 3c824109 Nathan Froyd
    ADDI32 = 0x04,
9333 3c824109 Nathan Froyd
    LBU32 = 0x05,
9334 3c824109 Nathan Froyd
    SB32 = 0x06,
9335 3c824109 Nathan Froyd
    LB32 = 0x07,
9336 3c824109 Nathan Froyd
9337 3c824109 Nathan Froyd
    POOL32B = 0x08,
9338 3c824109 Nathan Froyd
    POOL16B = 0x09,
9339 3c824109 Nathan Froyd
    LHU16 = 0x0a,
9340 3c824109 Nathan Froyd
    ANDI16 = 0x0b,
9341 3c824109 Nathan Froyd
    ADDIU32 = 0x0c,
9342 3c824109 Nathan Froyd
    LHU32 = 0x0d,
9343 3c824109 Nathan Froyd
    SH32 = 0x0e,
9344 3c824109 Nathan Froyd
    LH32 = 0x0f,
9345 3c824109 Nathan Froyd
9346 3c824109 Nathan Froyd
    POOL32I = 0x10,
9347 3c824109 Nathan Froyd
    POOL16C = 0x11,
9348 3c824109 Nathan Froyd
    LWSP16 = 0x12,
9349 3c824109 Nathan Froyd
    POOL16D = 0x13,
9350 3c824109 Nathan Froyd
    ORI32 = 0x14,
9351 3c824109 Nathan Froyd
    POOL32F = 0x15,
9352 3c824109 Nathan Froyd
    POOL32S = 0x16,
9353 3c824109 Nathan Froyd
    DADDIU32 = 0x17,
9354 3c824109 Nathan Froyd
9355 3c824109 Nathan Froyd
    POOL32C = 0x18,
9356 3c824109 Nathan Froyd
    LWGP16 = 0x19,
9357 3c824109 Nathan Froyd
    LW16 = 0x1a,
9358 3c824109 Nathan Froyd
    POOL16E = 0x1b,
9359 3c824109 Nathan Froyd
    XORI32 = 0x1c,
9360 3c824109 Nathan Froyd
    JALS32 = 0x1d,
9361 3c824109 Nathan Froyd
    ADDIUPC = 0x1e,
9362 3c824109 Nathan Froyd
    POOL48A = 0x1f,
9363 3c824109 Nathan Froyd
9364 3c824109 Nathan Froyd
    /* 0x20 is reserved */
9365 3c824109 Nathan Froyd
    RES_20 = 0x20,
9366 3c824109 Nathan Froyd
    POOL16F = 0x21,
9367 3c824109 Nathan Froyd
    SB16 = 0x22,
9368 3c824109 Nathan Froyd
    BEQZ16 = 0x23,
9369 3c824109 Nathan Froyd
    SLTI32 = 0x24,
9370 3c824109 Nathan Froyd
    BEQ32 = 0x25,
9371 3c824109 Nathan Froyd
    SWC132 = 0x26,
9372 3c824109 Nathan Froyd
    LWC132 = 0x27,
9373 3c824109 Nathan Froyd
9374 3c824109 Nathan Froyd
    /* 0x28 and 0x29 are reserved */
9375 3c824109 Nathan Froyd
    RES_28 = 0x28,
9376 3c824109 Nathan Froyd
    RES_29 = 0x29,
9377 3c824109 Nathan Froyd
    SH16 = 0x2a,
9378 3c824109 Nathan Froyd
    BNEZ16 = 0x2b,
9379 3c824109 Nathan Froyd
    SLTIU32 = 0x2c,
9380 3c824109 Nathan Froyd
    BNE32 = 0x2d,
9381 3c824109 Nathan Froyd
    SDC132 = 0x2e,
9382 3c824109 Nathan Froyd
    LDC132 = 0x2f,
9383 3c824109 Nathan Froyd
9384 3c824109 Nathan Froyd
    /* 0x30 and 0x31 are reserved */
9385 3c824109 Nathan Froyd
    RES_30 = 0x30,
9386 3c824109 Nathan Froyd
    RES_31 = 0x31,
9387 3c824109 Nathan Froyd
    SWSP16 = 0x32,
9388 3c824109 Nathan Froyd
    B16 = 0x33,
9389 3c824109 Nathan Froyd
    ANDI32 = 0x34,
9390 3c824109 Nathan Froyd
    J32 = 0x35,
9391 3c824109 Nathan Froyd
    SD32 = 0x36,
9392 3c824109 Nathan Froyd
    LD32 = 0x37,
9393 3c824109 Nathan Froyd
9394 3c824109 Nathan Froyd
    /* 0x38 and 0x39 are reserved */
9395 3c824109 Nathan Froyd
    RES_38 = 0x38,
9396 3c824109 Nathan Froyd
    RES_39 = 0x39,
9397 3c824109 Nathan Froyd
    SW16 = 0x3a,
9398 3c824109 Nathan Froyd
    LI16 = 0x3b,
9399 3c824109 Nathan Froyd
    JALX32 = 0x3c,
9400 3c824109 Nathan Froyd
    JAL32 = 0x3d,
9401 3c824109 Nathan Froyd
    SW32 = 0x3e,
9402 3c824109 Nathan Froyd
    LW32 = 0x3f
9403 3c824109 Nathan Froyd
};
9404 3c824109 Nathan Froyd
9405 3c824109 Nathan Froyd
/* POOL32A encoding of minor opcode field */
9406 3c824109 Nathan Froyd
9407 3c824109 Nathan Froyd
enum {
9408 3c824109 Nathan Froyd
    /* These opcodes are distinguished only by bits 9..6; those bits are
9409 3c824109 Nathan Froyd
     * what are recorded below. */
9410 3c824109 Nathan Froyd
    SLL32 = 0x0,
9411 3c824109 Nathan Froyd
    SRL32 = 0x1,
9412 3c824109 Nathan Froyd
    SRA = 0x2,
9413 3c824109 Nathan Froyd
    ROTR = 0x3,
9414 3c824109 Nathan Froyd
9415 3c824109 Nathan Froyd
    SLLV = 0x0,
9416 3c824109 Nathan Froyd
    SRLV = 0x1,
9417 3c824109 Nathan Froyd
    SRAV = 0x2,
9418 3c824109 Nathan Froyd
    ROTRV = 0x3,
9419 3c824109 Nathan Froyd
    ADD = 0x4,
9420 3c824109 Nathan Froyd
    ADDU32 = 0x5,
9421 3c824109 Nathan Froyd
    SUB = 0x6,
9422 3c824109 Nathan Froyd
    SUBU32 = 0x7,
9423 3c824109 Nathan Froyd
    MUL = 0x8,
9424 3c824109 Nathan Froyd
    AND = 0x9,
9425 3c824109 Nathan Froyd
    OR32 = 0xa,
9426 3c824109 Nathan Froyd
    NOR = 0xb,
9427 3c824109 Nathan Froyd
    XOR32 = 0xc,
9428 3c824109 Nathan Froyd
    SLT = 0xd,
9429 3c824109 Nathan Froyd
    SLTU = 0xe,
9430 3c824109 Nathan Froyd
9431 3c824109 Nathan Froyd
    MOVN = 0x0,
9432 3c824109 Nathan Froyd
    MOVZ = 0x1,
9433 3c824109 Nathan Froyd
    LWXS = 0x4,
9434 3c824109 Nathan Froyd
9435 3c824109 Nathan Froyd
    /* The following can be distinguished by their lower 6 bits. */
9436 3c824109 Nathan Froyd
    INS = 0x0c,
9437 3c824109 Nathan Froyd
    EXT = 0x2c,
9438 3c824109 Nathan Froyd
    POOL32AXF = 0x3c
9439 3c824109 Nathan Froyd
};
9440 3c824109 Nathan Froyd
9441 3c824109 Nathan Froyd
/* POOL32AXF encoding of minor opcode field extension */
9442 3c824109 Nathan Froyd
9443 3c824109 Nathan Froyd
enum {
9444 3c824109 Nathan Froyd
    /* bits 11..6 */
9445 3c824109 Nathan Froyd
    TEQ = 0x00,
9446 3c824109 Nathan Froyd
    TGE = 0x08,
9447 3c824109 Nathan Froyd
    TGEU = 0x10,
9448 3c824109 Nathan Froyd
    TLT = 0x20,
9449 3c824109 Nathan Froyd
    TLTU = 0x28,
9450 3c824109 Nathan Froyd
    TNE = 0x30,
9451 3c824109 Nathan Froyd
9452 3c824109 Nathan Froyd
    MFC0 = 0x03,
9453 3c824109 Nathan Froyd
    MTC0 = 0x0b,
9454 3c824109 Nathan Froyd
9455 3c824109 Nathan Froyd
    /* bits 13..12 for 0x01 */
9456 3c824109 Nathan Froyd
    MFHI_ACC = 0x0,
9457 3c824109 Nathan Froyd
    MFLO_ACC = 0x1,
9458 3c824109 Nathan Froyd
    MTHI_ACC = 0x2,
9459 3c824109 Nathan Froyd
    MTLO_ACC = 0x3,
9460 3c824109 Nathan Froyd
9461 3c824109 Nathan Froyd
    /* bits 13..12 for 0x2a */
9462 3c824109 Nathan Froyd
    MADD_ACC = 0x0,
9463 3c824109 Nathan Froyd
    MADDU_ACC = 0x1,
9464 3c824109 Nathan Froyd
    MSUB_ACC = 0x2,
9465 3c824109 Nathan Froyd
    MSUBU_ACC = 0x3,
9466 3c824109 Nathan Froyd
9467 3c824109 Nathan Froyd
    /* bits 13..12 for 0x32 */
9468 3c824109 Nathan Froyd
    MULT_ACC = 0x0,
9469 3c824109 Nathan Froyd
    MULTU_ACC = 0x0,
9470 3c824109 Nathan Froyd
9471 3c824109 Nathan Froyd
    /* bits 15..12 for 0x2c */
9472 3c824109 Nathan Froyd
    SEB = 0x2,
9473 3c824109 Nathan Froyd
    SEH = 0x3,
9474 3c824109 Nathan Froyd
    CLO = 0x4,
9475 3c824109 Nathan Froyd
    CLZ = 0x5,
9476 3c824109 Nathan Froyd
    RDHWR = 0x6,
9477 3c824109 Nathan Froyd
    WSBH = 0x7,
9478 3c824109 Nathan Froyd
    MULT = 0x8,
9479 3c824109 Nathan Froyd
    MULTU = 0x9,
9480 3c824109 Nathan Froyd
    DIV = 0xa,
9481 3c824109 Nathan Froyd
    DIVU = 0xb,
9482 3c824109 Nathan Froyd
    MADD = 0xc,
9483 3c824109 Nathan Froyd
    MADDU = 0xd,
9484 3c824109 Nathan Froyd
    MSUB = 0xe,
9485 3c824109 Nathan Froyd
    MSUBU = 0xf,
9486 3c824109 Nathan Froyd
9487 3c824109 Nathan Froyd
    /* bits 15..12 for 0x34 */
9488 3c824109 Nathan Froyd
    MFC2 = 0x4,
9489 3c824109 Nathan Froyd
    MTC2 = 0x5,
9490 3c824109 Nathan Froyd
    MFHC2 = 0x8,
9491 3c824109 Nathan Froyd
    MTHC2 = 0x9,
9492 3c824109 Nathan Froyd
    CFC2 = 0xc,
9493 3c824109 Nathan Froyd
    CTC2 = 0xd,
9494 3c824109 Nathan Froyd
9495 3c824109 Nathan Froyd
    /* bits 15..12 for 0x3c */
9496 3c824109 Nathan Froyd
    JALR = 0x0,
9497 3c824109 Nathan Froyd
    JR = 0x0,                   /* alias */
9498 3c824109 Nathan Froyd
    JALR_HB = 0x1,
9499 3c824109 Nathan Froyd
    JALRS = 0x4,
9500 3c824109 Nathan Froyd
    JALRS_HB = 0x5,
9501 3c824109 Nathan Froyd
9502 3c824109 Nathan Froyd
    /* bits 15..12 for 0x05 */
9503 3c824109 Nathan Froyd
    RDPGPR = 0xe,
9504 3c824109 Nathan Froyd
    WRPGPR = 0xf,
9505 3c824109 Nathan Froyd
9506 3c824109 Nathan Froyd
    /* bits 15..12 for 0x0d */
9507 3c824109 Nathan Froyd
    TLBP = 0x0,
9508 3c824109 Nathan Froyd
    TLBR = 0x1,
9509 3c824109 Nathan Froyd
    TLBWI = 0x2,
9510 3c824109 Nathan Froyd
    TLBWR = 0x3,
9511 3c824109 Nathan Froyd
    WAIT = 0x9,
9512 3c824109 Nathan Froyd
    IRET = 0xd,
9513 3c824109 Nathan Froyd
    DERET = 0xe,
9514 3c824109 Nathan Froyd
    ERET = 0xf,
9515 3c824109 Nathan Froyd
9516 3c824109 Nathan Froyd
    /* bits 15..12 for 0x15 */
9517 3c824109 Nathan Froyd
    DMT = 0x0,
9518 3c824109 Nathan Froyd
    DVPE = 0x1,
9519 3c824109 Nathan Froyd
    EMT = 0x2,
9520 3c824109 Nathan Froyd
    EVPE = 0x3,
9521 3c824109 Nathan Froyd
9522 3c824109 Nathan Froyd
    /* bits 15..12 for 0x1d */
9523 3c824109 Nathan Froyd
    DI = 0x4,
9524 3c824109 Nathan Froyd
    EI = 0x5,
9525 3c824109 Nathan Froyd
9526 3c824109 Nathan Froyd
    /* bits 15..12 for 0x2d */
9527 3c824109 Nathan Froyd
    SYNC = 0x6,
9528 3c824109 Nathan Froyd
    SYSCALL = 0x8,
9529 3c824109 Nathan Froyd
    SDBBP = 0xd,
9530 3c824109 Nathan Froyd
9531 3c824109 Nathan Froyd
    /* bits 15..12 for 0x35 */
9532 3c824109 Nathan Froyd
    MFHI32 = 0x0,
9533 3c824109 Nathan Froyd
    MFLO32 = 0x1,
9534 3c824109 Nathan Froyd
    MTHI32 = 0x2,
9535 3c824109 Nathan Froyd
    MTLO32 = 0x3,
9536 3c824109 Nathan Froyd
};
9537 3c824109 Nathan Froyd
9538 3c824109 Nathan Froyd
/* POOL32B encoding of minor opcode field (bits 15..12) */
9539 3c824109 Nathan Froyd
9540 3c824109 Nathan Froyd
enum {
9541 3c824109 Nathan Froyd
    LWC2 = 0x0,
9542 3c824109 Nathan Froyd
    LWP = 0x1,
9543 3c824109 Nathan Froyd
    LDP = 0x4,
9544 3c824109 Nathan Froyd
    LWM32 = 0x5,
9545 3c824109 Nathan Froyd
    CACHE = 0x6,
9546 3c824109 Nathan Froyd
    LDM = 0x7,
9547 3c824109 Nathan Froyd
    SWC2 = 0x8,
9548 3c824109 Nathan Froyd
    SWP = 0x9,
9549 3c824109 Nathan Froyd
    SDP = 0xc,
9550 3c824109 Nathan Froyd
    SWM32 = 0xd,
9551 3c824109 Nathan Froyd
    SDM = 0xf
9552 3c824109 Nathan Froyd
};
9553 3c824109 Nathan Froyd
9554 3c824109 Nathan Froyd
/* POOL32C encoding of minor opcode field (bits 15..12) */
9555 3c824109 Nathan Froyd
9556 3c824109 Nathan Froyd
enum {
9557 3c824109 Nathan Froyd
    LWL = 0x0,
9558 3c824109 Nathan Froyd
    SWL = 0x8,
9559 3c824109 Nathan Froyd
    LWR = 0x1,
9560 3c824109 Nathan Froyd
    SWR = 0x9,
9561 3c824109 Nathan Froyd
    PREF = 0x2,
9562 3c824109 Nathan Froyd
    /* 0xa is reserved */
9563 3c824109 Nathan Froyd
    LL = 0x3,
9564 3c824109 Nathan Froyd
    SC = 0xb,
9565 3c824109 Nathan Froyd
    LDL = 0x4,
9566 3c824109 Nathan Froyd
    SDL = 0xc,
9567 3c824109 Nathan Froyd
    LDR = 0x5,
9568 3c824109 Nathan Froyd
    SDR = 0xd,
9569 3c824109 Nathan Froyd
    /* 0x6 is reserved */
9570 3c824109 Nathan Froyd
    LWU = 0xe,
9571 3c824109 Nathan Froyd
    LLD = 0x7,
9572 3c824109 Nathan Froyd
    SCD = 0xf
9573 3c824109 Nathan Froyd
};
9574 3c824109 Nathan Froyd
9575 3c824109 Nathan Froyd
/* POOL32F encoding of minor opcode field (bits 5..0) */
9576 3c824109 Nathan Froyd
9577 3c824109 Nathan Froyd
enum {
9578 3c824109 Nathan Froyd
    /* These are the bit 7..6 values */
9579 3c824109 Nathan Froyd
    ADD_FMT = 0x0,
9580 3c824109 Nathan Froyd
    MOVN_FMT = 0x0,
9581 3c824109 Nathan Froyd
9582 3c824109 Nathan Froyd
    SUB_FMT = 0x1,
9583 3c824109 Nathan Froyd
    MOVZ_FMT = 0x1,
9584 3c824109 Nathan Froyd
9585 3c824109 Nathan Froyd
    MUL_FMT = 0x2,
9586 3c824109 Nathan Froyd
9587 3c824109 Nathan Froyd
    DIV_FMT = 0x3,
9588 3c824109 Nathan Froyd
9589 3c824109 Nathan Froyd
    /* These are the bit 8..6 values */
9590 3c824109 Nathan Froyd
    RSQRT2_FMT = 0x0,
9591 3c824109 Nathan Froyd
    MOVF_FMT = 0x0,
9592 3c824109 Nathan Froyd
9593 3c824109 Nathan Froyd
    LWXC1 = 0x1,
9594 3c824109 Nathan Froyd
    MOVT_FMT = 0x1,
9595 3c824109 Nathan Froyd
9596 3c824109 Nathan Froyd
    PLL_PS = 0x2,
9597 3c824109 Nathan Froyd
    SWXC1 = 0x2,
9598 3c824109 Nathan Froyd
9599 3c824109 Nathan Froyd
    PLU_PS = 0x3,
9600 3c824109 Nathan Froyd
    LDXC1 = 0x3,
9601 3c824109 Nathan Froyd
9602 3c824109 Nathan Froyd
    PUL_PS = 0x4,
9603 3c824109 Nathan Froyd
    SDXC1 = 0x4,
9604 3c824109 Nathan Froyd
    RECIP2_FMT = 0x4,
9605 3c824109 Nathan Froyd
9606 3c824109 Nathan Froyd
    PUU_PS = 0x5,
9607 3c824109 Nathan Froyd
    LUXC1 = 0x5,
9608 3c824109 Nathan Froyd
9609 3c824109 Nathan Froyd
    CVT_PS_S = 0x6,
9610 3c824109 Nathan Froyd
    SUXC1 = 0x6,
9611 3c824109 Nathan Froyd
    ADDR_PS = 0x6,
9612 3c824109 Nathan Froyd
    PREFX = 0x6,
9613 3c824109 Nathan Froyd
9614 3c824109 Nathan Froyd
    MULR_PS = 0x7,
9615 3c824109 Nathan Froyd
9616 3c824109 Nathan Froyd
    MADD_S = 0x01,
9617 3c824109 Nathan Froyd
    MADD_D = 0x09,
9618 3c824109 Nathan Froyd
    MADD_PS = 0x11,
9619 3c824109 Nathan Froyd
    ALNV_PS = 0x19,
9620 3c824109 Nathan Froyd
    MSUB_S = 0x21,
9621 3c824109 Nathan Froyd
    MSUB_D = 0x29,
9622 3c824109 Nathan Froyd
    MSUB_PS = 0x31,
9623 3c824109 Nathan Froyd
9624 3c824109 Nathan Froyd
    NMADD_S = 0x02,
9625 3c824109 Nathan Froyd
    NMADD_D = 0x0a,
9626 3c824109 Nathan Froyd
    NMADD_PS = 0x12,
9627 3c824109 Nathan Froyd
    NMSUB_S = 0x22,
9628 3c824109 Nathan Froyd
    NMSUB_D = 0x2a,
9629 3c824109 Nathan Froyd
    NMSUB_PS = 0x32,
9630 3c824109 Nathan Froyd
9631 3c824109 Nathan Froyd
    POOL32FXF = 0x3b,
9632 3c824109 Nathan Froyd
9633 3c824109 Nathan Froyd
    CABS_COND_FMT = 0x1c,              /* MIPS3D */
9634 3c824109 Nathan Froyd
    C_COND_FMT = 0x3c
9635 3c824109 Nathan Froyd
};
9636 3c824109 Nathan Froyd
9637 3c824109 Nathan Froyd
/* POOL32Fxf encoding of minor opcode extension field */
9638 3c824109 Nathan Froyd
9639 3c824109 Nathan Froyd
enum {
9640 3c824109 Nathan Froyd
    CVT_L = 0x04,
9641 3c824109 Nathan Froyd
    RSQRT_FMT = 0x08,
9642 3c824109 Nathan Froyd
    FLOOR_L = 0x0c,
9643 3c824109 Nathan Froyd
    CVT_PW_PS = 0x1c,
9644 3c824109 Nathan Froyd
    CVT_W = 0x24,
9645 3c824109 Nathan Froyd
    SQRT_FMT = 0x28,
9646 3c824109 Nathan Froyd
    FLOOR_W = 0x2c,
9647 3c824109 Nathan Froyd
    CVT_PS_PW = 0x3c,
9648 3c824109 Nathan Froyd
    CFC1 = 0x40,
9649 3c824109 Nathan Froyd
    RECIP_FMT = 0x48,
9650 3c824109 Nathan Froyd
    CEIL_L = 0x4c,
9651 3c824109 Nathan Froyd
    CTC1 = 0x60,
9652 3c824109 Nathan Froyd
    CEIL_W = 0x6c,
9653 3c824109 Nathan Froyd
    MFC1 = 0x80,
9654 3c824109 Nathan Froyd
    CVT_S_PL = 0x84,
9655 3c824109 Nathan Froyd
    TRUNC_L = 0x8c,
9656 3c824109 Nathan Froyd
    MTC1 = 0xa0,
9657 3c824109 Nathan Froyd
    CVT_S_PU = 0xa4,
9658 3c824109 Nathan Froyd
    TRUNC_W = 0xac,
9659 3c824109 Nathan Froyd
    MFHC1 = 0xc0,
9660 3c824109 Nathan Froyd
    ROUND_L = 0xcc,
9661 3c824109 Nathan Froyd
    MTHC1 = 0xe0,
9662 3c824109 Nathan Froyd
    ROUND_W = 0xec,
9663 3c824109 Nathan Froyd
9664 3c824109 Nathan Froyd
    MOV_FMT = 0x01,
9665 3c824109 Nathan Froyd
    MOVF = 0x05,
9666 3c824109 Nathan Froyd
    ABS_FMT = 0x0d,
9667 3c824109 Nathan Froyd
    RSQRT1_FMT = 0x1d,
9668 3c824109 Nathan Froyd
    MOVT = 0x25,
9669 3c824109 Nathan Froyd
    NEG_FMT = 0x2d,
9670 3c824109 Nathan Froyd
    CVT_D = 0x4d,
9671 3c824109 Nathan Froyd
    RECIP1_FMT = 0x5d,
9672 3c824109 Nathan Froyd
    CVT_S = 0x6d
9673 3c824109 Nathan Froyd
};
9674 3c824109 Nathan Froyd
9675 3c824109 Nathan Froyd
/* POOL32I encoding of minor opcode field (bits 25..21) */
9676 3c824109 Nathan Froyd
9677 3c824109 Nathan Froyd
enum {
9678 3c824109 Nathan Froyd
    BLTZ = 0x00,
9679 3c824109 Nathan Froyd
    BLTZAL = 0x01,
9680 3c824109 Nathan Froyd
    BGEZ = 0x02,
9681 3c824109 Nathan Froyd
    BGEZAL = 0x03,
9682 3c824109 Nathan Froyd
    BLEZ = 0x04,
9683 3c824109 Nathan Froyd
    BNEZC = 0x05,
9684 3c824109 Nathan Froyd
    BGTZ = 0x06,
9685 3c824109 Nathan Froyd
    BEQZC = 0x07,
9686 3c824109 Nathan Froyd
    TLTI = 0x08,
9687 3c824109 Nathan Froyd
    TGEI = 0x09,
9688 3c824109 Nathan Froyd
    TLTIU = 0x0a,
9689 3c824109 Nathan Froyd
    TGEIU = 0x0b,
9690 3c824109 Nathan Froyd
    TNEI = 0x0c,
9691 3c824109 Nathan Froyd
    LUI = 0x0d,
9692 3c824109 Nathan Froyd
    TEQI = 0x0e,
9693 3c824109 Nathan Froyd
    SYNCI = 0x10,
9694 3c824109 Nathan Froyd
    BLTZALS = 0x11,
9695 3c824109 Nathan Froyd
    BGEZALS = 0x13,
9696 3c824109 Nathan Froyd
    BC2F = 0x14,
9697 3c824109 Nathan Froyd
    BC2T = 0x15,
9698 3c824109 Nathan Froyd
    BPOSGE64 = 0x1a,
9699 3c824109 Nathan Froyd
    BPOSGE32 = 0x1b,
9700 3c824109 Nathan Froyd
    /* These overlap and are distinguished by bit16 of the instruction */
9701 3c824109 Nathan Froyd
    BC1F = 0x1c,
9702 3c824109 Nathan Froyd
    BC1T = 0x1d,
9703 3c824109 Nathan Froyd
    BC1ANY2F = 0x1c,
9704 3c824109 Nathan Froyd
    BC1ANY2T = 0x1d,
9705 3c824109 Nathan Froyd
    BC1ANY4F = 0x1e,
9706 3c824109 Nathan Froyd
    BC1ANY4T = 0x1f
9707 3c824109 Nathan Froyd
};
9708 3c824109 Nathan Froyd
9709 3c824109 Nathan Froyd
/* POOL16A encoding of minor opcode field */
9710 3c824109 Nathan Froyd
9711 3c824109 Nathan Froyd
enum {
9712 3c824109 Nathan Froyd
    ADDU16 = 0x0,
9713 3c824109 Nathan Froyd
    SUBU16 = 0x1
9714 3c824109 Nathan Froyd
};
9715 3c824109 Nathan Froyd
9716 3c824109 Nathan Froyd
/* POOL16B encoding of minor opcode field */
9717 3c824109 Nathan Froyd
9718 3c824109 Nathan Froyd
enum {
9719 3c824109 Nathan Froyd
    SLL16 = 0x0,
9720 3c824109 Nathan Froyd
    SRL16 = 0x1
9721 3c824109 Nathan Froyd
};
9722 3c824109 Nathan Froyd
9723 3c824109 Nathan Froyd
/* POOL16C encoding of minor opcode field */
9724 3c824109 Nathan Froyd
9725 3c824109 Nathan Froyd
enum {
9726 3c824109 Nathan Froyd
    NOT16 = 0x00,
9727 3c824109 Nathan Froyd
    XOR16 = 0x04,
9728 3c824109 Nathan Froyd
    AND16 = 0x08,
9729 3c824109 Nathan Froyd
    OR16 = 0x0c,
9730 3c824109 Nathan Froyd
    LWM16 = 0x10,
9731 3c824109 Nathan Froyd
    SWM16 = 0x14,
9732 3c824109 Nathan Froyd
    JR16 = 0x18,
9733 3c824109 Nathan Froyd
    JRC16 = 0x1a,
9734 3c824109 Nathan Froyd
    JALR16 = 0x1c,
9735 3c824109 Nathan Froyd
    JALR16S = 0x1e,
9736 3c824109 Nathan Froyd
    MFHI16 = 0x20,
9737 3c824109 Nathan Froyd
    MFLO16 = 0x24,
9738 3c824109 Nathan Froyd
    BREAK16 = 0x28,
9739 3c824109 Nathan Froyd
    SDBBP16 = 0x2c,
9740 3c824109 Nathan Froyd
    JRADDIUSP = 0x30
9741 3c824109 Nathan Froyd
};
9742 3c824109 Nathan Froyd
9743 3c824109 Nathan Froyd
/* POOL16D encoding of minor opcode field */
9744 3c824109 Nathan Froyd
9745 3c824109 Nathan Froyd
enum {
9746 3c824109 Nathan Froyd
    ADDIUS5 = 0x0,
9747 3c824109 Nathan Froyd
    ADDIUSP = 0x1
9748 3c824109 Nathan Froyd
};
9749 3c824109 Nathan Froyd
9750 3c824109 Nathan Froyd
/* POOL16E encoding of minor opcode field */
9751 3c824109 Nathan Froyd
9752 3c824109 Nathan Froyd
enum {
9753 3c824109 Nathan Froyd
    ADDIUR2 = 0x0,
9754 3c824109 Nathan Froyd
    ADDIUR1SP = 0x1
9755 3c824109 Nathan Froyd
};
9756 3c824109 Nathan Froyd
9757 3c824109 Nathan Froyd
static int mmreg (int r)
9758 3c824109 Nathan Froyd
{
9759 3c824109 Nathan Froyd
    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9760 3c824109 Nathan Froyd
9761 3c824109 Nathan Froyd
    return map[r];
9762 3c824109 Nathan Froyd
}
9763 3c824109 Nathan Froyd
9764 3c824109 Nathan Froyd
/* Used for 16-bit store instructions.  */
9765 3c824109 Nathan Froyd
static int mmreg2 (int r)
9766 3c824109 Nathan Froyd
{
9767 3c824109 Nathan Froyd
    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9768 3c824109 Nathan Froyd
9769 3c824109 Nathan Froyd
    return map[r];
9770 3c824109 Nathan Froyd
}
9771 3c824109 Nathan Froyd
9772 3c824109 Nathan Froyd
#define uMIPS_RD(op) ((op >> 7) & 0x7)
9773 3c824109 Nathan Froyd
#define uMIPS_RS(op) ((op >> 4) & 0x7)
9774 3c824109 Nathan Froyd
#define uMIPS_RS2(op) uMIPS_RS(op)
9775 3c824109 Nathan Froyd
#define uMIPS_RS1(op) ((op >> 1) & 0x7)
9776 3c824109 Nathan Froyd
#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9777 3c824109 Nathan Froyd
#define uMIPS_RS5(op) (op & 0x1f)
9778 3c824109 Nathan Froyd
9779 3c824109 Nathan Froyd
/* Signed immediate */
9780 3c824109 Nathan Froyd
#define SIMM(op, start, width)                                          \
9781 3c824109 Nathan Froyd
    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
9782 3c824109 Nathan Froyd
               << (32-width))                                           \
9783 3c824109 Nathan Froyd
     >> (32-width))
9784 3c824109 Nathan Froyd
/* Zero-extended immediate */
9785 3c824109 Nathan Froyd
#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9786 3c824109 Nathan Froyd
9787 3c824109 Nathan Froyd
static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
9788 3c824109 Nathan Froyd
{
9789 3c824109 Nathan Froyd
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9790 3c824109 Nathan Froyd
9791 3c824109 Nathan Froyd
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9792 3c824109 Nathan Froyd
}
9793 3c824109 Nathan Froyd
9794 3c824109 Nathan Froyd
static void gen_addiur2 (CPUState *env, DisasContext *ctx)
9795 3c824109 Nathan Froyd
{
9796 3c824109 Nathan Froyd
    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9797 3c824109 Nathan Froyd
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9798 3c824109 Nathan Froyd
    int rs = mmreg(uMIPS_RS(ctx->opcode));
9799 3c824109 Nathan Froyd
9800 3c824109 Nathan Froyd
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9801 3c824109 Nathan Froyd
}
9802 3c824109 Nathan Froyd
9803 3c824109 Nathan Froyd
static void gen_addiusp (CPUState *env, DisasContext *ctx)
9804 3c824109 Nathan Froyd
{
9805 3c824109 Nathan Froyd
    int encoded = ZIMM(ctx->opcode, 1, 9);
9806 3c824109 Nathan Froyd
    int decoded;
9807 3c824109 Nathan Froyd
9808 3c824109 Nathan Froyd
    if (encoded <= 1) {
9809 3c824109 Nathan Froyd
        decoded = 256 + encoded;
9810 3c824109 Nathan Froyd
    } else if (encoded <= 255) {
9811 3c824109 Nathan Froyd
        decoded = encoded;
9812 3c824109 Nathan Froyd
    } else if (encoded <= 509) {
9813 3c824109 Nathan Froyd
        decoded = encoded - 512;
9814 3c824109 Nathan Froyd
    } else {
9815 3c824109 Nathan Froyd
        decoded = encoded - 768;
9816 3c824109 Nathan Froyd
    }
9817 3c824109 Nathan Froyd
9818 3c824109 Nathan Froyd
    gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9819 3c824109 Nathan Froyd
}
9820 3c824109 Nathan Froyd
9821 3c824109 Nathan Froyd
static void gen_addius5 (CPUState *env, DisasContext *ctx)
9822 3c824109 Nathan Froyd
{
9823 3c824109 Nathan Froyd
    int imm = SIMM(ctx->opcode, 1, 4);
9824 3c824109 Nathan Froyd
    int rd = (ctx->opcode >> 5) & 0x1f;
9825 3c824109 Nathan Froyd
9826 3c824109 Nathan Froyd
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9827 3c824109 Nathan Froyd
}
9828 3c824109 Nathan Froyd
9829 3c824109 Nathan Froyd
static void gen_andi16 (CPUState *env, DisasContext *ctx)
9830 3c824109 Nathan Froyd
{
9831 3c824109 Nathan Froyd
    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9832 3c824109 Nathan Froyd
                                 31, 32, 63, 64, 255, 32768, 65535 };
9833 3c824109 Nathan Froyd
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9834 3c824109 Nathan Froyd
    int rs = mmreg(uMIPS_RS(ctx->opcode));
9835 3c824109 Nathan Froyd
    int encoded = ZIMM(ctx->opcode, 0, 4);
9836 3c824109 Nathan Froyd
9837 3c824109 Nathan Froyd
    gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9838 3c824109 Nathan Froyd
}
9839 3c824109 Nathan Froyd
9840 3c824109 Nathan Froyd
static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9841 3c824109 Nathan Froyd
                               int base, int16_t offset)
9842 3c824109 Nathan Froyd
{
9843 3c824109 Nathan Froyd
    TCGv t0, t1;
9844 3c824109 Nathan Froyd
    TCGv_i32 t2;
9845 3c824109 Nathan Froyd
9846 3c824109 Nathan Froyd
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9847 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
9848 3c824109 Nathan Froyd
        return;
9849 3c824109 Nathan Froyd
    }
9850 3c824109 Nathan Froyd
9851 3c824109 Nathan Froyd
    t0 = tcg_temp_new();
9852 3c824109 Nathan Froyd
9853 3c824109 Nathan Froyd
    gen_base_offset_addr(ctx, t0, base, offset);
9854 3c824109 Nathan Froyd
9855 3c824109 Nathan Froyd
    t1 = tcg_const_tl(reglist);
9856 3c824109 Nathan Froyd
    t2 = tcg_const_i32(ctx->mem_idx);
9857 6af0bf9c bellard
9858 3c824109 Nathan Froyd
    save_cpu_state(ctx, 1);
9859 3c824109 Nathan Froyd
    switch (opc) {
9860 3c824109 Nathan Froyd
    case LWM32:
9861 3c824109 Nathan Froyd
        gen_helper_lwm(t0, t1, t2);
9862 3c824109 Nathan Froyd
        break;
9863 3c824109 Nathan Froyd
    case SWM32:
9864 3c824109 Nathan Froyd
        gen_helper_swm(t0, t1, t2);
9865 3c824109 Nathan Froyd
        break;
9866 3c824109 Nathan Froyd
#ifdef TARGET_MIPS64
9867 3c824109 Nathan Froyd
    case LDM:
9868 3c824109 Nathan Froyd
        gen_helper_ldm(t0, t1, t2);
9869 3c824109 Nathan Froyd
        break;
9870 3c824109 Nathan Froyd
    case SDM:
9871 3c824109 Nathan Froyd
        gen_helper_sdm(t0, t1, t2);
9872 3c824109 Nathan Froyd
        break;
9873 6af0bf9c bellard
#endif
9874 3c824109 Nathan Froyd
    }
9875 3c824109 Nathan Froyd
    MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9876 3c824109 Nathan Froyd
    tcg_temp_free(t0);
9877 33087598 Stefan Weil
    tcg_temp_free(t1);
9878 3c824109 Nathan Froyd
    tcg_temp_free_i32(t2);
9879 3c824109 Nathan Froyd
}
9880 6af0bf9c bellard
9881 3c824109 Nathan Froyd
9882 3c824109 Nathan Froyd
static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
9883 6af0bf9c bellard
{
9884 3c824109 Nathan Froyd
    int rd = mmreg((ctx->opcode >> 3) & 0x7);
9885 3c824109 Nathan Froyd
    int rs = mmreg(ctx->opcode & 0x7);
9886 3c824109 Nathan Froyd
    int opc;
9887 6af0bf9c bellard
9888 3c824109 Nathan Froyd
    switch (((ctx->opcode) >> 4) & 0x3f) {
9889 3c824109 Nathan Froyd
    case NOT16 + 0:
9890 3c824109 Nathan Froyd
    case NOT16 + 1:
9891 3c824109 Nathan Froyd
    case NOT16 + 2:
9892 3c824109 Nathan Froyd
    case NOT16 + 3:
9893 3c824109 Nathan Froyd
        gen_logic(env, OPC_NOR, rd, rs, 0);
9894 3c824109 Nathan Froyd
        break;
9895 3c824109 Nathan Froyd
    case XOR16 + 0:
9896 3c824109 Nathan Froyd
    case XOR16 + 1:
9897 3c824109 Nathan Froyd
    case XOR16 + 2:
9898 3c824109 Nathan Froyd
    case XOR16 + 3:
9899 3c824109 Nathan Froyd
        gen_logic(env, OPC_XOR, rd, rd, rs);
9900 3c824109 Nathan Froyd
        break;
9901 3c824109 Nathan Froyd
    case AND16 + 0:
9902 3c824109 Nathan Froyd
    case AND16 + 1:
9903 3c824109 Nathan Froyd
    case AND16 + 2:
9904 3c824109 Nathan Froyd
    case AND16 + 3:
9905 3c824109 Nathan Froyd
        gen_logic(env, OPC_AND, rd, rd, rs);
9906 3c824109 Nathan Froyd
        break;
9907 3c824109 Nathan Froyd
    case OR16 + 0:
9908 3c824109 Nathan Froyd
    case OR16 + 1:
9909 3c824109 Nathan Froyd
    case OR16 + 2:
9910 3c824109 Nathan Froyd
    case OR16 + 3:
9911 3c824109 Nathan Froyd
        gen_logic(env, OPC_OR, rd, rd, rs);
9912 3c824109 Nathan Froyd
        break;
9913 3c824109 Nathan Froyd
    case LWM16 + 0:
9914 3c824109 Nathan Froyd
    case LWM16 + 1:
9915 3c824109 Nathan Froyd
    case LWM16 + 2:
9916 3c824109 Nathan Froyd
    case LWM16 + 3:
9917 3c824109 Nathan Froyd
        {
9918 3c824109 Nathan Froyd
            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9919 3c824109 Nathan Froyd
            int offset = ZIMM(ctx->opcode, 0, 4);
9920 3c824109 Nathan Froyd
9921 3c824109 Nathan Froyd
            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9922 3c824109 Nathan Froyd
                              29, offset << 2);
9923 3c824109 Nathan Froyd
        }
9924 3c824109 Nathan Froyd
        break;
9925 3c824109 Nathan Froyd
    case SWM16 + 0:
9926 3c824109 Nathan Froyd
    case SWM16 + 1:
9927 3c824109 Nathan Froyd
    case SWM16 + 2:
9928 3c824109 Nathan Froyd
    case SWM16 + 3:
9929 3c824109 Nathan Froyd
        {
9930 3c824109 Nathan Froyd
            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9931 3c824109 Nathan Froyd
            int offset = ZIMM(ctx->opcode, 0, 4);
9932 3c824109 Nathan Froyd
9933 3c824109 Nathan Froyd
            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9934 3c824109 Nathan Froyd
                              29, offset << 2);
9935 3c824109 Nathan Froyd
        }
9936 3c824109 Nathan Froyd
        break;
9937 3c824109 Nathan Froyd
    case JR16 + 0:
9938 3c824109 Nathan Froyd
    case JR16 + 1:
9939 3c824109 Nathan Froyd
        {
9940 3c824109 Nathan Froyd
            int reg = ctx->opcode & 0x1f;
9941 3c824109 Nathan Froyd
9942 3c824109 Nathan Froyd
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9943 3c824109 Nathan Froyd
        }
9944 3c824109 Nathan Froyd
        *is_branch = 1;
9945 3c824109 Nathan Froyd
        break;
9946 3c824109 Nathan Froyd
    case JRC16 + 0:
9947 3c824109 Nathan Froyd
    case JRC16 + 1:
9948 3c824109 Nathan Froyd
        {
9949 3c824109 Nathan Froyd
            int reg = ctx->opcode & 0x1f;
9950 3c824109 Nathan Froyd
9951 3c824109 Nathan Froyd
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9952 3c824109 Nathan Froyd
            /* Let normal delay slot handling in our caller take us
9953 3c824109 Nathan Froyd
               to the branch target.  */
9954 3c824109 Nathan Froyd
        }
9955 3c824109 Nathan Froyd
        break;
9956 3c824109 Nathan Froyd
    case JALR16 + 0:
9957 3c824109 Nathan Froyd
    case JALR16 + 1:
9958 3c824109 Nathan Froyd
        opc = OPC_JALR;
9959 3c824109 Nathan Froyd
        goto do_jalr;
9960 3c824109 Nathan Froyd
    case JALR16S + 0:
9961 3c824109 Nathan Froyd
    case JALR16S + 1:
9962 3c824109 Nathan Froyd
        opc = OPC_JALRS;
9963 3c824109 Nathan Froyd
    do_jalr:
9964 3c824109 Nathan Froyd
        {
9965 3c824109 Nathan Froyd
            int reg = ctx->opcode & 0x1f;
9966 3c824109 Nathan Froyd
9967 3c824109 Nathan Froyd
            gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9968 3c824109 Nathan Froyd
        }
9969 3c824109 Nathan Froyd
        *is_branch = 1;
9970 3c824109 Nathan Froyd
        break;
9971 3c824109 Nathan Froyd
    case MFHI16 + 0:
9972 3c824109 Nathan Froyd
    case MFHI16 + 1:
9973 3c824109 Nathan Froyd
        gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9974 3c824109 Nathan Froyd
        break;
9975 3c824109 Nathan Froyd
    case MFLO16 + 0:
9976 3c824109 Nathan Froyd
    case MFLO16 + 1:
9977 3c824109 Nathan Froyd
        gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9978 3c824109 Nathan Froyd
        break;
9979 3c824109 Nathan Froyd
    case BREAK16:
9980 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_BREAK);
9981 3c824109 Nathan Froyd
        break;
9982 3c824109 Nathan Froyd
    case SDBBP16:
9983 3c824109 Nathan Froyd
        /* XXX: not clear which exception should be raised
9984 3c824109 Nathan Froyd
         *      when in debug mode...
9985 3c824109 Nathan Froyd
         */
9986 3c824109 Nathan Froyd
        check_insn(env, ctx, ISA_MIPS32);
9987 3c824109 Nathan Froyd
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9988 3c824109 Nathan Froyd
            generate_exception(ctx, EXCP_DBp);
9989 3c824109 Nathan Froyd
        } else {
9990 3c824109 Nathan Froyd
            generate_exception(ctx, EXCP_DBp);
9991 3c824109 Nathan Froyd
        }
9992 3c824109 Nathan Froyd
        break;
9993 3c824109 Nathan Froyd
    case JRADDIUSP + 0:
9994 3c824109 Nathan Froyd
    case JRADDIUSP + 1:
9995 3c824109 Nathan Froyd
        {
9996 3c824109 Nathan Froyd
            int imm = ZIMM(ctx->opcode, 0, 5);
9997 3c824109 Nathan Froyd
9998 3c824109 Nathan Froyd
            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9999 3c824109 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10000 3c824109 Nathan Froyd
            /* Let normal delay slot handling in our caller take us
10001 3c824109 Nathan Froyd
               to the branch target.  */
10002 3c824109 Nathan Froyd
        }
10003 3c824109 Nathan Froyd
        break;
10004 3c824109 Nathan Froyd
    default:
10005 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
10006 3c824109 Nathan Froyd
        break;
10007 3c824109 Nathan Froyd
    }
10008 3c824109 Nathan Froyd
}
10009 3c824109 Nathan Froyd
10010 3c824109 Nathan Froyd
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10011 3c824109 Nathan Froyd
{
10012 3c824109 Nathan Froyd
    TCGv t0 = tcg_temp_new();
10013 3c824109 Nathan Froyd
    TCGv t1 = tcg_temp_new();
10014 3c824109 Nathan Froyd
10015 3c824109 Nathan Froyd
    gen_load_gpr(t0, base);
10016 3c824109 Nathan Froyd
10017 3c824109 Nathan Froyd
    if (index != 0) {
10018 3c824109 Nathan Froyd
        gen_load_gpr(t1, index);
10019 3c824109 Nathan Froyd
        tcg_gen_shli_tl(t1, t1, 2);
10020 3c824109 Nathan Froyd
        gen_op_addr_add(ctx, t0, t1, t0);
10021 3c824109 Nathan Froyd
    }
10022 3c824109 Nathan Froyd
10023 3c824109 Nathan Froyd
    save_cpu_state(ctx, 0);
10024 5c13fdfd Aurelien Jarno
    op_ld_lw(t1, t0, ctx);
10025 3c824109 Nathan Froyd
    gen_store_gpr(t1, rd);
10026 3c824109 Nathan Froyd
10027 3c824109 Nathan Froyd
    tcg_temp_free(t0);
10028 3c824109 Nathan Froyd
    tcg_temp_free(t1);
10029 3c824109 Nathan Froyd
}
10030 3c824109 Nathan Froyd
10031 3c824109 Nathan Froyd
static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10032 3c824109 Nathan Froyd
                           int base, int16_t offset)
10033 3c824109 Nathan Froyd
{
10034 3c824109 Nathan Froyd
    const char *opn = "ldst_pair";
10035 3c824109 Nathan Froyd
    TCGv t0, t1;
10036 3c824109 Nathan Froyd
10037 3c824109 Nathan Froyd
    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
10038 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
10039 d796321b bellard
        return;
10040 d796321b bellard
    }
10041 d796321b bellard
10042 3c824109 Nathan Froyd
    t0 = tcg_temp_new();
10043 3c824109 Nathan Froyd
    t1 = tcg_temp_new();
10044 8e9ade68 ths
10045 3c824109 Nathan Froyd
    gen_base_offset_addr(ctx, t0, base, offset);
10046 3c824109 Nathan Froyd
10047 3c824109 Nathan Froyd
    switch (opc) {
10048 3c824109 Nathan Froyd
    case LWP:
10049 3c824109 Nathan Froyd
        save_cpu_state(ctx, 0);
10050 5c13fdfd Aurelien Jarno
        op_ld_lw(t1, t0, ctx);
10051 3c824109 Nathan Froyd
        gen_store_gpr(t1, rd);
10052 3c824109 Nathan Froyd
        tcg_gen_movi_tl(t1, 4);
10053 3c824109 Nathan Froyd
        gen_op_addr_add(ctx, t0, t0, t1);
10054 5c13fdfd Aurelien Jarno
        op_ld_lw(t1, t0, ctx);
10055 3c824109 Nathan Froyd
        gen_store_gpr(t1, rd+1);
10056 3c824109 Nathan Froyd
        opn = "lwp";
10057 3c824109 Nathan Froyd
        break;
10058 3c824109 Nathan Froyd
    case SWP:
10059 b835e919 Aurelien Jarno
        save_cpu_state(ctx, 0);
10060 3c824109 Nathan Froyd
        gen_load_gpr(t1, rd);
10061 5c13fdfd Aurelien Jarno
        op_st_sw(t1, t0, ctx);
10062 3c824109 Nathan Froyd
        tcg_gen_movi_tl(t1, 4);
10063 3c824109 Nathan Froyd
        gen_op_addr_add(ctx, t0, t0, t1);
10064 3c824109 Nathan Froyd
        gen_load_gpr(t1, rd+1);
10065 5c13fdfd Aurelien Jarno
        op_st_sw(t1, t0, ctx);
10066 3c824109 Nathan Froyd
        opn = "swp";
10067 3c824109 Nathan Froyd
        break;
10068 3c824109 Nathan Froyd
#ifdef TARGET_MIPS64
10069 3c824109 Nathan Froyd
    case LDP:
10070 3c824109 Nathan Froyd
        save_cpu_state(ctx, 0);
10071 5c13fdfd Aurelien Jarno
        op_ld_ld(t1, t0, ctx);
10072 3c824109 Nathan Froyd
        gen_store_gpr(t1, rd);
10073 3c824109 Nathan Froyd
        tcg_gen_movi_tl(t1, 8);
10074 3c824109 Nathan Froyd
        gen_op_addr_add(ctx, t0, t0, t1);
10075 5c13fdfd Aurelien Jarno
        op_ld_ld(t1, t0, ctx);
10076 3c824109 Nathan Froyd
        gen_store_gpr(t1, rd+1);
10077 3c824109 Nathan Froyd
        opn = "ldp";
10078 3c824109 Nathan Froyd
        break;
10079 3c824109 Nathan Froyd
    case SDP:
10080 b835e919 Aurelien Jarno
        save_cpu_state(ctx, 0);
10081 3c824109 Nathan Froyd
        gen_load_gpr(t1, rd);
10082 5c13fdfd Aurelien Jarno
        op_st_sd(t1, t0, ctx);
10083 3c824109 Nathan Froyd
        tcg_gen_movi_tl(t1, 8);
10084 3c824109 Nathan Froyd
        gen_op_addr_add(ctx, t0, t0, t1);
10085 3c824109 Nathan Froyd
        gen_load_gpr(t1, rd+1);
10086 5c13fdfd Aurelien Jarno
        op_st_sd(t1, t0, ctx);
10087 3c824109 Nathan Froyd
        opn = "sdp";
10088 3c824109 Nathan Froyd
        break;
10089 3c824109 Nathan Froyd
#endif
10090 6af0bf9c bellard
    }
10091 2abf314d Blue Swirl
    (void)opn; /* avoid a compiler warning */
10092 3c824109 Nathan Froyd
    MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10093 3c824109 Nathan Froyd
    tcg_temp_free(t0);
10094 3c824109 Nathan Froyd
    tcg_temp_free(t1);
10095 3c824109 Nathan Froyd
}
10096 618b0fe9 Aurelien Jarno
10097 3c824109 Nathan Froyd
static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
10098 3c824109 Nathan Froyd
                           int *is_branch)
10099 3c824109 Nathan Froyd
{
10100 3c824109 Nathan Froyd
    int extension = (ctx->opcode >> 6) & 0x3f;
10101 3c824109 Nathan Froyd
    int minor = (ctx->opcode >> 12) & 0xf;
10102 3c824109 Nathan Froyd
    uint32_t mips32_op;
10103 3c824109 Nathan Froyd
10104 3c824109 Nathan Froyd
    switch (extension) {
10105 3c824109 Nathan Froyd
    case TEQ:
10106 3c824109 Nathan Froyd
        mips32_op = OPC_TEQ;
10107 3c824109 Nathan Froyd
        goto do_trap;
10108 3c824109 Nathan Froyd
    case TGE:
10109 3c824109 Nathan Froyd
        mips32_op = OPC_TGE;
10110 3c824109 Nathan Froyd
        goto do_trap;
10111 3c824109 Nathan Froyd
    case TGEU:
10112 3c824109 Nathan Froyd
        mips32_op = OPC_TGEU;
10113 3c824109 Nathan Froyd
        goto do_trap;
10114 3c824109 Nathan Froyd
    case TLT:
10115 3c824109 Nathan Froyd
        mips32_op = OPC_TLT;
10116 3c824109 Nathan Froyd
        goto do_trap;
10117 3c824109 Nathan Froyd
    case TLTU:
10118 3c824109 Nathan Froyd
        mips32_op = OPC_TLTU;
10119 3c824109 Nathan Froyd
        goto do_trap;
10120 3c824109 Nathan Froyd
    case TNE:
10121 3c824109 Nathan Froyd
        mips32_op = OPC_TNE;
10122 3c824109 Nathan Froyd
    do_trap:
10123 3c824109 Nathan Froyd
        gen_trap(ctx, mips32_op, rs, rt, -1);
10124 3c824109 Nathan Froyd
        break;
10125 3c824109 Nathan Froyd
#ifndef CONFIG_USER_ONLY
10126 3c824109 Nathan Froyd
    case MFC0:
10127 3c824109 Nathan Froyd
    case MFC0 + 32:
10128 3c824109 Nathan Froyd
        if (rt == 0) {
10129 3c824109 Nathan Froyd
            /* Treat as NOP. */
10130 3c824109 Nathan Froyd
            break;
10131 3c824109 Nathan Froyd
        }
10132 3c824109 Nathan Froyd
        gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10133 3c824109 Nathan Froyd
        break;
10134 3c824109 Nathan Froyd
    case MTC0:
10135 3c824109 Nathan Froyd
    case MTC0 + 32:
10136 3c824109 Nathan Froyd
        {
10137 3c824109 Nathan Froyd
            TCGv t0 = tcg_temp_new();
10138 618b0fe9 Aurelien Jarno
10139 3c824109 Nathan Froyd
            gen_load_gpr(t0, rt);
10140 3c824109 Nathan Froyd
            gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
10141 3c824109 Nathan Froyd
            tcg_temp_free(t0);
10142 3c824109 Nathan Froyd
        }
10143 3c824109 Nathan Froyd
        break;
10144 3c824109 Nathan Froyd
#endif
10145 3c824109 Nathan Froyd
    case 0x2c:
10146 3c824109 Nathan Froyd
        switch (minor) {
10147 3c824109 Nathan Froyd
        case SEB:
10148 3c824109 Nathan Froyd
            gen_bshfl(ctx, OPC_SEB, rs, rt);
10149 3c824109 Nathan Froyd
            break;
10150 3c824109 Nathan Froyd
        case SEH:
10151 3c824109 Nathan Froyd
            gen_bshfl(ctx, OPC_SEH, rs, rt);
10152 3c824109 Nathan Froyd
            break;
10153 3c824109 Nathan Froyd
        case CLO:
10154 3c824109 Nathan Froyd
            mips32_op = OPC_CLO;
10155 3c824109 Nathan Froyd
            goto do_cl;
10156 3c824109 Nathan Froyd
        case CLZ:
10157 3c824109 Nathan Froyd
            mips32_op = OPC_CLZ;
10158 3c824109 Nathan Froyd
        do_cl:
10159 3c824109 Nathan Froyd
            check_insn(env, ctx, ISA_MIPS32);
10160 3c824109 Nathan Froyd
            gen_cl(ctx, mips32_op, rt, rs);
10161 3c824109 Nathan Froyd
            break;
10162 3c824109 Nathan Froyd
        case RDHWR:
10163 3c824109 Nathan Froyd
            gen_rdhwr(env, ctx, rt, rs);
10164 3c824109 Nathan Froyd
            break;
10165 3c824109 Nathan Froyd
        case WSBH:
10166 3c824109 Nathan Froyd
            gen_bshfl(ctx, OPC_WSBH, rs, rt);
10167 3c824109 Nathan Froyd
            break;
10168 3c824109 Nathan Froyd
        case MULT:
10169 3c824109 Nathan Froyd
            mips32_op = OPC_MULT;
10170 3c824109 Nathan Froyd
            goto do_muldiv;
10171 3c824109 Nathan Froyd
        case MULTU:
10172 3c824109 Nathan Froyd
            mips32_op = OPC_MULTU;
10173 3c824109 Nathan Froyd
            goto do_muldiv;
10174 3c824109 Nathan Froyd
        case DIV:
10175 3c824109 Nathan Froyd
            mips32_op = OPC_DIV;
10176 3c824109 Nathan Froyd
            goto do_muldiv;
10177 3c824109 Nathan Froyd
        case DIVU:
10178 3c824109 Nathan Froyd
            mips32_op = OPC_DIVU;
10179 3c824109 Nathan Froyd
            goto do_muldiv;
10180 3c824109 Nathan Froyd
        case MADD:
10181 3c824109 Nathan Froyd
            mips32_op = OPC_MADD;
10182 3c824109 Nathan Froyd
            goto do_muldiv;
10183 3c824109 Nathan Froyd
        case MADDU:
10184 3c824109 Nathan Froyd
            mips32_op = OPC_MADDU;
10185 3c824109 Nathan Froyd
            goto do_muldiv;
10186 3c824109 Nathan Froyd
        case MSUB:
10187 3c824109 Nathan Froyd
            mips32_op = OPC_MSUB;
10188 3c824109 Nathan Froyd
            goto do_muldiv;
10189 3c824109 Nathan Froyd
        case MSUBU:
10190 3c824109 Nathan Froyd
            mips32_op = OPC_MSUBU;
10191 3c824109 Nathan Froyd
        do_muldiv:
10192 3c824109 Nathan Froyd
            check_insn(env, ctx, ISA_MIPS32);
10193 3c824109 Nathan Froyd
            gen_muldiv(ctx, mips32_op, rs, rt);
10194 3c824109 Nathan Froyd
            break;
10195 3c824109 Nathan Froyd
        default:
10196 3c824109 Nathan Froyd
            goto pool32axf_invalid;
10197 3c824109 Nathan Froyd
        }
10198 3c824109 Nathan Froyd
        break;
10199 3c824109 Nathan Froyd
    case 0x34:
10200 3c824109 Nathan Froyd
        switch (minor) {
10201 3c824109 Nathan Froyd
        case MFC2:
10202 3c824109 Nathan Froyd
        case MTC2:
10203 3c824109 Nathan Froyd
        case MFHC2:
10204 3c824109 Nathan Froyd
        case MTHC2:
10205 3c824109 Nathan Froyd
        case CFC2:
10206 3c824109 Nathan Froyd
        case CTC2:
10207 3c824109 Nathan Froyd
            generate_exception_err(ctx, EXCP_CpU, 2);
10208 3c824109 Nathan Froyd
            break;
10209 3c824109 Nathan Froyd
        default:
10210 3c824109 Nathan Froyd
            goto pool32axf_invalid;
10211 3c824109 Nathan Froyd
        }
10212 3c824109 Nathan Froyd
        break;
10213 3c824109 Nathan Froyd
    case 0x3c:
10214 3c824109 Nathan Froyd
        switch (minor) {
10215 3c824109 Nathan Froyd
        case JALR:
10216 3c824109 Nathan Froyd
        case JALR_HB:
10217 3c824109 Nathan Froyd
            gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10218 3c824109 Nathan Froyd
            *is_branch = 1;
10219 3c824109 Nathan Froyd
            break;
10220 3c824109 Nathan Froyd
        case JALRS:
10221 3c824109 Nathan Froyd
        case JALRS_HB:
10222 3c824109 Nathan Froyd
            gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10223 3c824109 Nathan Froyd
            *is_branch = 1;
10224 3c824109 Nathan Froyd
            break;
10225 3c824109 Nathan Froyd
        default:
10226 3c824109 Nathan Froyd
            goto pool32axf_invalid;
10227 3c824109 Nathan Froyd
        }
10228 3c824109 Nathan Froyd
        break;
10229 3c824109 Nathan Froyd
    case 0x05:
10230 3c824109 Nathan Froyd
        switch (minor) {
10231 3c824109 Nathan Froyd
        case RDPGPR:
10232 3c824109 Nathan Froyd
            check_insn(env, ctx, ISA_MIPS32R2);
10233 3c824109 Nathan Froyd
            gen_load_srsgpr(rt, rs);
10234 3c824109 Nathan Froyd
            break;
10235 3c824109 Nathan Froyd
        case WRPGPR:
10236 3c824109 Nathan Froyd
            check_insn(env, ctx, ISA_MIPS32R2);
10237 3c824109 Nathan Froyd
            gen_store_srsgpr(rt, rs);
10238 3c824109 Nathan Froyd
            break;
10239 3c824109 Nathan Froyd
        default:
10240 3c824109 Nathan Froyd
            goto pool32axf_invalid;
10241 3c824109 Nathan Froyd
        }
10242 3c824109 Nathan Froyd
        break;
10243 3c824109 Nathan Froyd
#ifndef CONFIG_USER_ONLY
10244 3c824109 Nathan Froyd
    case 0x0d:
10245 3c824109 Nathan Froyd
        switch (minor) {
10246 3c824109 Nathan Froyd
        case TLBP:
10247 3c824109 Nathan Froyd
            mips32_op = OPC_TLBP;
10248 3c824109 Nathan Froyd
            goto do_cp0;
10249 3c824109 Nathan Froyd
        case TLBR:
10250 3c824109 Nathan Froyd
            mips32_op = OPC_TLBR;
10251 3c824109 Nathan Froyd
            goto do_cp0;
10252 3c824109 Nathan Froyd
        case TLBWI:
10253 3c824109 Nathan Froyd
            mips32_op = OPC_TLBWI;
10254 3c824109 Nathan Froyd
            goto do_cp0;
10255 3c824109 Nathan Froyd
        case TLBWR:
10256 3c824109 Nathan Froyd
            mips32_op = OPC_TLBWR;
10257 3c824109 Nathan Froyd
            goto do_cp0;
10258 3c824109 Nathan Froyd
        case WAIT:
10259 3c824109 Nathan Froyd
            mips32_op = OPC_WAIT;
10260 3c824109 Nathan Froyd
            goto do_cp0;
10261 3c824109 Nathan Froyd
        case DERET:
10262 3c824109 Nathan Froyd
            mips32_op = OPC_DERET;
10263 3c824109 Nathan Froyd
            goto do_cp0;
10264 3c824109 Nathan Froyd
        case ERET:
10265 3c824109 Nathan Froyd
            mips32_op = OPC_ERET;
10266 3c824109 Nathan Froyd
        do_cp0:
10267 3c824109 Nathan Froyd
            gen_cp0(env, ctx, mips32_op, rt, rs);
10268 3c824109 Nathan Froyd
            break;
10269 3c824109 Nathan Froyd
        default:
10270 3c824109 Nathan Froyd
            goto pool32axf_invalid;
10271 3c824109 Nathan Froyd
        }
10272 3c824109 Nathan Froyd
        break;
10273 3c824109 Nathan Froyd
    case 0x1d:
10274 3c824109 Nathan Froyd
        switch (minor) {
10275 3c824109 Nathan Froyd
        case DI:
10276 3c824109 Nathan Froyd
            {
10277 3c824109 Nathan Froyd
                TCGv t0 = tcg_temp_new();
10278 3c824109 Nathan Froyd
10279 3c824109 Nathan Froyd
                save_cpu_state(ctx, 1);
10280 3c824109 Nathan Froyd
                gen_helper_di(t0);
10281 3c824109 Nathan Froyd
                gen_store_gpr(t0, rs);
10282 3c824109 Nathan Froyd
                /* Stop translation as we may have switched the execution mode */
10283 3c824109 Nathan Froyd
                ctx->bstate = BS_STOP;
10284 3c824109 Nathan Froyd
                tcg_temp_free(t0);
10285 3c824109 Nathan Froyd
            }
10286 3c824109 Nathan Froyd
            break;
10287 3c824109 Nathan Froyd
        case EI:
10288 3c824109 Nathan Froyd
            {
10289 3c824109 Nathan Froyd
                TCGv t0 = tcg_temp_new();
10290 3c824109 Nathan Froyd
10291 3c824109 Nathan Froyd
                save_cpu_state(ctx, 1);
10292 3c824109 Nathan Froyd
                gen_helper_ei(t0);
10293 3c824109 Nathan Froyd
                gen_store_gpr(t0, rs);
10294 3c824109 Nathan Froyd
                /* Stop translation as we may have switched the execution mode */
10295 3c824109 Nathan Froyd
                ctx->bstate = BS_STOP;
10296 3c824109 Nathan Froyd
                tcg_temp_free(t0);
10297 3c824109 Nathan Froyd
            }
10298 3c824109 Nathan Froyd
            break;
10299 3c824109 Nathan Froyd
        default:
10300 3c824109 Nathan Froyd
            goto pool32axf_invalid;
10301 3c824109 Nathan Froyd
        }
10302 3c824109 Nathan Froyd
        break;
10303 3c824109 Nathan Froyd
#endif
10304 3c824109 Nathan Froyd
    case 0x2d:
10305 3c824109 Nathan Froyd
        switch (minor) {
10306 3c824109 Nathan Froyd
        case SYNC:
10307 3c824109 Nathan Froyd
            /* NOP */
10308 3c824109 Nathan Froyd
            break;
10309 3c824109 Nathan Froyd
        case SYSCALL:
10310 3c824109 Nathan Froyd
            generate_exception(ctx, EXCP_SYSCALL);
10311 3c824109 Nathan Froyd
            ctx->bstate = BS_STOP;
10312 3c824109 Nathan Froyd
            break;
10313 3c824109 Nathan Froyd
        case SDBBP:
10314 3c824109 Nathan Froyd
            check_insn(env, ctx, ISA_MIPS32);
10315 3c824109 Nathan Froyd
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10316 3c824109 Nathan Froyd
                generate_exception(ctx, EXCP_DBp);
10317 3c824109 Nathan Froyd
            } else {
10318 3c824109 Nathan Froyd
                generate_exception(ctx, EXCP_DBp);
10319 3c824109 Nathan Froyd
            }
10320 3c824109 Nathan Froyd
            break;
10321 3c824109 Nathan Froyd
        default:
10322 3c824109 Nathan Froyd
            goto pool32axf_invalid;
10323 3c824109 Nathan Froyd
        }
10324 3c824109 Nathan Froyd
        break;
10325 3c824109 Nathan Froyd
    case 0x35:
10326 3c824109 Nathan Froyd
        switch (minor) {
10327 3c824109 Nathan Froyd
        case MFHI32:
10328 3c824109 Nathan Froyd
            gen_HILO(ctx, OPC_MFHI, rs);
10329 3c824109 Nathan Froyd
            break;
10330 3c824109 Nathan Froyd
        case MFLO32:
10331 3c824109 Nathan Froyd
            gen_HILO(ctx, OPC_MFLO, rs);
10332 3c824109 Nathan Froyd
            break;
10333 3c824109 Nathan Froyd
        case MTHI32:
10334 3c824109 Nathan Froyd
            gen_HILO(ctx, OPC_MTHI, rs);
10335 3c824109 Nathan Froyd
            break;
10336 3c824109 Nathan Froyd
        case MTLO32:
10337 3c824109 Nathan Froyd
            gen_HILO(ctx, OPC_MTLO, rs);
10338 3c824109 Nathan Froyd
            break;
10339 3c824109 Nathan Froyd
        default:
10340 3c824109 Nathan Froyd
            goto pool32axf_invalid;
10341 3c824109 Nathan Froyd
        }
10342 3c824109 Nathan Froyd
        break;
10343 3c824109 Nathan Froyd
    default:
10344 3c824109 Nathan Froyd
    pool32axf_invalid:
10345 3c824109 Nathan Froyd
        MIPS_INVAL("pool32axf");
10346 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
10347 3c824109 Nathan Froyd
        break;
10348 3c824109 Nathan Froyd
    }
10349 3c824109 Nathan Froyd
}
10350 3c824109 Nathan Froyd
10351 3c824109 Nathan Froyd
/* Values for microMIPS fmt field.  Variable-width, depending on which
10352 3c824109 Nathan Froyd
   formats the instruction supports.  */
10353 3c824109 Nathan Froyd
10354 3c824109 Nathan Froyd
enum {
10355 3c824109 Nathan Froyd
    FMT_SD_S = 0,
10356 3c824109 Nathan Froyd
    FMT_SD_D = 1,
10357 3c824109 Nathan Froyd
10358 3c824109 Nathan Froyd
    FMT_SDPS_S = 0,
10359 3c824109 Nathan Froyd
    FMT_SDPS_D = 1,
10360 3c824109 Nathan Froyd
    FMT_SDPS_PS = 2,
10361 3c824109 Nathan Froyd
10362 3c824109 Nathan Froyd
    FMT_SWL_S = 0,
10363 3c824109 Nathan Froyd
    FMT_SWL_W = 1,
10364 3c824109 Nathan Froyd
    FMT_SWL_L = 2,
10365 3c824109 Nathan Froyd
10366 3c824109 Nathan Froyd
    FMT_DWL_D = 0,
10367 3c824109 Nathan Froyd
    FMT_DWL_W = 1,
10368 3c824109 Nathan Froyd
    FMT_DWL_L = 2
10369 3c824109 Nathan Froyd
};
10370 3c824109 Nathan Froyd
10371 3c824109 Nathan Froyd
static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
10372 3c824109 Nathan Froyd
{
10373 3c824109 Nathan Froyd
    int extension = (ctx->opcode >> 6) & 0x3ff;
10374 3c824109 Nathan Froyd
    uint32_t mips32_op;
10375 3c824109 Nathan Froyd
10376 3c824109 Nathan Froyd
#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10377 3c824109 Nathan Froyd
#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10378 3c824109 Nathan Froyd
#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10379 3c824109 Nathan Froyd
10380 3c824109 Nathan Froyd
    switch (extension) {
10381 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CFC1, 0):
10382 3c824109 Nathan Froyd
        mips32_op = OPC_CFC1;
10383 3c824109 Nathan Froyd
        goto do_cp1;
10384 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CTC1, 0):
10385 3c824109 Nathan Froyd
        mips32_op = OPC_CTC1;
10386 3c824109 Nathan Froyd
        goto do_cp1;
10387 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(MFC1, 0):
10388 3c824109 Nathan Froyd
        mips32_op = OPC_MFC1;
10389 3c824109 Nathan Froyd
        goto do_cp1;
10390 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(MTC1, 0):
10391 3c824109 Nathan Froyd
        mips32_op = OPC_MTC1;
10392 3c824109 Nathan Froyd
        goto do_cp1;
10393 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(MFHC1, 0):
10394 3c824109 Nathan Froyd
        mips32_op = OPC_MFHC1;
10395 3c824109 Nathan Froyd
        goto do_cp1;
10396 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(MTHC1, 0):
10397 3c824109 Nathan Froyd
        mips32_op = OPC_MTHC1;
10398 3c824109 Nathan Froyd
    do_cp1:
10399 3c824109 Nathan Froyd
        gen_cp1(ctx, mips32_op, rt, rs);
10400 3c824109 Nathan Froyd
        break;
10401 3c824109 Nathan Froyd
10402 3c824109 Nathan Froyd
        /* Reciprocal square root */
10403 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10404 3c824109 Nathan Froyd
        mips32_op = OPC_RSQRT_S;
10405 3c824109 Nathan Froyd
        goto do_unaryfp;
10406 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10407 3c824109 Nathan Froyd
        mips32_op = OPC_RSQRT_D;
10408 3c824109 Nathan Froyd
        goto do_unaryfp;
10409 3c824109 Nathan Froyd
10410 3c824109 Nathan Froyd
        /* Square root */
10411 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10412 3c824109 Nathan Froyd
        mips32_op = OPC_SQRT_S;
10413 3c824109 Nathan Froyd
        goto do_unaryfp;
10414 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10415 3c824109 Nathan Froyd
        mips32_op = OPC_SQRT_D;
10416 3c824109 Nathan Froyd
        goto do_unaryfp;
10417 3c824109 Nathan Froyd
10418 3c824109 Nathan Froyd
        /* Reciprocal */
10419 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10420 3c824109 Nathan Froyd
        mips32_op = OPC_RECIP_S;
10421 3c824109 Nathan Froyd
        goto do_unaryfp;
10422 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10423 3c824109 Nathan Froyd
        mips32_op = OPC_RECIP_D;
10424 3c824109 Nathan Froyd
        goto do_unaryfp;
10425 3c824109 Nathan Froyd
10426 3c824109 Nathan Froyd
        /* Floor */
10427 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10428 3c824109 Nathan Froyd
        mips32_op = OPC_FLOOR_L_S;
10429 3c824109 Nathan Froyd
        goto do_unaryfp;
10430 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10431 3c824109 Nathan Froyd
        mips32_op = OPC_FLOOR_L_D;
10432 3c824109 Nathan Froyd
        goto do_unaryfp;
10433 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10434 3c824109 Nathan Froyd
        mips32_op = OPC_FLOOR_W_S;
10435 3c824109 Nathan Froyd
        goto do_unaryfp;
10436 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10437 3c824109 Nathan Froyd
        mips32_op = OPC_FLOOR_W_D;
10438 3c824109 Nathan Froyd
        goto do_unaryfp;
10439 3c824109 Nathan Froyd
10440 3c824109 Nathan Froyd
        /* Ceiling */
10441 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10442 3c824109 Nathan Froyd
        mips32_op = OPC_CEIL_L_S;
10443 3c824109 Nathan Froyd
        goto do_unaryfp;
10444 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10445 3c824109 Nathan Froyd
        mips32_op = OPC_CEIL_L_D;
10446 3c824109 Nathan Froyd
        goto do_unaryfp;
10447 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10448 3c824109 Nathan Froyd
        mips32_op = OPC_CEIL_W_S;
10449 3c824109 Nathan Froyd
        goto do_unaryfp;
10450 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10451 3c824109 Nathan Froyd
        mips32_op = OPC_CEIL_W_D;
10452 3c824109 Nathan Froyd
        goto do_unaryfp;
10453 3c824109 Nathan Froyd
10454 3c824109 Nathan Froyd
        /* Truncation */
10455 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10456 3c824109 Nathan Froyd
        mips32_op = OPC_TRUNC_L_S;
10457 3c824109 Nathan Froyd
        goto do_unaryfp;
10458 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10459 3c824109 Nathan Froyd
        mips32_op = OPC_TRUNC_L_D;
10460 3c824109 Nathan Froyd
        goto do_unaryfp;
10461 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10462 3c824109 Nathan Froyd
        mips32_op = OPC_TRUNC_W_S;
10463 3c824109 Nathan Froyd
        goto do_unaryfp;
10464 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10465 3c824109 Nathan Froyd
        mips32_op = OPC_TRUNC_W_D;
10466 3c824109 Nathan Froyd
        goto do_unaryfp;
10467 3c824109 Nathan Froyd
10468 3c824109 Nathan Froyd
        /* Round */
10469 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10470 3c824109 Nathan Froyd
        mips32_op = OPC_ROUND_L_S;
10471 3c824109 Nathan Froyd
        goto do_unaryfp;
10472 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10473 3c824109 Nathan Froyd
        mips32_op = OPC_ROUND_L_D;
10474 3c824109 Nathan Froyd
        goto do_unaryfp;
10475 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10476 3c824109 Nathan Froyd
        mips32_op = OPC_ROUND_W_S;
10477 3c824109 Nathan Froyd
        goto do_unaryfp;
10478 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10479 3c824109 Nathan Froyd
        mips32_op = OPC_ROUND_W_D;
10480 3c824109 Nathan Froyd
        goto do_unaryfp;
10481 3c824109 Nathan Froyd
10482 3c824109 Nathan Froyd
        /* Integer to floating-point conversion */
10483 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10484 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_L_S;
10485 3c824109 Nathan Froyd
        goto do_unaryfp;
10486 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10487 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_L_D;
10488 3c824109 Nathan Froyd
        goto do_unaryfp;
10489 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10490 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_W_S;
10491 3c824109 Nathan Froyd
        goto do_unaryfp;
10492 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10493 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_W_D;
10494 3c824109 Nathan Froyd
        goto do_unaryfp;
10495 3c824109 Nathan Froyd
10496 3c824109 Nathan Froyd
        /* Paired-foo conversions */
10497 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10498 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_S_PL;
10499 3c824109 Nathan Froyd
        goto do_unaryfp;
10500 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10501 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_S_PU;
10502 3c824109 Nathan Froyd
        goto do_unaryfp;
10503 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10504 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_PW_PS;
10505 3c824109 Nathan Froyd
        goto do_unaryfp;
10506 3c824109 Nathan Froyd
    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10507 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_PS_PW;
10508 3c824109 Nathan Froyd
        goto do_unaryfp;
10509 3c824109 Nathan Froyd
10510 3c824109 Nathan Froyd
        /* Floating-point moves */
10511 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10512 3c824109 Nathan Froyd
        mips32_op = OPC_MOV_S;
10513 3c824109 Nathan Froyd
        goto do_unaryfp;
10514 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10515 3c824109 Nathan Froyd
        mips32_op = OPC_MOV_D;
10516 3c824109 Nathan Froyd
        goto do_unaryfp;
10517 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10518 3c824109 Nathan Froyd
        mips32_op = OPC_MOV_PS;
10519 3c824109 Nathan Froyd
        goto do_unaryfp;
10520 3c824109 Nathan Froyd
10521 3c824109 Nathan Froyd
        /* Absolute value */
10522 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10523 3c824109 Nathan Froyd
        mips32_op = OPC_ABS_S;
10524 3c824109 Nathan Froyd
        goto do_unaryfp;
10525 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10526 3c824109 Nathan Froyd
        mips32_op = OPC_ABS_D;
10527 3c824109 Nathan Froyd
        goto do_unaryfp;
10528 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10529 3c824109 Nathan Froyd
        mips32_op = OPC_ABS_PS;
10530 3c824109 Nathan Froyd
        goto do_unaryfp;
10531 3c824109 Nathan Froyd
10532 3c824109 Nathan Froyd
        /* Negation */
10533 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10534 3c824109 Nathan Froyd
        mips32_op = OPC_NEG_S;
10535 3c824109 Nathan Froyd
        goto do_unaryfp;
10536 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10537 3c824109 Nathan Froyd
        mips32_op = OPC_NEG_D;
10538 3c824109 Nathan Froyd
        goto do_unaryfp;
10539 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10540 3c824109 Nathan Froyd
        mips32_op = OPC_NEG_PS;
10541 3c824109 Nathan Froyd
        goto do_unaryfp;
10542 3c824109 Nathan Froyd
10543 3c824109 Nathan Froyd
        /* Reciprocal square root step */
10544 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10545 3c824109 Nathan Froyd
        mips32_op = OPC_RSQRT1_S;
10546 3c824109 Nathan Froyd
        goto do_unaryfp;
10547 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10548 3c824109 Nathan Froyd
        mips32_op = OPC_RSQRT1_D;
10549 3c824109 Nathan Froyd
        goto do_unaryfp;
10550 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10551 3c824109 Nathan Froyd
        mips32_op = OPC_RSQRT1_PS;
10552 3c824109 Nathan Froyd
        goto do_unaryfp;
10553 3c824109 Nathan Froyd
10554 3c824109 Nathan Froyd
        /* Reciprocal step */
10555 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10556 3c824109 Nathan Froyd
        mips32_op = OPC_RECIP1_S;
10557 3c824109 Nathan Froyd
        goto do_unaryfp;
10558 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10559 3c824109 Nathan Froyd
        mips32_op = OPC_RECIP1_S;
10560 3c824109 Nathan Froyd
        goto do_unaryfp;
10561 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10562 3c824109 Nathan Froyd
        mips32_op = OPC_RECIP1_PS;
10563 3c824109 Nathan Froyd
        goto do_unaryfp;
10564 3c824109 Nathan Froyd
10565 3c824109 Nathan Froyd
        /* Conversions from double */
10566 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10567 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_D_S;
10568 3c824109 Nathan Froyd
        goto do_unaryfp;
10569 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10570 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_D_W;
10571 3c824109 Nathan Froyd
        goto do_unaryfp;
10572 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10573 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_D_L;
10574 3c824109 Nathan Froyd
        goto do_unaryfp;
10575 3c824109 Nathan Froyd
10576 3c824109 Nathan Froyd
        /* Conversions from single */
10577 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10578 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_S_D;
10579 3c824109 Nathan Froyd
        goto do_unaryfp;
10580 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10581 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_S_W;
10582 3c824109 Nathan Froyd
        goto do_unaryfp;
10583 3c824109 Nathan Froyd
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10584 3c824109 Nathan Froyd
        mips32_op = OPC_CVT_S_L;
10585 3c824109 Nathan Froyd
    do_unaryfp:
10586 3c824109 Nathan Froyd
        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10587 3c824109 Nathan Froyd
        break;
10588 3c824109 Nathan Froyd
10589 3c824109 Nathan Froyd
        /* Conditional moves on floating-point codes */
10590 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVT, 0):
10591 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVT, 1):
10592 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVT, 2):
10593 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVT, 3):
10594 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVT, 4):
10595 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVT, 5):
10596 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVT, 6):
10597 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVT, 7):
10598 3c824109 Nathan Froyd
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10599 3c824109 Nathan Froyd
        break;
10600 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVF, 0):
10601 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVF, 1):
10602 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVF, 2):
10603 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVF, 3):
10604 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVF, 4):
10605 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVF, 5):
10606 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVF, 6):
10607 3c824109 Nathan Froyd
    case COND_FLOAT_MOV(MOVF, 7):
10608 3c824109 Nathan Froyd
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10609 3c824109 Nathan Froyd
        break;
10610 3c824109 Nathan Froyd
    default:
10611 3c824109 Nathan Froyd
        MIPS_INVAL("pool32fxf");
10612 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
10613 3c824109 Nathan Froyd
        break;
10614 3c824109 Nathan Froyd
    }
10615 3c824109 Nathan Froyd
}
10616 3c824109 Nathan Froyd
10617 3c824109 Nathan Froyd
static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
10618 3c824109 Nathan Froyd
                                    uint16_t insn_hw1, int *is_branch)
10619 3c824109 Nathan Froyd
{
10620 3c824109 Nathan Froyd
    int32_t offset;
10621 3c824109 Nathan Froyd
    uint16_t insn;
10622 3c824109 Nathan Froyd
    int rt, rs, rd, rr;
10623 3c824109 Nathan Froyd
    int16_t imm;
10624 3c824109 Nathan Froyd
    uint32_t op, minor, mips32_op;
10625 3c824109 Nathan Froyd
    uint32_t cond, fmt, cc;
10626 3c824109 Nathan Froyd
10627 3c824109 Nathan Froyd
    insn = lduw_code(ctx->pc + 2);
10628 3c824109 Nathan Froyd
    ctx->opcode = (ctx->opcode << 16) | insn;
10629 3c824109 Nathan Froyd
10630 3c824109 Nathan Froyd
    rt = (ctx->opcode >> 21) & 0x1f;
10631 3c824109 Nathan Froyd
    rs = (ctx->opcode >> 16) & 0x1f;
10632 3c824109 Nathan Froyd
    rd = (ctx->opcode >> 11) & 0x1f;
10633 3c824109 Nathan Froyd
    rr = (ctx->opcode >> 6) & 0x1f;
10634 3c824109 Nathan Froyd
    imm = (int16_t) ctx->opcode;
10635 3c824109 Nathan Froyd
10636 3c824109 Nathan Froyd
    op = (ctx->opcode >> 26) & 0x3f;
10637 3c824109 Nathan Froyd
    switch (op) {
10638 3c824109 Nathan Froyd
    case POOL32A:
10639 3c824109 Nathan Froyd
        minor = ctx->opcode & 0x3f;
10640 3c824109 Nathan Froyd
        switch (minor) {
10641 3c824109 Nathan Froyd
        case 0x00:
10642 3c824109 Nathan Froyd
            minor = (ctx->opcode >> 6) & 0xf;
10643 3c824109 Nathan Froyd
            switch (minor) {
10644 3c824109 Nathan Froyd
            case SLL32:
10645 3c824109 Nathan Froyd
                mips32_op = OPC_SLL;
10646 3c824109 Nathan Froyd
                goto do_shifti;
10647 3c824109 Nathan Froyd
            case SRA:
10648 3c824109 Nathan Froyd
                mips32_op = OPC_SRA;
10649 3c824109 Nathan Froyd
                goto do_shifti;
10650 3c824109 Nathan Froyd
            case SRL32:
10651 3c824109 Nathan Froyd
                mips32_op = OPC_SRL;
10652 3c824109 Nathan Froyd
                goto do_shifti;
10653 3c824109 Nathan Froyd
            case ROTR:
10654 3c824109 Nathan Froyd
                mips32_op = OPC_ROTR;
10655 3c824109 Nathan Froyd
            do_shifti:
10656 3c824109 Nathan Froyd
                gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10657 3c824109 Nathan Froyd
                break;
10658 3c824109 Nathan Froyd
            default:
10659 3c824109 Nathan Froyd
                goto pool32a_invalid;
10660 3c824109 Nathan Froyd
            }
10661 3c824109 Nathan Froyd
            break;
10662 3c824109 Nathan Froyd
        case 0x10:
10663 3c824109 Nathan Froyd
            minor = (ctx->opcode >> 6) & 0xf;
10664 3c824109 Nathan Froyd
            switch (minor) {
10665 3c824109 Nathan Froyd
                /* Arithmetic */
10666 3c824109 Nathan Froyd
            case ADD:
10667 3c824109 Nathan Froyd
                mips32_op = OPC_ADD;
10668 3c824109 Nathan Froyd
                goto do_arith;
10669 3c824109 Nathan Froyd
            case ADDU32:
10670 3c824109 Nathan Froyd
                mips32_op = OPC_ADDU;
10671 3c824109 Nathan Froyd
                goto do_arith;
10672 3c824109 Nathan Froyd
            case SUB:
10673 3c824109 Nathan Froyd
                mips32_op = OPC_SUB;
10674 3c824109 Nathan Froyd
                goto do_arith;
10675 3c824109 Nathan Froyd
            case SUBU32:
10676 3c824109 Nathan Froyd
                mips32_op = OPC_SUBU;
10677 3c824109 Nathan Froyd
                goto do_arith;
10678 3c824109 Nathan Froyd
            case MUL:
10679 3c824109 Nathan Froyd
                mips32_op = OPC_MUL;
10680 3c824109 Nathan Froyd
            do_arith:
10681 3c824109 Nathan Froyd
                gen_arith(env, ctx, mips32_op, rd, rs, rt);
10682 3c824109 Nathan Froyd
                break;
10683 3c824109 Nathan Froyd
                /* Shifts */
10684 3c824109 Nathan Froyd
            case SLLV:
10685 3c824109 Nathan Froyd
                mips32_op = OPC_SLLV;
10686 3c824109 Nathan Froyd
                goto do_shift;
10687 3c824109 Nathan Froyd
            case SRLV:
10688 3c824109 Nathan Froyd
                mips32_op = OPC_SRLV;
10689 3c824109 Nathan Froyd
                goto do_shift;
10690 3c824109 Nathan Froyd
            case SRAV:
10691 3c824109 Nathan Froyd
                mips32_op = OPC_SRAV;
10692 3c824109 Nathan Froyd
                goto do_shift;
10693 3c824109 Nathan Froyd
            case ROTRV:
10694 3c824109 Nathan Froyd
                mips32_op = OPC_ROTRV;
10695 3c824109 Nathan Froyd
            do_shift:
10696 3c824109 Nathan Froyd
                gen_shift(env, ctx, mips32_op, rd, rs, rt);
10697 3c824109 Nathan Froyd
                break;
10698 3c824109 Nathan Froyd
                /* Logical operations */
10699 3c824109 Nathan Froyd
            case AND:
10700 3c824109 Nathan Froyd
                mips32_op = OPC_AND;
10701 3c824109 Nathan Froyd
                goto do_logic;
10702 3c824109 Nathan Froyd
            case OR32:
10703 3c824109 Nathan Froyd
                mips32_op = OPC_OR;
10704 3c824109 Nathan Froyd
                goto do_logic;
10705 3c824109 Nathan Froyd
            case NOR:
10706 3c824109 Nathan Froyd
                mips32_op = OPC_NOR;
10707 3c824109 Nathan Froyd
                goto do_logic;
10708 3c824109 Nathan Froyd
            case XOR32:
10709 3c824109 Nathan Froyd
                mips32_op = OPC_XOR;
10710 3c824109 Nathan Froyd
            do_logic:
10711 3c824109 Nathan Froyd
                gen_logic(env, mips32_op, rd, rs, rt);
10712 3c824109 Nathan Froyd
                break;
10713 3c824109 Nathan Froyd
                /* Set less than */
10714 3c824109 Nathan Froyd
            case SLT:
10715 3c824109 Nathan Froyd
                mips32_op = OPC_SLT;
10716 3c824109 Nathan Froyd
                goto do_slt;
10717 3c824109 Nathan Froyd
            case SLTU:
10718 3c824109 Nathan Froyd
                mips32_op = OPC_SLTU;
10719 3c824109 Nathan Froyd
            do_slt:
10720 3c824109 Nathan Froyd
                gen_slt(env, mips32_op, rd, rs, rt);
10721 3c824109 Nathan Froyd
                break;
10722 3c824109 Nathan Froyd
            default:
10723 3c824109 Nathan Froyd
                goto pool32a_invalid;
10724 3c824109 Nathan Froyd
            }
10725 3c824109 Nathan Froyd
            break;
10726 3c824109 Nathan Froyd
        case 0x18:
10727 3c824109 Nathan Froyd
            minor = (ctx->opcode >> 6) & 0xf;
10728 3c824109 Nathan Froyd
            switch (minor) {
10729 3c824109 Nathan Froyd
                /* Conditional moves */
10730 3c824109 Nathan Froyd
            case MOVN:
10731 3c824109 Nathan Froyd
                mips32_op = OPC_MOVN;
10732 3c824109 Nathan Froyd
                goto do_cmov;
10733 3c824109 Nathan Froyd
            case MOVZ:
10734 3c824109 Nathan Froyd
                mips32_op = OPC_MOVZ;
10735 3c824109 Nathan Froyd
            do_cmov:
10736 3c824109 Nathan Froyd
                gen_cond_move(env, mips32_op, rd, rs, rt);
10737 3c824109 Nathan Froyd
                break;
10738 3c824109 Nathan Froyd
            case LWXS:
10739 3c824109 Nathan Froyd
                gen_ldxs(ctx, rs, rt, rd);
10740 3c824109 Nathan Froyd
                break;
10741 3c824109 Nathan Froyd
            default:
10742 3c824109 Nathan Froyd
                goto pool32a_invalid;
10743 3c824109 Nathan Froyd
            }
10744 3c824109 Nathan Froyd
            break;
10745 3c824109 Nathan Froyd
        case INS:
10746 3c824109 Nathan Froyd
            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10747 3c824109 Nathan Froyd
            return;
10748 3c824109 Nathan Froyd
        case EXT:
10749 3c824109 Nathan Froyd
            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10750 3c824109 Nathan Froyd
            return;
10751 3c824109 Nathan Froyd
        case POOL32AXF:
10752 3c824109 Nathan Froyd
            gen_pool32axf(env, ctx, rt, rs, is_branch);
10753 3c824109 Nathan Froyd
            break;
10754 3c824109 Nathan Froyd
        case 0x07:
10755 3c824109 Nathan Froyd
            generate_exception(ctx, EXCP_BREAK);
10756 3c824109 Nathan Froyd
            break;
10757 3c824109 Nathan Froyd
        default:
10758 3c824109 Nathan Froyd
        pool32a_invalid:
10759 3c824109 Nathan Froyd
                MIPS_INVAL("pool32a");
10760 3c824109 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
10761 3c824109 Nathan Froyd
                break;
10762 3c824109 Nathan Froyd
        }
10763 3c824109 Nathan Froyd
        break;
10764 3c824109 Nathan Froyd
    case POOL32B:
10765 3c824109 Nathan Froyd
        minor = (ctx->opcode >> 12) & 0xf;
10766 3c824109 Nathan Froyd
        switch (minor) {
10767 3c824109 Nathan Froyd
        case CACHE:
10768 3c824109 Nathan Froyd
            /* Treat as no-op. */
10769 3c824109 Nathan Froyd
            break;
10770 3c824109 Nathan Froyd
        case LWC2:
10771 3c824109 Nathan Froyd
        case SWC2:
10772 3c824109 Nathan Froyd
            /* COP2: Not implemented. */
10773 3c824109 Nathan Froyd
            generate_exception_err(ctx, EXCP_CpU, 2);
10774 3c824109 Nathan Froyd
            break;
10775 3c824109 Nathan Froyd
        case LWP:
10776 3c824109 Nathan Froyd
        case SWP:
10777 3c824109 Nathan Froyd
#ifdef TARGET_MIPS64
10778 3c824109 Nathan Froyd
        case LDP:
10779 3c824109 Nathan Froyd
        case SDP:
10780 3c824109 Nathan Froyd
#endif
10781 3c824109 Nathan Froyd
            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10782 3c824109 Nathan Froyd
            break;
10783 3c824109 Nathan Froyd
        case LWM32:
10784 3c824109 Nathan Froyd
        case SWM32:
10785 3c824109 Nathan Froyd
#ifdef TARGET_MIPS64
10786 3c824109 Nathan Froyd
        case LDM:
10787 3c824109 Nathan Froyd
        case SDM:
10788 3c824109 Nathan Froyd
#endif
10789 3c824109 Nathan Froyd
            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10790 3c824109 Nathan Froyd
            break;
10791 3c824109 Nathan Froyd
        default:
10792 3c824109 Nathan Froyd
            MIPS_INVAL("pool32b");
10793 3c824109 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
10794 3c824109 Nathan Froyd
            break;
10795 3c824109 Nathan Froyd
        }
10796 3c824109 Nathan Froyd
        break;
10797 3c824109 Nathan Froyd
    case POOL32F:
10798 3c824109 Nathan Froyd
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10799 3c824109 Nathan Froyd
            minor = ctx->opcode & 0x3f;
10800 3c824109 Nathan Froyd
            check_cp1_enabled(ctx);
10801 3c824109 Nathan Froyd
            switch (minor) {
10802 3c824109 Nathan Froyd
            case ALNV_PS:
10803 3c824109 Nathan Froyd
                mips32_op = OPC_ALNV_PS;
10804 3c824109 Nathan Froyd
                goto do_madd;
10805 3c824109 Nathan Froyd
            case MADD_S:
10806 3c824109 Nathan Froyd
                mips32_op = OPC_MADD_S;
10807 3c824109 Nathan Froyd
                goto do_madd;
10808 3c824109 Nathan Froyd
            case MADD_D:
10809 3c824109 Nathan Froyd
                mips32_op = OPC_MADD_D;
10810 3c824109 Nathan Froyd
                goto do_madd;
10811 3c824109 Nathan Froyd
            case MADD_PS:
10812 3c824109 Nathan Froyd
                mips32_op = OPC_MADD_PS;
10813 3c824109 Nathan Froyd
                goto do_madd;
10814 3c824109 Nathan Froyd
            case MSUB_S:
10815 3c824109 Nathan Froyd
                mips32_op = OPC_MSUB_S;
10816 3c824109 Nathan Froyd
                goto do_madd;
10817 3c824109 Nathan Froyd
            case MSUB_D:
10818 3c824109 Nathan Froyd
                mips32_op = OPC_MSUB_D;
10819 3c824109 Nathan Froyd
                goto do_madd;
10820 3c824109 Nathan Froyd
            case MSUB_PS:
10821 3c824109 Nathan Froyd
                mips32_op = OPC_MSUB_PS;
10822 3c824109 Nathan Froyd
                goto do_madd;
10823 3c824109 Nathan Froyd
            case NMADD_S:
10824 3c824109 Nathan Froyd
                mips32_op = OPC_NMADD_S;
10825 3c824109 Nathan Froyd
                goto do_madd;
10826 3c824109 Nathan Froyd
            case NMADD_D:
10827 3c824109 Nathan Froyd
                mips32_op = OPC_NMADD_D;
10828 3c824109 Nathan Froyd
                goto do_madd;
10829 3c824109 Nathan Froyd
            case NMADD_PS:
10830 3c824109 Nathan Froyd
                mips32_op = OPC_NMADD_PS;
10831 3c824109 Nathan Froyd
                goto do_madd;
10832 3c824109 Nathan Froyd
            case NMSUB_S:
10833 3c824109 Nathan Froyd
                mips32_op = OPC_NMSUB_S;
10834 3c824109 Nathan Froyd
                goto do_madd;
10835 3c824109 Nathan Froyd
            case NMSUB_D:
10836 3c824109 Nathan Froyd
                mips32_op = OPC_NMSUB_D;
10837 3c824109 Nathan Froyd
                goto do_madd;
10838 3c824109 Nathan Froyd
            case NMSUB_PS:
10839 3c824109 Nathan Froyd
                mips32_op = OPC_NMSUB_PS;
10840 3c824109 Nathan Froyd
            do_madd:
10841 3c824109 Nathan Froyd
                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10842 3c824109 Nathan Froyd
                break;
10843 3c824109 Nathan Froyd
            case CABS_COND_FMT:
10844 3c824109 Nathan Froyd
                cond = (ctx->opcode >> 6) & 0xf;
10845 3c824109 Nathan Froyd
                cc = (ctx->opcode >> 13) & 0x7;
10846 3c824109 Nathan Froyd
                fmt = (ctx->opcode >> 10) & 0x3;
10847 3c824109 Nathan Froyd
                switch (fmt) {
10848 3c824109 Nathan Froyd
                case 0x0:
10849 3c824109 Nathan Froyd
                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
10850 3c824109 Nathan Froyd
                    break;
10851 3c824109 Nathan Froyd
                case 0x1:
10852 3c824109 Nathan Froyd
                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
10853 3c824109 Nathan Froyd
                    break;
10854 3c824109 Nathan Froyd
                case 0x2:
10855 3c824109 Nathan Froyd
                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10856 3c824109 Nathan Froyd
                    break;
10857 3c824109 Nathan Froyd
                default:
10858 3c824109 Nathan Froyd
                    goto pool32f_invalid;
10859 3c824109 Nathan Froyd
                }
10860 3c824109 Nathan Froyd
                break;
10861 3c824109 Nathan Froyd
            case C_COND_FMT:
10862 3c824109 Nathan Froyd
                cond = (ctx->opcode >> 6) & 0xf;
10863 3c824109 Nathan Froyd
                cc = (ctx->opcode >> 13) & 0x7;
10864 3c824109 Nathan Froyd
                fmt = (ctx->opcode >> 10) & 0x3;
10865 3c824109 Nathan Froyd
                switch (fmt) {
10866 3c824109 Nathan Froyd
                case 0x0:
10867 3c824109 Nathan Froyd
                    gen_cmp_s(ctx, cond, rt, rs, cc);
10868 3c824109 Nathan Froyd
                    break;
10869 3c824109 Nathan Froyd
                case 0x1:
10870 3c824109 Nathan Froyd
                    gen_cmp_d(ctx, cond, rt, rs, cc);
10871 3c824109 Nathan Froyd
                    break;
10872 3c824109 Nathan Froyd
                case 0x2:
10873 3c824109 Nathan Froyd
                    gen_cmp_ps(ctx, cond, rt, rs, cc);
10874 3c824109 Nathan Froyd
                    break;
10875 3c824109 Nathan Froyd
                default:
10876 3c824109 Nathan Froyd
                    goto pool32f_invalid;
10877 3c824109 Nathan Froyd
                }
10878 3c824109 Nathan Froyd
                break;
10879 3c824109 Nathan Froyd
            case POOL32FXF:
10880 3c824109 Nathan Froyd
                gen_pool32fxf(env, ctx, rt, rs);
10881 3c824109 Nathan Froyd
                break;
10882 3c824109 Nathan Froyd
            case 0x00:
10883 3c824109 Nathan Froyd
                /* PLL foo */
10884 3c824109 Nathan Froyd
                switch ((ctx->opcode >> 6) & 0x7) {
10885 3c824109 Nathan Froyd
                case PLL_PS:
10886 3c824109 Nathan Froyd
                    mips32_op = OPC_PLL_PS;
10887 3c824109 Nathan Froyd
                    goto do_ps;
10888 3c824109 Nathan Froyd
                case PLU_PS:
10889 3c824109 Nathan Froyd
                    mips32_op = OPC_PLU_PS;
10890 3c824109 Nathan Froyd
                    goto do_ps;
10891 3c824109 Nathan Froyd
                case PUL_PS:
10892 3c824109 Nathan Froyd
                    mips32_op = OPC_PUL_PS;
10893 3c824109 Nathan Froyd
                    goto do_ps;
10894 3c824109 Nathan Froyd
                case PUU_PS:
10895 3c824109 Nathan Froyd
                    mips32_op = OPC_PUU_PS;
10896 3c824109 Nathan Froyd
                    goto do_ps;
10897 3c824109 Nathan Froyd
                case CVT_PS_S:
10898 3c824109 Nathan Froyd
                    mips32_op = OPC_CVT_PS_S;
10899 3c824109 Nathan Froyd
                do_ps:
10900 3c824109 Nathan Froyd
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10901 3c824109 Nathan Froyd
                    break;
10902 3c824109 Nathan Froyd
                default:
10903 3c824109 Nathan Froyd
                    goto pool32f_invalid;
10904 3c824109 Nathan Froyd
                }
10905 3c824109 Nathan Froyd
                break;
10906 3c824109 Nathan Froyd
            case 0x08:
10907 3c824109 Nathan Froyd
                /* [LS][WDU]XC1 */
10908 3c824109 Nathan Froyd
                switch ((ctx->opcode >> 6) & 0x7) {
10909 3c824109 Nathan Froyd
                case LWXC1:
10910 3c824109 Nathan Froyd
                    mips32_op = OPC_LWXC1;
10911 3c824109 Nathan Froyd
                    goto do_ldst_cp1;
10912 3c824109 Nathan Froyd
                case SWXC1:
10913 3c824109 Nathan Froyd
                    mips32_op = OPC_SWXC1;
10914 3c824109 Nathan Froyd
                    goto do_ldst_cp1;
10915 3c824109 Nathan Froyd
                case LDXC1:
10916 3c824109 Nathan Froyd
                    mips32_op = OPC_LDXC1;
10917 3c824109 Nathan Froyd
                    goto do_ldst_cp1;
10918 3c824109 Nathan Froyd
                case SDXC1:
10919 3c824109 Nathan Froyd
                    mips32_op = OPC_SDXC1;
10920 3c824109 Nathan Froyd
                    goto do_ldst_cp1;
10921 3c824109 Nathan Froyd
                case LUXC1:
10922 3c824109 Nathan Froyd
                    mips32_op = OPC_LUXC1;
10923 3c824109 Nathan Froyd
                    goto do_ldst_cp1;
10924 3c824109 Nathan Froyd
                case SUXC1:
10925 3c824109 Nathan Froyd
                    mips32_op = OPC_SUXC1;
10926 3c824109 Nathan Froyd
                do_ldst_cp1:
10927 3c824109 Nathan Froyd
                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10928 3c824109 Nathan Froyd
                    break;
10929 3c824109 Nathan Froyd
                default:
10930 3c824109 Nathan Froyd
                    goto pool32f_invalid;
10931 3c824109 Nathan Froyd
                }
10932 3c824109 Nathan Froyd
                break;
10933 3c824109 Nathan Froyd
            case 0x18:
10934 3c824109 Nathan Froyd
                /* 3D insns */
10935 3c824109 Nathan Froyd
                fmt = (ctx->opcode >> 9) & 0x3;
10936 3c824109 Nathan Froyd
                switch ((ctx->opcode >> 6) & 0x7) {
10937 3c824109 Nathan Froyd
                case RSQRT2_FMT:
10938 3c824109 Nathan Froyd
                    switch (fmt) {
10939 3c824109 Nathan Froyd
                    case FMT_SDPS_S:
10940 3c824109 Nathan Froyd
                        mips32_op = OPC_RSQRT2_S;
10941 3c824109 Nathan Froyd
                        goto do_3d;
10942 3c824109 Nathan Froyd
                    case FMT_SDPS_D:
10943 3c824109 Nathan Froyd
                        mips32_op = OPC_RSQRT2_D;
10944 3c824109 Nathan Froyd
                        goto do_3d;
10945 3c824109 Nathan Froyd
                    case FMT_SDPS_PS:
10946 3c824109 Nathan Froyd
                        mips32_op = OPC_RSQRT2_PS;
10947 3c824109 Nathan Froyd
                        goto do_3d;
10948 3c824109 Nathan Froyd
                    default:
10949 3c824109 Nathan Froyd
                        goto pool32f_invalid;
10950 3c824109 Nathan Froyd
                    }
10951 3c824109 Nathan Froyd
                    break;
10952 3c824109 Nathan Froyd
                case RECIP2_FMT:
10953 3c824109 Nathan Froyd
                    switch (fmt) {
10954 3c824109 Nathan Froyd
                    case FMT_SDPS_S:
10955 3c824109 Nathan Froyd
                        mips32_op = OPC_RECIP2_S;
10956 3c824109 Nathan Froyd
                        goto do_3d;
10957 3c824109 Nathan Froyd
                    case FMT_SDPS_D:
10958 3c824109 Nathan Froyd
                        mips32_op = OPC_RECIP2_D;
10959 3c824109 Nathan Froyd
                        goto do_3d;
10960 3c824109 Nathan Froyd
                    case FMT_SDPS_PS:
10961 3c824109 Nathan Froyd
                        mips32_op = OPC_RECIP2_PS;
10962 3c824109 Nathan Froyd
                        goto do_3d;
10963 3c824109 Nathan Froyd
                    default:
10964 3c824109 Nathan Froyd
                        goto pool32f_invalid;
10965 3c824109 Nathan Froyd
                    }
10966 3c824109 Nathan Froyd
                    break;
10967 3c824109 Nathan Froyd
                case ADDR_PS:
10968 3c824109 Nathan Froyd
                    mips32_op = OPC_ADDR_PS;
10969 3c824109 Nathan Froyd
                    goto do_3d;
10970 3c824109 Nathan Froyd
                case MULR_PS:
10971 3c824109 Nathan Froyd
                    mips32_op = OPC_MULR_PS;
10972 3c824109 Nathan Froyd
                do_3d:
10973 3c824109 Nathan Froyd
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10974 3c824109 Nathan Froyd
                    break;
10975 3c824109 Nathan Froyd
                default:
10976 3c824109 Nathan Froyd
                    goto pool32f_invalid;
10977 3c824109 Nathan Froyd
                }
10978 3c824109 Nathan Froyd
                break;
10979 3c824109 Nathan Froyd
            case 0x20:
10980 3c824109 Nathan Froyd
                /* MOV[FT].fmt and PREFX */
10981 3c824109 Nathan Froyd
                cc = (ctx->opcode >> 13) & 0x7;
10982 3c824109 Nathan Froyd
                fmt = (ctx->opcode >> 9) & 0x3;
10983 3c824109 Nathan Froyd
                switch ((ctx->opcode >> 6) & 0x7) {
10984 3c824109 Nathan Froyd
                case MOVF_FMT:
10985 3c824109 Nathan Froyd
                    switch (fmt) {
10986 3c824109 Nathan Froyd
                    case FMT_SDPS_S:
10987 3c824109 Nathan Froyd
                        gen_movcf_s(rs, rt, cc, 0);
10988 3c824109 Nathan Froyd
                        break;
10989 3c824109 Nathan Froyd
                    case FMT_SDPS_D:
10990 3c824109 Nathan Froyd
                        gen_movcf_d(ctx, rs, rt, cc, 0);
10991 3c824109 Nathan Froyd
                        break;
10992 3c824109 Nathan Froyd
                    case FMT_SDPS_PS:
10993 3c824109 Nathan Froyd
                        gen_movcf_ps(rs, rt, cc, 0);
10994 3c824109 Nathan Froyd
                        break;
10995 3c824109 Nathan Froyd
                    default:
10996 3c824109 Nathan Froyd
                        goto pool32f_invalid;
10997 3c824109 Nathan Froyd
                    }
10998 3c824109 Nathan Froyd
                    break;
10999 3c824109 Nathan Froyd
                case MOVT_FMT:
11000 3c824109 Nathan Froyd
                    switch (fmt) {
11001 3c824109 Nathan Froyd
                    case FMT_SDPS_S:
11002 3c824109 Nathan Froyd
                        gen_movcf_s(rs, rt, cc, 1);
11003 3c824109 Nathan Froyd
                        break;
11004 3c824109 Nathan Froyd
                    case FMT_SDPS_D:
11005 3c824109 Nathan Froyd
                        gen_movcf_d(ctx, rs, rt, cc, 1);
11006 3c824109 Nathan Froyd
                        break;
11007 3c824109 Nathan Froyd
                    case FMT_SDPS_PS:
11008 3c824109 Nathan Froyd
                        gen_movcf_ps(rs, rt, cc, 1);
11009 3c824109 Nathan Froyd
                        break;
11010 3c824109 Nathan Froyd
                    default:
11011 3c824109 Nathan Froyd
                        goto pool32f_invalid;
11012 3c824109 Nathan Froyd
                    }
11013 3c824109 Nathan Froyd
                    break;
11014 3c824109 Nathan Froyd
                case PREFX:
11015 3c824109 Nathan Froyd
                    break;
11016 3c824109 Nathan Froyd
                default:
11017 3c824109 Nathan Froyd
                    goto pool32f_invalid;
11018 3c824109 Nathan Froyd
                }
11019 3c824109 Nathan Froyd
                break;
11020 3c824109 Nathan Froyd
#define FINSN_3ARG_SDPS(prfx)                           \
11021 3c824109 Nathan Froyd
                switch ((ctx->opcode >> 8) & 0x3) {     \
11022 3c824109 Nathan Froyd
                case FMT_SDPS_S:                        \
11023 3c824109 Nathan Froyd
                    mips32_op = OPC_##prfx##_S;         \
11024 3c824109 Nathan Froyd
                    goto do_fpop;                       \
11025 3c824109 Nathan Froyd
                case FMT_SDPS_D:                        \
11026 3c824109 Nathan Froyd
                    mips32_op = OPC_##prfx##_D;         \
11027 3c824109 Nathan Froyd
                    goto do_fpop;                       \
11028 3c824109 Nathan Froyd
                case FMT_SDPS_PS:                       \
11029 3c824109 Nathan Froyd
                    mips32_op = OPC_##prfx##_PS;        \
11030 3c824109 Nathan Froyd
                    goto do_fpop;                       \
11031 3c824109 Nathan Froyd
                default:                                \
11032 3c824109 Nathan Froyd
                    goto pool32f_invalid;               \
11033 3c824109 Nathan Froyd
                }
11034 3c824109 Nathan Froyd
            case 0x30:
11035 3c824109 Nathan Froyd
                /* regular FP ops */
11036 3c824109 Nathan Froyd
                switch ((ctx->opcode >> 6) & 0x3) {
11037 3c824109 Nathan Froyd
                case ADD_FMT:
11038 3c824109 Nathan Froyd
                    FINSN_3ARG_SDPS(ADD);
11039 3c824109 Nathan Froyd
                    break;
11040 3c824109 Nathan Froyd
                case SUB_FMT:
11041 3c824109 Nathan Froyd
                    FINSN_3ARG_SDPS(SUB);
11042 3c824109 Nathan Froyd
                    break;
11043 3c824109 Nathan Froyd
                case MUL_FMT:
11044 3c824109 Nathan Froyd
                    FINSN_3ARG_SDPS(MUL);
11045 3c824109 Nathan Froyd
                    break;
11046 3c824109 Nathan Froyd
                case DIV_FMT:
11047 3c824109 Nathan Froyd
                    fmt = (ctx->opcode >> 8) & 0x3;
11048 3c824109 Nathan Froyd
                    if (fmt == 1) {
11049 3c824109 Nathan Froyd
                        mips32_op = OPC_DIV_D;
11050 3c824109 Nathan Froyd
                    } else if (fmt == 0) {
11051 3c824109 Nathan Froyd
                        mips32_op = OPC_DIV_S;
11052 3c824109 Nathan Froyd
                    } else {
11053 3c824109 Nathan Froyd
                        goto pool32f_invalid;
11054 3c824109 Nathan Froyd
                    }
11055 3c824109 Nathan Froyd
                    goto do_fpop;
11056 3c824109 Nathan Froyd
                default:
11057 3c824109 Nathan Froyd
                    goto pool32f_invalid;
11058 3c824109 Nathan Froyd
                }
11059 3c824109 Nathan Froyd
                break;
11060 3c824109 Nathan Froyd
            case 0x38:
11061 3c824109 Nathan Froyd
                /* cmovs */
11062 3c824109 Nathan Froyd
                switch ((ctx->opcode >> 6) & 0x3) {
11063 3c824109 Nathan Froyd
                case MOVN_FMT:
11064 3c824109 Nathan Froyd
                    FINSN_3ARG_SDPS(MOVN);
11065 3c824109 Nathan Froyd
                    break;
11066 3c824109 Nathan Froyd
                case MOVZ_FMT:
11067 3c824109 Nathan Froyd
                    FINSN_3ARG_SDPS(MOVZ);
11068 3c824109 Nathan Froyd
                    break;
11069 3c824109 Nathan Froyd
                default:
11070 3c824109 Nathan Froyd
                    goto pool32f_invalid;
11071 3c824109 Nathan Froyd
                }
11072 3c824109 Nathan Froyd
                break;
11073 3c824109 Nathan Froyd
            do_fpop:
11074 3c824109 Nathan Froyd
                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11075 3c824109 Nathan Froyd
                break;
11076 3c824109 Nathan Froyd
            default:
11077 3c824109 Nathan Froyd
            pool32f_invalid:
11078 3c824109 Nathan Froyd
                MIPS_INVAL("pool32f");
11079 3c824109 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
11080 3c824109 Nathan Froyd
                break;
11081 3c824109 Nathan Froyd
            }
11082 3c824109 Nathan Froyd
        } else {
11083 3c824109 Nathan Froyd
            generate_exception_err(ctx, EXCP_CpU, 1);
11084 3c824109 Nathan Froyd
        }
11085 3c824109 Nathan Froyd
        break;
11086 3c824109 Nathan Froyd
    case POOL32I:
11087 3c824109 Nathan Froyd
        minor = (ctx->opcode >> 21) & 0x1f;
11088 3c824109 Nathan Froyd
        switch (minor) {
11089 3c824109 Nathan Froyd
        case BLTZ:
11090 3c824109 Nathan Froyd
            mips32_op = OPC_BLTZ;
11091 3c824109 Nathan Froyd
            goto do_branch;
11092 3c824109 Nathan Froyd
        case BLTZAL:
11093 3c824109 Nathan Froyd
            mips32_op = OPC_BLTZAL;
11094 3c824109 Nathan Froyd
            goto do_branch;
11095 3c824109 Nathan Froyd
        case BLTZALS:
11096 3c824109 Nathan Froyd
            mips32_op = OPC_BLTZALS;
11097 3c824109 Nathan Froyd
            goto do_branch;
11098 3c824109 Nathan Froyd
        case BGEZ:
11099 3c824109 Nathan Froyd
            mips32_op = OPC_BGEZ;
11100 3c824109 Nathan Froyd
            goto do_branch;
11101 3c824109 Nathan Froyd
        case BGEZAL:
11102 3c824109 Nathan Froyd
            mips32_op = OPC_BGEZAL;
11103 3c824109 Nathan Froyd
            goto do_branch;
11104 3c824109 Nathan Froyd
        case BGEZALS:
11105 3c824109 Nathan Froyd
            mips32_op = OPC_BGEZALS;
11106 3c824109 Nathan Froyd
            goto do_branch;
11107 3c824109 Nathan Froyd
        case BLEZ:
11108 3c824109 Nathan Froyd
            mips32_op = OPC_BLEZ;
11109 3c824109 Nathan Froyd
            goto do_branch;
11110 3c824109 Nathan Froyd
        case BGTZ:
11111 3c824109 Nathan Froyd
            mips32_op = OPC_BGTZ;
11112 3c824109 Nathan Froyd
        do_branch:
11113 3c824109 Nathan Froyd
            gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
11114 3c824109 Nathan Froyd
            *is_branch = 1;
11115 3c824109 Nathan Froyd
            break;
11116 3c824109 Nathan Froyd
11117 3c824109 Nathan Froyd
            /* Traps */
11118 3c824109 Nathan Froyd
        case TLTI:
11119 3c824109 Nathan Froyd
            mips32_op = OPC_TLTI;
11120 3c824109 Nathan Froyd
            goto do_trapi;
11121 3c824109 Nathan Froyd
        case TGEI:
11122 3c824109 Nathan Froyd
            mips32_op = OPC_TGEI;
11123 3c824109 Nathan Froyd
            goto do_trapi;
11124 3c824109 Nathan Froyd
        case TLTIU:
11125 3c824109 Nathan Froyd
            mips32_op = OPC_TLTIU;
11126 3c824109 Nathan Froyd
            goto do_trapi;
11127 3c824109 Nathan Froyd
        case TGEIU:
11128 3c824109 Nathan Froyd
            mips32_op = OPC_TGEIU;
11129 3c824109 Nathan Froyd
            goto do_trapi;
11130 3c824109 Nathan Froyd
        case TNEI:
11131 3c824109 Nathan Froyd
            mips32_op = OPC_TNEI;
11132 3c824109 Nathan Froyd
            goto do_trapi;
11133 3c824109 Nathan Froyd
        case TEQI:
11134 3c824109 Nathan Froyd
            mips32_op = OPC_TEQI;
11135 3c824109 Nathan Froyd
        do_trapi:
11136 3c824109 Nathan Froyd
            gen_trap(ctx, mips32_op, rs, -1, imm);
11137 3c824109 Nathan Froyd
            break;
11138 3c824109 Nathan Froyd
11139 3c824109 Nathan Froyd
        case BNEZC:
11140 3c824109 Nathan Froyd
        case BEQZC:
11141 3c824109 Nathan Froyd
            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
11142 3c824109 Nathan Froyd
                               4, rs, 0, imm << 1);
11143 3c824109 Nathan Froyd
            /* Compact branches don't have a delay slot, so just let
11144 3c824109 Nathan Froyd
               the normal delay slot handling take us to the branch
11145 3c824109 Nathan Froyd
               target. */
11146 3c824109 Nathan Froyd
            break;
11147 3c824109 Nathan Froyd
        case LUI:
11148 3c824109 Nathan Froyd
            gen_logic_imm(env, OPC_LUI, rs, -1, imm);
11149 3c824109 Nathan Froyd
            break;
11150 3c824109 Nathan Froyd
        case SYNCI:
11151 3c824109 Nathan Froyd
            break;
11152 3c824109 Nathan Froyd
        case BC2F:
11153 3c824109 Nathan Froyd
        case BC2T:
11154 3c824109 Nathan Froyd
            /* COP2: Not implemented. */
11155 3c824109 Nathan Froyd
            generate_exception_err(ctx, EXCP_CpU, 2);
11156 3c824109 Nathan Froyd
            break;
11157 3c824109 Nathan Froyd
        case BC1F:
11158 3c824109 Nathan Froyd
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11159 3c824109 Nathan Froyd
            goto do_cp1branch;
11160 3c824109 Nathan Froyd
        case BC1T:
11161 3c824109 Nathan Froyd
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11162 3c824109 Nathan Froyd
            goto do_cp1branch;
11163 3c824109 Nathan Froyd
        case BC1ANY4F:
11164 3c824109 Nathan Froyd
            mips32_op = OPC_BC1FANY4;
11165 3c824109 Nathan Froyd
            goto do_cp1mips3d;
11166 3c824109 Nathan Froyd
        case BC1ANY4T:
11167 3c824109 Nathan Froyd
            mips32_op = OPC_BC1TANY4;
11168 3c824109 Nathan Froyd
        do_cp1mips3d:
11169 3c824109 Nathan Froyd
            check_cop1x(ctx);
11170 3c824109 Nathan Froyd
            check_insn(env, ctx, ASE_MIPS3D);
11171 3c824109 Nathan Froyd
            /* Fall through */
11172 3c824109 Nathan Froyd
        do_cp1branch:
11173 3c824109 Nathan Froyd
            gen_compute_branch1(env, ctx, mips32_op,
11174 3c824109 Nathan Froyd
                                (ctx->opcode >> 18) & 0x7, imm << 1);
11175 3c824109 Nathan Froyd
            *is_branch = 1;
11176 3c824109 Nathan Froyd
            break;
11177 3c824109 Nathan Froyd
        case BPOSGE64:
11178 3c824109 Nathan Froyd
        case BPOSGE32:
11179 3c824109 Nathan Froyd
            /* MIPS DSP: not implemented */
11180 3c824109 Nathan Froyd
            /* Fall through */
11181 3c824109 Nathan Froyd
        default:
11182 3c824109 Nathan Froyd
            MIPS_INVAL("pool32i");
11183 3c824109 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
11184 3c824109 Nathan Froyd
            break;
11185 3c824109 Nathan Froyd
        }
11186 3c824109 Nathan Froyd
        break;
11187 3c824109 Nathan Froyd
    case POOL32C:
11188 3c824109 Nathan Froyd
        minor = (ctx->opcode >> 12) & 0xf;
11189 3c824109 Nathan Froyd
        switch (minor) {
11190 3c824109 Nathan Froyd
        case LWL:
11191 3c824109 Nathan Froyd
            mips32_op = OPC_LWL;
11192 5c13fdfd Aurelien Jarno
            goto do_ld_lr;
11193 3c824109 Nathan Froyd
        case SWL:
11194 3c824109 Nathan Froyd
            mips32_op = OPC_SWL;
11195 5c13fdfd Aurelien Jarno
            goto do_st_lr;
11196 3c824109 Nathan Froyd
        case LWR:
11197 3c824109 Nathan Froyd
            mips32_op = OPC_LWR;
11198 5c13fdfd Aurelien Jarno
            goto do_ld_lr;
11199 3c824109 Nathan Froyd
        case SWR:
11200 3c824109 Nathan Froyd
            mips32_op = OPC_SWR;
11201 5c13fdfd Aurelien Jarno
            goto do_st_lr;
11202 3c824109 Nathan Froyd
#if defined(TARGET_MIPS64)
11203 3c824109 Nathan Froyd
        case LDL:
11204 3c824109 Nathan Froyd
            mips32_op = OPC_LDL;
11205 5c13fdfd Aurelien Jarno
            goto do_ld_lr;
11206 3c824109 Nathan Froyd
        case SDL:
11207 3c824109 Nathan Froyd
            mips32_op = OPC_SDL;
11208 5c13fdfd Aurelien Jarno
            goto do_st_lr;
11209 3c824109 Nathan Froyd
        case LDR:
11210 3c824109 Nathan Froyd
            mips32_op = OPC_LDR;
11211 5c13fdfd Aurelien Jarno
            goto do_ld_lr;
11212 3c824109 Nathan Froyd
        case SDR:
11213 3c824109 Nathan Froyd
            mips32_op = OPC_SDR;
11214 5c13fdfd Aurelien Jarno
            goto do_st_lr;
11215 3c824109 Nathan Froyd
        case LWU:
11216 3c824109 Nathan Froyd
            mips32_op = OPC_LWU;
11217 5c13fdfd Aurelien Jarno
            goto do_ld_lr;
11218 3c824109 Nathan Froyd
        case LLD:
11219 3c824109 Nathan Froyd
            mips32_op = OPC_LLD;
11220 5c13fdfd Aurelien Jarno
            goto do_ld_lr;
11221 3c824109 Nathan Froyd
#endif
11222 3c824109 Nathan Froyd
        case LL:
11223 3c824109 Nathan Froyd
            mips32_op = OPC_LL;
11224 5c13fdfd Aurelien Jarno
            goto do_ld_lr;
11225 5c13fdfd Aurelien Jarno
        do_ld_lr:
11226 afa88c3a Aurelien Jarno
            gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11227 5c13fdfd Aurelien Jarno
            break;
11228 5c13fdfd Aurelien Jarno
        do_st_lr:
11229 5c13fdfd Aurelien Jarno
            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11230 3c824109 Nathan Froyd
            break;
11231 3c824109 Nathan Froyd
        case SC:
11232 3c824109 Nathan Froyd
            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11233 3c824109 Nathan Froyd
            break;
11234 3c824109 Nathan Froyd
#if defined(TARGET_MIPS64)
11235 3c824109 Nathan Froyd
        case SCD:
11236 3c824109 Nathan Froyd
            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11237 3c824109 Nathan Froyd
            break;
11238 3c824109 Nathan Froyd
#endif
11239 3c824109 Nathan Froyd
        case PREF:
11240 3c824109 Nathan Froyd
            /* Treat as no-op */
11241 3c824109 Nathan Froyd
            break;
11242 3c824109 Nathan Froyd
        default:
11243 3c824109 Nathan Froyd
            MIPS_INVAL("pool32c");
11244 3c824109 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
11245 3c824109 Nathan Froyd
            break;
11246 3c824109 Nathan Froyd
        }
11247 3c824109 Nathan Froyd
        break;
11248 3c824109 Nathan Froyd
    case ADDI32:
11249 3c824109 Nathan Froyd
        mips32_op = OPC_ADDI;
11250 3c824109 Nathan Froyd
        goto do_addi;
11251 3c824109 Nathan Froyd
    case ADDIU32:
11252 3c824109 Nathan Froyd
        mips32_op = OPC_ADDIU;
11253 3c824109 Nathan Froyd
    do_addi:
11254 3c824109 Nathan Froyd
        gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11255 3c824109 Nathan Froyd
        break;
11256 3c824109 Nathan Froyd
11257 3c824109 Nathan Froyd
        /* Logical operations */
11258 3c824109 Nathan Froyd
    case ORI32:
11259 3c824109 Nathan Froyd
        mips32_op = OPC_ORI;
11260 3c824109 Nathan Froyd
        goto do_logici;
11261 3c824109 Nathan Froyd
    case XORI32:
11262 3c824109 Nathan Froyd
        mips32_op = OPC_XORI;
11263 3c824109 Nathan Froyd
        goto do_logici;
11264 3c824109 Nathan Froyd
    case ANDI32:
11265 3c824109 Nathan Froyd
        mips32_op = OPC_ANDI;
11266 3c824109 Nathan Froyd
    do_logici:
11267 3c824109 Nathan Froyd
        gen_logic_imm(env, mips32_op, rt, rs, imm);
11268 3c824109 Nathan Froyd
        break;
11269 3c824109 Nathan Froyd
11270 3c824109 Nathan Froyd
        /* Set less than immediate */
11271 3c824109 Nathan Froyd
    case SLTI32:
11272 3c824109 Nathan Froyd
        mips32_op = OPC_SLTI;
11273 3c824109 Nathan Froyd
        goto do_slti;
11274 3c824109 Nathan Froyd
    case SLTIU32:
11275 3c824109 Nathan Froyd
        mips32_op = OPC_SLTIU;
11276 3c824109 Nathan Froyd
    do_slti:
11277 3c824109 Nathan Froyd
        gen_slt_imm(env, mips32_op, rt, rs, imm);
11278 3c824109 Nathan Froyd
        break;
11279 3c824109 Nathan Froyd
    case JALX32:
11280 3c824109 Nathan Froyd
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11281 3c824109 Nathan Froyd
        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11282 3c824109 Nathan Froyd
        *is_branch = 1;
11283 3c824109 Nathan Froyd
        break;
11284 3c824109 Nathan Froyd
    case JALS32:
11285 3c824109 Nathan Froyd
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11286 3c824109 Nathan Froyd
        gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11287 3c824109 Nathan Froyd
        *is_branch = 1;
11288 3c824109 Nathan Froyd
        break;
11289 3c824109 Nathan Froyd
    case BEQ32:
11290 3c824109 Nathan Froyd
        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11291 3c824109 Nathan Froyd
        *is_branch = 1;
11292 3c824109 Nathan Froyd
        break;
11293 3c824109 Nathan Froyd
    case BNE32:
11294 3c824109 Nathan Froyd
        gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11295 3c824109 Nathan Froyd
        *is_branch = 1;
11296 3c824109 Nathan Froyd
        break;
11297 3c824109 Nathan Froyd
    case J32:
11298 3c824109 Nathan Froyd
        gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11299 3c824109 Nathan Froyd
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11300 3c824109 Nathan Froyd
        *is_branch = 1;
11301 3c824109 Nathan Froyd
        break;
11302 3c824109 Nathan Froyd
    case JAL32:
11303 3c824109 Nathan Froyd
        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11304 3c824109 Nathan Froyd
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11305 3c824109 Nathan Froyd
        *is_branch = 1;
11306 3c824109 Nathan Froyd
        break;
11307 3c824109 Nathan Froyd
        /* Floating point (COP1) */
11308 3c824109 Nathan Froyd
    case LWC132:
11309 3c824109 Nathan Froyd
        mips32_op = OPC_LWC1;
11310 3c824109 Nathan Froyd
        goto do_cop1;
11311 3c824109 Nathan Froyd
    case LDC132:
11312 3c824109 Nathan Froyd
        mips32_op = OPC_LDC1;
11313 3c824109 Nathan Froyd
        goto do_cop1;
11314 3c824109 Nathan Froyd
    case SWC132:
11315 3c824109 Nathan Froyd
        mips32_op = OPC_SWC1;
11316 3c824109 Nathan Froyd
        goto do_cop1;
11317 3c824109 Nathan Froyd
    case SDC132:
11318 3c824109 Nathan Froyd
        mips32_op = OPC_SDC1;
11319 3c824109 Nathan Froyd
    do_cop1:
11320 3c824109 Nathan Froyd
        gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11321 3c824109 Nathan Froyd
        break;
11322 3c824109 Nathan Froyd
    case ADDIUPC:
11323 3c824109 Nathan Froyd
        {
11324 3c824109 Nathan Froyd
            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
11325 3c824109 Nathan Froyd
            int offset = SIMM(ctx->opcode, 0, 23) << 2;
11326 3c824109 Nathan Froyd
11327 3c824109 Nathan Froyd
            gen_addiupc(ctx, reg, offset, 0, 0);
11328 3c824109 Nathan Froyd
        }
11329 3c824109 Nathan Froyd
        break;
11330 3c824109 Nathan Froyd
        /* Loads and stores */
11331 3c824109 Nathan Froyd
    case LB32:
11332 3c824109 Nathan Froyd
        mips32_op = OPC_LB;
11333 5c13fdfd Aurelien Jarno
        goto do_ld;
11334 3c824109 Nathan Froyd
    case LBU32:
11335 3c824109 Nathan Froyd
        mips32_op = OPC_LBU;
11336 5c13fdfd Aurelien Jarno
        goto do_ld;
11337 3c824109 Nathan Froyd
    case LH32:
11338 3c824109 Nathan Froyd
        mips32_op = OPC_LH;
11339 5c13fdfd Aurelien Jarno
        goto do_ld;
11340 3c824109 Nathan Froyd
    case LHU32:
11341 3c824109 Nathan Froyd
        mips32_op = OPC_LHU;
11342 5c13fdfd Aurelien Jarno
        goto do_ld;
11343 3c824109 Nathan Froyd
    case LW32:
11344 3c824109 Nathan Froyd
        mips32_op = OPC_LW;
11345 5c13fdfd Aurelien Jarno
        goto do_ld;
11346 3c824109 Nathan Froyd
#ifdef TARGET_MIPS64
11347 3c824109 Nathan Froyd
    case LD32:
11348 3c824109 Nathan Froyd
        mips32_op = OPC_LD;
11349 5c13fdfd Aurelien Jarno
        goto do_ld;
11350 3c824109 Nathan Froyd
    case SD32:
11351 3c824109 Nathan Froyd
        mips32_op = OPC_SD;
11352 5c13fdfd Aurelien Jarno
        goto do_st;
11353 3c824109 Nathan Froyd
#endif
11354 3c824109 Nathan Froyd
    case SB32:
11355 3c824109 Nathan Froyd
        mips32_op = OPC_SB;
11356 5c13fdfd Aurelien Jarno
        goto do_st;
11357 3c824109 Nathan Froyd
    case SH32:
11358 3c824109 Nathan Froyd
        mips32_op = OPC_SH;
11359 5c13fdfd Aurelien Jarno
        goto do_st;
11360 3c824109 Nathan Froyd
    case SW32:
11361 3c824109 Nathan Froyd
        mips32_op = OPC_SW;
11362 5c13fdfd Aurelien Jarno
        goto do_st;
11363 5c13fdfd Aurelien Jarno
    do_ld:
11364 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, mips32_op, rt, rs, imm);
11365 5c13fdfd Aurelien Jarno
        break;
11366 5c13fdfd Aurelien Jarno
    do_st:
11367 5c13fdfd Aurelien Jarno
        gen_st(ctx, mips32_op, rt, rs, imm);
11368 3c824109 Nathan Froyd
        break;
11369 3c824109 Nathan Froyd
    default:
11370 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
11371 3c824109 Nathan Froyd
        break;
11372 3c824109 Nathan Froyd
    }
11373 3c824109 Nathan Froyd
}
11374 3c824109 Nathan Froyd
11375 3c824109 Nathan Froyd
static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11376 3c824109 Nathan Froyd
{
11377 3c824109 Nathan Froyd
    uint32_t op;
11378 3c824109 Nathan Froyd
11379 3c824109 Nathan Froyd
    /* make sure instructions are on a halfword boundary */
11380 3c824109 Nathan Froyd
    if (ctx->pc & 0x1) {
11381 3c824109 Nathan Froyd
        env->CP0_BadVAddr = ctx->pc;
11382 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_AdEL);
11383 3c824109 Nathan Froyd
        ctx->bstate = BS_STOP;
11384 3c824109 Nathan Froyd
        return 2;
11385 3c824109 Nathan Froyd
    }
11386 3c824109 Nathan Froyd
11387 3c824109 Nathan Froyd
    op = (ctx->opcode >> 10) & 0x3f;
11388 3c824109 Nathan Froyd
    /* Enforce properly-sized instructions in a delay slot */
11389 3c824109 Nathan Froyd
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11390 3c824109 Nathan Froyd
        int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11391 3c824109 Nathan Froyd
11392 3c824109 Nathan Froyd
        switch (op) {
11393 3c824109 Nathan Froyd
        case POOL32A:
11394 3c824109 Nathan Froyd
        case POOL32B:
11395 3c824109 Nathan Froyd
        case POOL32I:
11396 3c824109 Nathan Froyd
        case POOL32C:
11397 3c824109 Nathan Froyd
        case ADDI32:
11398 3c824109 Nathan Froyd
        case ADDIU32:
11399 3c824109 Nathan Froyd
        case ORI32:
11400 3c824109 Nathan Froyd
        case XORI32:
11401 3c824109 Nathan Froyd
        case SLTI32:
11402 3c824109 Nathan Froyd
        case SLTIU32:
11403 3c824109 Nathan Froyd
        case ANDI32:
11404 3c824109 Nathan Froyd
        case JALX32:
11405 3c824109 Nathan Froyd
        case LBU32:
11406 3c824109 Nathan Froyd
        case LHU32:
11407 3c824109 Nathan Froyd
        case POOL32F:
11408 3c824109 Nathan Froyd
        case JALS32:
11409 3c824109 Nathan Froyd
        case BEQ32:
11410 3c824109 Nathan Froyd
        case BNE32:
11411 3c824109 Nathan Froyd
        case J32:
11412 3c824109 Nathan Froyd
        case JAL32:
11413 3c824109 Nathan Froyd
        case SB32:
11414 3c824109 Nathan Froyd
        case SH32:
11415 3c824109 Nathan Froyd
        case POOL32S:
11416 3c824109 Nathan Froyd
        case ADDIUPC:
11417 3c824109 Nathan Froyd
        case SWC132:
11418 3c824109 Nathan Froyd
        case SDC132:
11419 3c824109 Nathan Froyd
        case SD32:
11420 3c824109 Nathan Froyd
        case SW32:
11421 3c824109 Nathan Froyd
        case LB32:
11422 3c824109 Nathan Froyd
        case LH32:
11423 3c824109 Nathan Froyd
        case DADDIU32:
11424 3c824109 Nathan Froyd
        case POOL48A:           /* ??? */
11425 3c824109 Nathan Froyd
        case LWC132:
11426 3c824109 Nathan Froyd
        case LDC132:
11427 3c824109 Nathan Froyd
        case LD32:
11428 3c824109 Nathan Froyd
        case LW32:
11429 3c824109 Nathan Froyd
            if (bits & MIPS_HFLAG_BDS16) {
11430 3c824109 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
11431 3c824109 Nathan Froyd
                /* Just stop translation; the user is confused.  */
11432 3c824109 Nathan Froyd
                ctx->bstate = BS_STOP;
11433 3c824109 Nathan Froyd
                return 2;
11434 3c824109 Nathan Froyd
            }
11435 3c824109 Nathan Froyd
            break;
11436 3c824109 Nathan Froyd
        case POOL16A:
11437 3c824109 Nathan Froyd
        case POOL16B:
11438 3c824109 Nathan Froyd
        case POOL16C:
11439 3c824109 Nathan Froyd
        case LWGP16:
11440 3c824109 Nathan Froyd
        case POOL16F:
11441 3c824109 Nathan Froyd
        case LBU16:
11442 3c824109 Nathan Froyd
        case LHU16:
11443 3c824109 Nathan Froyd
        case LWSP16:
11444 3c824109 Nathan Froyd
        case LW16:
11445 3c824109 Nathan Froyd
        case SB16:
11446 3c824109 Nathan Froyd
        case SH16:
11447 3c824109 Nathan Froyd
        case SWSP16:
11448 3c824109 Nathan Froyd
        case SW16:
11449 3c824109 Nathan Froyd
        case MOVE16:
11450 3c824109 Nathan Froyd
        case ANDI16:
11451 3c824109 Nathan Froyd
        case POOL16D:
11452 3c824109 Nathan Froyd
        case POOL16E:
11453 3c824109 Nathan Froyd
        case BEQZ16:
11454 3c824109 Nathan Froyd
        case BNEZ16:
11455 3c824109 Nathan Froyd
        case B16:
11456 3c824109 Nathan Froyd
        case LI16:
11457 3c824109 Nathan Froyd
            if (bits & MIPS_HFLAG_BDS32) {
11458 3c824109 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
11459 3c824109 Nathan Froyd
                /* Just stop translation; the user is confused.  */
11460 3c824109 Nathan Froyd
                ctx->bstate = BS_STOP;
11461 3c824109 Nathan Froyd
                return 2;
11462 3c824109 Nathan Froyd
            }
11463 3c824109 Nathan Froyd
            break;
11464 3c824109 Nathan Froyd
        default:
11465 3c824109 Nathan Froyd
            break;
11466 3c824109 Nathan Froyd
        }
11467 3c824109 Nathan Froyd
    }
11468 3c824109 Nathan Froyd
    switch (op) {
11469 3c824109 Nathan Froyd
    case POOL16A:
11470 3c824109 Nathan Froyd
        {
11471 3c824109 Nathan Froyd
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11472 3c824109 Nathan Froyd
            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11473 3c824109 Nathan Froyd
            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11474 3c824109 Nathan Froyd
            uint32_t opc = 0;
11475 3c824109 Nathan Froyd
11476 3c824109 Nathan Froyd
            switch (ctx->opcode & 0x1) {
11477 3c824109 Nathan Froyd
            case ADDU16:
11478 3c824109 Nathan Froyd
                opc = OPC_ADDU;
11479 3c824109 Nathan Froyd
                break;
11480 3c824109 Nathan Froyd
            case SUBU16:
11481 3c824109 Nathan Froyd
                opc = OPC_SUBU;
11482 3c824109 Nathan Froyd
                break;
11483 3c824109 Nathan Froyd
            }
11484 3c824109 Nathan Froyd
11485 3c824109 Nathan Froyd
            gen_arith(env, ctx, opc, rd, rs1, rs2);
11486 3c824109 Nathan Froyd
        }
11487 3c824109 Nathan Froyd
        break;
11488 3c824109 Nathan Froyd
    case POOL16B:
11489 3c824109 Nathan Froyd
        {
11490 3c824109 Nathan Froyd
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11491 3c824109 Nathan Froyd
            int rs = mmreg(uMIPS_RS(ctx->opcode));
11492 3c824109 Nathan Froyd
            int amount = (ctx->opcode >> 1) & 0x7;
11493 3c824109 Nathan Froyd
            uint32_t opc = 0;
11494 3c824109 Nathan Froyd
            amount = amount == 0 ? 8 : amount;
11495 3c824109 Nathan Froyd
11496 3c824109 Nathan Froyd
            switch (ctx->opcode & 0x1) {
11497 3c824109 Nathan Froyd
            case SLL16:
11498 3c824109 Nathan Froyd
                opc = OPC_SLL;
11499 3c824109 Nathan Froyd
                break;
11500 3c824109 Nathan Froyd
            case SRL16:
11501 3c824109 Nathan Froyd
                opc = OPC_SRL;
11502 3c824109 Nathan Froyd
                break;
11503 3c824109 Nathan Froyd
            }
11504 3c824109 Nathan Froyd
11505 3c824109 Nathan Froyd
            gen_shift_imm(env, ctx, opc, rd, rs, amount);
11506 3c824109 Nathan Froyd
        }
11507 3c824109 Nathan Froyd
        break;
11508 3c824109 Nathan Froyd
    case POOL16C:
11509 3c824109 Nathan Froyd
        gen_pool16c_insn(env, ctx, is_branch);
11510 3c824109 Nathan Froyd
        break;
11511 3c824109 Nathan Froyd
    case LWGP16:
11512 3c824109 Nathan Froyd
        {
11513 3c824109 Nathan Froyd
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11514 3c824109 Nathan Froyd
            int rb = 28;            /* GP */
11515 3c824109 Nathan Froyd
            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11516 3c824109 Nathan Froyd
11517 afa88c3a Aurelien Jarno
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11518 3c824109 Nathan Froyd
        }
11519 3c824109 Nathan Froyd
        break;
11520 3c824109 Nathan Froyd
    case POOL16F:
11521 3c824109 Nathan Froyd
        if (ctx->opcode & 1) {
11522 3c824109 Nathan Froyd
            generate_exception(ctx, EXCP_RI);
11523 3c824109 Nathan Froyd
        } else {
11524 3c824109 Nathan Froyd
            /* MOVEP */
11525 3c824109 Nathan Froyd
            int enc_dest = uMIPS_RD(ctx->opcode);
11526 3c824109 Nathan Froyd
            int enc_rt = uMIPS_RS2(ctx->opcode);
11527 3c824109 Nathan Froyd
            int enc_rs = uMIPS_RS1(ctx->opcode);
11528 3c824109 Nathan Froyd
            int rd, rs, re, rt;
11529 3c824109 Nathan Froyd
            static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11530 3c824109 Nathan Froyd
            static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11531 3c824109 Nathan Froyd
            static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11532 3c824109 Nathan Froyd
11533 3c824109 Nathan Froyd
            rd = rd_enc[enc_dest];
11534 3c824109 Nathan Froyd
            re = re_enc[enc_dest];
11535 3c824109 Nathan Froyd
            rs = rs_rt_enc[enc_rs];
11536 3c824109 Nathan Froyd
            rt = rs_rt_enc[enc_rt];
11537 3c824109 Nathan Froyd
11538 3c824109 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11539 3c824109 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11540 3c824109 Nathan Froyd
        }
11541 3c824109 Nathan Froyd
        break;
11542 3c824109 Nathan Froyd
    case LBU16:
11543 3c824109 Nathan Froyd
        {
11544 3c824109 Nathan Froyd
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11545 3c824109 Nathan Froyd
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11546 3c824109 Nathan Froyd
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
11547 3c824109 Nathan Froyd
            offset = (offset == 0xf ? -1 : offset);
11548 3c824109 Nathan Froyd
11549 afa88c3a Aurelien Jarno
            gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
11550 3c824109 Nathan Froyd
        }
11551 3c824109 Nathan Froyd
        break;
11552 3c824109 Nathan Froyd
    case LHU16:
11553 3c824109 Nathan Froyd
        {
11554 3c824109 Nathan Froyd
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11555 3c824109 Nathan Froyd
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11556 3c824109 Nathan Froyd
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11557 3c824109 Nathan Froyd
11558 afa88c3a Aurelien Jarno
            gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
11559 3c824109 Nathan Froyd
        }
11560 3c824109 Nathan Froyd
        break;
11561 3c824109 Nathan Froyd
    case LWSP16:
11562 3c824109 Nathan Froyd
        {
11563 3c824109 Nathan Froyd
            int rd = (ctx->opcode >> 5) & 0x1f;
11564 3c824109 Nathan Froyd
            int rb = 29;            /* SP */
11565 3c824109 Nathan Froyd
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11566 3c824109 Nathan Froyd
11567 afa88c3a Aurelien Jarno
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11568 3c824109 Nathan Froyd
        }
11569 3c824109 Nathan Froyd
        break;
11570 3c824109 Nathan Froyd
    case LW16:
11571 3c824109 Nathan Froyd
        {
11572 3c824109 Nathan Froyd
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11573 3c824109 Nathan Froyd
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11574 3c824109 Nathan Froyd
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11575 3c824109 Nathan Froyd
11576 afa88c3a Aurelien Jarno
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11577 3c824109 Nathan Froyd
        }
11578 3c824109 Nathan Froyd
        break;
11579 3c824109 Nathan Froyd
    case SB16:
11580 3c824109 Nathan Froyd
        {
11581 3c824109 Nathan Froyd
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11582 3c824109 Nathan Froyd
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11583 3c824109 Nathan Froyd
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
11584 3c824109 Nathan Froyd
11585 5c13fdfd Aurelien Jarno
            gen_st(ctx, OPC_SB, rd, rb, offset);
11586 3c824109 Nathan Froyd
        }
11587 3c824109 Nathan Froyd
        break;
11588 3c824109 Nathan Froyd
    case SH16:
11589 3c824109 Nathan Froyd
        {
11590 3c824109 Nathan Froyd
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11591 3c824109 Nathan Froyd
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11592 3c824109 Nathan Froyd
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11593 3c824109 Nathan Froyd
11594 5c13fdfd Aurelien Jarno
            gen_st(ctx, OPC_SH, rd, rb, offset);
11595 3c824109 Nathan Froyd
        }
11596 3c824109 Nathan Froyd
        break;
11597 3c824109 Nathan Froyd
    case SWSP16:
11598 3c824109 Nathan Froyd
        {
11599 3c824109 Nathan Froyd
            int rd = (ctx->opcode >> 5) & 0x1f;
11600 3c824109 Nathan Froyd
            int rb = 29;            /* SP */
11601 3c824109 Nathan Froyd
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11602 3c824109 Nathan Froyd
11603 5c13fdfd Aurelien Jarno
            gen_st(ctx, OPC_SW, rd, rb, offset);
11604 3c824109 Nathan Froyd
        }
11605 3c824109 Nathan Froyd
        break;
11606 3c824109 Nathan Froyd
    case SW16:
11607 3c824109 Nathan Froyd
        {
11608 3c824109 Nathan Froyd
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11609 3c824109 Nathan Froyd
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11610 3c824109 Nathan Froyd
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11611 3c824109 Nathan Froyd
11612 5c13fdfd Aurelien Jarno
            gen_st(ctx, OPC_SW, rd, rb, offset);
11613 3c824109 Nathan Froyd
        }
11614 3c824109 Nathan Froyd
        break;
11615 3c824109 Nathan Froyd
    case MOVE16:
11616 3c824109 Nathan Froyd
        {
11617 3c824109 Nathan Froyd
            int rd = uMIPS_RD5(ctx->opcode);
11618 3c824109 Nathan Froyd
            int rs = uMIPS_RS5(ctx->opcode);
11619 3c824109 Nathan Froyd
11620 3c824109 Nathan Froyd
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11621 3c824109 Nathan Froyd
        }
11622 3c824109 Nathan Froyd
        break;
11623 3c824109 Nathan Froyd
    case ANDI16:
11624 3c824109 Nathan Froyd
        gen_andi16(env, ctx);
11625 3c824109 Nathan Froyd
        break;
11626 3c824109 Nathan Froyd
    case POOL16D:
11627 3c824109 Nathan Froyd
        switch (ctx->opcode & 0x1) {
11628 3c824109 Nathan Froyd
        case ADDIUS5:
11629 3c824109 Nathan Froyd
            gen_addius5(env, ctx);
11630 3c824109 Nathan Froyd
            break;
11631 3c824109 Nathan Froyd
        case ADDIUSP:
11632 3c824109 Nathan Froyd
            gen_addiusp(env, ctx);
11633 3c824109 Nathan Froyd
            break;
11634 3c824109 Nathan Froyd
        }
11635 3c824109 Nathan Froyd
        break;
11636 3c824109 Nathan Froyd
    case POOL16E:
11637 3c824109 Nathan Froyd
        switch (ctx->opcode & 0x1) {
11638 3c824109 Nathan Froyd
        case ADDIUR2:
11639 3c824109 Nathan Froyd
            gen_addiur2(env, ctx);
11640 3c824109 Nathan Froyd
            break;
11641 3c824109 Nathan Froyd
        case ADDIUR1SP:
11642 3c824109 Nathan Froyd
            gen_addiur1sp(env, ctx);
11643 3c824109 Nathan Froyd
            break;
11644 3c824109 Nathan Froyd
        }
11645 3c824109 Nathan Froyd
        break;
11646 3c824109 Nathan Froyd
    case B16:
11647 3c824109 Nathan Froyd
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11648 3c824109 Nathan Froyd
                           SIMM(ctx->opcode, 0, 10) << 1);
11649 3c824109 Nathan Froyd
        *is_branch = 1;
11650 3c824109 Nathan Froyd
        break;
11651 3c824109 Nathan Froyd
    case BNEZ16:
11652 3c824109 Nathan Froyd
    case BEQZ16:
11653 3c824109 Nathan Froyd
        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11654 3c824109 Nathan Froyd
                           mmreg(uMIPS_RD(ctx->opcode)),
11655 3c824109 Nathan Froyd
                           0, SIMM(ctx->opcode, 0, 7) << 1);
11656 3c824109 Nathan Froyd
        *is_branch = 1;
11657 3c824109 Nathan Froyd
        break;
11658 3c824109 Nathan Froyd
    case LI16:
11659 3c824109 Nathan Froyd
        {
11660 3c824109 Nathan Froyd
            int reg = mmreg(uMIPS_RD(ctx->opcode));
11661 3c824109 Nathan Froyd
            int imm = ZIMM(ctx->opcode, 0, 7);
11662 3c824109 Nathan Froyd
11663 3c824109 Nathan Froyd
            imm = (imm == 0x7f ? -1 : imm);
11664 3c824109 Nathan Froyd
            tcg_gen_movi_tl(cpu_gpr[reg], imm);
11665 3c824109 Nathan Froyd
        }
11666 3c824109 Nathan Froyd
        break;
11667 3c824109 Nathan Froyd
    case RES_20:
11668 3c824109 Nathan Froyd
    case RES_28:
11669 3c824109 Nathan Froyd
    case RES_29:
11670 3c824109 Nathan Froyd
    case RES_30:
11671 3c824109 Nathan Froyd
    case RES_31:
11672 3c824109 Nathan Froyd
    case RES_38:
11673 3c824109 Nathan Froyd
    case RES_39:
11674 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_RI);
11675 3c824109 Nathan Froyd
        break;
11676 3c824109 Nathan Froyd
    default:
11677 3c824109 Nathan Froyd
        decode_micromips32_opc (env, ctx, op, is_branch);
11678 3c824109 Nathan Froyd
        return 4;
11679 3c824109 Nathan Froyd
    }
11680 3c824109 Nathan Froyd
11681 3c824109 Nathan Froyd
    return 2;
11682 3c824109 Nathan Froyd
}
11683 3c824109 Nathan Froyd
11684 3c824109 Nathan Froyd
/* SmartMIPS extension to MIPS32 */
11685 3c824109 Nathan Froyd
11686 3c824109 Nathan Froyd
#if defined(TARGET_MIPS64)
11687 3c824109 Nathan Froyd
11688 3c824109 Nathan Froyd
/* MDMX extension to MIPS64 */
11689 3c824109 Nathan Froyd
11690 3c824109 Nathan Froyd
#endif
11691 3c824109 Nathan Froyd
11692 3c824109 Nathan Froyd
static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11693 3c824109 Nathan Froyd
{
11694 3c824109 Nathan Froyd
    int32_t offset;
11695 3c824109 Nathan Froyd
    int rs, rt, rd, sa;
11696 3c824109 Nathan Froyd
    uint32_t op, op1, op2;
11697 3c824109 Nathan Froyd
    int16_t imm;
11698 3c824109 Nathan Froyd
11699 3c824109 Nathan Froyd
    /* make sure instructions are on a word boundary */
11700 3c824109 Nathan Froyd
    if (ctx->pc & 0x3) {
11701 3c824109 Nathan Froyd
        env->CP0_BadVAddr = ctx->pc;
11702 3c824109 Nathan Froyd
        generate_exception(ctx, EXCP_AdEL);
11703 3c824109 Nathan Froyd
        return;
11704 3c824109 Nathan Froyd
    }
11705 3c824109 Nathan Froyd
11706 3c824109 Nathan Froyd
    /* Handle blikely not taken case */
11707 3c824109 Nathan Froyd
    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11708 3c824109 Nathan Froyd
        int l1 = gen_new_label();
11709 3c824109 Nathan Froyd
11710 3c824109 Nathan Froyd
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11711 3c824109 Nathan Froyd
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11712 3c824109 Nathan Froyd
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11713 3c824109 Nathan Froyd
        gen_goto_tb(ctx, 1, ctx->pc + 4);
11714 3c824109 Nathan Froyd
        gen_set_label(l1);
11715 3c824109 Nathan Froyd
    }
11716 3c824109 Nathan Froyd
11717 3c824109 Nathan Froyd
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11718 3c824109 Nathan Froyd
        tcg_gen_debug_insn_start(ctx->pc);
11719 3c824109 Nathan Froyd
11720 3c824109 Nathan Froyd
    op = MASK_OP_MAJOR(ctx->opcode);
11721 3c824109 Nathan Froyd
    rs = (ctx->opcode >> 21) & 0x1f;
11722 3c824109 Nathan Froyd
    rt = (ctx->opcode >> 16) & 0x1f;
11723 3c824109 Nathan Froyd
    rd = (ctx->opcode >> 11) & 0x1f;
11724 3c824109 Nathan Froyd
    sa = (ctx->opcode >> 6) & 0x1f;
11725 3c824109 Nathan Froyd
    imm = (int16_t)ctx->opcode;
11726 3c824109 Nathan Froyd
    switch (op) {
11727 7a387fff ths
    case OPC_SPECIAL:
11728 7a387fff ths
        op1 = MASK_SPECIAL(ctx->opcode);
11729 6af0bf9c bellard
        switch (op1) {
11730 324d9e32 aurel32
        case OPC_SLL:          /* Shift with immediate */
11731 324d9e32 aurel32
        case OPC_SRA:
11732 324d9e32 aurel32
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
11733 7a387fff ths
            break;
11734 ea63e2c3 Nathan Froyd
        case OPC_SRL:
11735 ea63e2c3 Nathan Froyd
            switch ((ctx->opcode >> 21) & 0x1f) {
11736 ea63e2c3 Nathan Froyd
            case 1:
11737 ea63e2c3 Nathan Froyd
                /* rotr is decoded as srl on non-R2 CPUs */
11738 ea63e2c3 Nathan Froyd
                if (env->insn_flags & ISA_MIPS32R2) {
11739 ea63e2c3 Nathan Froyd
                    op1 = OPC_ROTR;
11740 ea63e2c3 Nathan Froyd
                }
11741 ea63e2c3 Nathan Froyd
                /* Fallthrough */
11742 ea63e2c3 Nathan Froyd
            case 0:
11743 ea63e2c3 Nathan Froyd
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11744 ea63e2c3 Nathan Froyd
                break;
11745 ea63e2c3 Nathan Froyd
            default:
11746 ea63e2c3 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
11747 ea63e2c3 Nathan Froyd
                break;
11748 ea63e2c3 Nathan Froyd
            }
11749 ea63e2c3 Nathan Froyd
            break;
11750 460f00c4 aurel32
        case OPC_MOVN:         /* Conditional move */
11751 460f00c4 aurel32
        case OPC_MOVZ:
11752 aa8f4009 Aurelien Jarno
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11753 aa8f4009 Aurelien Jarno
                                 INSN_LOONGSON2E | INSN_LOONGSON2F);
11754 460f00c4 aurel32
            gen_cond_move(env, op1, rd, rs, rt);
11755 460f00c4 aurel32
            break;
11756 460f00c4 aurel32
        case OPC_ADD ... OPC_SUBU:
11757 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
11758 7a387fff ths
            break;
11759 460f00c4 aurel32
        case OPC_SLLV:         /* Shifts */
11760 460f00c4 aurel32
        case OPC_SRAV:
11761 460f00c4 aurel32
            gen_shift(env, ctx, op1, rd, rs, rt);
11762 460f00c4 aurel32
            break;
11763 ea63e2c3 Nathan Froyd
        case OPC_SRLV:
11764 ea63e2c3 Nathan Froyd
            switch ((ctx->opcode >> 6) & 0x1f) {
11765 ea63e2c3 Nathan Froyd
            case 1:
11766 ea63e2c3 Nathan Froyd
                /* rotrv is decoded as srlv on non-R2 CPUs */
11767 ea63e2c3 Nathan Froyd
                if (env->insn_flags & ISA_MIPS32R2) {
11768 ea63e2c3 Nathan Froyd
                    op1 = OPC_ROTRV;
11769 ea63e2c3 Nathan Froyd
                }
11770 ea63e2c3 Nathan Froyd
                /* Fallthrough */
11771 ea63e2c3 Nathan Froyd
            case 0:
11772 ea63e2c3 Nathan Froyd
                gen_shift(env, ctx, op1, rd, rs, rt);
11773 ea63e2c3 Nathan Froyd
                break;
11774 ea63e2c3 Nathan Froyd
            default:
11775 ea63e2c3 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
11776 ea63e2c3 Nathan Froyd
                break;
11777 ea63e2c3 Nathan Froyd
            }
11778 ea63e2c3 Nathan Froyd
            break;
11779 460f00c4 aurel32
        case OPC_SLT:          /* Set on less than */
11780 460f00c4 aurel32
        case OPC_SLTU:
11781 460f00c4 aurel32
            gen_slt(env, op1, rd, rs, rt);
11782 460f00c4 aurel32
            break;
11783 460f00c4 aurel32
        case OPC_AND:          /* Logic*/
11784 460f00c4 aurel32
        case OPC_OR:
11785 460f00c4 aurel32
        case OPC_NOR:
11786 460f00c4 aurel32
        case OPC_XOR:
11787 460f00c4 aurel32
            gen_logic(env, op1, rd, rs, rt);
11788 460f00c4 aurel32
            break;
11789 7a387fff ths
        case OPC_MULT ... OPC_DIVU:
11790 e9c71dd1 ths
            if (sa) {
11791 e9c71dd1 ths
                check_insn(env, ctx, INSN_VR54XX);
11792 e9c71dd1 ths
                op1 = MASK_MUL_VR54XX(ctx->opcode);
11793 e9c71dd1 ths
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11794 e9c71dd1 ths
            } else
11795 e9c71dd1 ths
                gen_muldiv(ctx, op1, rs, rt);
11796 7a387fff ths
            break;
11797 7a387fff ths
        case OPC_JR ... OPC_JALR:
11798 7dca4ad0 Nathan Froyd
            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11799 c9602061 Nathan Froyd
            *is_branch = 1;
11800 c9602061 Nathan Froyd
            break;
11801 7a387fff ths
        case OPC_TGE ... OPC_TEQ: /* Traps */
11802 7a387fff ths
        case OPC_TNE:
11803 7a387fff ths
            gen_trap(ctx, op1, rs, rt, -1);
11804 6af0bf9c bellard
            break;
11805 7a387fff ths
        case OPC_MFHI:          /* Move from HI/LO */
11806 7a387fff ths
        case OPC_MFLO:
11807 7a387fff ths
            gen_HILO(ctx, op1, rd);
11808 6af0bf9c bellard
            break;
11809 7a387fff ths
        case OPC_MTHI:
11810 7a387fff ths
        case OPC_MTLO:          /* Move to HI/LO */
11811 7a387fff ths
            gen_HILO(ctx, op1, rs);
11812 6af0bf9c bellard
            break;
11813 b48cfdff ths
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
11814 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
11815 b48cfdff ths
            MIPS_INVAL("PMON / selsl");
11816 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
11817 b48cfdff ths
#else
11818 a7812ae4 pbrook
            gen_helper_0i(pmon, sa);
11819 b48cfdff ths
#endif
11820 7a387fff ths
            break;
11821 7a387fff ths
        case OPC_SYSCALL:
11822 6af0bf9c bellard
            generate_exception(ctx, EXCP_SYSCALL);
11823 8e0f950d pbrook
            ctx->bstate = BS_STOP;
11824 6af0bf9c bellard
            break;
11825 7a387fff ths
        case OPC_BREAK:
11826 6af0bf9c bellard
            generate_exception(ctx, EXCP_BREAK);
11827 6af0bf9c bellard
            break;
11828 b48cfdff ths
        case OPC_SPIM:
11829 b48cfdff ths
#ifdef MIPS_STRICT_STANDARD
11830 b48cfdff ths
            MIPS_INVAL("SPIM");
11831 b48cfdff ths
            generate_exception(ctx, EXCP_RI);
11832 b48cfdff ths
#else
11833 7a387fff ths
           /* Implemented as RI exception for now. */
11834 7a387fff ths
            MIPS_INVAL("spim (unofficial)");
11835 7a387fff ths
            generate_exception(ctx, EXCP_RI);
11836 b48cfdff ths
#endif
11837 6af0bf9c bellard
            break;
11838 7a387fff ths
        case OPC_SYNC:
11839 ead9360e ths
            /* Treat as NOP. */
11840 6af0bf9c bellard
            break;
11841 4ad40f36 bellard
11842 7a387fff ths
        case OPC_MOVCI:
11843 e189e748 ths
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11844 36d23958 ths
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11845 5e755519 ths
                check_cp1_enabled(ctx);
11846 36d23958 ths
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11847 36d23958 ths
                          (ctx->opcode >> 16) & 1);
11848 36d23958 ths
            } else {
11849 e397ee33 ths
                generate_exception_err(ctx, EXCP_CpU, 1);
11850 36d23958 ths
            }
11851 4ad40f36 bellard
            break;
11852 4ad40f36 bellard
11853 d26bc211 ths
#if defined(TARGET_MIPS64)
11854 7a387fff ths
       /* MIPS64 specific opcodes */
11855 7a387fff ths
        case OPC_DSLL:
11856 324d9e32 aurel32
        case OPC_DSRA:
11857 7a387fff ths
        case OPC_DSLL32:
11858 324d9e32 aurel32
        case OPC_DSRA32:
11859 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
11860 e189e748 ths
            check_mips_64(ctx);
11861 324d9e32 aurel32
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
11862 7a387fff ths
            break;
11863 ea63e2c3 Nathan Froyd
        case OPC_DSRL:
11864 ea63e2c3 Nathan Froyd
            switch ((ctx->opcode >> 21) & 0x1f) {
11865 ea63e2c3 Nathan Froyd
            case 1:
11866 ea63e2c3 Nathan Froyd
                /* drotr is decoded as dsrl on non-R2 CPUs */
11867 ea63e2c3 Nathan Froyd
                if (env->insn_flags & ISA_MIPS32R2) {
11868 ea63e2c3 Nathan Froyd
                    op1 = OPC_DROTR;
11869 ea63e2c3 Nathan Froyd
                }
11870 ea63e2c3 Nathan Froyd
                /* Fallthrough */
11871 ea63e2c3 Nathan Froyd
            case 0:
11872 ea63e2c3 Nathan Froyd
                check_insn(env, ctx, ISA_MIPS3);
11873 ea63e2c3 Nathan Froyd
                check_mips_64(ctx);
11874 ea63e2c3 Nathan Froyd
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11875 ea63e2c3 Nathan Froyd
                break;
11876 ea63e2c3 Nathan Froyd
            default:
11877 ea63e2c3 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
11878 ea63e2c3 Nathan Froyd
                break;
11879 ea63e2c3 Nathan Froyd
            }
11880 ea63e2c3 Nathan Froyd
            break;
11881 ea63e2c3 Nathan Froyd
        case OPC_DSRL32:
11882 ea63e2c3 Nathan Froyd
            switch ((ctx->opcode >> 21) & 0x1f) {
11883 ea63e2c3 Nathan Froyd
            case 1:
11884 ea63e2c3 Nathan Froyd
                /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11885 ea63e2c3 Nathan Froyd
                if (env->insn_flags & ISA_MIPS32R2) {
11886 ea63e2c3 Nathan Froyd
                    op1 = OPC_DROTR32;
11887 ea63e2c3 Nathan Froyd
                }
11888 ea63e2c3 Nathan Froyd
                /* Fallthrough */
11889 ea63e2c3 Nathan Froyd
            case 0:
11890 ea63e2c3 Nathan Froyd
                check_insn(env, ctx, ISA_MIPS3);
11891 ea63e2c3 Nathan Froyd
                check_mips_64(ctx);
11892 ea63e2c3 Nathan Froyd
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11893 ea63e2c3 Nathan Froyd
                break;
11894 ea63e2c3 Nathan Froyd
            default:
11895 ea63e2c3 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
11896 ea63e2c3 Nathan Froyd
                break;
11897 ea63e2c3 Nathan Froyd
            }
11898 ea63e2c3 Nathan Froyd
            break;
11899 7a387fff ths
        case OPC_DADD ... OPC_DSUBU:
11900 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
11901 e189e748 ths
            check_mips_64(ctx);
11902 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
11903 7a387fff ths
            break;
11904 460f00c4 aurel32
        case OPC_DSLLV:
11905 460f00c4 aurel32
        case OPC_DSRAV:
11906 460f00c4 aurel32
            check_insn(env, ctx, ISA_MIPS3);
11907 460f00c4 aurel32
            check_mips_64(ctx);
11908 460f00c4 aurel32
            gen_shift(env, ctx, op1, rd, rs, rt);
11909 460f00c4 aurel32
            break;
11910 ea63e2c3 Nathan Froyd
        case OPC_DSRLV:
11911 ea63e2c3 Nathan Froyd
            switch ((ctx->opcode >> 6) & 0x1f) {
11912 ea63e2c3 Nathan Froyd
            case 1:
11913 ea63e2c3 Nathan Froyd
                /* drotrv is decoded as dsrlv on non-R2 CPUs */
11914 ea63e2c3 Nathan Froyd
                if (env->insn_flags & ISA_MIPS32R2) {
11915 ea63e2c3 Nathan Froyd
                    op1 = OPC_DROTRV;
11916 ea63e2c3 Nathan Froyd
                }
11917 ea63e2c3 Nathan Froyd
                /* Fallthrough */
11918 ea63e2c3 Nathan Froyd
            case 0:
11919 ea63e2c3 Nathan Froyd
                check_insn(env, ctx, ISA_MIPS3);
11920 ea63e2c3 Nathan Froyd
                check_mips_64(ctx);
11921 ea63e2c3 Nathan Froyd
                gen_shift(env, ctx, op1, rd, rs, rt);
11922 ea63e2c3 Nathan Froyd
                break;
11923 ea63e2c3 Nathan Froyd
            default:
11924 ea63e2c3 Nathan Froyd
                generate_exception(ctx, EXCP_RI);
11925 ea63e2c3 Nathan Froyd
                break;
11926 ea63e2c3 Nathan Froyd
            }
11927 ea63e2c3 Nathan Froyd
            break;
11928 7a387fff ths
        case OPC_DMULT ... OPC_DDIVU:
11929 e189e748 ths
            check_insn(env, ctx, ISA_MIPS3);
11930 e189e748 ths
            check_mips_64(ctx);
11931 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
11932 7a387fff ths
            break;
11933 6af0bf9c bellard
#endif
11934 6af0bf9c bellard
        default:            /* Invalid */
11935 6af0bf9c bellard
            MIPS_INVAL("special");
11936 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
11937 6af0bf9c bellard
            break;
11938 6af0bf9c bellard
        }
11939 6af0bf9c bellard
        break;
11940 7a387fff ths
    case OPC_SPECIAL2:
11941 7a387fff ths
        op1 = MASK_SPECIAL2(ctx->opcode);
11942 6af0bf9c bellard
        switch (op1) {
11943 7a387fff ths
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11944 7a387fff ths
        case OPC_MSUB ... OPC_MSUBU:
11945 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
11946 7a387fff ths
            gen_muldiv(ctx, op1, rs, rt);
11947 6af0bf9c bellard
            break;
11948 7a387fff ths
        case OPC_MUL:
11949 e189e748 ths
            gen_arith(env, ctx, op1, rd, rs, rt);
11950 6af0bf9c bellard
            break;
11951 20e1fb52 aurel32
        case OPC_CLO:
11952 20e1fb52 aurel32
        case OPC_CLZ:
11953 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
11954 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
11955 6af0bf9c bellard
            break;
11956 7a387fff ths
        case OPC_SDBBP:
11957 6af0bf9c bellard
            /* XXX: not clear which exception should be raised
11958 6af0bf9c bellard
             *      when in debug mode...
11959 6af0bf9c bellard
             */
11960 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32);
11961 6af0bf9c bellard
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11962 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
11963 6af0bf9c bellard
            } else {
11964 6af0bf9c bellard
                generate_exception(ctx, EXCP_DBp);
11965 6af0bf9c bellard
            }
11966 ead9360e ths
            /* Treat as NOP. */
11967 6af0bf9c bellard
            break;
11968 161f85e6 Aurelien Jarno
        case OPC_DIV_G_2F:
11969 161f85e6 Aurelien Jarno
        case OPC_DIVU_G_2F:
11970 161f85e6 Aurelien Jarno
        case OPC_MULT_G_2F:
11971 161f85e6 Aurelien Jarno
        case OPC_MULTU_G_2F:
11972 161f85e6 Aurelien Jarno
        case OPC_MOD_G_2F:
11973 161f85e6 Aurelien Jarno
        case OPC_MODU_G_2F:
11974 161f85e6 Aurelien Jarno
            check_insn(env, ctx, INSN_LOONGSON2F);
11975 161f85e6 Aurelien Jarno
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11976 161f85e6 Aurelien Jarno
            break;
11977 d26bc211 ths
#if defined(TARGET_MIPS64)
11978 20e1fb52 aurel32
        case OPC_DCLO:
11979 20e1fb52 aurel32
        case OPC_DCLZ:
11980 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64);
11981 e189e748 ths
            check_mips_64(ctx);
11982 7a387fff ths
            gen_cl(ctx, op1, rd, rs);
11983 7a387fff ths
            break;
11984 161f85e6 Aurelien Jarno
        case OPC_DMULT_G_2F:
11985 161f85e6 Aurelien Jarno
        case OPC_DMULTU_G_2F:
11986 161f85e6 Aurelien Jarno
        case OPC_DDIV_G_2F:
11987 161f85e6 Aurelien Jarno
        case OPC_DDIVU_G_2F:
11988 161f85e6 Aurelien Jarno
        case OPC_DMOD_G_2F:
11989 161f85e6 Aurelien Jarno
        case OPC_DMODU_G_2F:
11990 161f85e6 Aurelien Jarno
            check_insn(env, ctx, INSN_LOONGSON2F);
11991 161f85e6 Aurelien Jarno
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11992 161f85e6 Aurelien Jarno
            break;
11993 7a387fff ths
#endif
11994 6af0bf9c bellard
        default:            /* Invalid */
11995 6af0bf9c bellard
            MIPS_INVAL("special2");
11996 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
11997 6af0bf9c bellard
            break;
11998 6af0bf9c bellard
        }
11999 6af0bf9c bellard
        break;
12000 7a387fff ths
    case OPC_SPECIAL3:
12001 2b0233ab ths
        op1 = MASK_SPECIAL3(ctx->opcode);
12002 2b0233ab ths
        switch (op1) {
12003 2b0233ab ths
        case OPC_EXT:
12004 2b0233ab ths
        case OPC_INS:
12005 2b0233ab ths
            check_insn(env, ctx, ISA_MIPS32R2);
12006 2b0233ab ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
12007 2b0233ab ths
            break;
12008 2b0233ab ths
        case OPC_BSHFL:
12009 2b0233ab ths
            check_insn(env, ctx, ISA_MIPS32R2);
12010 2b0233ab ths
            op2 = MASK_BSHFL(ctx->opcode);
12011 49bcf33c aurel32
            gen_bshfl(ctx, op2, rt, rd);
12012 7a387fff ths
            break;
12013 1579a72e ths
        case OPC_RDHWR:
12014 26ebe468 Nathan Froyd
            gen_rdhwr(env, ctx, rt, rd);
12015 1579a72e ths
            break;
12016 ead9360e ths
        case OPC_FORK:
12017 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
12018 6c5c1e20 ths
            {
12019 35fbce2c aurel32
                TCGv t0 = tcg_temp_new();
12020 35fbce2c aurel32
                TCGv t1 = tcg_temp_new();
12021 6c5c1e20 ths
12022 6c5c1e20 ths
                gen_load_gpr(t0, rt);
12023 6c5c1e20 ths
                gen_load_gpr(t1, rs);
12024 a7812ae4 pbrook
                gen_helper_fork(t0, t1);
12025 6c5c1e20 ths
                tcg_temp_free(t0);
12026 6c5c1e20 ths
                tcg_temp_free(t1);
12027 6c5c1e20 ths
            }
12028 ead9360e ths
            break;
12029 ead9360e ths
        case OPC_YIELD:
12030 7385ac0b ths
            check_insn(env, ctx, ASE_MT);
12031 6c5c1e20 ths
            {
12032 35fbce2c aurel32
                TCGv t0 = tcg_temp_new();
12033 6c5c1e20 ths
12034 35fbce2c aurel32
                save_cpu_state(ctx, 1);
12035 6c5c1e20 ths
                gen_load_gpr(t0, rs);
12036 a7812ae4 pbrook
                gen_helper_yield(t0, t0);
12037 6c5c1e20 ths
                gen_store_gpr(t0, rd);
12038 6c5c1e20 ths
                tcg_temp_free(t0);
12039 6c5c1e20 ths
            }
12040 ead9360e ths
            break;
12041 161f85e6 Aurelien Jarno
        case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
12042 161f85e6 Aurelien Jarno
        case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
12043 161f85e6 Aurelien Jarno
        case OPC_MOD_G_2E ... OPC_MODU_G_2E:
12044 161f85e6 Aurelien Jarno
            check_insn(env, ctx, INSN_LOONGSON2E);
12045 161f85e6 Aurelien Jarno
            gen_loongson_integer(ctx, op1, rd, rs, rt);
12046 161f85e6 Aurelien Jarno
            break;
12047 d26bc211 ths
#if defined(TARGET_MIPS64)
12048 1579a72e ths
        case OPC_DEXTM ... OPC_DEXT:
12049 1579a72e ths
        case OPC_DINSM ... OPC_DINS:
12050 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64R2);
12051 e189e748 ths
            check_mips_64(ctx);
12052 1579a72e ths
            gen_bitops(ctx, op1, rt, rs, sa, rd);
12053 7a387fff ths
            break;
12054 1579a72e ths
        case OPC_DBSHFL:
12055 e189e748 ths
            check_insn(env, ctx, ISA_MIPS64R2);
12056 e189e748 ths
            check_mips_64(ctx);
12057 1579a72e ths
            op2 = MASK_DBSHFL(ctx->opcode);
12058 49bcf33c aurel32
            gen_bshfl(ctx, op2, rt, rd);
12059 c6d6dd7c ths
            break;
12060 161f85e6 Aurelien Jarno
        case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
12061 161f85e6 Aurelien Jarno
        case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
12062 161f85e6 Aurelien Jarno
        case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
12063 161f85e6 Aurelien Jarno
            check_insn(env, ctx, INSN_LOONGSON2E);
12064 161f85e6 Aurelien Jarno
            gen_loongson_integer(ctx, op1, rd, rs, rt);
12065 161f85e6 Aurelien Jarno
            break;
12066 7a387fff ths
#endif
12067 7a387fff ths
        default:            /* Invalid */
12068 7a387fff ths
            MIPS_INVAL("special3");
12069 7a387fff ths
            generate_exception(ctx, EXCP_RI);
12070 7a387fff ths
            break;
12071 7a387fff ths
        }
12072 7a387fff ths
        break;
12073 7a387fff ths
    case OPC_REGIMM:
12074 7a387fff ths
        op1 = MASK_REGIMM(ctx->opcode);
12075 7a387fff ths
        switch (op1) {
12076 7a387fff ths
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
12077 7a387fff ths
        case OPC_BLTZAL ... OPC_BGEZALL:
12078 7dca4ad0 Nathan Froyd
            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
12079 c9602061 Nathan Froyd
            *is_branch = 1;
12080 c9602061 Nathan Froyd
            break;
12081 7a387fff ths
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
12082 7a387fff ths
        case OPC_TNEI:
12083 7a387fff ths
            gen_trap(ctx, op1, rs, -1, imm);
12084 7a387fff ths
            break;
12085 7a387fff ths
        case OPC_SYNCI:
12086 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
12087 ead9360e ths
            /* Treat as NOP. */
12088 6af0bf9c bellard
            break;
12089 6af0bf9c bellard
        default:            /* Invalid */
12090 923617a3 ths
            MIPS_INVAL("regimm");
12091 6af0bf9c bellard
            generate_exception(ctx, EXCP_RI);
12092 6af0bf9c bellard
            break;
12093 6af0bf9c bellard
        }
12094 6af0bf9c bellard
        break;
12095 7a387fff ths
    case OPC_CP0:
12096 387a8fe5 ths
        check_cp0_enabled(ctx);
12097 7a387fff ths
        op1 = MASK_CP0(ctx->opcode);
12098 6af0bf9c bellard
        switch (op1) {
12099 7a387fff ths
        case OPC_MFC0:
12100 7a387fff ths
        case OPC_MTC0:
12101 ead9360e ths
        case OPC_MFTR:
12102 ead9360e ths
        case OPC_MTTR:
12103 d26bc211 ths
#if defined(TARGET_MIPS64)
12104 7a387fff ths
        case OPC_DMFC0:
12105 7a387fff ths
        case OPC_DMTC0:
12106 7a387fff ths
#endif
12107 f1aa6320 ths
#ifndef CONFIG_USER_ONLY
12108 932e71cd aurel32
            gen_cp0(env, ctx, op1, rt, rd);
12109 0eaef5aa ths
#endif /* !CONFIG_USER_ONLY */
12110 7a387fff ths
            break;
12111 7a387fff ths
        case OPC_C0_FIRST ... OPC_C0_LAST:
12112 f1aa6320 ths
#ifndef CONFIG_USER_ONLY
12113 932e71cd aurel32
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
12114 0eaef5aa ths
#endif /* !CONFIG_USER_ONLY */
12115 7a387fff ths
            break;
12116 7a387fff ths
        case OPC_MFMC0:
12117 8706c382 ths
#ifndef CONFIG_USER_ONLY
12118 932e71cd aurel32
            {
12119 35fbce2c aurel32
                TCGv t0 = tcg_temp_new();
12120 6c5c1e20 ths
12121 0eaef5aa ths
                op2 = MASK_MFMC0(ctx->opcode);
12122 6c5c1e20 ths
                switch (op2) {
12123 6c5c1e20 ths
                case OPC_DMT:
12124 6c5c1e20 ths
                    check_insn(env, ctx, ASE_MT);
12125 9ed5726c Nathan Froyd
                    gen_helper_dmt(t0);
12126 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
12127 6c5c1e20 ths
                    break;
12128 6c5c1e20 ths
                case OPC_EMT:
12129 6c5c1e20 ths
                    check_insn(env, ctx, ASE_MT);
12130 9ed5726c Nathan Froyd
                    gen_helper_emt(t0);
12131 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
12132 da80682b aurel32
                    break;
12133 6c5c1e20 ths
                case OPC_DVPE:
12134 6c5c1e20 ths
                    check_insn(env, ctx, ASE_MT);
12135 9ed5726c Nathan Froyd
                    gen_helper_dvpe(t0);
12136 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
12137 6c5c1e20 ths
                    break;
12138 6c5c1e20 ths
                case OPC_EVPE:
12139 6c5c1e20 ths
                    check_insn(env, ctx, ASE_MT);
12140 9ed5726c Nathan Froyd
                    gen_helper_evpe(t0);
12141 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
12142 6c5c1e20 ths
                    break;
12143 6c5c1e20 ths
                case OPC_DI:
12144 6c5c1e20 ths
                    check_insn(env, ctx, ISA_MIPS32R2);
12145 867abc7e aurel32
                    save_cpu_state(ctx, 1);
12146 a7812ae4 pbrook
                    gen_helper_di(t0);
12147 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
12148 6c5c1e20 ths
                    /* Stop translation as we may have switched the execution mode */
12149 6c5c1e20 ths
                    ctx->bstate = BS_STOP;
12150 6c5c1e20 ths
                    break;
12151 6c5c1e20 ths
                case OPC_EI:
12152 6c5c1e20 ths
                    check_insn(env, ctx, ISA_MIPS32R2);
12153 867abc7e aurel32
                    save_cpu_state(ctx, 1);
12154 a7812ae4 pbrook
                    gen_helper_ei(t0);
12155 35fbce2c aurel32
                    gen_store_gpr(t0, rt);
12156 6c5c1e20 ths
                    /* Stop translation as we may have switched the execution mode */
12157 6c5c1e20 ths
                    ctx->bstate = BS_STOP;
12158 6c5c1e20 ths
                    break;
12159 6c5c1e20 ths
                default:            /* Invalid */
12160 6c5c1e20 ths
                    MIPS_INVAL("mfmc0");
12161 6c5c1e20 ths
                    generate_exception(ctx, EXCP_RI);
12162 6c5c1e20 ths
                    break;
12163 6c5c1e20 ths
                }
12164 6c5c1e20 ths
                tcg_temp_free(t0);
12165 7a387fff ths
            }
12166 0eaef5aa ths
#endif /* !CONFIG_USER_ONLY */
12167 6af0bf9c bellard
            break;
12168 7a387fff ths
        case OPC_RDPGPR:
12169 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
12170 be24bb4f ths
            gen_load_srsgpr(rt, rd);
12171 ead9360e ths
            break;
12172 7a387fff ths
        case OPC_WRPGPR:
12173 e189e748 ths
            check_insn(env, ctx, ISA_MIPS32R2);
12174 be24bb4f ths
            gen_store_srsgpr(rt, rd);
12175 38121543 ths
            break;
12176 6af0bf9c bellard
        default:
12177 923617a3 ths
            MIPS_INVAL("cp0");
12178 7a387fff ths
            generate_exception(ctx, EXCP_RI);
12179 6af0bf9c bellard
            break;
12180 6af0bf9c bellard
        }
12181 6af0bf9c bellard
        break;
12182 324d9e32 aurel32
    case OPC_ADDI: /* Arithmetic with immediate opcode */
12183 324d9e32 aurel32
    case OPC_ADDIU:
12184 e189e748 ths
         gen_arith_imm(env, ctx, op, rt, rs, imm);
12185 7a387fff ths
         break;
12186 324d9e32 aurel32
    case OPC_SLTI: /* Set on less than with immediate opcode */
12187 324d9e32 aurel32
    case OPC_SLTIU:
12188 324d9e32 aurel32
         gen_slt_imm(env, op, rt, rs, imm);
12189 324d9e32 aurel32
         break;
12190 324d9e32 aurel32
    case OPC_ANDI: /* Arithmetic with immediate opcode */
12191 324d9e32 aurel32
    case OPC_LUI:
12192 324d9e32 aurel32
    case OPC_ORI:
12193 324d9e32 aurel32
    case OPC_XORI:
12194 324d9e32 aurel32
         gen_logic_imm(env, op, rt, rs, imm);
12195 324d9e32 aurel32
         break;
12196 7a387fff ths
    case OPC_J ... OPC_JAL: /* Jump */
12197 7a387fff ths
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12198 7dca4ad0 Nathan Froyd
         gen_compute_branch(ctx, op, 4, rs, rt, offset);
12199 c9602061 Nathan Froyd
         *is_branch = 1;
12200 c9602061 Nathan Froyd
         break;
12201 7a387fff ths
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
12202 7a387fff ths
    case OPC_BEQL ... OPC_BGTZL:
12203 7dca4ad0 Nathan Froyd
         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12204 c9602061 Nathan Froyd
         *is_branch = 1;
12205 c9602061 Nathan Froyd
         break;
12206 7a387fff ths
    case OPC_LB ... OPC_LWR: /* Load and stores */
12207 5c13fdfd Aurelien Jarno
    case OPC_LL:
12208 afa88c3a Aurelien Jarno
         gen_ld(env, ctx, op, rt, rs, imm);
12209 5c13fdfd Aurelien Jarno
         break;
12210 7a387fff ths
    case OPC_SB ... OPC_SW:
12211 7a387fff ths
    case OPC_SWR:
12212 5c13fdfd Aurelien Jarno
         gen_st(ctx, op, rt, rs, imm);
12213 7a387fff ths
         break;
12214 d66c7132 aurel32
    case OPC_SC:
12215 d66c7132 aurel32
         gen_st_cond(ctx, op, rt, rs, imm);
12216 d66c7132 aurel32
         break;
12217 7a387fff ths
    case OPC_CACHE:
12218 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12219 ead9360e ths
        /* Treat as NOP. */
12220 34ae7b51 ths
        break;
12221 7a387fff ths
    case OPC_PREF:
12222 e189e748 ths
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12223 ead9360e ths
        /* Treat as NOP. */
12224 6af0bf9c bellard
        break;
12225 4ad40f36 bellard
12226 923617a3 ths
    /* Floating point (COP1). */
12227 7a387fff ths
    case OPC_LWC1:
12228 7a387fff ths
    case OPC_LDC1:
12229 7a387fff ths
    case OPC_SWC1:
12230 7a387fff ths
    case OPC_SDC1:
12231 26ebe468 Nathan Froyd
        gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12232 6ea83fed bellard
        break;
12233 6ea83fed bellard
12234 7a387fff ths
    case OPC_CP1:
12235 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12236 5e755519 ths
            check_cp1_enabled(ctx);
12237 36d23958 ths
            op1 = MASK_CP1(ctx->opcode);
12238 36d23958 ths
            switch (op1) {
12239 3a95e3a7 ths
            case OPC_MFHC1:
12240 3a95e3a7 ths
            case OPC_MTHC1:
12241 e189e748 ths
                check_insn(env, ctx, ISA_MIPS32R2);
12242 36d23958 ths
            case OPC_MFC1:
12243 36d23958 ths
            case OPC_CFC1:
12244 36d23958 ths
            case OPC_MTC1:
12245 36d23958 ths
            case OPC_CTC1:
12246 e189e748 ths
                gen_cp1(ctx, op1, rt, rd);
12247 e189e748 ths
                break;
12248 d26bc211 ths
#if defined(TARGET_MIPS64)
12249 36d23958 ths
            case OPC_DMFC1:
12250 36d23958 ths
            case OPC_DMTC1:
12251 e189e748 ths
                check_insn(env, ctx, ISA_MIPS3);
12252 36d23958 ths
                gen_cp1(ctx, op1, rt, rd);
12253 36d23958 ths
                break;
12254 e189e748 ths
#endif
12255 fbcc6828 ths
            case OPC_BC1ANY2:
12256 fbcc6828 ths
            case OPC_BC1ANY4:
12257 b8aa4598 ths
                check_cop1x(ctx);
12258 7385ac0b ths
                check_insn(env, ctx, ASE_MIPS3D);
12259 d8a5950a ths
                /* fall through */
12260 d8a5950a ths
            case OPC_BC1:
12261 e189e748 ths
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12262 5a5012ec ths
                                    (rt >> 2) & 0x7, imm << 2);
12263 c9602061 Nathan Froyd
                *is_branch = 1;
12264 c9602061 Nathan Froyd
                break;
12265 36d23958 ths
            case OPC_S_FMT:
12266 36d23958 ths
            case OPC_D_FMT:
12267 36d23958 ths
            case OPC_W_FMT:
12268 36d23958 ths
            case OPC_L_FMT:
12269 5a5012ec ths
            case OPC_PS_FMT:
12270 bf4120ad Nathan Froyd
                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12271 5a5012ec ths
                           (imm >> 8) & 0x7);
12272 36d23958 ths
                break;
12273 36d23958 ths
            default:
12274 923617a3 ths
                MIPS_INVAL("cp1");
12275 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
12276 36d23958 ths
                break;
12277 36d23958 ths
            }
12278 36d23958 ths
        } else {
12279 36d23958 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
12280 6ea83fed bellard
        }
12281 4ad40f36 bellard
        break;
12282 4ad40f36 bellard
12283 4ad40f36 bellard
    /* COP2.  */
12284 7a387fff ths
    case OPC_LWC2:
12285 7a387fff ths
    case OPC_LDC2:
12286 7a387fff ths
    case OPC_SWC2:
12287 7a387fff ths
    case OPC_SDC2:
12288 7a387fff ths
    case OPC_CP2:
12289 7a387fff ths
        /* COP2: Not implemented. */
12290 4ad40f36 bellard
        generate_exception_err(ctx, EXCP_CpU, 2);
12291 4ad40f36 bellard
        break;
12292 4ad40f36 bellard
12293 7a387fff ths
    case OPC_CP3:
12294 36d23958 ths
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12295 5e755519 ths
            check_cp1_enabled(ctx);
12296 36d23958 ths
            op1 = MASK_CP3(ctx->opcode);
12297 36d23958 ths
            switch (op1) {
12298 5a5012ec ths
            case OPC_LWXC1:
12299 5a5012ec ths
            case OPC_LDXC1:
12300 5a5012ec ths
            case OPC_LUXC1:
12301 5a5012ec ths
            case OPC_SWXC1:
12302 5a5012ec ths
            case OPC_SDXC1:
12303 5a5012ec ths
            case OPC_SUXC1:
12304 93b12ccc ths
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12305 5a5012ec ths
                break;
12306 e0c84da7 ths
            case OPC_PREFX:
12307 ead9360e ths
                /* Treat as NOP. */
12308 e0c84da7 ths
                break;
12309 5a5012ec ths
            case OPC_ALNV_PS:
12310 5a5012ec ths
            case OPC_MADD_S:
12311 5a5012ec ths
            case OPC_MADD_D:
12312 5a5012ec ths
            case OPC_MADD_PS:
12313 5a5012ec ths
            case OPC_MSUB_S:
12314 5a5012ec ths
            case OPC_MSUB_D:
12315 5a5012ec ths
            case OPC_MSUB_PS:
12316 5a5012ec ths
            case OPC_NMADD_S:
12317 5a5012ec ths
            case OPC_NMADD_D:
12318 5a5012ec ths
            case OPC_NMADD_PS:
12319 5a5012ec ths
            case OPC_NMSUB_S:
12320 5a5012ec ths
            case OPC_NMSUB_D:
12321 5a5012ec ths
            case OPC_NMSUB_PS:
12322 5a5012ec ths
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12323 5a5012ec ths
                break;
12324 36d23958 ths
            default:
12325 923617a3 ths
                MIPS_INVAL("cp3");
12326 e397ee33 ths
                generate_exception (ctx, EXCP_RI);
12327 36d23958 ths
                break;
12328 36d23958 ths
            }
12329 36d23958 ths
        } else {
12330 e397ee33 ths
            generate_exception_err(ctx, EXCP_CpU, 1);
12331 7a387fff ths
        }
12332 4ad40f36 bellard
        break;
12333 4ad40f36 bellard
12334 d26bc211 ths
#if defined(TARGET_MIPS64)
12335 7a387fff ths
    /* MIPS64 opcodes */
12336 7a387fff ths
    case OPC_LWU:
12337 7a387fff ths
    case OPC_LDL ... OPC_LDR:
12338 7a387fff ths
    case OPC_LLD:
12339 7a387fff ths
    case OPC_LD:
12340 5c13fdfd Aurelien Jarno
        check_insn(env, ctx, ISA_MIPS3);
12341 5c13fdfd Aurelien Jarno
        check_mips_64(ctx);
12342 afa88c3a Aurelien Jarno
        gen_ld(env, ctx, op, rt, rs, imm);
12343 5c13fdfd Aurelien Jarno
        break;
12344 5c13fdfd Aurelien Jarno
    case OPC_SDL ... OPC_SDR:
12345 7a387fff ths
    case OPC_SD:
12346 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
12347 e189e748 ths
        check_mips_64(ctx);
12348 5c13fdfd Aurelien Jarno
        gen_st(ctx, op, rt, rs, imm);
12349 7a387fff ths
        break;
12350 d66c7132 aurel32
    case OPC_SCD:
12351 d66c7132 aurel32
        check_insn(env, ctx, ISA_MIPS3);
12352 d66c7132 aurel32
        check_mips_64(ctx);
12353 d66c7132 aurel32
        gen_st_cond(ctx, op, rt, rs, imm);
12354 d66c7132 aurel32
        break;
12355 324d9e32 aurel32
    case OPC_DADDI:
12356 324d9e32 aurel32
    case OPC_DADDIU:
12357 e189e748 ths
        check_insn(env, ctx, ISA_MIPS3);
12358 e189e748 ths
        check_mips_64(ctx);
12359 e189e748 ths
        gen_arith_imm(env, ctx, op, rt, rs, imm);
12360 7a387fff ths
        break;
12361 6af0bf9c bellard
#endif
12362 7a387fff ths
    case OPC_JALX:
12363 3c824109 Nathan Froyd
        check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
12364 364d4831 Nathan Froyd
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12365 364d4831 Nathan Froyd
        gen_compute_branch(ctx, op, 4, rs, rt, offset);
12366 364d4831 Nathan Froyd
        *is_branch = 1;
12367 364d4831 Nathan Froyd
        break;
12368 7a387fff ths
    case OPC_MDMX:
12369 e189e748 ths
        check_insn(env, ctx, ASE_MDMX);
12370 7a387fff ths
        /* MDMX: Not implemented. */
12371 6af0bf9c bellard
    default:            /* Invalid */
12372 923617a3 ths
        MIPS_INVAL("major opcode");
12373 6af0bf9c bellard
        generate_exception(ctx, EXCP_RI);
12374 6af0bf9c bellard
        break;
12375 6af0bf9c bellard
    }
12376 6af0bf9c bellard
}
12377 6af0bf9c bellard
12378 2cfc5f17 ths
static inline void
12379 820e00f2 ths
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
12380 820e00f2 ths
                                int search_pc)
12381 6af0bf9c bellard
{
12382 278d0702 ths
    DisasContext ctx;
12383 6af0bf9c bellard
    target_ulong pc_start;
12384 6af0bf9c bellard
    uint16_t *gen_opc_end;
12385 a1d1bb31 aliguori
    CPUBreakpoint *bp;
12386 6af0bf9c bellard
    int j, lj = -1;
12387 2e70f6ef pbrook
    int num_insns;
12388 2e70f6ef pbrook
    int max_insns;
12389 c9602061 Nathan Froyd
    int insn_bytes;
12390 c9602061 Nathan Froyd
    int is_branch;
12391 6af0bf9c bellard
12392 93fcfe39 aliguori
    if (search_pc)
12393 93fcfe39 aliguori
        qemu_log("search pc %d\n", search_pc);
12394 4ad40f36 bellard
12395 6af0bf9c bellard
    pc_start = tb->pc;
12396 d42320c2 Aurelien Jarno
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12397 6af0bf9c bellard
    ctx.pc = pc_start;
12398 4ad40f36 bellard
    ctx.saved_pc = -1;
12399 7b270ef2 Nathan Froyd
    ctx.singlestep_enabled = env->singlestep_enabled;
12400 6af0bf9c bellard
    ctx.tb = tb;
12401 6af0bf9c bellard
    ctx.bstate = BS_NONE;
12402 4ad40f36 bellard
    /* Restore delay slot state from the tb context.  */
12403 c068688b j_mayer
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
12404 fd4a04eb ths
    restore_cpu_state(env, &ctx);
12405 932e71cd aurel32
#ifdef CONFIG_USER_ONLY
12406 0eaef5aa ths
        ctx.mem_idx = MIPS_HFLAG_UM;
12407 932e71cd aurel32
#else
12408 0eaef5aa ths
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12409 932e71cd aurel32
#endif
12410 2e70f6ef pbrook
    num_insns = 0;
12411 2e70f6ef pbrook
    max_insns = tb->cflags & CF_COUNT_MASK;
12412 2e70f6ef pbrook
    if (max_insns == 0)
12413 2e70f6ef pbrook
        max_insns = CF_COUNT_MASK;
12414 d12d51d5 aliguori
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
12415 2e70f6ef pbrook
    gen_icount_start();
12416 faf7aaa9 ths
    while (ctx.bstate == BS_NONE) {
12417 72cf2d4f Blue Swirl
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
12418 72cf2d4f Blue Swirl
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
12419 a1d1bb31 aliguori
                if (bp->pc == ctx.pc) {
12420 278d0702 ths
                    save_cpu_state(&ctx, 1);
12421 4ad40f36 bellard
                    ctx.bstate = BS_BRANCH;
12422 a7812ae4 pbrook
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
12423 ce62e5ba ths
                    /* Include the breakpoint location or the tb won't
12424 ce62e5ba ths
                     * be flushed when it must be.  */
12425 ce62e5ba ths
                    ctx.pc += 4;
12426 4ad40f36 bellard
                    goto done_generating;
12427 4ad40f36 bellard
                }
12428 4ad40f36 bellard
            }
12429 4ad40f36 bellard
        }
12430 4ad40f36 bellard
12431 6af0bf9c bellard
        if (search_pc) {
12432 6af0bf9c bellard
            j = gen_opc_ptr - gen_opc_buf;
12433 6af0bf9c bellard
            if (lj < j) {
12434 6af0bf9c bellard
                lj++;
12435 6af0bf9c bellard
                while (lj < j)
12436 6af0bf9c bellard
                    gen_opc_instr_start[lj++] = 0;
12437 6af0bf9c bellard
            }
12438 4ad40f36 bellard
            gen_opc_pc[lj] = ctx.pc;
12439 4ad40f36 bellard
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12440 4ad40f36 bellard
            gen_opc_instr_start[lj] = 1;
12441 2e70f6ef pbrook
            gen_opc_icount[lj] = num_insns;
12442 6af0bf9c bellard
        }
12443 2e70f6ef pbrook
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12444 2e70f6ef pbrook
            gen_io_start();
12445 c9602061 Nathan Froyd
12446 c9602061 Nathan Froyd
        is_branch = 0;
12447 364d4831 Nathan Froyd
        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12448 c9602061 Nathan Froyd
            ctx.opcode = ldl_code(ctx.pc);
12449 c9602061 Nathan Froyd
            insn_bytes = 4;
12450 c9602061 Nathan Froyd
            decode_opc(env, &ctx, &is_branch);
12451 3c824109 Nathan Froyd
        } else if (env->insn_flags & ASE_MICROMIPS) {
12452 3c824109 Nathan Froyd
            ctx.opcode = lduw_code(ctx.pc);
12453 3c824109 Nathan Froyd
            insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12454 364d4831 Nathan Froyd
        } else if (env->insn_flags & ASE_MIPS16) {
12455 364d4831 Nathan Froyd
            ctx.opcode = lduw_code(ctx.pc);
12456 364d4831 Nathan Froyd
            insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12457 c9602061 Nathan Froyd
        } else {
12458 c9602061 Nathan Froyd
            generate_exception(&ctx, EXCP_RI);
12459 3c824109 Nathan Froyd
            ctx.bstate = BS_STOP;
12460 c9602061 Nathan Froyd
            break;
12461 c9602061 Nathan Froyd
        }
12462 c9602061 Nathan Froyd
        if (!is_branch) {
12463 c9602061 Nathan Froyd
            handle_delay_slot(env, &ctx, insn_bytes);
12464 c9602061 Nathan Froyd
        }
12465 c9602061 Nathan Froyd
        ctx.pc += insn_bytes;
12466 c9602061 Nathan Froyd
12467 2e70f6ef pbrook
        num_insns++;
12468 4ad40f36 bellard
12469 7b270ef2 Nathan Froyd
        /* Execute a branch and its delay slot as a single instruction.
12470 7b270ef2 Nathan Froyd
           This is what GDB expects and is consistent with what the
12471 7b270ef2 Nathan Froyd
           hardware does (e.g. if a delay slot instruction faults, the
12472 7b270ef2 Nathan Froyd
           reported PC is the PC of the branch).  */
12473 7b270ef2 Nathan Froyd
        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12474 4ad40f36 bellard
            break;
12475 4ad40f36 bellard
12476 6af0bf9c bellard
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12477 6af0bf9c bellard
            break;
12478 4ad40f36 bellard
12479 faf7aaa9 ths
        if (gen_opc_ptr >= gen_opc_end)
12480 faf7aaa9 ths
            break;
12481 faf7aaa9 ths
12482 2e70f6ef pbrook
        if (num_insns >= max_insns)
12483 2e70f6ef pbrook
            break;
12484 1b530a6d aurel32
12485 1b530a6d aurel32
        if (singlestep)
12486 1b530a6d aurel32
            break;
12487 6af0bf9c bellard
    }
12488 2e70f6ef pbrook
    if (tb->cflags & CF_LAST_IO)
12489 2e70f6ef pbrook
        gen_io_end();
12490 7b270ef2 Nathan Froyd
    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12491 278d0702 ths
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12492 a7812ae4 pbrook
        gen_helper_0i(raise_exception, EXCP_DEBUG);
12493 16c00cb2 ths
    } else {
12494 6958549d aurel32
        switch (ctx.bstate) {
12495 16c00cb2 ths
        case BS_STOP:
12496 df1561e2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
12497 df1561e2 ths
            break;
12498 16c00cb2 ths
        case BS_NONE:
12499 278d0702 ths
            save_cpu_state(&ctx, 0);
12500 16c00cb2 ths
            gen_goto_tb(&ctx, 0, ctx.pc);
12501 16c00cb2 ths
            break;
12502 5a5012ec ths
        case BS_EXCP:
12503 57fec1fe bellard
            tcg_gen_exit_tb(0);
12504 16c00cb2 ths
            break;
12505 5a5012ec ths
        case BS_BRANCH:
12506 5a5012ec ths
        default:
12507 5a5012ec ths
            break;
12508 6958549d aurel32
        }
12509 6af0bf9c bellard
    }
12510 4ad40f36 bellard
done_generating:
12511 2e70f6ef pbrook
    gen_icount_end(tb, num_insns);
12512 6af0bf9c bellard
    *gen_opc_ptr = INDEX_op_end;
12513 6af0bf9c bellard
    if (search_pc) {
12514 6af0bf9c bellard
        j = gen_opc_ptr - gen_opc_buf;
12515 6af0bf9c bellard
        lj++;
12516 6af0bf9c bellard
        while (lj <= j)
12517 6af0bf9c bellard
            gen_opc_instr_start[lj++] = 0;
12518 6af0bf9c bellard
    } else {
12519 6af0bf9c bellard
        tb->size = ctx.pc - pc_start;
12520 2e70f6ef pbrook
        tb->icount = num_insns;
12521 6af0bf9c bellard
    }
12522 6af0bf9c bellard
#ifdef DEBUG_DISAS
12523 d12d51d5 aliguori
    LOG_DISAS("\n");
12524 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12525 93fcfe39 aliguori
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
12526 93fcfe39 aliguori
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
12527 93fcfe39 aliguori
        qemu_log("\n");
12528 6af0bf9c bellard
    }
12529 6af0bf9c bellard
#endif
12530 6af0bf9c bellard
}
12531 6af0bf9c bellard
12532 2cfc5f17 ths
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
12533 6af0bf9c bellard
{
12534 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 0);
12535 6af0bf9c bellard
}
12536 6af0bf9c bellard
12537 2cfc5f17 ths
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
12538 6af0bf9c bellard
{
12539 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 1);
12540 6af0bf9c bellard
}
12541 6af0bf9c bellard
12542 9a78eead Stefan Weil
static void fpu_dump_state(CPUState *env, FILE *f, fprintf_function fpu_fprintf,
12543 8706c382 ths
                           int flags)
12544 6ea83fed bellard
{
12545 6ea83fed bellard
    int i;
12546 5e755519 ths
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12547 5a5012ec ths
12548 2a5612e6 Stefan Weil
#define printfpr(fp)                                                    \
12549 2a5612e6 Stefan Weil
    do {                                                                \
12550 2a5612e6 Stefan Weil
        if (is_fpu64)                                                   \
12551 2a5612e6 Stefan Weil
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
12552 2a5612e6 Stefan Weil
                        " fd:%13g fs:%13g psu: %13g\n",                 \
12553 2a5612e6 Stefan Weil
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
12554 2a5612e6 Stefan Weil
                        (double)(fp)->fd,                               \
12555 2a5612e6 Stefan Weil
                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
12556 2a5612e6 Stefan Weil
                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
12557 2a5612e6 Stefan Weil
        else {                                                          \
12558 2a5612e6 Stefan Weil
            fpr_t tmp;                                                  \
12559 2a5612e6 Stefan Weil
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
12560 2a5612e6 Stefan Weil
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
12561 2a5612e6 Stefan Weil
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
12562 2a5612e6 Stefan Weil
                        " fd:%13g fs:%13g psu:%13g\n",                  \
12563 2a5612e6 Stefan Weil
                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
12564 2a5612e6 Stefan Weil
                        (double)tmp.fd,                                 \
12565 2a5612e6 Stefan Weil
                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
12566 2a5612e6 Stefan Weil
                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
12567 2a5612e6 Stefan Weil
        }                                                               \
12568 6ea83fed bellard
    } while(0)
12569 6ea83fed bellard
12570 5a5012ec ths
12571 9a78eead Stefan Weil
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
12572 9a78eead Stefan Weil
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
12573 f01be154 ths
                get_float_exception_flags(&env->active_fpu.fp_status));
12574 5a5012ec ths
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12575 5a5012ec ths
        fpu_fprintf(f, "%3s: ", fregnames[i]);
12576 f01be154 ths
        printfpr(&env->active_fpu.fpr[i]);
12577 6ea83fed bellard
    }
12578 6ea83fed bellard
12579 6ea83fed bellard
#undef printfpr
12580 6ea83fed bellard
}
12581 6ea83fed bellard
12582 d26bc211 ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12583 c570fd16 ths
/* Debug help: The architecture requires 32bit code to maintain proper
12584 c7e8a937 ths
   sign-extended values on 64bit machines.  */
12585 c570fd16 ths
12586 c570fd16 ths
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12587 c570fd16 ths
12588 8706c382 ths
static void
12589 8706c382 ths
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
12590 9a78eead Stefan Weil
                                fprintf_function cpu_fprintf,
12591 8706c382 ths
                                int flags)
12592 c570fd16 ths
{
12593 c570fd16 ths
    int i;
12594 c570fd16 ths
12595 b5dc7732 ths
    if (!SIGN_EXT_P(env->active_tc.PC))
12596 b5dc7732 ths
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12597 b5dc7732 ths
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
12598 b5dc7732 ths
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12599 b5dc7732 ths
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
12600 b5dc7732 ths
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12601 c570fd16 ths
    if (!SIGN_EXT_P(env->btarget))
12602 3594c774 ths
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12603 c570fd16 ths
12604 c570fd16 ths
    for (i = 0; i < 32; i++) {
12605 b5dc7732 ths
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12606 b5dc7732 ths
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12607 c570fd16 ths
    }
12608 c570fd16 ths
12609 c570fd16 ths
    if (!SIGN_EXT_P(env->CP0_EPC))
12610 3594c774 ths
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12611 5499b6ff Aurelien Jarno
    if (!SIGN_EXT_P(env->lladdr))
12612 5499b6ff Aurelien Jarno
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12613 c570fd16 ths
}
12614 c570fd16 ths
#endif
12615 c570fd16 ths
12616 9a78eead Stefan Weil
void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
12617 6af0bf9c bellard
                     int flags)
12618 6af0bf9c bellard
{
12619 6af0bf9c bellard
    int i;
12620 3b46e624 ths
12621 a7200c9f Stefan Weil
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12622 a7200c9f Stefan Weil
                " LO=0x" TARGET_FMT_lx " ds %04x "
12623 a7200c9f Stefan Weil
                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12624 3d5be870 ths
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12625 3d5be870 ths
                env->hflags, env->btarget, env->bcond);
12626 6af0bf9c bellard
    for (i = 0; i < 32; i++) {
12627 6af0bf9c bellard
        if ((i & 3) == 0)
12628 6af0bf9c bellard
            cpu_fprintf(f, "GPR%02d:", i);
12629 b5dc7732 ths
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12630 6af0bf9c bellard
        if ((i & 3) == 3)
12631 6af0bf9c bellard
            cpu_fprintf(f, "\n");
12632 6af0bf9c bellard
    }
12633 568b600d bellard
12634 3594c774 ths
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
12635 5e755519 ths
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12636 3594c774 ths
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12637 5499b6ff Aurelien Jarno
                env->CP0_Config0, env->CP0_Config1, env->lladdr);
12638 5e755519 ths
    if (env->hflags & MIPS_HFLAG_FPU)
12639 7a387fff ths
        fpu_dump_state(env, f, cpu_fprintf, flags);
12640 d26bc211 ths
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12641 c570fd16 ths
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12642 c570fd16 ths
#endif
12643 6af0bf9c bellard
}
12644 6af0bf9c bellard
12645 39454628 ths
static void mips_tcg_init(void)
12646 39454628 ths
{
12647 f01be154 ths
    int i;
12648 39454628 ths
    static int inited;
12649 39454628 ths
12650 39454628 ths
    /* Initialize various static tables. */
12651 39454628 ths
    if (inited)
12652 6958549d aurel32
        return;
12653 39454628 ths
12654 a7812ae4 pbrook
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12655 f2c94b92 aurel32
    TCGV_UNUSED(cpu_gpr[0]);
12656 bb928dbe aurel32
    for (i = 1; i < 32; i++)
12657 a7812ae4 pbrook
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12658 4b2eb8d2 ths
                                        offsetof(CPUState, active_tc.gpr[i]),
12659 4b2eb8d2 ths
                                        regnames[i]);
12660 a7812ae4 pbrook
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
12661 4b2eb8d2 ths
                                offsetof(CPUState, active_tc.PC), "PC");
12662 4b2eb8d2 ths
    for (i = 0; i < MIPS_DSP_ACC; i++) {
12663 a7812ae4 pbrook
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12664 4b2eb8d2 ths
                                       offsetof(CPUState, active_tc.HI[i]),
12665 4b2eb8d2 ths
                                       regnames_HI[i]);
12666 a7812ae4 pbrook
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12667 4b2eb8d2 ths
                                       offsetof(CPUState, active_tc.LO[i]),
12668 4b2eb8d2 ths
                                       regnames_LO[i]);
12669 a7812ae4 pbrook
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12670 4b2eb8d2 ths
                                        offsetof(CPUState, active_tc.ACX[i]),
12671 4b2eb8d2 ths
                                        regnames_ACX[i]);
12672 4b2eb8d2 ths
    }
12673 a7812ae4 pbrook
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12674 4b2eb8d2 ths
                                     offsetof(CPUState, active_tc.DSPControl),
12675 4b2eb8d2 ths
                                     "DSPControl");
12676 1ba74fb8 aurel32
    bcond = tcg_global_mem_new(TCG_AREG0,
12677 1ba74fb8 aurel32
                               offsetof(CPUState, bcond), "bcond");
12678 a7812ae4 pbrook
    btarget = tcg_global_mem_new(TCG_AREG0,
12679 d077b6f7 ths
                                 offsetof(CPUState, btarget), "btarget");
12680 41db4607 aurel32
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
12681 41db4607 aurel32
                                    offsetof(CPUState, hflags), "hflags");
12682 41db4607 aurel32
12683 a7812ae4 pbrook
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12684 a7812ae4 pbrook
                                      offsetof(CPUState, active_fpu.fcr0),
12685 a7812ae4 pbrook
                                      "fcr0");
12686 a7812ae4 pbrook
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12687 a7812ae4 pbrook
                                       offsetof(CPUState, active_fpu.fcr31),
12688 a7812ae4 pbrook
                                       "fcr31");
12689 39454628 ths
12690 7dd9e556 ths
    /* register helpers */
12691 a7812ae4 pbrook
#define GEN_HELPER 2
12692 7dd9e556 ths
#include "helper.h"
12693 7dd9e556 ths
12694 39454628 ths
    inited = 1;
12695 39454628 ths
}
12696 39454628 ths
12697 aaed909a bellard
#include "translate_init.c"
12698 aaed909a bellard
12699 aaed909a bellard
CPUMIPSState *cpu_mips_init (const char *cpu_model)
12700 6af0bf9c bellard
{
12701 6af0bf9c bellard
    CPUMIPSState *env;
12702 c227f099 Anthony Liguori
    const mips_def_t *def;
12703 6af0bf9c bellard
12704 aaed909a bellard
    def = cpu_mips_find_by_name(cpu_model);
12705 aaed909a bellard
    if (!def)
12706 aaed909a bellard
        return NULL;
12707 7267c094 Anthony Liguori
    env = g_malloc0(sizeof(CPUMIPSState));
12708 aaed909a bellard
    env->cpu_model = def;
12709 51cc2e78 Blue Swirl
    env->cpu_model_str = cpu_model;
12710 aaed909a bellard
12711 173d6cfe bellard
    cpu_exec_init(env);
12712 51cc2e78 Blue Swirl
#ifndef CONFIG_USER_ONLY
12713 51cc2e78 Blue Swirl
    mmu_init(env, def);
12714 51cc2e78 Blue Swirl
#endif
12715 51cc2e78 Blue Swirl
    fpu_init(env, def);
12716 51cc2e78 Blue Swirl
    mvp_init(env, def);
12717 39454628 ths
    mips_tcg_init();
12718 6ae81775 ths
    cpu_reset(env);
12719 0bf46a40 aliguori
    qemu_init_vcpu(env);
12720 6ae81775 ths
    return env;
12721 6ae81775 ths
}
12722 6ae81775 ths
12723 6ae81775 ths
void cpu_reset (CPUMIPSState *env)
12724 6ae81775 ths
{
12725 eca1bdf4 aliguori
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12726 eca1bdf4 aliguori
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12727 eca1bdf4 aliguori
        log_cpu_state(env, 0);
12728 eca1bdf4 aliguori
    }
12729 eca1bdf4 aliguori
12730 6ae81775 ths
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12731 6af0bf9c bellard
    tlb_flush(env, 1);
12732 6ae81775 ths
12733 51cc2e78 Blue Swirl
    /* Reset registers to their default values */
12734 51cc2e78 Blue Swirl
    env->CP0_PRid = env->cpu_model->CP0_PRid;
12735 51cc2e78 Blue Swirl
    env->CP0_Config0 = env->cpu_model->CP0_Config0;
12736 51cc2e78 Blue Swirl
#ifdef TARGET_WORDS_BIGENDIAN
12737 51cc2e78 Blue Swirl
    env->CP0_Config0 |= (1 << CP0C0_BE);
12738 51cc2e78 Blue Swirl
#endif
12739 51cc2e78 Blue Swirl
    env->CP0_Config1 = env->cpu_model->CP0_Config1;
12740 51cc2e78 Blue Swirl
    env->CP0_Config2 = env->cpu_model->CP0_Config2;
12741 51cc2e78 Blue Swirl
    env->CP0_Config3 = env->cpu_model->CP0_Config3;
12742 51cc2e78 Blue Swirl
    env->CP0_Config6 = env->cpu_model->CP0_Config6;
12743 51cc2e78 Blue Swirl
    env->CP0_Config7 = env->cpu_model->CP0_Config7;
12744 2a6e32dd Aurelien Jarno
    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12745 2a6e32dd Aurelien Jarno
                                 << env->cpu_model->CP0_LLAddr_shift;
12746 2a6e32dd Aurelien Jarno
    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12747 51cc2e78 Blue Swirl
    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12748 51cc2e78 Blue Swirl
    env->CCRes = env->cpu_model->CCRes;
12749 51cc2e78 Blue Swirl
    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12750 51cc2e78 Blue Swirl
    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12751 51cc2e78 Blue Swirl
    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12752 51cc2e78 Blue Swirl
    env->current_tc = 0;
12753 51cc2e78 Blue Swirl
    env->SEGBITS = env->cpu_model->SEGBITS;
12754 51cc2e78 Blue Swirl
    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12755 51cc2e78 Blue Swirl
#if defined(TARGET_MIPS64)
12756 51cc2e78 Blue Swirl
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
12757 51cc2e78 Blue Swirl
        env->SEGMask |= 3ULL << 62;
12758 51cc2e78 Blue Swirl
    }
12759 51cc2e78 Blue Swirl
#endif
12760 51cc2e78 Blue Swirl
    env->PABITS = env->cpu_model->PABITS;
12761 51cc2e78 Blue Swirl
    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12762 51cc2e78 Blue Swirl
    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12763 51cc2e78 Blue Swirl
    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12764 51cc2e78 Blue Swirl
    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12765 51cc2e78 Blue Swirl
    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12766 51cc2e78 Blue Swirl
    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12767 51cc2e78 Blue Swirl
    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12768 51cc2e78 Blue Swirl
    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12769 51cc2e78 Blue Swirl
    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12770 51cc2e78 Blue Swirl
    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12771 51cc2e78 Blue Swirl
    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12772 51cc2e78 Blue Swirl
    env->insn_flags = env->cpu_model->insn_flags;
12773 51cc2e78 Blue Swirl
12774 0eaef5aa ths
#if defined(CONFIG_USER_ONLY)
12775 932e71cd aurel32
    env->hflags = MIPS_HFLAG_UM;
12776 df357f0e pbrook
    /* Enable access to the SYNCI_Step register.  */
12777 df357f0e pbrook
    env->CP0_HWREna |= (1 << 1);
12778 91a75935 Nathan Froyd
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12779 91a75935 Nathan Froyd
        env->hflags |= MIPS_HFLAG_FPU;
12780 91a75935 Nathan Froyd
    }
12781 91a75935 Nathan Froyd
#ifdef TARGET_MIPS64
12782 91a75935 Nathan Froyd
    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12783 91a75935 Nathan Froyd
        env->hflags |= MIPS_HFLAG_F64;
12784 91a75935 Nathan Froyd
    }
12785 91a75935 Nathan Froyd
#endif
12786 932e71cd aurel32
#else
12787 932e71cd aurel32
    if (env->hflags & MIPS_HFLAG_BMASK) {
12788 932e71cd aurel32
        /* If the exception was raised from a delay slot,
12789 932e71cd aurel32
           come back to the jump.  */
12790 932e71cd aurel32
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
12791 aa328add ths
    } else {
12792 932e71cd aurel32
        env->CP0_ErrorEPC = env->active_tc.PC;
12793 932e71cd aurel32
    }
12794 932e71cd aurel32
    env->active_tc.PC = (int32_t)0xBFC00000;
12795 51cc2e78 Blue Swirl
    env->CP0_Random = env->tlb->nb_tlb - 1;
12796 51cc2e78 Blue Swirl
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
12797 932e71cd aurel32
    env->CP0_Wired = 0;
12798 671b0f36 Hervé Poussineau
    env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
12799 932e71cd aurel32
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12800 932e71cd aurel32
    /* vectored interrupts not implemented, timer on int 7,
12801 932e71cd aurel32
       no performance counters. */
12802 932e71cd aurel32
    env->CP0_IntCtl = 0xe0000000;
12803 932e71cd aurel32
    {
12804 932e71cd aurel32
        int i;
12805 932e71cd aurel32
12806 932e71cd aurel32
        for (i = 0; i < 7; i++) {
12807 932e71cd aurel32
            env->CP0_WatchLo[i] = 0;
12808 932e71cd aurel32
            env->CP0_WatchHi[i] = 0x80000000;
12809 fd88b6ab ths
        }
12810 932e71cd aurel32
        env->CP0_WatchLo[7] = 0;
12811 932e71cd aurel32
        env->CP0_WatchHi[7] = 0;
12812 fd88b6ab ths
    }
12813 932e71cd aurel32
    /* Count register increments in debug mode, EJTAG version 1 */
12814 932e71cd aurel32
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12815 932e71cd aurel32
    env->hflags = MIPS_HFLAG_CP0;
12816 9e56e756 Edgar E. Iglesias
12817 9e56e756 Edgar E. Iglesias
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
12818 9e56e756 Edgar E. Iglesias
        int i;
12819 9e56e756 Edgar E. Iglesias
12820 9e56e756 Edgar E. Iglesias
        /* Only TC0 on VPE 0 starts as active.  */
12821 9e56e756 Edgar E. Iglesias
        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
12822 9e56e756 Edgar E. Iglesias
            env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
12823 9e56e756 Edgar E. Iglesias
            env->tcs[i].CP0_TCHalt = 1;
12824 9e56e756 Edgar E. Iglesias
        }
12825 9e56e756 Edgar E. Iglesias
        env->active_tc.CP0_TCHalt = 1;
12826 9e56e756 Edgar E. Iglesias
        env->halted = 1;
12827 9e56e756 Edgar E. Iglesias
12828 9e56e756 Edgar E. Iglesias
        if (!env->cpu_index) {
12829 9e56e756 Edgar E. Iglesias
            /* VPE0 starts up enabled.  */
12830 9e56e756 Edgar E. Iglesias
            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
12831 9e56e756 Edgar E. Iglesias
            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
12832 9e56e756 Edgar E. Iglesias
12833 9e56e756 Edgar E. Iglesias
            /* TC0 starts up unhalted.  */
12834 9e56e756 Edgar E. Iglesias
            env->halted = 0;
12835 9e56e756 Edgar E. Iglesias
            env->active_tc.CP0_TCHalt = 0;
12836 9e56e756 Edgar E. Iglesias
            env->tcs[0].CP0_TCHalt = 0;
12837 9e56e756 Edgar E. Iglesias
            /* With thread 0 active.  */
12838 9e56e756 Edgar E. Iglesias
            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
12839 9e56e756 Edgar E. Iglesias
            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
12840 9e56e756 Edgar E. Iglesias
        }
12841 9e56e756 Edgar E. Iglesias
    }
12842 932e71cd aurel32
#endif
12843 51cc2e78 Blue Swirl
#if defined(TARGET_MIPS64)
12844 51cc2e78 Blue Swirl
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
12845 51cc2e78 Blue Swirl
        env->hflags |= MIPS_HFLAG_64;
12846 51cc2e78 Blue Swirl
    }
12847 51cc2e78 Blue Swirl
#endif
12848 6af0bf9c bellard
    env->exception_index = EXCP_NONE;
12849 6af0bf9c bellard
}
12850 d2856f1a aurel32
12851 e87b7cb0 Stefan Weil
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
12852 d2856f1a aurel32
{
12853 b5dc7732 ths
    env->active_tc.PC = gen_opc_pc[pc_pos];
12854 d2856f1a aurel32
    env->hflags &= ~MIPS_HFLAG_BMASK;
12855 d2856f1a aurel32
    env->hflags |= gen_opc_hflags[pc_pos];
12856 d2856f1a aurel32
}