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