diff --git a/dev/ppc64le/README.md b/dev/ppc64le/README.md index def9e7e7ef..de50aeaaca 100644 --- a/dev/ppc64le/README.md +++ b/dev/ppc64le/README.md @@ -2,6 +2,5 @@ # ppc64le backend (little endian) -This directory contains a native backend for little endian POWER 9 (ppc64le) and above systems. -Or, Power systems supporting ISA 2.07 and above. - +This directory contains a native backend for little endian PPC64. +It requires POWER8 or above as well as the AltiVec and VSX extensions. diff --git a/dev/ppc64le/meta.h b/dev/ppc64le/meta.h index e10ecd6907..882f9aeef4 100644 --- a/dev/ppc64le/meta.h +++ b/dev/ppc64le/meta.h @@ -28,52 +28,48 @@ MLK_MUST_CHECK_RETURN_VALUE static MLK_INLINE int mlk_ntt_native(int16_t data[MLKEM_N]) { -#if defined(__POWER8_VECTOR__) + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + return MLK_NATIVE_FUNC_FALLBACK; + } mlk_ntt_ppc_asm(data, mlk_ppc_qdata); return MLK_NATIVE_FUNC_SUCCESS; -#else - (void)data; - return MLK_NATIVE_FUNC_FALLBACK; -#endif } #if !defined(MLK_CONFIG_NO_ENCAPS_API) || !defined(MLK_CONFIG_NO_DECAPS_API) MLK_MUST_CHECK_RETURN_VALUE static MLK_INLINE int mlk_intt_native(int16_t data[MLKEM_N]) { -#if defined(__POWER8_VECTOR__) + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + return MLK_NATIVE_FUNC_FALLBACK; + } mlk_intt_ppc_asm(data, mlk_ppc_qdata); return MLK_NATIVE_FUNC_SUCCESS; -#else - (void)data; - return MLK_NATIVE_FUNC_FALLBACK; -#endif } #endif /* !MLK_CONFIG_NO_ENCAPS_API || !MLK_CONFIG_NO_DECAPS_API */ MLK_MUST_CHECK_RETURN_VALUE static MLK_INLINE int mlk_poly_reduce_native(int16_t data[MLKEM_N]) { -#if defined(__POWER8_VECTOR__) + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + return MLK_NATIVE_FUNC_FALLBACK; + } mlk_reduce_ppc_asm(data, mlk_ppc_qdata); return MLK_NATIVE_FUNC_SUCCESS; -#else - (void)data; - return MLK_NATIVE_FUNC_FALLBACK; -#endif } #if !defined(MLK_CONFIG_NO_KEYPAIR_API) MLK_MUST_CHECK_RETURN_VALUE static MLK_INLINE int mlk_poly_tomont_native(int16_t data[MLKEM_N]) { -#if defined(__POWER8_VECTOR__) + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + return MLK_NATIVE_FUNC_FALLBACK; + } mlk_poly_tomont_ppc_asm(data, mlk_ppc_qdata); return MLK_NATIVE_FUNC_SUCCESS; -#else - (void)data; - return MLK_NATIVE_FUNC_FALLBACK; -#endif } #endif /* !MLK_CONFIG_NO_KEYPAIR_API */ #endif /* !__ASSEMBLER__ */ diff --git a/dev/ppc64le/src/consts.c b/dev/ppc64le/src/consts.c index f6e1abd5b9..ec700ac6f0 100644 --- a/dev/ppc64le/src/consts.c +++ b/dev/ppc64le/src/consts.c @@ -12,7 +12,7 @@ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) #include "consts.h" @@ -296,4 +296,4 @@ MLK_ALIGN MLK_INTERNAL_DATA_DEFINITION const int16_t mlk_ppc_qdata[2072] = { /* clang-format on */ #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && \ - !MLK_CONFIG_MULTILEVEL_NO_SHARED && __POWER8_VECTOR__ */ + !MLK_CONFIG_MULTILEVEL_NO_SHARED */ diff --git a/dev/ppc64le/src/mlkem_intt_ppc_asm.S b/dev/ppc64le/src/mlkem_intt_ppc_asm.S index 3a67ee8e6b..c702a281dd 100644 --- a/dev/ppc64le/src/mlkem_intt_ppc_asm.S +++ b/dev/ppc64le/src/mlkem_intt_ppc_asm.S @@ -8,7 +8,7 @@ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) && \ + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && \ (!defined(MLK_CONFIG_NO_ENCAPS_API) || \ !defined(MLK_CONFIG_NO_DECAPS_API)) /*yaml @@ -18,7 +18,7 @@ ABI: Architecture: powerpc64le CallingConvention: ELFv2 - Features: [VSX] + Features: [POWER8_VECTOR] r3: type: buffer size_bytes: 512 @@ -1004,5 +1004,4 @@ mlk_intt_ppc_asm_Loopf: /* simpasm: footer-start */ #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && !MLK_CONFIG_MULTILEVEL_NO_SHARED \ - && __POWER8_VECTOR__ && (!MLK_CONFIG_NO_ENCAPS_API || \ - !MLK_CONFIG_NO_DECAPS_API) */ + && (!MLK_CONFIG_NO_ENCAPS_API || !MLK_CONFIG_NO_DECAPS_API) */ diff --git a/dev/ppc64le/src/mlkem_ntt_ppc_asm.S b/dev/ppc64le/src/mlkem_ntt_ppc_asm.S index d88738a792..0319d96bea 100644 --- a/dev/ppc64le/src/mlkem_ntt_ppc_asm.S +++ b/dev/ppc64le/src/mlkem_ntt_ppc_asm.S @@ -8,7 +8,7 @@ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) /*yaml Name: ntt_ppc_asm Description: PowerPC64 VSX forward NTT @@ -16,7 +16,7 @@ ABI: Architecture: powerpc64le CallingConvention: ELFv2 - Features: [VSX] + Features: [POWER8_VECTOR] r3: type: buffer size_bytes: 512 @@ -767,4 +767,4 @@ MLK_ASM_FN_SYMBOL(ntt_ppc_asm) /* simpasm: footer-start */ #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && !MLK_CONFIG_MULTILEVEL_NO_SHARED \ - && __POWER8_VECTOR__ */ + */ diff --git a/dev/ppc64le/src/mlkem_poly_tomont_ppc_asm.S b/dev/ppc64le/src/mlkem_poly_tomont_ppc_asm.S index 52f93d3cb3..13e427b4b1 100644 --- a/dev/ppc64le/src/mlkem_poly_tomont_ppc_asm.S +++ b/dev/ppc64le/src/mlkem_poly_tomont_ppc_asm.S @@ -15,7 +15,7 @@ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) && \ + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && \ !defined(MLK_CONFIG_NO_KEYPAIR_API) /*yaml Name: poly_tomont_ppc_asm @@ -24,7 +24,7 @@ ABI: Architecture: powerpc64le CallingConvention: ELFv2 - Features: [VSX] + Features: [POWER8_VECTOR] r3: type: buffer size_bytes: 512 @@ -242,4 +242,4 @@ MLK_ASM_FN_SYMBOL(poly_tomont_ppc_asm) /* simpasm: footer-start */ #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && !MLK_CONFIG_MULTILEVEL_NO_SHARED \ - && __POWER8_VECTOR__ && !MLK_CONFIG_NO_KEYPAIR_API */ + && !MLK_CONFIG_NO_KEYPAIR_API */ diff --git a/dev/ppc64le/src/mlkem_reduce_ppc_asm.S b/dev/ppc64le/src/mlkem_reduce_ppc_asm.S index 9795d70bb4..1b4e43fabb 100644 --- a/dev/ppc64le/src/mlkem_reduce_ppc_asm.S +++ b/dev/ppc64le/src/mlkem_reduce_ppc_asm.S @@ -7,7 +7,7 @@ */ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) /*yaml Name: reduce_ppc_asm Description: PowerPC64 VSX modular reduction @@ -15,7 +15,7 @@ ABI: Architecture: powerpc64le CallingConvention: ELFv2 - Features: [VSX] + Features: [POWER8_VECTOR] r3: type: buffer size_bytes: 512 @@ -463,4 +463,4 @@ MLK_ASM_FN_SYMBOL(reduce_ppc_asm) /* simpasm: footer-start */ #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && !MLK_CONFIG_MULTILEVEL_NO_SHARED \ - && __POWER8_VECTOR__ */ + */ diff --git a/mlkem/mlkem_native.c b/mlkem/mlkem_native.c index 84adf0806c..840734539e 100644 --- a/mlkem/mlkem_native.c +++ b/mlkem/mlkem_native.c @@ -684,6 +684,7 @@ #undef MLK_SYS_LINUX #undef MLK_SYS_LITTLE_ENDIAN #undef MLK_SYS_PPC64LE +#undef MLK_SYS_PPC64LE_POWER8_VECTOR #undef MLK_SYS_RISCV32 #undef MLK_SYS_RISCV64 #undef MLK_SYS_RISCV64_RVV diff --git a/mlkem/mlkem_native_asm.S b/mlkem/mlkem_native_asm.S index e0a0213c57..f393c22dfa 100644 --- a/mlkem/mlkem_native_asm.S +++ b/mlkem/mlkem_native_asm.S @@ -715,6 +715,7 @@ #undef MLK_SYS_LINUX #undef MLK_SYS_LITTLE_ENDIAN #undef MLK_SYS_PPC64LE +#undef MLK_SYS_PPC64LE_POWER8_VECTOR #undef MLK_SYS_RISCV32 #undef MLK_SYS_RISCV64 #undef MLK_SYS_RISCV64_RVV diff --git a/mlkem/src/native/meta.h b/mlkem/src/native/meta.h index dbd07a5bda..d12726db2a 100644 --- a/mlkem/src/native/meta.h +++ b/mlkem/src/native/meta.h @@ -10,7 +10,7 @@ */ #include "../sys.h" -#ifdef MLK_SYS_AARCH64_NEON +#if defined(MLK_SYS_AARCH64_NEON) #include "aarch64/meta.h" #endif @@ -23,7 +23,7 @@ #include "riscv64/meta.h" #endif -#ifdef MLK_SYS_PPC64LE +#if defined(MLK_SYS_PPC64LE_POWER8_VECTOR) #include "ppc64le/meta.h" #endif diff --git a/mlkem/src/native/ppc64le/README.md b/mlkem/src/native/ppc64le/README.md index 733e32e113..de50aeaaca 100644 --- a/mlkem/src/native/ppc64le/README.md +++ b/mlkem/src/native/ppc64le/README.md @@ -2,5 +2,5 @@ # ppc64le backend (little endian) -This directory contains a native backend for little endian POWER 9 (ppc64le) and above systems. -Or, Power systems supporting ISA 2.07 and above. +This directory contains a native backend for little endian PPC64. +It requires POWER8 or above as well as the AltiVec and VSX extensions. diff --git a/mlkem/src/native/ppc64le/meta.h b/mlkem/src/native/ppc64le/meta.h index 2f292432df..94923174af 100644 --- a/mlkem/src/native/ppc64le/meta.h +++ b/mlkem/src/native/ppc64le/meta.h @@ -28,52 +28,48 @@ MLK_MUST_CHECK_RETURN_VALUE static MLK_INLINE int mlk_ntt_native(int16_t data[MLKEM_N]) { -#if defined(__POWER8_VECTOR__) + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + return MLK_NATIVE_FUNC_FALLBACK; + } mlk_ntt_ppc_asm(data, mlk_ppc_qdata); return MLK_NATIVE_FUNC_SUCCESS; -#else - (void)data; - return MLK_NATIVE_FUNC_FALLBACK; -#endif } #if !defined(MLK_CONFIG_NO_ENCAPS_API) || !defined(MLK_CONFIG_NO_DECAPS_API) MLK_MUST_CHECK_RETURN_VALUE static MLK_INLINE int mlk_intt_native(int16_t data[MLKEM_N]) { -#if defined(__POWER8_VECTOR__) + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + return MLK_NATIVE_FUNC_FALLBACK; + } mlk_intt_ppc_asm(data, mlk_ppc_qdata); return MLK_NATIVE_FUNC_SUCCESS; -#else - (void)data; - return MLK_NATIVE_FUNC_FALLBACK; -#endif } #endif /* !MLK_CONFIG_NO_ENCAPS_API || !MLK_CONFIG_NO_DECAPS_API */ MLK_MUST_CHECK_RETURN_VALUE static MLK_INLINE int mlk_poly_reduce_native(int16_t data[MLKEM_N]) { -#if defined(__POWER8_VECTOR__) + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + return MLK_NATIVE_FUNC_FALLBACK; + } mlk_reduce_ppc_asm(data, mlk_ppc_qdata); return MLK_NATIVE_FUNC_SUCCESS; -#else - (void)data; - return MLK_NATIVE_FUNC_FALLBACK; -#endif } #if !defined(MLK_CONFIG_NO_KEYPAIR_API) MLK_MUST_CHECK_RETURN_VALUE static MLK_INLINE int mlk_poly_tomont_native(int16_t data[MLKEM_N]) { -#if defined(__POWER8_VECTOR__) + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + return MLK_NATIVE_FUNC_FALLBACK; + } mlk_poly_tomont_ppc_asm(data, mlk_ppc_qdata); return MLK_NATIVE_FUNC_SUCCESS; -#else - (void)data; - return MLK_NATIVE_FUNC_FALLBACK; -#endif } #endif /* !MLK_CONFIG_NO_KEYPAIR_API */ #endif /* !__ASSEMBLER__ */ diff --git a/mlkem/src/native/ppc64le/src/consts.c b/mlkem/src/native/ppc64le/src/consts.c index f6e1abd5b9..ec700ac6f0 100644 --- a/mlkem/src/native/ppc64le/src/consts.c +++ b/mlkem/src/native/ppc64le/src/consts.c @@ -12,7 +12,7 @@ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) #include "consts.h" @@ -296,4 +296,4 @@ MLK_ALIGN MLK_INTERNAL_DATA_DEFINITION const int16_t mlk_ppc_qdata[2072] = { /* clang-format on */ #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && \ - !MLK_CONFIG_MULTILEVEL_NO_SHARED && __POWER8_VECTOR__ */ + !MLK_CONFIG_MULTILEVEL_NO_SHARED */ diff --git a/mlkem/src/native/ppc64le/src/mlkem_intt_ppc_asm.S b/mlkem/src/native/ppc64le/src/mlkem_intt_ppc_asm.S index cd6929f6ac..e665bc0da2 100644 --- a/mlkem/src/native/ppc64le/src/mlkem_intt_ppc_asm.S +++ b/mlkem/src/native/ppc64le/src/mlkem_intt_ppc_asm.S @@ -8,7 +8,7 @@ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) && \ + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && \ (!defined(MLK_CONFIG_NO_ENCAPS_API) || \ !defined(MLK_CONFIG_NO_DECAPS_API)) /*yaml @@ -18,7 +18,7 @@ ABI: Architecture: powerpc64le CallingConvention: ELFv2 - Features: [VSX] + Features: [POWER8_VECTOR] r3: type: buffer size_bytes: 512 @@ -3238,8 +3238,7 @@ mlk_intt_ppc_asm_Loopf: MLK_ASM_FN_SIZE(intt_ppc_asm) #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && !MLK_CONFIG_MULTILEVEL_NO_SHARED \ - && __POWER8_VECTOR__ && (!MLK_CONFIG_NO_ENCAPS_API || \ - !MLK_CONFIG_NO_DECAPS_API) */ + && (!MLK_CONFIG_NO_ENCAPS_API || !MLK_CONFIG_NO_DECAPS_API) */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/mlkem/src/native/ppc64le/src/mlkem_ntt_ppc_asm.S b/mlkem/src/native/ppc64le/src/mlkem_ntt_ppc_asm.S index 09ec84a966..cd9c7b810a 100644 --- a/mlkem/src/native/ppc64le/src/mlkem_ntt_ppc_asm.S +++ b/mlkem/src/native/ppc64le/src/mlkem_ntt_ppc_asm.S @@ -8,7 +8,7 @@ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) /*yaml Name: ntt_ppc_asm Description: PowerPC64 VSX forward NTT @@ -16,7 +16,7 @@ ABI: Architecture: powerpc64le CallingConvention: ELFv2 - Features: [VSX] + Features: [POWER8_VECTOR] r3: type: buffer size_bytes: 512 @@ -1665,7 +1665,7 @@ MLK_ASM_FN_SYMBOL(ntt_ppc_asm) MLK_ASM_FN_SIZE(ntt_ppc_asm) #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && !MLK_CONFIG_MULTILEVEL_NO_SHARED \ - && __POWER8_VECTOR__ */ + */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/mlkem/src/native/ppc64le/src/mlkem_poly_tomont_ppc_asm.S b/mlkem/src/native/ppc64le/src/mlkem_poly_tomont_ppc_asm.S index 3e430638d3..7a9be58fa3 100644 --- a/mlkem/src/native/ppc64le/src/mlkem_poly_tomont_ppc_asm.S +++ b/mlkem/src/native/ppc64le/src/mlkem_poly_tomont_ppc_asm.S @@ -15,7 +15,7 @@ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) && \ + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && \ !defined(MLK_CONFIG_NO_KEYPAIR_API) /*yaml Name: poly_tomont_ppc_asm @@ -24,7 +24,7 @@ ABI: Architecture: powerpc64le CallingConvention: ELFv2 - Features: [VSX] + Features: [POWER8_VECTOR] r3: type: buffer size_bytes: 512 @@ -309,7 +309,7 @@ MLK_ASM_FN_SYMBOL(poly_tomont_ppc_asm) MLK_ASM_FN_SIZE(poly_tomont_ppc_asm) #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && !MLK_CONFIG_MULTILEVEL_NO_SHARED \ - && __POWER8_VECTOR__ && !MLK_CONFIG_NO_KEYPAIR_API */ + && !MLK_CONFIG_NO_KEYPAIR_API */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/mlkem/src/native/ppc64le/src/mlkem_reduce_ppc_asm.S b/mlkem/src/native/ppc64le/src/mlkem_reduce_ppc_asm.S index e82376c74b..c3fffcf3f4 100644 --- a/mlkem/src/native/ppc64le/src/mlkem_reduce_ppc_asm.S +++ b/mlkem/src/native/ppc64le/src/mlkem_reduce_ppc_asm.S @@ -7,7 +7,7 @@ */ #include "../../../common.h" #if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \ - !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__) + !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) /*yaml Name: reduce_ppc_asm Description: PowerPC64 VSX modular reduction @@ -15,7 +15,7 @@ ABI: Architecture: powerpc64le CallingConvention: ELFv2 - Features: [VSX] + Features: [POWER8_VECTOR] r3: type: buffer size_bytes: 512 @@ -724,7 +724,7 @@ MLK_ASM_FN_SYMBOL(reduce_ppc_asm) MLK_ASM_FN_SIZE(reduce_ppc_asm) #endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && !MLK_CONFIG_MULTILEVEL_NO_SHARED \ - && __POWER8_VECTOR__ */ + */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/mlkem/src/sys.h b/mlkem/src/sys.h index b93882257e..5b65630106 100644 --- a/mlkem/src/sys.h +++ b/mlkem/src/sys.h @@ -74,6 +74,14 @@ #define MLK_SYS_PPC64LE #endif +/* Check if the PPC64LE compilation target supports the vector instructions + * used by the POWER8 backend: AltiVec/VMX, VSX, and POWER8 vector extensions + * (Power ISA 2.07). AltiVec predates POWER8; VSX was introduced in POWER7. */ +#if defined(MLK_SYS_PPC64LE) && defined(__ALTIVEC__) && defined(__VSX__) && \ + defined(__POWER8_VECTOR__) +#define MLK_SYS_PPC64LE_POWER8_VECTOR +#endif + #if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64 #define MLK_SYS_RISCV64 #endif @@ -281,7 +289,10 @@ typedef enum MLK_SYS_CAP_AARCH64_NEON, MLK_SYS_CAP_AARCH64_SHA3, /* Armv8.1-M */ - MLK_SYS_CAP_ARMV81M_MVE + MLK_SYS_CAP_ARMV81M_MVE, + /* PowerPC64 */ + /* AltiVec/VMX, VSX, and POWER8 vector extensions (Power ISA 2.07). */ + MLK_SYS_CAP_PPC64LE_POWER8_VECTOR } mlk_sys_cap; #endif /* !__ASSEMBLER__ */ diff --git a/scripts/autogen b/scripts/autogen index 2b1ab95284..cf47c21a8e 100755 --- a/scripts/autogen +++ b/scripts/autogen @@ -2276,7 +2276,7 @@ def gen_ppc64le_zeta_files(): yield '#include "../../../common.h"' yield "" yield "#if defined(MLK_ARITH_BACKEND_PPC64LE_DEFAULT) && \\" - yield " !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED) && defined(__POWER8_VECTOR__)" + yield " !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)" yield "" yield '#include "consts.h"' yield "" @@ -2288,7 +2288,7 @@ def gen_ppc64le_zeta_files(): def gen_c_epilogue(): yield "" yield "#endif /* MLK_ARITH_BACKEND_PPC64LE_DEFAULT && \\" - yield " !MLK_CONFIG_MULTILEVEL_NO_SHARED && __POWER8_VECTOR__ */" + yield " !MLK_CONFIG_MULTILEVEL_NO_SHARED */" yield "" # dev copy: one array, annotated per region, LANES values per line. @@ -2954,6 +2954,7 @@ def get_syscaps(): "MLK_SYS_CAP_AARCH64_NEON", "MLK_SYS_CAP_AARCH64_SHA3", "MLK_SYS_CAP_ARMV81M_MVE", + "MLK_SYS_CAP_PPC64LE_POWER8_VECTOR", ] @@ -4916,14 +4917,14 @@ ABI_CAPS = { "mlkem/src/fips202/native/armv81m/src/keccak_f1600_x4_state_xor_bytes_mve.S", ], }, - # VSX is build-time only: every ppc64le kernel requires it, the call - # stub saves vr20-vr31 unconditionally, and we never run the binary on - # a non-VSX host. No #if guard, no syscap. - "VSX": { + # NTT/INTT use the POWER8 vector merges vmrgew/vmrgow (ISA 2.07). + # AltiVec predates POWER8, and VSX was introduced in POWER7. + # All current PPC64 kernels and ABI stubs share the backend's guard. + "POWER8_VECTOR": { "asm_subdir": "ppc64le", - "guard": None, - "syscap": None, - "description": "PPC64 VSX/Altivec (POWER8)", + "guard": "MLK_SYS_PPC64LE_POWER8_VECTOR", + "syscap": "MLK_SYS_CAP_PPC64LE_POWER8_VECTOR", + "description": "AltiVec/VSX and POWER8 vector extensions (Power ISA 2.07)", "cflags": ["-mcpu=power8", "-maltivec", "-mvsx"], "aux_files": [ "test/abicheck/ppc64le/callstub_ppc64le.S", @@ -5228,7 +5229,7 @@ def gen_abicheck(): # Emit a runtime mlk_sys_check_capability() skip (returning # MLK_ABICHECK_SKIPPED) per Features cap that has a syscap; caps - # without a syscap (build-time-only, e.g. PPC64 VSX) are no-ops here. + # without a syscap are no-ops here. # Emitted after the buffer decls to keep C90 mixed-decl-and-code happy. for cap in features: cap_enum = ABI_CAPS[cap]["syscap"] diff --git a/test/abicheck/README.md b/test/abicheck/README.md index ba6cd7c81f..c83e1a13f7 100644 --- a/test/abicheck/README.md +++ b/test/abicheck/README.md @@ -31,8 +31,10 @@ Before trusting any verdict, `abicheck.c` runs a self-test: hand-written corrupters (`/selftest_.S`) that each clobber one callee-saved register, confirming the checker fires. -The `mlkem/src/.../*.S` sources are assembled directly. On unsupported -architectures the registry is empty and the driver exits cleanly. +The `mlkem/src/.../*.S` sources are assembled directly. Compile-time feature +guards select which checks are registered; a check is skipped if +`mlk_sys_check_capability()` reports a required feature as unavailable. +On unsupported architectures the registry is empty and the driver exits cleanly. ## Code generation diff --git a/test/abicheck/ppc64le/abicheck_ppc64le.mk b/test/abicheck/ppc64le/abicheck_ppc64le.mk index 7e32c0bc57..acc89c0360 100644 --- a/test/abicheck/ppc64le/abicheck_ppc64le.mk +++ b/test/abicheck/ppc64le/abicheck_ppc64le.mk @@ -14,15 +14,15 @@ # Default each cap's file list to empty so the unconditional appends # below are safe even when a cap has no kernels on this arch. -ABICHECK_REQ_VSX_FILES := +ABICHECK_REQ_POWER8_VECTOR_FILES := -# VSX: PPC64 VSX/Altivec (POWER8) -ABICHECK_REQ_VSX_FILES := \ +# POWER8_VECTOR: AltiVec/VSX and POWER8 vector extensions (Power ISA 2.07) +ABICHECK_REQ_POWER8_VECTOR_FILES := \ mlkem/src/native/ppc64le/src/mlkem_intt_ppc_asm.S \ mlkem/src/native/ppc64le/src/mlkem_ntt_ppc_asm.S \ mlkem/src/native/ppc64le/src/mlkem_poly_tomont_ppc_asm.S \ mlkem/src/native/ppc64le/src/mlkem_reduce_ppc_asm.S \ test/abicheck/ppc64le/callstub_ppc64le.S \ test/abicheck/ppc64le/selftest_ppc64le.S -ABICHECK_REQ_VSX_OBJS := $(call MAKE_OBJS,$(ABICHECK_DIR),$(ABICHECK_REQ_VSX_FILES)) -$(ABICHECK_REQ_VSX_OBJS): CFLAGS += -mcpu=power8 -maltivec -mvsx +ABICHECK_REQ_POWER8_VECTOR_OBJS := $(call MAKE_OBJS,$(ABICHECK_DIR),$(ABICHECK_REQ_POWER8_VECTOR_FILES)) +$(ABICHECK_REQ_POWER8_VECTOR_OBJS): CFLAGS += -mcpu=power8 -maltivec -mvsx diff --git a/test/abicheck/ppc64le/callstub_ppc64le.S b/test/abicheck/ppc64le/callstub_ppc64le.S index 31c14fcd42..caa373d6f2 100644 --- a/test/abicheck/ppc64le/callstub_ppc64le.S +++ b/test/abicheck/ppc64le/callstub_ppc64le.S @@ -29,6 +29,10 @@ * CR2-CR4, and LR. */ +#include "../../../mlkem/src/sys.h" + +#if defined(MLK_SYS_PPC64LE_POWER8_VECTOR) + #define ST_GPR_ARG 0 /* r3-r10 */ #define ST_GPR_NV 64 /* r14-r31 */ #define ST_FPR 208 /* f14-f31 */ @@ -456,6 +460,8 @@ asm_call_stub_ppc64le: blr .cfi_endproc +#endif /* MLK_SYS_PPC64LE_POWER8_VECTOR */ + #if defined(__ELF__) .section .note.GNU-stack, "", @progbits #endif diff --git a/test/abicheck/ppc64le/checks/check_intt_ppc_asm.c b/test/abicheck/ppc64le/checks/check_intt_ppc_asm.c index 995f83a677..3f75fe2a2c 100644 --- a/test/abicheck/ppc64le/checks/check_intt_ppc_asm.c +++ b/test/abicheck/ppc64le/checks/check_intt_ppc_asm.c @@ -14,7 +14,7 @@ #include "../abicheck_ppc64le.h" #include "../checks_ppc64le_all.h" -#if defined(MLK_SYS_PPC64LE) +#if defined(MLK_SYS_PPC64LE) && defined(MLK_SYS_PPC64LE_POWER8_VECTOR) #include "../../../notrandombytes/notrandombytes.h" @@ -30,6 +30,14 @@ int check_intt_ppc_asm(void) MLK_ALIGN uint8_t buf_r3[512]; /* Input/output polynomial (256 x int16_t) */ MLK_ALIGN uint8_t buf_r4[4144]; /* Precomputed constants (2072 x int16_t) */ + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + fprintf(stderr, + "ABI check intt_ppc_asm: host lacks AltiVec/VSX and POWER8 vector " + "extensions (Power ISA 2.07), skipping\n"); + return MLK_ABICHECK_SKIPPED; + } + for (test_iter = 0; test_iter < MLK_ABICHECK_NUM_TESTS; test_iter++) { /* Initialize random register state */ @@ -62,4 +70,4 @@ int check_intt_ppc_asm(void) return MLK_ABICHECK_PASSED; } -#endif /* MLK_SYS_PPC64LE */ +#endif /* MLK_SYS_PPC64LE && MLK_SYS_PPC64LE_POWER8_VECTOR */ diff --git a/test/abicheck/ppc64le/checks/check_ntt_ppc_asm.c b/test/abicheck/ppc64le/checks/check_ntt_ppc_asm.c index 40dab3e356..5a2565fe82 100644 --- a/test/abicheck/ppc64le/checks/check_ntt_ppc_asm.c +++ b/test/abicheck/ppc64le/checks/check_ntt_ppc_asm.c @@ -14,7 +14,7 @@ #include "../abicheck_ppc64le.h" #include "../checks_ppc64le_all.h" -#if defined(MLK_SYS_PPC64LE) +#if defined(MLK_SYS_PPC64LE) && defined(MLK_SYS_PPC64LE_POWER8_VECTOR) #include "../../../notrandombytes/notrandombytes.h" @@ -30,6 +30,14 @@ int check_ntt_ppc_asm(void) MLK_ALIGN uint8_t buf_r3[512]; /* Input/output polynomial (256 x int16_t) */ MLK_ALIGN uint8_t buf_r4[4144]; /* Precomputed constants (2072 x int16_t) */ + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + fprintf(stderr, + "ABI check ntt_ppc_asm: host lacks AltiVec/VSX and POWER8 vector " + "extensions (Power ISA 2.07), skipping\n"); + return MLK_ABICHECK_SKIPPED; + } + for (test_iter = 0; test_iter < MLK_ABICHECK_NUM_TESTS; test_iter++) { /* Initialize random register state */ @@ -61,4 +69,4 @@ int check_ntt_ppc_asm(void) return MLK_ABICHECK_PASSED; } -#endif /* MLK_SYS_PPC64LE */ +#endif /* MLK_SYS_PPC64LE && MLK_SYS_PPC64LE_POWER8_VECTOR */ diff --git a/test/abicheck/ppc64le/checks/check_poly_tomont_ppc_asm.c b/test/abicheck/ppc64le/checks/check_poly_tomont_ppc_asm.c index 69d43e2b3c..cb6c2caf44 100644 --- a/test/abicheck/ppc64le/checks/check_poly_tomont_ppc_asm.c +++ b/test/abicheck/ppc64le/checks/check_poly_tomont_ppc_asm.c @@ -14,7 +14,7 @@ #include "../abicheck_ppc64le.h" #include "../checks_ppc64le_all.h" -#if defined(MLK_SYS_PPC64LE) +#if defined(MLK_SYS_PPC64LE) && defined(MLK_SYS_PPC64LE_POWER8_VECTOR) #include "../../../notrandombytes/notrandombytes.h" @@ -30,6 +30,14 @@ int check_poly_tomont_ppc_asm(void) MLK_ALIGN uint8_t buf_r3[512]; /* Input/output polynomial (256 x int16_t) */ MLK_ALIGN uint8_t buf_r4[4144]; /* Precomputed constants (2072 x int16_t) */ + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + fprintf(stderr, + "ABI check poly_tomont_ppc_asm: host lacks AltiVec/VSX and POWER8 " + "vector extensions (Power ISA 2.07), skipping\n"); + return MLK_ABICHECK_SKIPPED; + } + for (test_iter = 0; test_iter < MLK_ABICHECK_NUM_TESTS; test_iter++) { /* Initialize random register state */ @@ -62,4 +70,4 @@ int check_poly_tomont_ppc_asm(void) return MLK_ABICHECK_PASSED; } -#endif /* MLK_SYS_PPC64LE */ +#endif /* MLK_SYS_PPC64LE && MLK_SYS_PPC64LE_POWER8_VECTOR */ diff --git a/test/abicheck/ppc64le/checks/check_reduce_ppc_asm.c b/test/abicheck/ppc64le/checks/check_reduce_ppc_asm.c index c5bbafed9b..f4583760ba 100644 --- a/test/abicheck/ppc64le/checks/check_reduce_ppc_asm.c +++ b/test/abicheck/ppc64le/checks/check_reduce_ppc_asm.c @@ -14,7 +14,7 @@ #include "../abicheck_ppc64le.h" #include "../checks_ppc64le_all.h" -#if defined(MLK_SYS_PPC64LE) +#if defined(MLK_SYS_PPC64LE) && defined(MLK_SYS_PPC64LE_POWER8_VECTOR) #include "../../../notrandombytes/notrandombytes.h" @@ -30,6 +30,14 @@ int check_reduce_ppc_asm(void) MLK_ALIGN uint8_t buf_r3[512]; /* Input/output polynomial (256 x int16_t) */ MLK_ALIGN uint8_t buf_r4[4144]; /* Precomputed constants (2072 x int16_t) */ + if (!mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + fprintf(stderr, + "ABI check reduce_ppc_asm: host lacks AltiVec/VSX and POWER8 " + "vector extensions (Power ISA 2.07), skipping\n"); + return MLK_ABICHECK_SKIPPED; + } + for (test_iter = 0; test_iter < MLK_ABICHECK_NUM_TESTS; test_iter++) { /* Initialize random register state */ @@ -62,4 +70,4 @@ int check_reduce_ppc_asm(void) return MLK_ABICHECK_PASSED; } -#endif /* MLK_SYS_PPC64LE */ +#endif /* MLK_SYS_PPC64LE && MLK_SYS_PPC64LE_POWER8_VECTOR */ diff --git a/test/abicheck/ppc64le/checks_ppc64le_all.h b/test/abicheck/ppc64le/checks_ppc64le_all.h index de497c488d..0c23aaf539 100644 --- a/test/abicheck/ppc64le/checks_ppc64le_all.h +++ b/test/abicheck/ppc64le/checks_ppc64le_all.h @@ -18,16 +18,20 @@ #if defined(MLK_SYS_PPC64LE) +#if defined(MLK_SYS_PPC64LE_POWER8_VECTOR) int check_intt_ppc_asm(void); int check_ntt_ppc_asm(void); int check_poly_tomont_ppc_asm(void); int check_reduce_ppc_asm(void); +#endif /* MLK_SYS_PPC64LE_POWER8_VECTOR */ static const abicheck_entry_t all_checks[] = { +#if defined(MLK_SYS_PPC64LE_POWER8_VECTOR) {"intt_ppc_asm", check_intt_ppc_asm}, {"ntt_ppc_asm", check_ntt_ppc_asm}, {"poly_tomont_ppc_asm", check_poly_tomont_ppc_asm}, {"reduce_ppc_asm", check_reduce_ppc_asm}, +#endif /* MLK_SYS_PPC64LE_POWER8_VECTOR */ {NULL, NULL} /* Sentinel */ }; diff --git a/test/abicheck/ppc64le/selftest_ppc64le.S b/test/abicheck/ppc64le/selftest_ppc64le.S index b68ecfefb8..633871cff3 100644 --- a/test/abicheck/ppc64le/selftest_ppc64le.S +++ b/test/abicheck/ppc64le/selftest_ppc64le.S @@ -12,10 +12,14 @@ * input. */ +#include "../../../mlkem/src/sys.h" + #if defined(__ELF__) .section .note.GNU-stack,"",@progbits #endif +#if defined(MLK_SYS_PPC64LE_POWER8_VECTOR) + .text .machine power8 .abiversion 2 @@ -118,3 +122,5 @@ define_local \name corrupt_cr selftest_ppc64le_corrupt_cr2, 8 corrupt_cr selftest_ppc64le_corrupt_cr3, 12 corrupt_cr selftest_ppc64le_corrupt_cr4, 16 + +#endif /* MLK_SYS_PPC64LE_POWER8_VECTOR */ diff --git a/test/abicheck/selftest.c b/test/abicheck/selftest.c index ce4a05e869..d631a4e7d9 100644 --- a/test/abicheck/selftest.c +++ b/test/abicheck/selftest.c @@ -175,7 +175,7 @@ static const selftest_entry_t x86_64_entries[] = { {NULL, NULL, 0}, }; -#elif defined(MLK_SYS_PPC64LE) +#elif defined(MLK_SYS_PPC64LE_POWER8_VECTOR) extern void selftest_ppc64le_noop(void); /* GPRs r14..r31 (18) */ @@ -325,7 +325,7 @@ static const selftest_entry_t armv81m_entries[] = { }; #endif /* !MLK_SYS_AARCH64 && !(MLK_SYS_X86_64 && MLK_SYSV_ABI_SUPPORTED) && \ - !MLK_SYS_PPC64LE && MLK_SYS_ARMV81M_MVE */ + !MLK_SYS_PPC64LE_POWER8_VECTOR && MLK_SYS_ARMV81M_MVE */ int abicheck_selftest(void) { @@ -354,21 +354,26 @@ int abicheck_selftest(void) asm_call_stub_x86_64_sysv, check_x86_64_sysv_compliance, x86_64_entries, (MLK_SYSV_ABI void (*)(void))); -#elif defined(MLK_SYS_PPC64LE) - SELFTEST_RUN_ARCH("ppc64le", struct ppc64le_register_state, - init_ppc64le_register_state, asm_call_stub_ppc64le, - check_ppc64le_elfv2_compliance, ppc64le_entries, - (void (*)(void))); +#elif defined(MLK_SYS_PPC64LE_POWER8_VECTOR) + /* The call stub saves vector registers. Keep the self-test's capability + * check aligned with the current backend's POWER8 minimum. */ + if (mlk_sys_check_capability(MLK_SYS_CAP_PPC64LE_POWER8_VECTOR)) + { + SELFTEST_RUN_ARCH("ppc64le", struct ppc64le_register_state, + init_ppc64le_register_state, asm_call_stub_ppc64le, + check_ppc64le_elfv2_compliance, ppc64le_entries, + (void (*)(void))); + } #elif defined(MLK_SYS_ARMV81M_MVE) SELFTEST_RUN_ARCH("armv81m", struct armv81m_register_state, init_armv81m_register_state, asm_call_stub_armv81m, check_armv81m_aapcs32_compliance, armv81m_entries, (void (*)(void))); #else /* !MLK_SYS_AARCH64 && !(MLK_SYS_X86_64 && MLK_SYSV_ABI_SUPPORTED) && \ - !MLK_SYS_PPC64LE && MLK_SYS_ARMV81M_MVE */ + !MLK_SYS_PPC64LE_POWER8_VECTOR && MLK_SYS_ARMV81M_MVE */ /* No abicheck support on this architecture. */ #endif /* !MLK_SYS_AARCH64 && !(MLK_SYS_X86_64 && MLK_SYSV_ABI_SUPPORTED) && \ - !MLK_SYS_PPC64LE && !MLK_SYS_ARMV81M_MVE */ + !MLK_SYS_PPC64LE_POWER8_VECTOR && !MLK_SYS_ARMV81M_MVE */ return failures; }