From 30933c60156c67a9624fefae2be6504300ce71bb Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 30 Jan 2015 07:04:39 +0100 Subject: Bug 1122: Add AArch64 support (Android, GNU/Linux and in general) - Add AArch64 detection via - Elf Parser - Android properties - Java properties - Android: Validate CPUType.Family _and_ ABIType - MachineDescription - Remove redundant Type ID and its field - Reuse X86_64_UNIX for AArch64 (static config) New ARCH 'aarch64' for ant: armv8a aarch64 New CPUType.ARM64 (ARM): java: os.arch aarch64 arm64 New CPUType.ARMv8_A (ARM): java: os.arch armv8-a arm64-v8a New ABIType: EABI_AARCH64 --- src/java/com/jogamp/common/os/AndroidVersion.java | 11 +++- .../com/jogamp/common/os/MachineDescription.java | 57 +++++------------ src/java/com/jogamp/common/os/Platform.java | 15 +++-- .../common/os/MachineDescriptionRuntime.java | 6 +- src/java/jogamp/common/os/PlatformPropsImpl.java | 72 ++++++++++++++-------- 5 files changed, 86 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/java/com/jogamp/common/os/AndroidVersion.java b/src/java/com/jogamp/common/os/AndroidVersion.java index adfb1ef..0e30602 100644 --- a/src/java/com/jogamp/common/os/AndroidVersion.java +++ b/src/java/com/jogamp/common/os/AndroidVersion.java @@ -85,10 +85,16 @@ public class AndroidVersion { private static final CPUType getCPUTypeImpl(final String cpuABI) { if( null == cpuABI ) { return null; + } else if( cpuABI.equals("armv8-a") || + cpuABI.equals("arm64-v8a") ) { + return CPUType.ARMv8_A; + } else if( cpuABI.equals("aarch64") || + cpuABI.startsWith("arm64") ) { + return CPUType.ARM64; } else if( cpuABI.equals("armeabi-v7a") ) { return CPUType.ARMv7; } else if( cpuABI.equals("armeabi") || - cpuABI.startsWith("arm") ) { // last chance .. + cpuABI.startsWith("arm") ) { // last 32bit chance .. return CPUType.ARM; } else if( cpuABI.equals("x86") ) { return CPUType.X86_32; @@ -103,6 +109,9 @@ public class AndroidVersion { return null; } else if( CPUFamily.ARM != cpuType.family ) { return ABIType.GENERIC_ABI; + } else if( CPUType.ARM64 == cpuType || + CPUType.ARMv8_A == cpuType ) { + return ABIType.EABI_AARCH64; } return ABIType.EABI_GNU_ARMEL; // FIXME: How will they name ABIType.EABI_GNU_ARMHF } diff --git a/src/java/com/jogamp/common/os/MachineDescription.java b/src/java/com/jogamp/common/os/MachineDescription.java index ca9819a..a9a46b2 100644 --- a/src/java/com/jogamp/common/os/MachineDescription.java +++ b/src/java/com/jogamp/common/os/MachineDescription.java @@ -46,29 +46,6 @@ import jogamp.common.os.PlatformPropsImpl; * For alignment and size see {@link com.jogamp.gluegen} */ public class MachineDescription { - public enum ID { - /** {@link Platform.CPUType#ARM} EABI Little Endian */ - ARMle_EABI(Platform.CPUType.ARM), - /** {@link Platform.CPUType#X86_32} Little Endian Unix */ - X86_32_UNIX(Platform.CPUType.X86_32), - /** {@link Platform.CPUType#X86_64} Little Endian Unix */ - X86_64_UNIX(Platform.CPUType.X86_64), - /** {@link Platform.CPUType#X86_32} Little Endian MacOS (Special case gcc4/OSX) */ - X86_32_MACOS(Platform.CPUType.X86_32), - /** {@link Platform.CPUType#X86_64} Little Endian MacOS */ - X86_32_WINDOWS(Platform.CPUType.X86_32), - /** {@link Platform.CPUType#X86_64} Little Endian Windows */ - X86_64_WINDOWS(Platform.CPUType.X86_64), - /** {@link Platform.CPUType#SPARC_32} Big Endian Solaris */ - SPARC_32_SUNOS(Platform.CPUType.SPARC_32); - - public final Platform.CPUType cpu; - - ID(final Platform.CPUType cpu){ - this.cpu = cpu; - } - } - /* arch os int, long, float, doubl, ldoubl, ptr, page */ private final static int[] size_armeabi = { 4, 4, 4, 8, 8, 4, 4096 }; private final static int[] size_x86_32_unix = { 4, 4, 4, 8, 12, 4, 4096 }; @@ -88,26 +65,24 @@ public class MachineDescription { private final static int[] align_sparc_32_sunos = { 1, 2, 4, 8, 4, 4, 4, 8, 8, 4 }; public enum StaticConfig { - /** {@link MachineDescription.ID#ARMle_EABI } */ - ARMle_EABI(ID.ARMle_EABI, true, size_armeabi, align_armeabi), - /** {@link MachineDescription.ID#X86_32_UNIX } */ - X86_32_UNIX(ID.X86_32_UNIX, true, size_x86_32_unix, align_x86_32_unix), - /** {@link MachineDescription.ID#X86_64_UNIX } */ - X86_64_UNIX(ID.X86_64_UNIX, true, size_x86_64_unix, align_x86_64_unix), - /** {@link MachineDescription.ID#X86_32_MACOS } */ - X86_32_MACOS(ID.X86_32_MACOS, true, size_x86_32_macos, align_x86_32_macos), - /** {@link MachineDescription.ID#X86_32_WINDOWS } */ - X86_32_WINDOWS(ID.X86_32_WINDOWS, true, size_x86_32_windows, align_x86_32_windows), - /** {@link MachineDescription.ID#X86_64_WINDOWS } */ - X86_64_WINDOWS(ID.X86_64_WINDOWS, true, size_x86_64_windows, align_x86_64_windows), - /** {@link MachineDescription.ID#SPARC_32_SUNOS } */ - SPARC_32_SUNOS(ID.SPARC_32_SUNOS, false, size_sparc_32_sunos, align_sparc_32_sunos); - - public final ID id; + /** {@link Platform.CPUType#ARM} EABI Little Endian */ + ARMle_EABI(true, size_armeabi, align_armeabi), + /** {@link Platform.CPUType#X86_32} Little Endian Unix */ + X86_32_UNIX(true, size_x86_32_unix, align_x86_32_unix), + /** {@link Platform.CPUType#X86_64} Little Endian Unix, {@link Platform.CPUType#ARM64} EABI Little Endian */ + X86_64_UNIX(true, size_x86_64_unix, align_x86_64_unix), + /** {@link Platform.CPUType#X86_32} Little Endian MacOS (Special case gcc4/OSX) */ + X86_32_MACOS(true, size_x86_32_macos, align_x86_32_macos), + /** {@link Platform.CPUType#X86_32} Little Endian Windows */ + X86_32_WINDOWS(true, size_x86_32_windows, align_x86_32_windows), + /** {@link Platform.CPUType#X86_64} Little Endian Windows */ + X86_64_WINDOWS(true, size_x86_64_windows, align_x86_64_windows), + /** {@link Platform.CPUType#SPARC_32} Big Endian Solaris */ + SPARC_32_SUNOS(false, size_sparc_32_sunos, align_sparc_32_sunos); + public final MachineDescription md; - StaticConfig(final ID id, final boolean littleEndian, final int[] sizes, final int[] alignments) { - this.id = id; + StaticConfig(final boolean littleEndian, final int[] sizes, final int[] alignments) { int i=0, j=0; this.md = new MachineDescription(false, littleEndian, sizes[i++], diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java index 513d215..5b3befa 100644 --- a/src/java/com/jogamp/common/os/Platform.java +++ b/src/java/com/jogamp/common/os/Platform.java @@ -103,6 +103,10 @@ public class Platform extends PlatformPropsImpl { ARMv6( CPUFamily.ARM, 0x0002), /** ARM Cortex */ ARMv7( CPUFamily.ARM, 0x0004), + /** ARM64 default (64bit) */ + ARM64( CPUFamily.ARM, 0x0008), + /** ARM AArch64 (64bit) and AArch32 (32bit) */ + ARMv8_A( CPUFamily.ARM, 0x0010), /** PPC default */ PPC( CPUFamily.PPC, 0x0000), /** SPARC 32bit */ @@ -130,11 +134,13 @@ public class Platform extends PlatformPropsImpl { } public enum ABIType { - GENERIC_ABI ( 0x0000 ), + GENERIC_ABI ( 0x0000 ), /** ARM GNU-EABI ARMEL -mfloat-abi=softfp */ - EABI_GNU_ARMEL ( 0x0001 ), + EABI_GNU_ARMEL ( 0x0001 ), /** ARM GNU-EABI ARMHF -mfloat-abi=hard */ - EABI_GNU_ARMHF ( 0x0002 ); + EABI_GNU_ARMHF ( 0x0002 ), + /** ARM EABI AARCH64 (64bit) */ + EABI_AARCH64 ( 0x0003 ); public final int id; @@ -225,13 +231,12 @@ public class Platform extends PlatformPropsImpl { USE_TEMP_JAR_CACHE = _USE_TEMP_JAR_CACHE[0]; AWT_AVAILABLE = _AWT_AVAILABLE[0]; + final MachineDescription.StaticConfig smd = MachineDescriptionRuntime.getStatic(); MachineDescription md = MachineDescriptionRuntime.getRuntime(); if(null == md) { - final MachineDescription.StaticConfig smd = MachineDescriptionRuntime.getStatic(); md = smd.md; System.err.println("Warning: Using static MachineDescription: "+smd); } else { - final MachineDescription.StaticConfig smd = MachineDescriptionRuntime.getStatic(); if(!md.compatible(smd.md)) { throw new RuntimeException("Incompatible MachineDescriptions:"+PlatformPropsImpl.NEWLINE+ " Static "+smd+PlatformPropsImpl.NEWLINE+ diff --git a/src/java/jogamp/common/os/MachineDescriptionRuntime.java b/src/java/jogamp/common/os/MachineDescriptionRuntime.java index e62c914..c45aeb7 100644 --- a/src/java/jogamp/common/os/MachineDescriptionRuntime.java +++ b/src/java/jogamp/common/os/MachineDescriptionRuntime.java @@ -82,6 +82,8 @@ public class MachineDescriptionRuntime { case PPC: return true; case X86_64: + case ARM64: + case ARMv8_A: case IA64: case SPARCV9_64: case PA_RISC2_0: @@ -107,7 +109,9 @@ public class MachineDescriptionRuntime { } return StaticConfig.X86_32_UNIX; } else { - if( osType == Platform.OSType.WINDOWS ) { + if( cpuType.getFamily() == Platform.CPUFamily.ARM && littleEndian) { + return StaticConfig.X86_64_UNIX; + } else if( osType == Platform.OSType.WINDOWS ) { return StaticConfig.X86_64_WINDOWS; } return StaticConfig.X86_64_UNIX; diff --git a/src/java/jogamp/common/os/PlatformPropsImpl.java b/src/java/jogamp/common/os/PlatformPropsImpl.java index d5ea012..b12ab6f 100644 --- a/src/java/jogamp/common/os/PlatformPropsImpl.java +++ b/src/java/jogamp/common/os/PlatformPropsImpl.java @@ -133,7 +133,11 @@ public abstract class PlatformPropsImpl { final String sARCH_lower = sARCH.toLowerCase(); sCpuType = getCPUTypeImpl(sARCH_lower); if( DEBUG ) { - System.err.println("Platform.Soft: str "+sARCH+", cpuType "+sCpuType); + System.err.println("Platform.Soft: sARCH "+sARCH+", sCpuType "+sCpuType); + if( isAndroid ) { + System.err.println("Android: CPU_ABI1 str "+AndroidVersion.CPU_ABI+", CPU_TYPE "+AndroidVersion.CPU_TYPE+", ABI_TYPE "+AndroidVersion.ABI_TYPE); + System.err.println("Android: CPU_ABI2 str "+AndroidVersion.CPU_ABI2+", CPU_TYPE2 "+AndroidVersion.CPU_TYPE2+", ABI_TYPE2 "+AndroidVersion.ABI_TYPE2); + } } // Hard values, i.e. w/ probing binaries @@ -146,59 +150,57 @@ public abstract class PlatformPropsImpl { // We could use Elf Ehdr's machine value to determine the bit-size // used for it's offset table! // However, 'os.arch' should be a good guess for this task. - final CPUType ehCpuType; - final ABIType ehAbiType; - final boolean ehValid; + final CPUType elfCpuType; + final ABIType elfAbiType; + final boolean elfValid; { final CPUType[] _ehCpuType = { null }; final ABIType[] _ehAbiType = { null }; final ElfHeader eh = queryABITypeImpl(OS_TYPE, _ehCpuType, _ehAbiType); if( null != eh && null != _ehCpuType[0] && null != _ehAbiType[0] ) { - ehCpuType = _ehCpuType[0]; - ehAbiType = _ehAbiType[0]; + elfCpuType = _ehCpuType[0]; + elfAbiType = _ehAbiType[0]; if( isAndroid ) { - if( DEBUG ) { - System.err.println("Android: CPU_ABI1 str "+AndroidVersion.CPU_ABI+", cpu "+AndroidVersion.CPU_TYPE+", abi "+AndroidVersion.ABI_TYPE); - System.err.println("Android: CPU_ABI2 str "+AndroidVersion.CPU_ABI2+", cpu "+AndroidVersion.CPU_TYPE2+", abi "+AndroidVersion.ABI_TYPE2); - } final CPUFamily aCpuFamily1 = null != AndroidVersion.CPU_TYPE ? AndroidVersion.CPU_TYPE.family : null; final CPUFamily aCpuFamily2 = null != AndroidVersion.CPU_TYPE2 ? AndroidVersion.CPU_TYPE2.family : null; - if( ehCpuType.family != aCpuFamily1 && ehCpuType.family != aCpuFamily2 ) { + if( elfCpuType.family != aCpuFamily1 && elfCpuType.family != aCpuFamily2 ) { // Ooops ! - ehValid = false; + elfValid = false; } else { - ehValid = true; + elfValid = true; } } else { - if( ehCpuType.family != sCpuType.family ) { + if( elfCpuType.family != sCpuType.family ) { // Ooops ! - ehValid = false; + elfValid = false; } else { - ehValid = true; + elfValid = true; } } if( DEBUG ) { - System.err.println("Platform.Elf: cpuType "+ehCpuType+", abiType "+ehAbiType+", valid "+ehValid); + System.err.println("Platform.Elf: cpuType "+elfCpuType+", abiType "+elfAbiType+", valid "+elfValid); } } else { - ehCpuType = null; - ehAbiType = null; - ehValid = false; + elfCpuType = null; + elfAbiType = null; + elfValid = false; if( DEBUG ) { System.err.println("Platform.Elf: n/a"); } } } if( isAndroid ) { - if( ehValid ) { - if( ehCpuType.family == AndroidVersion.CPU_TYPE.family ) { + if( elfValid ) { + if( elfCpuType.family == AndroidVersion.CPU_TYPE.family && + elfAbiType == AndroidVersion.ABI_TYPE ) + { ARCH = AndroidVersion.CPU_ABI; CPU_ARCH = AndroidVersion.CPU_TYPE; } else { ARCH = AndroidVersion.CPU_ABI2; CPU_ARCH = AndroidVersion.CPU_TYPE2; } - ABI_TYPE = ehAbiType; + ABI_TYPE = elfAbiType; } else { // default if( AndroidVersion.CPU_TYPE.family == CPUFamily.ARM || null == AndroidVersion.CPU_TYPE2 ) { @@ -215,16 +217,19 @@ public abstract class PlatformPropsImpl { } else { ARCH = sARCH; ARCH_lower = sARCH_lower; - if( ehValid && CPUFamily.ARM == ehCpuType.family ) { + if( elfValid && CPUFamily.ARM == elfCpuType.family ) { // Use Elf for ARM - CPU_ARCH = ehCpuType; - ABI_TYPE = ehAbiType; + CPU_ARCH = elfCpuType; + ABI_TYPE = elfAbiType; } else { // Otherwise trust detailed os.arch (?) CPU_ARCH = sCpuType; ABI_TYPE = ABIType.GENERIC_ABI; } } + if( DEBUG ) { + System.err.println("Platform.Hard: ARCH "+ARCH+", CPU_ARCH "+CPU_ARCH+", ABI_TYPE "+ABI_TYPE+" - isAndroid "+isAndroid+", elfValid "+elfValid); + } MachineDescriptionRuntime.notifyPropsInitialized(); os_and_arch = getOSAndArch(OS_TYPE, CPU_ARCH, ABI_TYPE); } @@ -288,6 +293,12 @@ public abstract class PlatformPropsImpl { archLower.equals("armeabi") || // android archLower.equals("armeabi-v7a") ) { // android return CPUType.ARMv7; + } else if( archLower.equals("aarch64") || + archLower.equals("arm64") ) { + return CPUType.ARM64; + } else if( archLower.equals("armv8-a") || + archLower.equals("arm64-v8a") ) { + return CPUType.ARMv8_A; } else if( archLower.equals("sparc") ) { return CPUType.SPARC_32; } else if( archLower.equals("sparcv9") ) { @@ -389,11 +400,14 @@ public abstract class PlatformPropsImpl { abiVFPArgsAcceptsVFPVariant = SectionArmAttributes.abiVFPArgsAcceptsVFPVariant(abiVFPArgsAttr.getULEB128()); } } - cpuType[0] = CPUType.ARM; // lowest denominator, ok for us + cpuType[0] = CPUType.ARM; // lowest 32bit denominator, ok for us abiType[0] = abiVFPArgsAcceptsVFPVariant ? ABIType.EABI_GNU_ARMHF : ABIType.EABI_GNU_ARMEL; if(DEBUG) { System.err.println("ELF: abiARM, abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant); } + } else if ( eh.isAARCH64() ) { + cpuType[0] = CPUType.ARM64; + abiType[0] = ABIType.EABI_AARCH64; } else if ( eh.isX86_64() ) { cpuType[0] = CPUType.X86_64; abiType[0] = ABIType.GENERIC_ABI; @@ -530,6 +544,10 @@ public abstract class PlatformPropsImpl { _and_arch_tmp = "armv6"; // TODO: sync with gluegen-cpptasks-base.xml } break; + case ARM64: + case ARMv8_A: + _and_arch_tmp = "aarch64"; + break; case SPARC_32: _and_arch_tmp = "sparc"; break; -- cgit v1.2.3