From 0e6e90baf0ec18bf318754ab7b42f0f7b42c9031 Mon Sep 17 00:00:00 2001 From: dev Date: Tue, 15 Dec 2015 05:29:58 +0000 Subject: [PATCH] Cleaned up BMI1/BMI2/AVX2/FMA3/MOVBE/ABM support. --- .../freenet/support/CPUInformation/CPUID.java | 6 ++- .../support/CPUInformation/CPUIDCPUInfo.java | 54 ++++++++++++++++--- .../support/CPUInformation/CPUInfo.java | 35 ++++++++++-- .../support/CPUInformation/IntelInfoImpl.java | 32 ++--------- 4 files changed, 85 insertions(+), 42 deletions(-) diff --git a/core/java/src/freenet/support/CPUInformation/CPUID.java b/core/java/src/freenet/support/CPUInformation/CPUID.java index 1a15464c0e..a4468ddd6c 100644 --- a/core/java/src/freenet/support/CPUInformation/CPUID.java +++ b/core/java/src/freenet/support/CPUInformation/CPUID.java @@ -324,7 +324,6 @@ public class CPUID { System.out.println("\n **More CPUInfo**"); System.out.println("CPU model string: " + c.getCPUModelString()); System.out.println("CPU has MMX: " + c.hasMMX()); - System.out.println("CPU has BMI2: " + c.hasBMI2()); System.out.println("CPU has SSE: " + c.hasSSE()); System.out.println("CPU has SSE2: " + c.hasSSE2()); System.out.println("CPU has SSE3: " + c.hasSSE3()); @@ -336,6 +335,11 @@ public class CPUID { System.out.println("CPU has AVX512: " + c.hasAVX512()); System.out.println("CPU has ADX: " + c.hasADX()); System.out.println("CPU has TBM: " + c.hasTBM()); + System.out.println("CPU has BMI1: " + c.hasBMI1()); + System.out.println("CPU has BMI2: " + c.hasBMI2()); + System.out.println("CPU has FMA3: " + c.hasFMA3()); + System.out.println("CPU has MOVBE: " + c.hasMOVBE()); + System.out.println("CPU has ABM: " + c.hasABM()); if(c instanceof IntelCPUInfo){ System.out.println("\n **Intel-info**"); System.out.println("Is PII-compatible: "+((IntelCPUInfo)c).IsPentium2Compatible()); diff --git a/core/java/src/freenet/support/CPUInformation/CPUIDCPUInfo.java b/core/java/src/freenet/support/CPUInformation/CPUIDCPUInfo.java index fa268a03f5..cc835d8f0c 100644 --- a/core/java/src/freenet/support/CPUInformation/CPUIDCPUInfo.java +++ b/core/java/src/freenet/support/CPUInformation/CPUIDCPUInfo.java @@ -17,10 +17,6 @@ abstract class CPUIDCPUInfo implements CPUInfo return (CPUID.getEDXCPUFlags() & (1 << 23)) != 0; //EDX Bit 23 } - public boolean hasBMI2(){ - return (CPUID.getExtendedEBXFeatureFlags() & (1 << 8)) != 0; // Extended EBX Bit 8 - } - public boolean hasSSE(){ return (CPUID.getEDXCPUFlags() & (1 << 25)) != 0; //EDX Bit 25 } @@ -65,9 +61,9 @@ abstract class CPUIDCPUInfo implements CPUInfo * @return true iff the CPU supports the AVX2 instruction set. * @since 0.9.21 */ - public boolean hasAVX2() - { - return (CPUID.getExtendedEBXFeatureFlags() & (1 << 5)) != 0; //Extended EBX Bit 5 + public boolean hasAVX2() { + return this.hasABM() && + (CPUID.getExtendedEBXFeatureFlags() & (1 << 5)) != 0; //Extended EBX Feature Bit 5 } /** @@ -122,4 +118,48 @@ abstract class CPUIDCPUInfo implements CPUInfo public boolean hasX64() { return (CPUID.getExtendedEDXCPUFlags() & (1 << 29)) != 0; //Extended EDX Bit 29 } + + /** + * @return true iff the CPU supports the BMI1 instruction set. + * @since 0.9.24 + */ + public boolean hasBMI1() { + return this.hasABM() && + (CPUID.getExtendedEBXFeatureFlags() & (1 << 3)) != 0; // Extended EBX Feature Bit 3 + } + + /** + * @return true iff the CPU supports the BMI2 instruction set. + * @since 0.9.24 + */ + public boolean hasBMI2() { + return this.hasABM() && + (CPUID.getExtendedEBXFeatureFlags() & (1 << 8)) != 0; // Extended EBX Feature Bit 8 + } + + /** + * @return true iff the CPU supports the FMA3 instruction set. + * @since 0.9.24 + */ + public boolean hasFMA3() { + return (CPUID.getECXCPUFlags() & (1 << 12)) != 0; // ECX Bit 12 + } + + /** + * @return true iff the CPU supports the MOVBE instruction set. + * @since 0.9.24 + */ + public boolean hasMOVBE() { + return (CPUID.getECXCPUFlags() & (1 << 22)) != 0; // ECX Bit 22 + } + + /** + * @return true iff the CPU supports the ABM instruction set. + * @since 0.9.24 + */ + public boolean hasABM() { + return this.hasFMA3() && + this.hasMOVBE() && + (CPUID.getExtendedECXCPUFlags() & (1 << 5)) != 0; // Extended EBX Bit 5 + } } diff --git a/core/java/src/freenet/support/CPUInformation/CPUInfo.java b/core/java/src/freenet/support/CPUInformation/CPUInfo.java index 7531e05722..0076e56f85 100644 --- a/core/java/src/freenet/support/CPUInformation/CPUInfo.java +++ b/core/java/src/freenet/support/CPUInformation/CPUInfo.java @@ -36,11 +36,6 @@ public interface CPUInfo */ public boolean hasMMX(); - /** - * @return true iff the CPU supports the BMI2 instruction set. - */ - public boolean hasBMI2(); - /** * @return true iff the CPU supports the SSE instruction set. */ @@ -125,4 +120,34 @@ public interface CPUInfo * @since 0.9.21 */ public boolean hasX64(); + + /** + * @return true iff the CPU supports the BMI1 instruction set. + * @since 0.9.24 + */ + public boolean hasBMI1(); + + /** + * @return true iff the CPU supports the BMI2 instruction set. + * @since 0.9.24 + */ + public boolean hasBMI2(); + + /** + * @return true iff the CPU supports the FMA3 instruction set. + * @since 0.9.24 + */ + public boolean hasFMA3(); + + /** + * @return true iff the CPU supports the MOVBE instruction set. + * @since 0.9.24 + */ + public boolean hasMOVBE(); + + /** + * @return true iff the CPU supports the ABM instruction set. + * @since 0.9.24 + */ + public boolean hasABM(); } diff --git a/core/java/src/freenet/support/CPUInformation/IntelInfoImpl.java b/core/java/src/freenet/support/CPUInformation/IntelInfoImpl.java index dd50f4b7e1..57f33b26ee 100644 --- a/core/java/src/freenet/support/CPUInformation/IntelInfoImpl.java +++ b/core/java/src/freenet/support/CPUInformation/IntelInfoImpl.java @@ -382,34 +382,8 @@ class IntelInfoImpl extends CPUIDCPUInfo implements IntelCPUInfo case 0x3f: case 0x45: case 0x46: - boolean hasNewInstructions = false; - int reg = CPUID.getECXCPUFlags(); - boolean hasFMA3 = (reg & (1 << 12)) != 0; - boolean hasMOVBE = (reg & (1 << 22)) != 0; - // AVX is implied by AVX2, so we don't need to check the value here, - // but we will need it below to enable Sandy Bridge if the Haswell checks fail. - // This is the same as hasAVX(). - boolean hasAVX = (reg & (1 << 28)) != 0 && (reg & (1 << 27)) != 0; - //System.out.println("FMA3 MOVBE: " + - // hasFMA3 + ' ' + hasMOVBE); - if (hasFMA3 && hasMOVBE) { - reg = CPUID.getExtendedECXCPUFlags(); - boolean hasABM = (reg & (1 << 5)) != 0; // aka LZCNT - //System.out.println("FMA3 MOVBE ABM: " + - // hasFMA3 + ' ' + hasMOVBE + ' ' + hasABM); - if (hasABM) { - reg = CPUID.getExtendedEBXFeatureFlags(); - boolean hasAVX2 = (reg & (1 << 5)) != 0; - boolean hasBMI1 = (reg & (1 << 3)) != 0; - boolean hasBMI2 = (reg & (1 << 8)) != 0; - //System.out.println("FMA3 MOVBE ABM AVX2 BMI1 BMI2: " + - // hasFMA3 + ' ' + hasMOVBE + ' ' + hasABM + ' ' + - // hasAVX2 + ' ' + hasBMI1 + ' ' + hasBMI2); - if (hasAVX2 && hasBMI1 && hasBMI2) - hasNewInstructions = true; - } - } - if (hasNewInstructions) { + CPUInfo c = CPUID.getInfo(); + if (c.hasAVX2() && c.hasBMI1() && c.hasBMI2()) { isSandyCompatible = true; isIvyCompatible = true; isHaswellCompatible = true; @@ -417,7 +391,7 @@ class IntelInfoImpl extends CPUIDCPUInfo implements IntelCPUInfo } else { // This processor is "corei" compatible, as we define it, // i.e. SSE4.2 but not necessarily AVX. - if (hasAVX) { + if (c.hasAVX()) { isSandyCompatible = true; isIvyCompatible = true; modelString = "Haswell Celeron/Pentium w/ AVX model " + model;