CPUID: Clear ECX register to ensure it will work with EAX=7

Tested on linux only
Add nativeJcpuidVersion()
Only call getCPUVendorID() once in getInfo()
Change all @since to 0.9.25 in hopes it will come true
Tab removal
Javadoc tweaks
This commit is contained in:
zzz
2015-12-16 15:02:03 +00:00
parent 1f4a266c22
commit 1e3e02d1f0
7 changed files with 75 additions and 43 deletions

View File

@@ -1,5 +1,27 @@
#include "jcpuid.h"
/*
* Versions:
*
* 1: Original version
*
* 2: (I2P 0.8.7)
* Add PIC-compatibility
*
* 3: (I2P 0.9.25)
* Added:
* nativeJcpuidVersion()
* Set ECX to 0 to support function 7
*
*/
#define JCPUID_VERSION 3
/* since version 3 */
JNIEXPORT jint JNICALL Java_net_i2p_util_NativeBigInteger_nativeJcpuidVersion
(JNIEnv* env, jclass cls) {
return (jint) JCPUID_VERSION;
}
/**
From: http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well
@@ -52,6 +74,8 @@ JNIEXPORT jobject JNICALL Java_freenet_support_CPUInformation_CPUID_doCPUID
_asm
{
mov eax, iFunction
// When iFunction is 7, ECX must be 0, just set it all the time
mov ecx, 0
cpuid
mov a, eax
mov b, ebx
@@ -76,7 +100,8 @@ JNIEXPORT jobject JNICALL Java_freenet_support_CPUInformation_CPUID_doCPUID
/* 64 bit */
: "=a" (a), "=b" (b), "=c" (c), "=d" (d)
#endif
:"a"(iFunction)
/* When iFunction is 7, ECX must be 0, just set it all the time */
:"a"(iFunction), "c"(0)
: "cc"
);
#endif

View File

