077d9d
diff --git a/cipher/crc-ppc.c b/cipher/crc-ppc.c
077d9d
index 4d7f0add..b9a40130 100644
077d9d
--- a/cipher/crc-ppc.c
077d9d
+++ b/cipher/crc-ppc.c
077d9d
@@ -154,26 +154,63 @@ static const vector16x_u8 bswap_const ALIGNED_64 =
077d9d
 #ifdef WORDS_BIGENDIAN
077d9d
 # define CRC_VEC_U64_DEF(lo, hi) { (hi), (lo) }
077d9d
 # define CRC_VEC_U64_LOAD(offs, ptr) \
077d9d
-          asm_swap_u64(vec_vsx_ld((offs), (const unsigned long long *)(ptr)))
077d9d
+	  asm_swap_u64(asm_vec_u64_load(offs, ptr))
077d9d
 # define CRC_VEC_U64_LOAD_LE(offs, ptr) \
077d9d
-	  CRC_VEC_SWAP(vec_vsx_ld((offs), (const unsigned long long *)(ptr)))
077d9d
+	  CRC_VEC_SWAP(asm_vec_u64_load(offs, ptr))
077d9d
 # define CRC_VEC_U64_LOAD_BE(offs, ptr) \
077d9d
-         vec_vsx_ld((offs), (const unsigned long long *)(ptr))
077d9d
+	  asm_vec_u64_load(offs, ptr)
077d9d
 # define CRC_VEC_SWAP_TO_LE(v) CRC_VEC_SWAP(v)
077d9d
 # define CRC_VEC_SWAP_TO_BE(v) (v)
077d9d
 # define VEC_U64_LO 1
077d9d
 # define VEC_U64_HI 0
077d9d
+
077d9d
+static ASM_FUNC_ATTR_INLINE vector2x_u64
077d9d
+asm_vec_u64_load(unsigned long offset, const void *ptr)
077d9d
+{
077d9d
+  vector2x_u64 vecu64;
077d9d
+#if __GNUC__ >= 4
077d9d
+  if (__builtin_constant_p (offset) && offset == 0)
077d9d
+    __asm__ volatile ("lxvd2x %x0,0,%1\n\t"
077d9d
+		      : "=wa" (vecu64)
077d9d
+		      : "r" ((uintptr_t)ptr)
077d9d
+		      : "memory");
077d9d
+  else
077d9d
+#endif
077d9d
+    __asm__ volatile ("lxvd2x %x0,%1,%2\n\t"
077d9d
+		      : "=wa" (vecu64)
077d9d
+		      : "r" (offset), "r" ((uintptr_t)ptr)
077d9d
+		      : "memory", "r0");
077d9d
+  return vecu64;
077d9d
+}
077d9d
 #else
077d9d
 # define CRC_VEC_U64_DEF(lo, hi) { (lo), (hi) }
077d9d
-# define CRC_VEC_U64_LOAD(offs, ptr) \
077d9d
-	  vec_vsx_ld((offs), (const unsigned long long *)(ptr))
077d9d
-# define CRC_VEC_U64_LOAD_LE(offs, ptr) CRC_VEC_U64_LOAD((offs), (ptr))
077d9d
+# define CRC_VEC_U64_LOAD(offs, ptr) asm_vec_u64_load_le(offs, ptr)
077d9d
+# define CRC_VEC_U64_LOAD_LE(offs, ptr) asm_vec_u64_load_le(offs, ptr)
077d9d
 # define CRC_VEC_U64_LOAD_BE(offs, ptr) asm_vec_u64_load_be(offs, ptr)
077d9d
 # define CRC_VEC_SWAP_TO_LE(v) (v)
077d9d
 # define CRC_VEC_SWAP_TO_BE(v) CRC_VEC_SWAP(v)
077d9d
 # define VEC_U64_LO 0
077d9d
 # define VEC_U64_HI 1
077d9d
 
