From: Petar Jovanovic Date: Tue, 16 May 2017 15:21:35 +0000 (+0000) Subject: mips: rewrite parts of mips_dirtyhelper_rdhwr X-Git-Tag: svn/VALGRIND_3_13_0^2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d9eaeb90facd44d8d53d057cc0b23a78e8326349;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/VEX/priv/guest_mips_defs.h b/VEX/priv/guest_mips_defs.h index a748657b83..5ea213d222 100644 --- a/VEX/priv/guest_mips_defs.h +++ b/VEX/priv/guest_mips_defs.h @@ -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, diff --git a/VEX/priv/guest_mips_helpers.c b/VEX/priv/guest_mips_helpers.c index fdc00bd57d..00a92c3ac7 100644 --- a/VEX/priv/guest_mips_helpers.c +++ b/VEX/priv/guest_mips_helpers.c @@ -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; diff --git a/VEX/priv/guest_mips_toIR.c b/VEX/priv/guest_mips_toIR.c index 46e3824321..a73b5dc344 100644 --- a/VEX/priv/guest_mips_toIR.c +++ b/VEX/priv/guest_mips_toIR.c @@ -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;