From 94a41ceaad9fc9eb0a6cb0e75a6e2c1a1b55d224 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Mon, 2 Apr 2012 21:24:12 +0000 Subject: [PATCH] Fixes for capabilities checking w.r.t. Power DFP instructions (VEX side). Fixes #297329. (Maynard Johnson, maynardj@us.ibm.com) git-svn-id: svn://svn.valgrind.org/vex/trunk@2272 --- VEX/priv/guest_ppc_toIR.c | 18 ++++++++++++++---- VEX/priv/host_ppc_isel.c | 5 +++-- VEX/priv/main_main.c | 8 ++++++-- VEX/pub/libvex.h | 3 +++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index 85d3b0c311..27c00ad1cb 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -13591,6 +13591,7 @@ DisResult disInstr_PPC_WRK ( Bool allow_FX = False; Bool allow_GX = False; Bool allow_VX = False; // Equates to "supports Power ISA 2.06 + Bool allow_DFP = False; UInt hwcaps = archinfo->hwcaps; Long delta; @@ -13601,12 +13602,14 @@ DisResult disInstr_PPC_WRK ( allow_FX = (0 != (hwcaps & VEX_HWCAPS_PPC64_FX)); allow_GX = (0 != (hwcaps & VEX_HWCAPS_PPC64_GX)); allow_VX = (0 != (hwcaps & VEX_HWCAPS_PPC64_VX)); + allow_DFP = (0 != (hwcaps & VEX_HWCAPS_PPC64_DFP)); } else { allow_F = (0 != (hwcaps & VEX_HWCAPS_PPC32_F)); allow_V = (0 != (hwcaps & VEX_HWCAPS_PPC32_V)); allow_FX = (0 != (hwcaps & VEX_HWCAPS_PPC32_FX)); allow_GX = (0 != (hwcaps & VEX_HWCAPS_PPC32_GX)); allow_VX = (0 != (hwcaps & VEX_HWCAPS_PPC32_VX)); + allow_DFP = (0 != (hwcaps & VEX_HWCAPS_PPC32_DFP)); } /* The running delta */ @@ -13805,7 +13808,7 @@ DisResult disInstr_PPC_WRK ( case 0x202: // dsub - DFP Subtract case 0x22: // dmul - DFP Mult case 0x222: // ddiv - DFP Divide - if (!allow_GX) goto decode_failure; + if (!allow_DFP) goto decode_noDFP; if (dis_dfp_arith( theInstr )) goto decode_success; case 0x3CE: // fcfidus (implemented as native insn) @@ -14029,7 +14032,7 @@ DisResult disInstr_PPC_WRK ( case 0x202: // dsubq - DFP Subtract case 0x22: // dmulq - DFP Mult case 0x222: // ddivq - DFP Divide - if (!allow_GX) goto decode_failure; + if (!allow_DFP) goto decode_noDFP; if (dis_dfp_arithq( theInstr )) goto decode_success; goto decode_failure; @@ -14586,6 +14589,12 @@ DisResult disInstr_PPC_WRK ( vex_printf("disInstr(ppc): " "declined to decode a Graphics-Optional insn.\n"); goto decode_failure; + decode_noDFP: + vassert(!allow_DFP); + vex_printf("disInstr(ppc): " + "declined to decode a Decimal Floating Point insn.\n"); + goto decode_failure; + decode_failure: /* All decode failures end up here. */ @@ -14658,10 +14667,11 @@ DisResult disInstr_PPC ( IRSB* irsb_IN, /* do some sanity checks */ mask32 = VEX_HWCAPS_PPC32_F | VEX_HWCAPS_PPC32_V - | VEX_HWCAPS_PPC32_FX | VEX_HWCAPS_PPC32_GX | VEX_HWCAPS_PPC32_VX; + | VEX_HWCAPS_PPC32_FX | VEX_HWCAPS_PPC32_GX | VEX_HWCAPS_PPC32_VX + | VEX_HWCAPS_PPC32_DFP; mask64 = VEX_HWCAPS_PPC64_V | VEX_HWCAPS_PPC64_FX - | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX; + | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX | VEX_HWCAPS_PPC64_DFP; if (mode64) { vassert((hwcaps_guest & mask32) == 0); diff --git a/VEX/priv/host_ppc_isel.c b/VEX/priv/host_ppc_isel.c index 78b2a08b58..c0e74e47de 100644 --- a/VEX/priv/host_ppc_isel.c +++ b/VEX/priv/host_ppc_isel.c @@ -4610,10 +4610,11 @@ HInstrArray* iselSB_PPC ( IRSB* bb, VexArch arch_host, /* do some sanity checks */ mask32 = VEX_HWCAPS_PPC32_F | VEX_HWCAPS_PPC32_V - | VEX_HWCAPS_PPC32_FX | VEX_HWCAPS_PPC32_GX | VEX_HWCAPS_PPC32_VX; + | VEX_HWCAPS_PPC32_FX | VEX_HWCAPS_PPC32_GX | VEX_HWCAPS_PPC32_VX + | VEX_HWCAPS_PPC32_DFP; mask64 = VEX_HWCAPS_PPC64_V | VEX_HWCAPS_PPC64_FX - | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX; + | VEX_HWCAPS_PPC64_GX | VEX_HWCAPS_PPC64_VX | VEX_HWCAPS_PPC64_DFP; if (mode64) { vassert((hwcaps_host & mask32) == 0); diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index 5b818ae41d..c8777fe554 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -890,6 +890,7 @@ static HChar* show_hwcaps_ppc32 ( UInt hwcaps ) const UInt FX = VEX_HWCAPS_PPC32_FX; const UInt GX = VEX_HWCAPS_PPC32_GX; const UInt VX = VEX_HWCAPS_PPC32_VX; + const UInt DFP = VEX_HWCAPS_PPC32_DFP; UInt c = hwcaps; if (c == 0) return "ppc32-int"; if (c == F) return "ppc32-int-flt"; @@ -900,7 +901,8 @@ static HChar* show_hwcaps_ppc32 ( UInt hwcaps ) if (c == (F|V|FX)) return "ppc32-int-flt-vmx-FX"; if (c == (F|V|GX)) return "ppc32-int-flt-vmx-GX"; if (c == (F|V|FX|GX)) return "ppc32-int-flt-vmx-FX-GX"; - if (c == (F|V|FX|GX|VX)) return "ppc32-int-flt-vmx-FX-GX-VX"; + if (c == (F|V|FX|GX|DFP)) return "ppc32-int-flt-vmx-FX-GX-DFP"; + if (c == (F|V|FX|GX|VX|DFP)) return "ppc32-int-flt-vmx-FX-GX-VX-DFP"; return NULL; } @@ -912,6 +914,7 @@ static HChar* show_hwcaps_ppc64 ( UInt hwcaps ) const UInt FX = VEX_HWCAPS_PPC64_FX; const UInt GX = VEX_HWCAPS_PPC64_GX; const UInt VX = VEX_HWCAPS_PPC64_VX; + const UInt DFP = VEX_HWCAPS_PPC64_DFP; UInt c = hwcaps; if (c == 0) return "ppc64-int-flt"; if (c == FX) return "ppc64-int-flt-FX"; @@ -921,7 +924,8 @@ static HChar* show_hwcaps_ppc64 ( UInt hwcaps ) if (c == (V|FX)) return "ppc64-int-flt-vmx-FX"; if (c == (V|GX)) return "ppc64-int-flt-vmx-GX"; if (c == (V|FX|GX)) return "ppc64-int-flt-vmx-FX-GX"; - if (c == (V|FX|GX|VX)) return "ppc64-int-flt-vmx-FX-GX-VX"; + if (c == (V|FX|GX|DFP)) return "ppc64-int-flt-vmx-FX-GX-DFP"; + if (c == (V|FX|GX|VX|DFP)) return "ppc64-int-flt-vmx-FX-GX-VX-DFP"; return NULL; } diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index a259fcce8e..7b81598778 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -96,6 +96,9 @@ typedef (fres,frsqrte,fsel,stfiwx) */ #define VEX_HWCAPS_PPC64_VX (1<<16) /* Vector-scalar floating-point (VSX); implies ISA 2.06 or higher */ +#define VEX_HWCAPS_PPC32_DFP (1<<17) /* Decimal Floating Point (DFP) -- e.g., dadd */ +#define VEX_HWCAPS_PPC64_DFP (1<<18) /* Decimal Floating Point (DFP) -- e.g., dadd */ + /* s390x: Hardware capability encoding Bits Information -- 2.47.2