077d9d
+static ASM_FUNC_ATTR_INLINE vector2x_u64
077d9d
+asm_vec_u64_load_le(unsigned long offset, const void *ptr)
077d9d
+{
077d9d
+  vector2x_u64 vecu64;
077d9d
+#if __GNUC__ >= 4
077d9d
+  if (__builtin_constant_p (offset) && offset == 0)
077d9d
+    __asm__ volatile ("lxvd2x %x0,0,%1\n\t"
077d9d
+		      : "=wa" (vecu64)
077d9d
+		      : "r" ((uintptr_t)ptr)
077d9d
+		      : "memory");
077d9d
+  else
077d9d
+#endif
077d9d
+    __asm__ volatile ("lxvd2x %x0,%1,%2\n\t"
077d9d
+		      : "=wa" (vecu64)
077d9d
+		      : "r" (offset), "r" ((uintptr_t)ptr)
077d9d
+		      : "memory", "r0");
077d9d
+  return asm_swap_u64(vecu64);
077d9d
+}
077d9d
+
077d9d
 static ASM_FUNC_ATTR_INLINE vector2x_u64
077d9d
 asm_vec_u64_load_be(unsigned int offset, const void *ptr)
077d9d
 {
077d9d
diff --git a/cipher/sha512-ppc.c b/cipher/sha512-ppc.c
077d9d
index a758e1ea..31ea25bf 100644
077d9d
--- a/cipher/sha512-ppc.c
077d9d
+++ b/cipher/sha512-ppc.c
077d9d
@@ -115,14 +115,62 @@ vec_merge_idx0_elems(vector2x_u64 v0, vector2x_u64 v1)
077d9d
 static ASM_FUNC_ATTR_INLINE vector2x_u64
077d9d
 vec_vshasigma_u64(vector2x_u64 v, unsigned int a, unsigned int b)
077d9d
 {
077d9d
-  asm ("vshasigmad %0,%1,%2,%3"
077d9d
-       : "=v" (v)
077d9d
-       : "v" (v), "g" (a), "g" (b)
077d9d
-       : "memory");
077d9d
+  __asm__ ("vshasigmad %0,%1,%2,%3"
077d9d
+	   : "=v" (v)
077d9d
+	   : "v" (v), "g" (a), "g" (b)
077d9d
+	   : "memory");
077d9d
   return v;
077d9d
 }
077d9d
 
077d9d
 
077d9d
+static ASM_FUNC_ATTR_INLINE vector2x_u64
077d9d
+vec_u64_load(unsigned long offset, const void *ptr)
077d9d
+{
077d9d
+  vector2x_u64 vecu64;
077d9d
+#if __GNUC__ >= 4
077d9d
+  if (__builtin_constant_p (offset) && offset == 0)
077d9d
+    __asm__ ("lxvd2x %x0,0,%1\n\t"
077d9d
+	     : "=wa" (vecu64)
077d9d
+	     : "r" ((uintptr_t)ptr)
077d9d
+	     : "memory");
077d9d
+  else
077d9d
+#endif
077d9d
+    __asm__ ("lxvd2x %x0,%1,%2\n\t"
077d9d
+	     : "=wa" (vecu64)
077d9d
+	     : "r" (offset), "r" ((uintptr_t)ptr)
077d9d
+	     : "memory", "r0");
077d9d
+#ifndef WORDS_BIGENDIAN
077d9d
+  __asm__ ("xxswapd %x0, %x1"
077d9d
+	   : "=wa" (vecu64)
077d9d
+	   : "wa" (vecu64));
077d9d
+#endif
077d9d
+  return vecu64;
077d9d
+}
077d9d
+
077d9d
+
077d9d
+static ASM_FUNC_ATTR_INLINE void
077d9d
+vec_u64_store(vector2x_u64 vecu64, unsigned long offset, void *ptr)
077d9d
+{
077d9d
+#ifndef WORDS_BIGENDIAN
077d9d
+  __asm__ ("xxswapd %x0, %x1"
077d9d
+	   : "=wa" (vecu64)
077d9d
+	   : "wa" (vecu64));
077d9d
+#endif
077d9d
+#if __GNUC__ >= 4
077d9d
+  if (__builtin_constant_p (offset) && offset == 0)
077d9d
+    __asm__ ("stxvd2x %x0,0,%1\n\t"
077d9d
+	     :
077d9d
+	     : "wa" (vecu64), "r" ((uintptr_t)ptr)
077d9d
+	     : "memory");
077d9d
+  else
077d9d
+#endif
077d9d
+    __asm__ ("stxvd2x %x0,%1,%2\n\t"
077d9d
+	     :
077d9d
+	     : "wa" (vecu64), "r" (offset), "r" ((uintptr_t)ptr)
077d9d
+	     : "memory", "r0");
077d9d
+}
077d9d
+
077d9d
+
077d9d
 /* SHA2 round in vector registers */
077d9d
 #define R(a,b,c,d,e,f,g,h,k,w) do                             \
077d9d
     {                                                         \
077d9d
@@ -168,13 +216,13 @@ _gcry_sha512_transform_ppc8(u64 state[8],
077d9d
   vector2x_u64 a, b, c, d, e, f, g, h, t1, t2;
077d9d
   u64 w[16];
077d9d
 
077d9d
-  h0 = vec_vsx_ld (8 * 0, (unsigned long long *)state);
077d9d
+  h0 = vec_u64_load (8 * 0, (unsigned long long *)state);
077d9d
   h1 = vec_rol_elems (h0, 1);
077d9d
-  h2 = vec_vsx_ld (8 * 2, (unsigned long long *)state);
077d9d
+  h2 = vec_u64_load (8 * 2, (unsigned long long *)state);
077d9d
   h3 = vec_rol_elems (h2, 1);
077d9d
-  h4 = vec_vsx_ld (8 * 4, (unsigned long long *)state);
077d9d
+  h4 = vec_u64_load (8 * 4, (unsigned long long *)state);
077d9d
   h5 = vec_rol_elems (h4, 1);
077d9d
-  h6 = vec_vsx_ld (8 * 6, (unsigned long long *)state);
077d9d
+  h6 = vec_u64_load (8 * 6, (unsigned long long *)state);
077d9d
   h7 = vec_rol_elems (h6, 1);
077d9d
 
077d9d
   while (nblks >= 2)
077d9d
@@ -514,10 +562,10 @@ _gcry_sha512_transform_ppc8(u64 state[8],
077d9d
   h2 = vec_merge_idx0_elems (h2, h3);
077d9d
   h4 = vec_merge_idx0_elems (h4, h5);
077d9d
   h6 = vec_merge_idx0_elems (h6, h7);
077d9d
-  vec_vsx_st (h0, 8 * 0, (unsigned long long *)state);
077d9d
-  vec_vsx_st (h2, 8 * 2, (unsigned long long *)state);
077d9d
-  vec_vsx_st (h4, 8 * 4, (unsigned long long *)state);
077d9d
-  vec_vsx_st (h6, 8 * 6, (unsigned long long *)state);
077d9d
+  vec_u64_store (h0, 8 * 0, (unsigned long long *)state);
077d9d
+  vec_u64_store (h2, 8 * 2, (unsigned long long *)state);
077d9d
+  vec_u64_store (h4, 8 * 4, (unsigned long long *)state);
077d9d
+  vec_u64_store (h6, 8 * 6, (unsigned long long *)state);
077d9d
 
077d9d
   return sizeof(w);
077d9d
 }
077d9d
diff --git a/configure.ac b/configure.ac
077d9d
index b6b6455a..be35ce42 100644
077d9d
--- a/configure.ac
077d9d
+++ b/configure.ac
077d9d
@@ -1745,10 +1745,12 @@ AC_CACHE_CHECK([whether compiler supports PowerPC AltiVec/VSX intrinsics],
077d9d
 	AC_COMPILE_IFELSE([AC_LANG_SOURCE(
077d9d
 	[[#include <altivec.h>
077d9d
 	  typedef vector unsigned char block;
077d9d
+	  typedef vector unsigned int vecu32;
077d9d
 	  block fn(block in)
077d9d
 	  {
077d9d
 	    block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0));
077d9d
-	    return vec_cipher_be (t, in);
077d9d
+	    vecu32 y = vec_vsx_ld (0, (unsigned int*)0);
077d9d
+	    return vec_cipher_be (t, in) ^ (block)y;
077d9d
 	  }
077d9d
 	  ]])],
077d9d
 	[gcry_cv_cc_ppc_altivec=yes])
077d9d
@@ -1769,10 +1771,12 @@ if test "$gcry_cv_cc_ppc_altivec" = "no" &&
077d9d
     AC_COMPILE_IFELSE([AC_LANG_SOURCE(
077d9d
       [[#include <altivec.h>
077d9d
 	typedef vector unsigned char block;
077d9d
+	typedef vector unsigned int vecu32;
077d9d
 	block fn(block in)
077d9d
 	{
077d9d
 	  block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0));
077d9d
-	  return vec_cipher_be (t, in);
077d9d
+	  vecu32 y = vec_vsx_ld (0, (unsigned int*)0);
077d9d
+	  return vec_cipher_be (t, in) ^ (block)y;
077d9d
 	}]])],
077d9d
       [gcry_cv_cc_ppc_altivec_cflags=yes])])
