---
Makefile.in | 2 +-
aclocal.m4 | 52 ++++++++++++++++++++++++++++++++++++++++
configure.ac | 11 +++++++++
powerpc64/README | 67
++++++++++++++++++++++++++++++++++++++++++++++++++++
powerpc64/machine.m4 | 24 +++++++++++++++++++
5 files changed, 155 insertions(+), 1 deletion(-)
create mode 100644 powerpc64/README
create mode 100644 powerpc64/machine.m4
diff --git a/Makefile.in b/Makefile.in
index 77efb5c9..1508e8f4 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -603,7 +603,7 @@ distdir: $(DISTFILES)
done
set -e; for d in sparc32 sparc64 x86 \
x86_64 x86_64/aesni x86_64/sha_ni x86_64/fat \
- arm arm/neon arm/v6 arm/fat ; do \
+ arm arm/neon arm/v6 arm/fat powerpc64 ; do \
mkdir "$(distdir)/$$d" ; \
find "$(srcdir)/$$d" -maxdepth 1 '(' -name '*.asm' -o -name '*.m4' ')' \
-exec cp '{}' "$(distdir)/$$d" ';' ; \
diff --git a/aclocal.m4 b/aclocal.m4
index 513b2df4..e38181ad 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -462,6 +462,58 @@ foo:
fi
])
+dnl NETTLE_CHECK_POWER_CRYPTO_EXT
+dnl ---------------------
+dnl Check if POWER crypto extensions should be used.
+dnl Obeys enable_power_crypto_ext, which should be set earlier.
+AC_DEFUN([NETTLE_CHECK_POWER_CRYPTO_EXT],
+[if test "$enable_power_crypto_ext" = auto ; then
+ if test "$cross_compiling" = yes ; then
+ dnl Check if compiler/assembler accepts it.
+ AC_CACHE_CHECK([if assembler accepts crypto instructions],
+ nettle_cv_asm_power_vcrypto,
+ [GMP_TRY_ASSEMBLE([
+.text
+foo:
+ vcipher 0, 0, 1
+],
+ [nettle_cv_asm_power_vcrypto=yes],
+ [nettle_cv_asm_power_vcrypto=no])])
+ enable_power_crypto_ext="$nettle_cv_asm_power_vcrypto"
+ else
+ AC_CACHE_CHECK([if crypto extensions supported],
+ nettle_cv_asm_power_vcrypto,
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#if defined(__FreeBSD__) && __FreeBSD__ < 12
+#include <sys/sysctl.h>
+#else
+#include <sys/auxv.h>
+#endif
+// Define from arch/powerpc/include/uapi/asm/cputable.h in Linux kernel
+#ifndef PPC_FEATURE2_VEC_CRYPTO
+#define PPC_FEATURE2_VEC_CRYPTO 0x02000000
+#endif
+ unsigned long hwcap2 = 0;
+ ]], [[
+#if defined(__FreeBSD__)
+#if __FreeBSD__ < 12
+ size_t len = sizeof(hwcap2);
+ sysctlbyname("hw.cpu_features2", &hwcap2, &len, NULL, 0);
+#else
+ elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2));
+#endif
+#else
+ hwcap2 = getauxval(AT_HWCAP2);
+#endif
+ return (hwcap2 & PPC_FEATURE2_VEC_CRYPTO) ==
PPC_FEATURE2_VEC_CRYPTO ? 0 : 1;
+ ]])],
+ [nettle_cv_asm_power_vcrypto=yes],
+ [nettle_cv_asm_power_vcrypto=no])])
+ enable_power_crypto_ext="$nettle_cv_asm_power_vcrypto"
+ fi
+fi
+])
+
dnl NETTLE_CHECK_IFUNC
dnl ------------------
dnl Check if __attribute__ ((ifunc(...))) works
diff --git a/configure.ac b/configure.ac
index 1c0b7393..cc0d67ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -89,6 +89,10 @@ AC_ARG_ENABLE(x86-sha-ni,
AC_HELP_STRING([--enable-x86-sha-ni], [Enable x86_64 sha_ni
instructions. (default=no)]),,
[enable_x86_sha_ni=no])
+AC_ARG_ENABLE(power-crypto-ext,
+ AC_HELP_STRING([--enable-power-crypto-ext], [Enable POWER crypto
extentions. (default=auto)]),,
+ [enable_power_crypto_ext=auto])
+
AC_ARG_ENABLE(mini-gmp,
AC_HELP_STRING([--enable-mini-gmp], [Enable mini-gmp, used instead of
libgmp.]),,
[enable_mini_gmp=no])
@@ -434,6 +438,13 @@ if test "x$enable_assembler" = xyes ; then
fi
fi
;;
+ *powerpc64*)
+ NETTLE_CHECK_POWER_CRYPTO_EXT
+
+ if test "x$enable_power_crypto_ext" = xyes ; then
+ asm_path=powerpc64
+ fi
+ ;;
*)
enable_assembler=no
;;
diff --git a/powerpc64/README b/powerpc64/README
new file mode 100644
index 00000000..1890ee9a
--- /dev/null
+++ b/powerpc64/README
@@ -0,0 +1,67 @@
+General-Purpose Register Conventions
+
+Register Status Use
+
+GPR0 volatile In function prologs.
+GPR1 dedicated Stack pointer.
+GPR2 dedicated Table of Contents (TOC) pointer.
+GPR3 volatile First word of a function's argument list;
+ first word of a scalar function return.
+GPR4 volatile Second word of a function's argument list;
+ second word of a scalar function return.
+GPR5 volatile Third word of a function's argument list.
+GPR6 volatile Fourth word of a function's argument list.
+GPR7 volatile Fifth word of a function's argument list.
+GPR8 volatile Sixth word of a function's argument list.
+GPR9 volatile Seventh word of a function's argument list.
+GPR10 volatile Eighth word of a function's argument list.
+GPR11 volatile In calls by pointer and as an environment pointer for
languages
+ that require it (for example, PASCAL).
+GPR12 volatile For special exception handling required by certain
languages and in
+ glink code.
+GPR13 reserved Reserved under 64-bit environment; not restored across
system calls.
+GPR14:GPR31 nonvolatile These registers must be preserved across a
function call.
+
+Vector Register Conventions
+
+Register Status
+
+VR0 Volatile
+VR1 Volatile
+VR2 Volatile
+VR3 Volatile
+VR4 Volatile
+VR5 Volatile
+VR6 Volatile
+VR7 Volatile
+VR8 Volatile
+VR9 Volatile
+VR10 Volatile
+VR11 Volatile
+VR12 Volatile
+VR13 Volatile
+VR14 Volatile
+VR15 Volatile
+VR16 Volatile
+VR17 Volatile
+VR18 Volatile
+VR19 Volatile
+VR20:31 Nonvolatile (extended ABI mode) their values are preserved across
function calls
+
+Addressing memory
+
+There are many ways to reference data, the current implementations uses
GOT-indirect addressing
+(Accessing data through the global offset table):
+1. Define data in .data section
+2. Load the address of data into register from the global offset table
e.g. ld 7, my_var@got(2)
+3. Use the address to load the value of data into register e.g. ld 3, 0(7)
+
+VSX instructions (lxvd2x and stxvd2x) are used to load and store data to
memory
+instead of VR instructions (lvx and stvx) as it produces a fewer
instructions
+(lvx and stvx) can be used to load and store data into storage operands
+but additional instructions are needed to access unaligned storage
operands, please
+refer to "6.4.1 Accessing Unaligned Storage Operands" in "POWER ISA
Version 2.07 B"
+to see an example of accessing unaligned storage operands (lxvd2x and
stxvd2x) can
+be used to load and store data into unaligned storage operands but
permuting is needed
+for loading and storing data in little-endian mode
+VSX registers are defined with "X" suffix
diff --git a/powerpc64/machine.m4 b/powerpc64/machine.m4
new file mode 100644
index 00000000..c8005cd8
--- /dev/null
+++ b/powerpc64/machine.m4
@@ -0,0 +1,24 @@
+define(<PROLOGUE>,
+<ifelse(WORDS_BIGENDIAN,no,
+<.align 5
+.globl C_NAME($1)
+DECLARE_FUNC(C_NAME($1))
+C_NAME($1):
+addis 2,12,(.TOC.-C_NAME($1))@ha
+addi 2,2,(.TOC.-C_NAME($1))@l
+.localentry C_NAME($1), .-C_NAME($1)>,
+<.globl C_NAME($1)
+DECLARE_FUNC(C_NAME($1))
+.section ".opd","aw"
+.align 3
+C_NAME($1):
+.quad .C_NAME($1),.TOC.@tocbase,0
+.previous
+.align 5
+.C_NAME($1):>)>)
+
+define(<EPILOGUE>,
+<ifelse(WORDS_BIGENDIAN,no,
+<.size C_NAME($1), . - C_NAME($1)>,
+<.size .C_NAME($1), . - .C_NAME($1)
+.size C_NAME($1), . - .C_NAME($1)>)>)
--
2.17.1