Skip to content

Commit

Permalink
Add AArch32 and AArch64 CPU name and feature detection code
Browse files Browse the repository at this point in the history
Also implement internal runtime API.

The detection code avoid using `/proc/cpuinfo` whenever possible and should be much more
reliable than the one in LLVM. It also contains a much larger CPUID table to decode CPU names.

Compare to X86, the feature encoding/decoding is more complex due to the way LLVM takes
attributes. Certain information (arch version) also needs to be moved between name
and feature list.
  • Loading branch information
yuyichao committed Oct 13, 2017
1 parent 0f2e51c commit c3d75da
Show file tree
Hide file tree
Showing 5 changed files with 1,504 additions and 34 deletions.
28 changes: 28 additions & 0 deletions src/features_aarch32.h
@@ -0,0 +1,28 @@
// This file is a part of Julia. License is MIT: https://julialang.org/license

// AArch32 features definition
// hwcap
JL_FEATURE_DEF(neon, 12, 0)
JL_FEATURE_DEF(vfp3, 13, 0)
// JL_FEATURE_DEF(vfpv3d16, 14, 0) // d16
JL_FEATURE_DEF(vfp4, 16, 0)
JL_FEATURE_DEF_NAME(hwdiv_arm, 17, 0, "hwdiv-arm")
JL_FEATURE_DEF(hwdiv, 18, 0)
JL_FEATURE_DEF(d32, 19, 0) // -d16

// hwcap2
JL_FEATURE_DEF(crypto, 32 + 0, 0)
JL_FEATURE_DEF(crc, 32 + 4, 0)
// JL_FEATURE_DEF(ras, 32 + ???, 0)
// JL_FEATURE_DEF(fullfp16, 32 + ???, 0)

// custom bits to match llvm model
JL_FEATURE_DEF(aclass, 32 * 2 + 0, 0)
JL_FEATURE_DEF(rclass, 32 * 2 + 1, 0)
JL_FEATURE_DEF(mclass, 32 * 2 + 2, 0)
JL_FEATURE_DEF(v7, 32 * 2 + 3, 0)
JL_FEATURE_DEF(v8, 32 * 2 + 4, 0)
JL_FEATURE_DEF(v8_1a, 32 * 2 + 5, 0)
JL_FEATURE_DEF(v8_2a, 32 * 2 + 6, 0)
JL_FEATURE_DEF(v8_3a, 32 * 2 + 7, 60000)
JL_FEATURE_DEF(v8_m_main, 32 * 2 + 8, 0)
25 changes: 25 additions & 0 deletions src/features_aarch64.h
@@ -0,0 +1,25 @@
// This file is a part of Julia. License is MIT: https://julialang.org/license

// AArch64 features definition
// hwcap
JL_FEATURE_DEF(crypto, 3, 0)
JL_FEATURE_DEF(crc, 7, 0)
JL_FEATURE_DEF(lse, 8, 40000) // ARMv8.1-Atomics
JL_FEATURE_DEF(fullfp16, 9, 0)
JL_FEATURE_DEF(rdm, 12, 50000) // ARMv8.1-SIMD
JL_FEATURE_DEF(jscvt, 13, UINT32_MAX) // Linux Kernel HWCAP name
JL_FEATURE_DEF(fcma, 14, UINT32_MAX) // Linux Kernel HWCAP name
JL_FEATURE_DEF(rcpc, 15, 60000)
JL_FEATURE_DEF(dcpop, 16, UINT32_MAX) // Linux Kernel HWCAP name
// JL_FEATURE_DEF(dotprod, ???, 60000) // ARMv8.2-DotProd
// JL_FEATURE_DEF(ras, ???, 0)
// JL_FEATURE_DEF(sve, ???, UINT32_MAX)

// hwcap2
// JL_FEATURE_DEF(?, 32 + ?, 0)

// custom bits to match llvm model
JL_FEATURE_DEF(v8_1a, 32 * 2 + 0, 0)
JL_FEATURE_DEF(v8_2a, 32 * 2 + 1, 0)
JL_FEATURE_DEF(v8_3a, 32 * 2 + 2, 60000)
// JL_FEATURE_DEF(v8_4a, 32 * 2 + 3, ???)
36 changes: 2 additions & 34 deletions src/processor.cpp
Expand Up @@ -797,41 +797,9 @@ static inline void dump_cpu_spec(uint32_t cpu, const FeatureList<n> &features,

#include "processor_x86.cpp"

#elif defined(_CPU_AARCH64_)
#elif defined(_CPU_AARCH64_) || defined(_CPU_ARM_)

// TODO
JL_DLLEXPORT jl_value_t *jl_get_cpu_name(void)
{
return jl_cstr_to_string(jl_get_cpu_name_llvm().c_str());
}

// FZ, bit [24]
static const uint32_t fpcr_fz_mask = 1 << 24;

static inline uint32_t get_fpcr_aarch64(void)
{
uint32_t fpcr;
asm volatile("mrs %0, fpcr" : "=r"(fpcr));
return fpcr;
}

static inline void set_fpcr_aarch64(uint32_t fpcr)
{
asm volatile("msr fpcr, %0" :: "r"(fpcr));
}

extern "C" JL_DLLEXPORT int32_t jl_get_zero_subnormals(void)
{
return (get_fpcr_aarch64() & fpcr_fz_mask) != 0;
}

extern "C" JL_DLLEXPORT int32_t jl_set_zero_subnormals(int8_t isZero)
{
uint32_t fpcr = get_fpcr_aarch64();
fpcr = isZero ? (fpcr | fpcr_fz_mask) : (fpcr & ~fpcr_fz_mask);
set_fpcr_aarch64(fpcr);
return 0;
}
#include "processor_arm.cpp"

#else

Expand Down
6 changes: 6 additions & 0 deletions src/processor.h
Expand Up @@ -110,6 +110,12 @@ typedef enum {
#define JL_FEATURE_DEF(name, bit, llvmver) JL_X86_##name = bit,
#include "features_x86.h"
#undef JL_FEATURE_DEF
#define JL_FEATURE_DEF(name, bit, llvmver) JL_AArch32_##name = bit,
#include "features_aarch32.h"
#undef JL_FEATURE_DEF
#define JL_FEATURE_DEF(name, bit, llvmver) JL_AArch64_##name = bit,
#include "features_aarch64.h"
#undef JL_FEATURE_DEF
} jl_cpu_feature_t;
#undef JL_FEATURE_DEF_NAME

Expand Down

0 comments on commit c3d75da

Please sign in to comment.