077d9d
   if test "$gcry_cv_cc_ppc_altivec_cflags" = "yes" ; then
077d9d
077d9d
diff --git a/configure.ac b/configure.ac
077d9d
index 202ac888..fd447906 100644
077d9d
--- a/configure.ac
077d9d
+++ b/configure.ac
077d9d
@@ -2562,13 +2562,13 @@ if test "$found" = "1" ; then
077d9d
          GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc-intel-pclmul.lo"
077d9d
       ;;
077d9d
       powerpc64le-*-*)
077d9d
-         GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-ppc.lo"
077d9d
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc-ppc.lo"
077d9d
       ;;
077d9d
       powerpc64-*-*)
077d9d
-         GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-ppc.lo"
077d9d
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc-ppc.lo"
077d9d
       ;;
077d9d
       powerpc-*-*)
077d9d
-         GCRYPT_CIPHERS="$GCRYPT_CIPHERS crc-ppc.lo"
077d9d
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc-ppc.lo"
077d9d
       ;;
077d9d
    esac
077d9d
 fi
077d9d
@@ -2635,17 +2635,17 @@ if test "$found" = "1" ; then
077d9d
       ;;
077d9d
       powerpc64le-*-*)
077d9d
          # Build with the crypto extension implementation
077d9d
-         GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha256-ppc.lo"
077d9d
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-ppc.lo"
077d9d
       ;;
