|
From: <sv...@va...> - 2017-05-08 15:32:33
|
Author: petarj
Date: Mon May 8 16:32:25 2017
New Revision: 3362
Log:
mips: improve support for RDHWR instruction
Add support for reading CPUNum, CC and CCRes registers using RDHWR.
This is a fix for KDE #379473.
Patch by Aleksandar Rikalo.
Modified:
trunk/priv/guest_mips_defs.h
trunk/priv/guest_mips_helpers.c
trunk/priv/guest_mips_toIR.c
Modified: trunk/priv/guest_mips_defs.h
==============================================================================
--- trunk/priv/guest_mips_defs.h (original)
+++ trunk/priv/guest_mips_defs.h Mon May 8 16:32:25 2017
@@ -101,8 +101,7 @@
#endif
#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
-extern UInt mips32_dirtyhelper_rdhwr ( UInt rt, UInt rd );
-extern ULong mips64_dirtyhelper_rdhwr ( ULong rt, ULong rd );
+extern HWord mips_dirtyhelper_rdhwr ( UInt rt, UInt rd );
#endif
/* Calculate FCSR in fp32 mode. */
Modified: trunk/priv/guest_mips_helpers.c
==============================================================================
--- trunk/priv/guest_mips_helpers.c (original)
+++ trunk/priv/guest_mips_helpers.c Mon May 8 16:32:25 2017
@@ -425,31 +425,24 @@
};
#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
-UInt mips32_dirtyhelper_rdhwr ( UInt rt, UInt rd )
+HWord mips_dirtyhelper_rdhwr ( UInt rt, UInt rd )
{
- UInt x = 0;
+ HWord x = 0;
switch (rd) {
- case 1: /* x = SYNCI_StepSize() */
- __asm__ __volatile__("rdhwr %0, $1\n\t" : "=r" (x) );
+ case 0: /* x = CPUNum() */
+ __asm__ __volatile__("rdhwr %0, $0\n\t" : "=r" (x) );
break;
- case 31: /* x = CVMX_get_cycles() */
- __asm__ __volatile__("rdhwr %0, $31\n\t" : "=r" (x) );
+ case 1: /* x = SYNCI_Step() */
+ __asm__ __volatile__("rdhwr %0, $1\n\t" : "=r" (x) );
break;
- default:
- vassert(0);
+ case 2: /* x = CC() */
+ __asm__ __volatile__("rdhwr %0, $2\n\t" : "=r" (x) );
break;
- }
- return x;
-}
-ULong mips64_dirtyhelper_rdhwr ( ULong rt, ULong rd )
-{
- ULong x = 0;
- switch (rd) {
- case 1: /* x = SYNCI_StepSize() */
- __asm__ __volatile__("rdhwr %0, $1\n\t" : "=r" (x) );
+ case 3: /* x = CCRes() */
+ __asm__ __volatile__("rdhwr %0, $3\n\t" : "=r" (x) );
break;
case 31: /* x = CVMX_get_cycles() */
Modified: trunk/priv/guest_mips_toIR.c
==============================================================================
--- trunk/priv/guest_mips_toIR.c (original)
+++ trunk/priv/guest_mips_toIR.c Mon May 8 16:32:25 2017
@@ -15096,31 +15096,19 @@
if (rd == 29) {
putIReg(rt, getULR());
#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
- } else if (rd == 1
+ } else if (rd <= 3
|| (rd == 31
&& VEX_MIPS_COMP_ID(archinfo->hwcaps)
== VEX_PRID_COMP_CAVIUM)) {
- if (mode64) {
- IRTemp val = newTemp(Ity_I64);
- IRExpr** args = mkIRExprVec_2 (mkU64(rt), mkU64(rd));
- IRDirty *d = unsafeIRDirty_1_N(val,
- 0,
- "mips64_dirtyhelper_rdhwr",
- &mips64_dirtyhelper_rdhwr,
- args);
- stmt(IRStmt_Dirty(d));
- putIReg(rt, mkexpr(val));
- } else {
- IRTemp val = newTemp(Ity_I32);
- IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd));
- IRDirty *d = unsafeIRDirty_1_N(val,
- 0,
- "mips32_dirtyhelper_rdhwr",
- &mips32_dirtyhelper_rdhwr,
- args);
- stmt(IRStmt_Dirty(d));
- putIReg(rt, mkexpr(val));
- }
+ IRExpr** args = mkIRExprVec_2 (mkU32(rt), mkU32(rd));
+ IRTemp val = newTemp(ty);
+ IRDirty *d = unsafeIRDirty_1_N(val,
+ 0,
+ "mips_dirtyhelper_rdhwr",
+ &mips_dirtyhelper_rdhwr,
+ args);
+ stmt(IRStmt_Dirty(d));
+ putIReg(rt, mkexpr(val));
#endif
} else
goto decode_failure;
|