#define MIPS_IEND Iend_BE
#endif
-#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
-extern HWord mips_dirtyhelper_rdhwr ( UInt rt, UInt rd );
-#endif
+extern HWord mips_dirtyhelper_rdhwr ( UInt rd );
/* Calculate FCSR in fp32 mode. */
extern UInt mips_dirtyhelper_calculate_FCSR_fp32 ( void* guest_state, UInt fs,
}
};
-#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
-HWord mips_dirtyhelper_rdhwr ( UInt rt, UInt rd )
+#define ASM_VOLATILE_RDHWR(opcode) \
+ __asm__ __volatile__(".word 0x7C02003B | "#opcode" << 11 \n\t" \
+ : "+r" (x) : : \
+ )
+
+HWord mips_dirtyhelper_rdhwr ( UInt rd )
{
- HWord x = 0;
+#if defined(__mips__)
+ register HWord x __asm__("v0") = 0;
+
switch (rd) {
case 0: /* x = CPUNum() */
- __asm__ __volatile__("rdhwr %0, $0\n\t" : "=r" (x) );
+ ASM_VOLATILE_RDHWR(0); /* rdhwr v0, $0 */
break;
case 1: /* x = SYNCI_Step() */
- __asm__ __volatile__("rdhwr %0, $1\n\t" : "=r" (x) );
+ ASM_VOLATILE_RDHWR(1); /* rdhwr v0, $1 */
break;
case 2: /* x = CC() */
- __asm__ __volatile__("rdhwr %0, $2\n\t" : "=r" (x) );
+ ASM_VOLATILE_RDHWR(2); /* rdhwr v0, $2 */
break;
case 3: /* x = CCRes() */
- __asm__ __volatile__("rdhwr %0, $3\n\t" : "=r" (x) );
+ ASM_VOLATILE_RDHWR(3); /* rdhwr v0, $3 */
break;
case 31: /* x = CVMX_get_cycles() */
- __asm__ __volatile__("rdhwr %0, $31\n\t" : "=r" (x) );
+ ASM_VOLATILE_RDHWR(31); /* rdhwr v0, $31 */
break;
default:
break;
}
return x;
-}
+#else
+ return 0;
#endif
+}
#define ASM_VOLATILE_UNARY32(inst) \
__asm__ volatile(".set push" "\n\t" \
flt_op inst )
{
UInt ret = 0;
-#if defined(__mips__)
+#if defined(__mips__) && ((__mips == 64) || \
+ (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)))
#if defined(VGA_mips32)
VexGuestMIPS32State* guest_state = (VexGuestMIPS32State*)gs;
#else
case ROUNDWS:
ASM_VOLATILE_UNARY64(round.w.s)
break;
-#if ((__mips == 32) && defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) \
- || (__mips == 64)
case CEILLS:
ASM_VOLATILE_UNARY64(ceil.l.s)
break;
case TRUNCLD:
ASM_VOLATILE_UNARY64(trunc.l.d)
break;
-#endif
case ADDS:
ASM_VOLATILE_BINARY64(add.s)
break;
goto decode_failure;;
}
break;
- case 0x3B: { /* RDHWR */
+ case 0x3B: /* RDHWR */
DIP("rdhwr r%u, r%u", rt, rd);
+ if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps) ||
+ (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_BROADCOM)) {
if (rd == 29) {
putIReg(rt, getULR());
-#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
} else if (rd <= 3
|| (rd == 31
&& VEX_MIPS_COMP_ID(archinfo->hwcaps)
== VEX_PRID_COMP_CAVIUM)) {
- IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd));
+ IRExpr** arg = mkIRExprVec_1(mkU32(rd));
IRTemp val = newTemp(ty);
IRDirty *d = unsafeIRDirty_1_N(val,
0,
"mips_dirtyhelper_rdhwr",
&mips_dirtyhelper_rdhwr,
- args);
+ arg);
stmt(IRStmt_Dirty(d));
putIReg(rt, mkexpr(val));
-#endif
} else
goto decode_failure;
- break;
+ } else {
+ ILLEGAL_INSTRUCTON;
}
+ break;
case 0x04: /* INS */
msb = get_msb(cins);
lsb = get_lsb(cins);
mode64 = guest_arch != VexArchMIPS32;
fp_mode64 = abiinfo->guest_mips_fp_mode64;
+ vassert(VEX_MIPS_HOST_FP_MODE(archinfo->hwcaps) >= fp_mode64);
+
guest_code = guest_code_IN;
irsb = irsb_IN;
host_endness = host_endness_IN;