mips: rewrite parts of mips_dirtyhelper_rdhwr

The idea behind this change is to be less dependent on build-flags, and
more dependent on runtime environment.
So, if the code is compiled for mips32r1, it should be able to execute
mips32r2 code if the platforms supports it.


git-svn-id: svn://svn.valgrind.org/vex/trunk@3373
This commit is contained in:
Petar Jovanovic
2017-05-16 15:21:35 +00:00
parent 646d0e8b99
commit d9eaeb90fa
3 changed files with 30 additions and 22 deletions

View File

@@ -100,9 +100,7 @@ typedef enum {
#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,

View File

@@ -424,29 +424,35 @@ VexGuestLayout mips64Guest_layout = {
}
};
#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:
@@ -454,8 +460,10 @@ HWord mips_dirtyhelper_rdhwr ( UInt rt, UInt rd )
break;
}
return x;
}
#else
return 0;
#endif
}
#define ASM_VOLATILE_UNARY32(inst) \
__asm__ volatile(".set push" "\n\t" \
@@ -648,7 +656,8 @@ extern UInt mips_dirtyhelper_calculate_FCSR_fp64 ( void* gs, UInt fs, UInt ft,
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
@@ -699,8 +708,6 @@ extern UInt mips_dirtyhelper_calculate_FCSR_fp64 ( void* gs, UInt fs, UInt ft,
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;
@@ -737,7 +744,6 @@ extern UInt mips_dirtyhelper_calculate_FCSR_fp64 ( void* gs, UInt fs, UInt ft,
case TRUNCLD:
ASM_VOLATILE_UNARY64(trunc.l.d)
break;
#endif
case ADDS:
ASM_VOLATILE_BINARY64(add.s)
break;

View File

@@ -15091,29 +15091,31 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
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);
@@ -17299,6 +17301,8 @@ DisResult disInstr_MIPS( IRSB* irsb_IN,
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;