Merge remote-tracking branch 'origin/armv8-a-compatibility' into integration_2026_w07 (!3896)

Add fallbacks for ARMv8a to make it compile

The current code, on ARM, uses ARMv8.1-A RDM instructions. Add a
fallback for processors that do not have this instruction set.

Add some specific compile options for this platform.

Add debian 12 to the list of architectures.
This commit is contained in:
Robert Schmidt
2026-02-10 14:46:57 +01:00
4 changed files with 44 additions and 5 deletions
+8 -1
View File
@@ -166,6 +166,8 @@ elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mcpu=neoverse-n1 -lgcc -lrt")
elseif (CPUPART MATCHES "0xd49") # Neoverse-N2
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mcpu=neoverse-n2 -ftree-vectorize -lgcc -lrt")
elseif (CPUPART MATCHES "0xd03") # Cortex-A53
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mcpu=cortex-a53 -lgcc -lrt")
else ()
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -gdwarf-2 -mcpu=native -lgcc -lrt")
endif()
@@ -174,7 +176,12 @@ else()
endif()
if (NOT CROSS_COMPILE)
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -march=native")
if (CPUPART MATCHES "0xd03")
# Cortex-A53 does not support ARMv8.2-A extensions
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -march=armv8-a+simd")
else()
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -march=native")
endif()
else ()
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -march=armv8.2-a")
endif()
+3 -2
View File
@@ -107,6 +107,7 @@ check_supported_distribution() {
"ubuntu22.04") return 0 ;;
"ubuntu20.04") return 0 ;;
"debian11") return 0 ;;
"debian12") return 0 ;;
"fedora41") return 0 ;;
"fedora40") return 0 ;;
"rhel8.2") return 0 ;;
@@ -453,7 +454,7 @@ check_install_additional_tools (){
local optional_packages=""
if [[ "$OS_BASEDISTRO" == "debian" ]]; then
case "$(get_distribution_release)" in
"ubuntu20.04" | "ubuntu22.04" | "debian11" )
"ubuntu20.04" | "ubuntu22.04" | "debian11" | "debian12" )
optional_packages="python3 python3-pip python3-dev python3-scipy python3-matplotlib python3-pyroute2 universal-ctags"
;;
esac
@@ -496,7 +497,7 @@ check_install_oai_software() {
if [[ "$OS_BASEDISTRO" == "debian" ]]; then
$SUDO apt install -y software-properties-common
case "$(get_distribution_release)" in
"debian11")
"debian11" | "debian12" )
specific_packages="libz-dev"
;;
esac
+17 -1
View File
@@ -760,6 +760,8 @@ static inline __attribute__((always_inline)) int16x8_t cmac0_prec128(int16x8_t x
//
int16x8_t xr = vuzp1q_s16(x, x); // even lanes
int16x8_t xi = vuzp2q_s16(x, x); // odd lanes
#ifdef __ARM_FEATURE_QRDMX
// ARMv8.1-A: Use RDM instructions
// real = ar*br - ai*bi (Q15 scaling via high-half doubling muls)
int16x8_t real = vqdmulhq_s16(xr, wr); // ≈ round((2*xr*wr)/2^16)
real = vqrdmlshq_s16(real, xi, wi); // real -= round((2*xi*wi)/2^16)
@@ -767,7 +769,21 @@ static inline __attribute__((always_inline)) int16x8_t cmac0_prec128(int16x8_t x
// imag = ar*bi + ai*br
int16x8_t imag = vqdmulhq_s16(xr, wi);
imag = vqrdmlahq_s16(imag, xi, wr); // imag += round((2*xi*wr)/2^16)
//
#else
// ARMv8.0-A fallback: Use standard 32-bit multiply
int32x4_t real_lo = vmull_s16(vget_low_s16(xr), vget_low_s16(wr));
int32x4_t real_hi = vmull_s16(vget_high_s16(xr), vget_high_s16(wr));
real_lo = vmlsl_s16(real_lo, vget_low_s16(xi), vget_low_s16(wi));
real_hi = vmlsl_s16(real_hi, vget_high_s16(xi), vget_high_s16(wi));
int32x4_t imag_lo = vmull_s16(vget_low_s16(xr), vget_low_s16(wi));
int32x4_t imag_hi = vmull_s16(vget_high_s16(xr), vget_high_s16(wi));
imag_lo = vmlal_s16(imag_lo, vget_low_s16(xi), vget_low_s16(wr));
imag_hi = vmlal_s16(imag_hi, vget_high_s16(xi), vget_high_s16(wr));
int16x8_t real = vcombine_s16(vqrshrn_n_s32(real_lo, 15), vqrshrn_n_s32(real_hi, 15));
int16x8_t imag = vcombine_s16(vqrshrn_n_s32(imag_lo, 15), vqrshrn_n_s32(imag_hi, 15));
#endif
// Re-interleave [real, imag]
int16x8x2_t produ = vzipq_s16(real, imag);
return produ.val[0];
+16 -1
View File
@@ -816,7 +816,8 @@ static inline void rotate_cpx_vector(const c16_t *const x, const c16_t *const al
// Split interleaved -> separate real/imag
int16x8_t br = vuzp1q_s16(x_128[i], x_128[i]);
int16x8_t bi = vuzp2q_s16(x_128[i], x_128[i]);
#ifdef __ARM_FEATURE_QRDMX
// ARMv8.1-A: Use RDM instructions (rounding doubling multiply)
// Start with the two “diagonal” products using high-half, doubling, sat:
// x = round( (2*ar*br) / 2^16 ), y = round( (2*ar*bi) / 2^16 )
int16x8_t real = vqdmulhq_s16(ar, br);
@@ -827,7 +828,21 @@ static inline void rotate_cpx_vector(const c16_t *const x, const c16_t *const al
// imag += round( (2*ai*br) / 2^16 )
imag = vqrdmlahq_s16(imag, ai, br);
#else
// ARMv8.0-A fallback: Use standard 32-bit multiply
int32x4_t real_lo = vmull_s16(vget_low_s16(ar), vget_low_s16(br));
int32x4_t real_hi = vmull_s16(vget_high_s16(ar), vget_high_s16(br));
real_lo = vmlsl_s16(real_lo, vget_low_s16(ai), vget_low_s16(bi));
real_hi = vmlsl_s16(real_hi, vget_high_s16(ai), vget_high_s16(bi));
int32x4_t imag_lo = vmull_s16(vget_low_s16(ar), vget_low_s16(bi));
int32x4_t imag_hi = vmull_s16(vget_high_s16(ar), vget_high_s16(bi));
imag_lo = vmlal_s16(imag_lo, vget_low_s16(ai), vget_low_s16(br));
imag_hi = vmlal_s16(imag_hi, vget_high_s16(ai), vget_high_s16(br));
int16x8_t real = vcombine_s16(vqrshrn_n_s32(real_lo, 15), vqrshrn_n_s32(real_hi, 15));
int16x8_t imag = vcombine_s16(vqrshrn_n_s32(imag_lo, 15), vqrshrn_n_s32(imag_hi, 15));
#endif
// Re-interleave [real, imag]
int16x8x2_t z = vzipq_s16(real, imag);