@@ -204,7 +204,7 @@ public class CPUID {
}
/**
* @since 0.9.24
* @since 0.9.25
*/
static int getExtendedEBXFeatureFlags()
{
@@ -217,7 +217,7 @@ public class CPUID {
/**
* There's almost nothing in here.
* @since 0.9.24
* @since 0.9.25
*/
static int getExtendedECXFeatureFlags()
{
@@ -274,15 +274,16 @@ public class CPUID {
{
if(!_nativeOk)
throw new UnknownCPUException("Failed to read CPU information from the system. Please verify the existence of the jcpuid dll/so.");
if(getCPUVendorID().equals("CentaurHauls"))
String id = getCPUVendorID();
if(id.equals("CentaurHauls"))
return new VIAInfoImpl();
if(!isX86)
throw new UnknownCPUException("Failed to read CPU information from the system. The CPUID instruction exists on x86 CPU's only");
if(getCPUVendorID().equals("AuthenticAMD"))
if(id.equals("AuthenticAMD"))
return new AMDInfoImpl();
if(getCPUVendorID().equals("GenuineIntel"))
if(id.equals("GenuineIntel"))
return new IntelInfoImpl();
throw new UnknownCPUException("Unknown CPU type: '"+getCPUVendorID()+"'");
throw new UnknownCPUException("Unknown CPU type: '" + id + '\'');
}

View File

@@ -48,7 +48,7 @@ public class CPUIDCPUInfo implements CPUInfo
/**
* @return true iff the CPU supports the AVX instruction set.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasAVX()
{
@@ -59,7 +59,7 @@ public class CPUIDCPUInfo implements CPUInfo
/**
* @return true iff the CPU supports the AVX2 instruction set.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasAVX2() {
return (CPUID.getExtendedEBXFeatureFlags() & (1 << 5)) != 0; //Extended EBX Feature Bit 5
@@ -77,7 +77,7 @@ public class CPUIDCPUInfo implements CPUInfo
* ref: https://en.wikipedia.org/wiki/AVX-512
*
* @return true iff the CPU supports the AVX-512 Foundation instruction set.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasAVX512()
{
@@ -86,7 +86,7 @@ public class CPUIDCPUInfo implements CPUInfo
/**
* @return true iff the CPU supports the ADX instruction set.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasADX()
{
@@ -95,7 +95,7 @@ public class CPUIDCPUInfo implements CPUInfo
/**
* @return true iff the CPU supports TBM.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasTBM()
{
@@ -112,7 +112,7 @@ public class CPUIDCPUInfo implements CPUInfo
/**
* @return true iff the CPU supports the 64-bit support
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasX64() {
return (CPUID.getExtendedEDXCPUFlags() & (1 << 29)) != 0; //Extended EDX Bit 29
@@ -120,7 +120,7 @@ public class CPUIDCPUInfo implements CPUInfo
/**
* @return true iff the CPU supports the BMI1 instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasBMI1() {
return (CPUID.getExtendedEBXFeatureFlags() & (1 << 3)) != 0; // Extended EBX Feature Bit 3
@@ -128,7 +128,7 @@ public class CPUIDCPUInfo implements CPUInfo
/**
* @return true iff the CPU supports the BMI2 instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasBMI2() {
return (CPUID.getExtendedEBXFeatureFlags() & (1 << 8)) != 0; // Extended EBX Feature Bit 8
@@ -136,7 +136,7 @@ public class CPUIDCPUInfo implements CPUInfo
/**
* @return true iff the CPU supports the FMA3 instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasFMA3() {
return (CPUID.getECXCPUFlags() & (1 << 12)) != 0; // ECX Bit 12
@@ -144,22 +144,23 @@ public class CPUIDCPUInfo implements CPUInfo
/**
* @return true iff the CPU supports the MOVBE instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasMOVBE() {
return (CPUID.getECXCPUFlags() & (1 << 22)) != 0; // ECX Bit 22
}
/**
* Also known as LZCNT
* @return true iff the CPU supports the ABM instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasABM() {
return (CPUID.getExtendedECXCPUFlags() & (1 << 5)) != 0; // Extended EBX Bit 5
return (CPUID.getExtendedECXCPUFlags() & (1 << 5)) != 0; // Extended ECX Bit 5
}
@Override
public String getCPUModelString() throws UnknownCPUException {
@Override
public String getCPUModelString() throws UnknownCPUException {
throw new UnknownCPUException("Class CPUIDCPUInfo cannot indentify CPUs");
}
}
}
}

View File

@@ -71,13 +71,13 @@ public interface CPUInfo
/**
* @return true iff the CPU supports the AVX instruction set.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasAVX();
/**
* @return true iff the CPU supports the AVX2 instruction set.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasAVX2();
@@ -93,19 +93,19 @@ public interface CPUInfo
* ref: https://en.wikipedia.org/wiki/AVX-512
*
* @return true iff the CPU supports the AVX-512 Foundation instruction set.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasAVX512();
/**
* @return true iff the CPU supports the ADX instruction set.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasADX();
/**
* @return true iff the CPU supports TBM.
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasTBM();
@@ -117,37 +117,38 @@ public interface CPUInfo
/**
* @return true iff the CPU supports the 64-bit support
* @since 0.9.21
* @since 0.9.25
*/
public boolean hasX64();
/**
* @return true iff the CPU supports the BMI1 instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasBMI1();
/**
* @return true iff the CPU supports the BMI2 instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasBMI2();
/**
* @return true iff the CPU supports the FMA3 instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasFMA3();
/**
* @return true iff the CPU supports the MOVBE instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasMOVBE();
/**
* Also known as LZCNT
* @return true iff the CPU supports the ABM instruction set.
* @since 0.9.24
* @since 0.9.25
*/
public boolean hasABM();
}

View File

@@ -79,6 +79,7 @@ public interface IntelCPUInfo extends CPUInfo {
* Supports the AVX 1 instructions.
* In general, this requires 32nm or smaller process.
* @return true if the CPU implements at least a SandyBridge level instruction/feature set.
* @since 0.9.25
*/
public boolean IsSandyCompatible();
@@ -92,6 +93,7 @@ public interface IntelCPUInfo extends CPUInfo {
* Ivy Bridge is a successor to Sandy Bridge, so use IsSandyCompatible().
*
* @return true if the CPU implements at least a IvyBridge level instruction/feature set.
* @since 0.9.25
*/
public boolean IsIvyCompatible();
@@ -113,6 +115,7 @@ public interface IntelCPUInfo extends CPUInfo {
*
* In general, this requires 22nm or smaller process.
* @return true if the CPU implements at least a Haswell level instruction/feature set.
* @since 0.9.25
*/
public boolean IsHaswellCompatible();
@@ -126,6 +129,7 @@ public interface IntelCPUInfo extends CPUInfo {
* so we do not distribute any. However, this is called from NativeBigInteger.
*
* @return true if the CPU implements at least a Broadwell level instruction/feature set.
* @since 0.9.25
*/
public boolean IsBroadwellCompatible();
}

View File

@@ -376,9 +376,9 @@ class IntelInfoImpl extends CPUIDCPUInfo implements IntelCPUInfo
case 0x3f:
case 0x45:
case 0x46:
CPUIDCPUInfo c = new CPUIDCPUInfo();
CPUIDCPUInfo c = new CPUIDCPUInfo();
if (c.hasAVX2() && c.hasBMI1() && c.hasBMI2() &&
c.hasFMA3() && c.hasMOVBE() && c.hasABM()) {
c.hasFMA3() && c.hasMOVBE() && c.hasABM()) {
isSandyCompatible = true;
isIvyCompatible = true;
isHaswellCompatible = true;

View File

@@ -156,10 +156,10 @@ public class NativeBigInteger extends BigInteger {
/** all libjbibi builds are identical to pentium3, case handled in getMiddleName2() */
private final static String JBIGI_OPTIMIZATION_VIAC32 = "viac32";
/**
* The optimization levels defined here are since 0.9.21. Each of the 32-bit processors below
* The optimization levels defined here are since 0.9.25. Each of the 32-bit processors below
* needs an explicit fallback in getResourceList() or getMiddleName2().
* 64-bit processors will fallback to athlon64 and athlon in getResourceList().
* @since 0.9.21
* @since 0.9.25
*/
private final static String JBIGI_OPTIMIZATION_COREI_SBR = "coreisbr";
private final static String JBIGI_OPTIMIZATION_COREI_HWL = "coreihwl";
@@ -179,7 +179,7 @@ public class NativeBigInteger extends BigInteger {
/**
* ARM
* @since 0.9.21
* @since 0.9.25
*/
private final static String JBIGI_OPTIMIZATION_ARM_ARMV5 = "armv5";
private final static String JBIGI_OPTIMIZATION_ARM_ARMV6 = "armv6";
@@ -192,7 +192,7 @@ public class NativeBigInteger extends BigInteger {
/**
* None, no optimizations. The default fallback for x86.
* @since 0.9.21
* @since 0.9.25
*/
private final static String JBIGI_OPTIMIZATION_X86 = "none";
@@ -561,7 +561,7 @@ public class NativeBigInteger extends BigInteger {
/**
* Set the jbigi and libgmp versions. Call after loading.
* Sets _jbigiVersion, _nativeOk3, and _libGMPVersion.
* @since 0.9.21
* @since 0.9.25
*/
private static void setVersions() {
_jbigiVersion = fetchJbigiVersion();
@@ -1001,12 +1001,12 @@ public class NativeBigInteger extends BigInteger {
_loadStatus = s;
}
/** @since 0.9.21 */
/** @since 0.9.25 */
private static void error(String s) {
error(s, null);
}
/** @since 0.9.21 */
/** @since 0.9.25 */
private static void error(String s, Throwable t) {
if(_doLog) {
System.err.println("ERROR: " + s);