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