077d9d
       powerpc64-*-*)
077d9d
          # Big-Endian.
077d9d
          # Build with the crypto extension implementation
077d9d
-         GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha256-ppc.lo"
077d9d
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-ppc.lo"
077d9d
       ;;
077d9d
       powerpc-*-*)
077d9d
          # Big-Endian.
077d9d
          # Build with the crypto extension implementation
077d9d
-         GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha256-ppc.lo"
077d9d
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-ppc.lo"
077d9d
    esac
077d9d
 fi
077d9d
 
077d9d
@@ -2667,17 +2667,17 @@ if test "$found" = "1" ; then
077d9d
       ;;
077d9d
       powerpc64le-*-*)
077d9d
          # Build with the crypto extension implementation
077d9d
-         GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha512-ppc.lo"
077d9d
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-ppc.lo"
077d9d
       ;;
077d9d
       powerpc64-*-*)
077d9d
          # Big-Endian.
077d9d
          # Build with the crypto extension implementation
077d9d
-         GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha512-ppc.lo"
077d9d
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-ppc.lo"
077d9d
       ;;
077d9d
       powerpc-*-*)
077d9d
          # Big-Endian.
077d9d
          # Build with the crypto extension implementation
077d9d
-         GCRYPT_CIPHERS="$GCRYPT_CIPHERS sha512-ppc.lo"
077d9d
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-ppc.lo"
077d9d
    esac
077d9d
 
077d9d
    if test x"$neonsupport" = xyes ; then