Enable AMD64 AES implementation for WIN64
authorJussi Kivilinna <jussi.kivilinna@iki.fi>
Sat, 2 May 2015 10:27:06 +0000 (13:27 +0300)
committerJussi Kivilinna <jussi.kivilinna@iki.fi>
Sat, 2 May 2015 11:45:30 +0000 (14:45 +0300)
* cipher/rijndael-amd64.S: Enable when
HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
(ELF): New macro to mask lines with ELF specific commands.
* cipher/rijndael-internal.h (USE_AMD64_ASM): Enable when
HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS defined.
(do_encrypt, do_decrypt)
[USE_AMD64_ASM && !HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS]: Use
assembly block to call AMD64 assembly encrypt/decrypt function.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
cipher/rijndael-amd64.S
cipher/rijndael-internal.h
cipher/rijndael.c

index 24c555a..b149e94 100644 (file)
@@ -20,7 +20,8 @@
 
 #ifdef __x86_64
 #include <config.h>
-#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_AES)
+#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_AES)
 
 #ifdef __PIC__
 #  define RIP (%rip)
 #  define RIP
 #endif
 
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
 .text
 
 /* table macros */
 
 .align 8
 .globl _gcry_aes_amd64_encrypt_block
-.type   _gcry_aes_amd64_encrypt_block,@function;
+ELF(.type   _gcry_aes_amd64_encrypt_block,@function;)
 
 _gcry_aes_amd64_encrypt_block:
        /* input:
@@ -279,7 +286,7 @@ _gcry_aes_amd64_encrypt_block:
        lastencround(11);
 
        jmp .Lenc_done;
-.size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block;
+ELF(.size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block;)
 
 #define do_decround(next_r) \
        do16bit_shr(16, mov, RA, Dsize, D0, RNA, D0, RNB, RT0, RT1); \
@@ -365,7 +372,7 @@ _gcry_aes_amd64_encrypt_block:
 
 .align 8
 .globl _gcry_aes_amd64_decrypt_block
-.type   _gcry_aes_amd64_decrypt_block,@function;
+ELF(.type   _gcry_aes_amd64_decrypt_block,@function;)
 
 _gcry_aes_amd64_decrypt_block:
        /* input:
@@ -440,7 +447,7 @@ _gcry_aes_amd64_decrypt_block:
        decround(9);
 
        jmp .Ldec_tail;
-.size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block;
+ELF(.size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block;)
 
 #endif /*USE_AES*/
 #endif /*__x86_64*/
index 33ca53f..6641728 100644 (file)
@@ -39,7 +39,8 @@
 
 /* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */
 #undef USE_AMD64_ASM
-#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+#if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
+    defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
 # define USE_AMD64_ASM 1
 #endif
 
index ade41c9..7ebf329 100644 (file)
@@ -665,8 +665,25 @@ do_encrypt (const RIJNDAEL_context *ctx,
             unsigned char *bx, const unsigned char *ax)
 {
 #ifdef USE_AMD64_ASM
+# ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
   return _gcry_aes_amd64_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds,
                                       encT);
+# else
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  uintptr_t ret;
+  asm ("movq %[encT], %%r8\n\t"
+       "callq *%[ret]\n\t"
+       : [ret] "=a" (ret)
+       : "0" (_gcry_aes_amd64_encrypt_block),
+         "D" (ctx->keyschenc),
+         "S" (bx),
+         "d" (ax),
+         "c" (ctx->rounds),
+         [encT] "r" (encT)
+       : "cc", "memory", "r8", "r9", "r10", "r11");
+  return ret;
+# endif /* HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS */
 #elif defined(USE_ARM_ASM)
   return _gcry_aes_arm_encrypt_block(ctx->keyschenc, bx, ax, ctx->rounds, encT);
 #else
@@ -1008,8 +1025,25 @@ do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx,
             const unsigned char *ax)
 {
 #ifdef USE_AMD64_ASM
+# ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
   return _gcry_aes_amd64_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds,
                                       &dec_tables);
+# else
+  /* Call SystemV ABI function without storing non-volatile XMM registers,
+   * as target function does not use vector instruction sets. */
+  uintptr_t ret;
+  asm ("movq %[dectabs], %%r8\n\t"
+       "callq *%[ret]\n\t"
+       : [ret] "=a" (ret)
+       : "0" (_gcry_aes_amd64_decrypt_block),
+         "D" (ctx->keyschdec),
+         "S" (bx),
+         "d" (ax),
+         "c" (ctx->rounds),
+         [dectabs] "r" (&dec_tables)
+       : "cc", "memory", "r8", "r9", "r10", "r11");
+  return ret;
+# endif /* HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS */
 #elif defined(USE_ARM_ASM)
   return _gcry_aes_arm_decrypt_block(ctx->keyschdec, bx, ax, ctx->rounds,
                                     &dec_tables);