[PATCH 1/2] Move AMD64 MS to SysV calling convention conversion to assembly side
Jussi Kivilinna
jussi.kivilinna at iki.fi
Tue Jan 9 18:25:12 CET 2018
* cipher/Makefile.am: Add 'asm-common-amd64.h'.
* cipher/asm-common-amd64.h: New.
* cipher/blowfish-amd64.S: Add ENTER_SYSV_FUNC_* and EXIT_SYSV_FUNC for
each global function from 'asm-common-amd64.h'.
* cipher/cast5-amd64.S: Ditto.
* cipher/des-amd64.S: Ditto.
* cipher/rijndael-amd64.S: Ditto.
* cipher/twofish-amd64.S: Ditto.
* cipher/arcfour-amd64.S: Ditto.
* cipher/blowfish.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
(call_sysv_fn): Remove.
* cipher/cast5.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
(call_sysv_fn): Remove.
* cipher/twofish.c [HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]
(call_sysv_fn, call_sysv_fn5, call_sysv_fn6): Remove.
* cipher/rijndael.c (do_encrypt, do_decrypt)
[HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS]: Remove assembly block for
calling SysV ABI function.
* cipher/arcfour.c [USE_AMD64_ASM] (encrypt_stream): Ditto.
--
Old approach was to convert MS ABI to SysV ABI calling convention
for AMD64 assembly functions at caller side. This patch moves
calling convention conversion to assembly/callee side.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
cipher/Makefile.am | 1 +
cipher/arcfour-amd64.S | 8 ++--
cipher/arcfour.c | 14 -------
cipher/asm-common-amd64.h | 90 +++++++++++++++++++++++++++++++++++++++++++++
cipher/blowfish-amd64.S | 24 ++++++++++--
cipher/blowfish.c | 44 ----------------------
cipher/cast5-amd64.S | 42 +++++++++------------
cipher/cast5.c | 38 -------------------
cipher/des-amd64.S | 27 +++++++-------
cipher/des.c | 33 -----------------
cipher/rijndael-amd64.S | 20 +++++-----
cipher/rijndael.c | 38 -------------------
cipher/twofish-amd64.S | 36 +++++++++++++-----
cipher/twofish.c | 87 --------------------------------------------
14 files changed, 179 insertions(+), 323 deletions(-)
create mode 100644 cipher/asm-common-amd64.h
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 3c4eae0b9..bba815bbe 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -61,6 +61,7 @@ dsa-common.c rsa-common.c \
sha1.h
EXTRA_libcipher_la_SOURCES = \
+asm-common-amd64.h \
arcfour.c arcfour-amd64.S \
blowfish.c blowfish-amd64.S blowfish-arm.S \
cast5.c cast5-amd64.S cast5-arm.S \
diff --git a/cipher/arcfour-amd64.S b/cipher/arcfour-amd64.S
index 2e52ea00d..c08f3453b 100644
--- a/cipher/arcfour-amd64.S
+++ b/cipher/arcfour-amd64.S
@@ -18,17 +18,14 @@
#if defined(USE_ARCFOUR) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
-#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
-# define ELF(...) __VA_ARGS__
-#else
-# define ELF(...) /*_*/
-#endif
+#include "asm-common-amd64.h"
.text
.align 16
.globl _gcry_arcfour_amd64
ELF(.type _gcry_arcfour_amd64, at function)
_gcry_arcfour_amd64:
+ ENTER_SYSV_FUNC_PARAMS_0_4
push %rbp
push %rbx
mov %rdi, %rbp # key = ARG(key)
@@ -96,6 +93,7 @@ _gcry_arcfour_amd64:
movb %dl, (4*256+4)(%rbp) # key->x = x
pop %rbx
pop %rbp
+ EXIT_SYSV_FUNC
ret
.L__gcry_arcfour_amd64_end:
ELF(.size _gcry_arcfour_amd64,.L__gcry_arcfour_amd64_end-_gcry_arcfour_amd64)
diff --git a/cipher/arcfour.c b/cipher/arcfour.c
index 44e8ef46c..085df9bbd 100644
--- a/cipher/arcfour.c
+++ b/cipher/arcfour.c
@@ -54,21 +54,7 @@ static void
encrypt_stream (void *context,
byte *outbuf, const byte *inbuf, size_t length)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- const void *fn = _gcry_arcfour_amd64;
- /* Call SystemV ABI function without storing non-volatile XMM registers,
- * as target function does not use vector instruction sets. */
- asm volatile ("callq *%0\n\t"
- : "+a" (fn),
- "+D" (context),
- "+S" (length),
- "+d" (inbuf),
- "+c" (outbuf)
- :
- : "cc", "memory", "r8", "r9", "r10", "r11");
-#else
_gcry_arcfour_amd64 (context, length, inbuf, outbuf );
-#endif
}
#else /*!USE_AMD64_ASM*/
diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h
new file mode 100644
index 000000000..7eb426495
--- /dev/null
+++ b/cipher/asm-common-amd64.h
@@ -0,0 +1,90 @@
+/* asm-common-amd64.h - Common macros for AMD64 assembly
+ *
+ * Copyright (C) 2018 Jussi Kivilinna <jussi.kivilinna at iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_ASM_COMMON_AMD64_H
+#define GCRY_ASM_COMMON_AMD64_H
+
+#include <config.h>
+
+#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+# define ELF(...) __VA_ARGS__
+#else
+# define ELF(...) /*_*/
+#endif
+
+#ifdef __PIC__
+# define rRIP (%rip)
+#else
+# define rRIP
+#endif
+
+#ifdef __PIC__
+# define RIP %rip
+#else
+# define RIP
+#endif
+
+#if defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS) || !defined(__PIC__)
+# define GET_EXTERN_POINTER(name, reg) movabsq $name, reg
+#else
+# ifdef __code_model_large__
+# define GET_EXTERN_POINTER(name, reg) \
+ pushq %r15; \
+ pushq %r14; \
+ 1: leaq 1b(%rip), reg; \
+ movabsq $_GLOBAL_OFFSET_TABLE_-1b, %r14; \
+ movabsq $name at GOT, %r15; \
+ addq %r14, reg; \
+ popq %r14; \
+ movq (reg, %r15), reg; \
+ popq %r15;
+# else
+# define GET_EXTERN_POINTER(name, reg) movq name at GOTPCREL(%rip), reg
+# endif
+#endif
+
+#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
+# define ENTER_SYSV_FUNC_PARAMS_0_4 \
+ pushq %rdi; \
+ pushq %rsi; \
+ movq %rcx, %rdi; \
+ movq %rdx, %rsi; \
+ movq %r8, %rdx; \
+ movq %r9, %rcx; \
+
+# define ENTER_SYSV_FUNC_PARAMS_5 \
+ ENTER_SYSV_FUNC_PARAMS_0_4; \
+ movq 0x38(%rsp), %r8;
+
+# define ENTER_SYSV_FUNC_PARAMS_6 \
+ ENTER_SYSV_FUNC_PARAMS_5; \
+ movq 0x40(%rsp), %r9;
+
+# define EXIT_SYSV_FUNC \
+ popq %rsi; \
+ popq %rdi;
+#else
+# define ENTER_SYSV_FUNC_PARAMS_0_4
+# define ENTER_SYSV_FUNC_PARAMS_5
+# define ENTER_SYSV_FUNC_PARAMS_6
+# define EXIT_SYSV_FUNC
+#endif
+
+#endif /* GCRY_ASM_COMMON_AMD64_H */
diff --git a/cipher/blowfish-amd64.S b/cipher/blowfish-amd64.S
index 21b63fc1c..02d3b7102 100644
--- a/cipher/blowfish-amd64.S
+++ b/cipher/blowfish-amd64.S
@@ -24,11 +24,7 @@
(defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
-#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
-# define ELF(...) __VA_ARGS__
-#else
-# define ELF(...) /*_*/
-#endif
+#include "asm-common-amd64.h"
.text
@@ -165,6 +161,8 @@ _gcry_blowfish_amd64_do_encrypt:
* %rsi: u32 *ret_xl
* %rdx: u32 *ret_xr
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
movl (%rdx), RX0d;
shlq $32, RX0;
movl (%rsi), RT3d;
@@ -178,6 +176,7 @@ _gcry_blowfish_amd64_do_encrypt:
shrq $32, RX0;
movl RX0d, (RX2);
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_blowfish_amd64_do_encrypt,.-_gcry_blowfish_amd64_do_encrypt;)
@@ -191,6 +190,7 @@ _gcry_blowfish_amd64_encrypt_block:
* %rsi: dst
* %rdx: src
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
movq %rsi, %r10;
@@ -202,6 +202,7 @@ _gcry_blowfish_amd64_encrypt_block:
movq %r10, RIO;
write_block();
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_blowfish_amd64_encrypt_block,.-_gcry_blowfish_amd64_encrypt_block;)
@@ -215,6 +216,8 @@ _gcry_blowfish_amd64_decrypt_block:
* %rsi: dst
* %rdx: src
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
movq %rbp, %r11;
movq %rsi, %r10;
@@ -238,6 +241,7 @@ _gcry_blowfish_amd64_decrypt_block:
movq %r11, %rbp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_blowfish_amd64_decrypt_block,.-_gcry_blowfish_amd64_decrypt_block;)
@@ -392,6 +396,8 @@ _gcry_blowfish_amd64_ctr_enc:
* %rdx: src (4 blocks)
* %rcx: iv (big endian, 64bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
pushq %rbp;
pushq %rbx;
pushq %r12;
@@ -436,6 +442,7 @@ _gcry_blowfish_amd64_ctr_enc:
popq %rbx;
popq %rbp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_blowfish_amd64_ctr_enc,.-_gcry_blowfish_amd64_ctr_enc;)
@@ -449,6 +456,8 @@ _gcry_blowfish_amd64_cbc_dec:
* %rdx: src (4 blocks)
* %rcx: iv (64bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
pushq %rbp;
pushq %rbx;
pushq %r12;
@@ -484,6 +493,7 @@ _gcry_blowfish_amd64_cbc_dec:
popq %rbx;
popq %rbp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_blowfish_amd64_cbc_dec,.-_gcry_blowfish_amd64_cbc_dec;)
@@ -497,6 +507,8 @@ _gcry_blowfish_amd64_cfb_dec:
* %rdx: src (4 blocks)
* %rcx: iv (64bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
pushq %rbp;
pushq %rbx;
pushq %r12;
@@ -534,6 +546,8 @@ _gcry_blowfish_amd64_cfb_dec:
popq %r12;
popq %rbx;
popq %rbp;
+
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_blowfish_amd64_cfb_dec,.-_gcry_blowfish_amd64_cfb_dec;)
diff --git a/cipher/blowfish.c b/cipher/blowfish.c
index a3fc26ce2..724d64e98 100644
--- a/cipher/blowfish.c
+++ b/cipher/blowfish.c
@@ -281,87 +281,43 @@ extern void _gcry_blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out,
extern void _gcry_blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out,
const byte *in, byte *iv);
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
-static inline void
-call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
- const void *arg3, const void *arg4)
-{
- /* Call SystemV ABI function without storing non-volatile XMM registers,
- * as target function does not use vector instruction sets. */
- asm volatile ("callq *%0\n\t"
- : "+a" (fn),
- "+D" (arg1),
- "+S" (arg2),
- "+d" (arg3),
- "+c" (arg4)
- :
- : "cc", "memory", "r8", "r9", "r10", "r11");
-}
-#endif
-
static void
do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_blowfish_amd64_do_encrypt, bc, ret_xl, ret_xr, NULL);
-#else
_gcry_blowfish_amd64_do_encrypt (bc, ret_xl, ret_xr);
-#endif
}
static void
do_encrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_blowfish_amd64_encrypt_block, context, outbuf, inbuf,
- NULL);
-#else
_gcry_blowfish_amd64_encrypt_block (context, outbuf, inbuf);
-#endif
}
static void
do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_blowfish_amd64_decrypt_block, context, outbuf, inbuf,
- NULL);
-#else
_gcry_blowfish_amd64_decrypt_block (context, outbuf, inbuf);
-#endif
}
static inline void
blowfish_amd64_ctr_enc(BLOWFISH_context *ctx, byte *out, const byte *in,
byte *ctr)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_blowfish_amd64_ctr_enc, ctx, out, in, ctr);
-#else
_gcry_blowfish_amd64_ctr_enc(ctx, out, in, ctr);
-#endif
}
static inline void
blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out, const byte *in,
byte *iv)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_blowfish_amd64_cbc_dec, ctx, out, in, iv);
-#else
_gcry_blowfish_amd64_cbc_dec(ctx, out, in, iv);
-#endif
}
static inline void
blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out, const byte *in,
byte *iv)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_blowfish_amd64_cfb_dec, ctx, out, in, iv);
-#else
_gcry_blowfish_amd64_cfb_dec(ctx, out, in, iv);
-#endif
}
static unsigned int
diff --git a/cipher/cast5-amd64.S b/cipher/cast5-amd64.S
index c04015a29..1a1d43fd5 100644
--- a/cipher/cast5-amd64.S
+++ b/cipher/cast5-amd64.S
@@ -23,30 +23,7 @@
#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_CAST5)
-#if defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS) || !defined(__PIC__)
-# define GET_EXTERN_POINTER(name, reg) movabsq $name, reg
-#else
-# ifdef __code_model_large__
-# define GET_EXTERN_POINTER(name, reg) \
- pushq %r15; \
- pushq %r14; \
- 1: leaq 1b(%rip), reg; \
- movabsq $_GLOBAL_OFFSET_TABLE_-1b, %r14; \
- movabsq $name at GOT, %r15; \
- addq %r14, reg; \
- popq %r14; \
- movq (reg, %r15), reg; \
- popq %r15;
-# else
-# define GET_EXTERN_POINTER(name, reg) movq name at GOTPCREL(%rip), reg
-# endif
-#endif
-
-#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
-# define ELF(...) __VA_ARGS__
-#else
-# define ELF(...) /*_*/
-#endif
+#include "asm-common-amd64.h"
.text
@@ -206,6 +183,8 @@ _gcry_cast5_amd64_encrypt_block:
* %rsi: dst
* %rdx: src
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
pushq %rbp;
pushq %rbx;
@@ -233,6 +212,8 @@ _gcry_cast5_amd64_encrypt_block:
popq %rbx;
popq %rbp;
+
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_cast5_amd64_encrypt_block,.-_gcry_cast5_amd64_encrypt_block;)
@@ -246,6 +227,8 @@ _gcry_cast5_amd64_decrypt_block:
* %rsi: dst
* %rdx: src
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
pushq %rbp;
pushq %rbx;
@@ -273,6 +256,8 @@ _gcry_cast5_amd64_decrypt_block:
popq %rbx;
popq %rbp;
+
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_cast5_amd64_decrypt_block,.-_gcry_cast5_amd64_decrypt_block;)
@@ -444,6 +429,7 @@ _gcry_cast5_amd64_ctr_enc:
* %rdx: src (8 blocks)
* %rcx: iv (big endian, 64bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
pushq %rbp;
pushq %rbx;
@@ -489,6 +475,8 @@ _gcry_cast5_amd64_ctr_enc:
popq %r12;
popq %rbx;
popq %rbp;
+
+ EXIT_SYSV_FUNC
ret
ELF(.size _gcry_cast5_amd64_ctr_enc,.-_gcry_cast5_amd64_ctr_enc;)
@@ -502,6 +490,7 @@ _gcry_cast5_amd64_cbc_dec:
* %rdx: src (8 blocks)
* %rcx: iv (64bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
pushq %rbp;
pushq %rbx;
@@ -542,6 +531,8 @@ _gcry_cast5_amd64_cbc_dec:
popq %r12;
popq %rbx;
popq %rbp;
+
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_cast5_amd64_cbc_dec,.-_gcry_cast5_amd64_cbc_dec;)
@@ -556,6 +547,7 @@ _gcry_cast5_amd64_cfb_dec:
* %rdx: src (8 blocks)
* %rcx: iv (64bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
pushq %rbp;
pushq %rbx;
@@ -597,6 +589,8 @@ _gcry_cast5_amd64_cfb_dec:
popq %r12;
popq %rbx;
popq %rbp;
+
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_cast5_amd64_cfb_dec,.-_gcry_cast5_amd64_cfb_dec;)
diff --git a/cipher/cast5.c b/cipher/cast5.c
index 94dcee76a..d23882b9a 100644
--- a/cipher/cast5.c
+++ b/cipher/cast5.c
@@ -373,72 +373,34 @@ extern void _gcry_cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out,
extern void _gcry_cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out,
const byte *in, byte *iv);
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
-static inline void
-call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
- const void *arg3, const void *arg4)
-{
- /* Call SystemV ABI function without storing non-volatile XMM registers,
- * as target function does not use vector instruction sets. */
- asm volatile ("callq *%0\n\t"
- : "+a" (fn),
- "+D" (arg1),
- "+S" (arg2),
- "+d" (arg3),
- "+c" (arg4)
- :
- : "cc", "memory", "r8", "r9", "r10", "r11");
-}
-#endif
-
static void
do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_cast5_amd64_encrypt_block, context, outbuf, inbuf, NULL);
-#else
_gcry_cast5_amd64_encrypt_block (context, outbuf, inbuf);
-#endif
}
static void
do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_cast5_amd64_decrypt_block, context, outbuf, inbuf, NULL);
-#else
_gcry_cast5_amd64_decrypt_block (context, outbuf, inbuf);
-#endif
}
static void
cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out, const byte *in, byte *ctr)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_cast5_amd64_ctr_enc, ctx, out, in, ctr);
-#else
_gcry_cast5_amd64_ctr_enc (ctx, out, in, ctr);
-#endif
}
static void
cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_cast5_amd64_cbc_dec, ctx, out, in, iv);
-#else
_gcry_cast5_amd64_cbc_dec (ctx, out, in, iv);
-#endif
}
static void
cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out, const byte *in, byte *iv)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_cast5_amd64_cfb_dec, ctx, out, in, iv);
-#else
_gcry_cast5_amd64_cfb_dec (ctx, out, in, iv);
-#endif
}
static unsigned int
diff --git a/cipher/des-amd64.S b/cipher/des-amd64.S
index 1b7cfba85..f25573d99 100644
--- a/cipher/des-amd64.S
+++ b/cipher/des-amd64.S
@@ -23,17 +23,7 @@
#if defined(USE_DES) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
-#ifdef __PIC__
-# define RIP (%rip)
-#else
-# define RIP
-#endif
-
-#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
-# define ELF(...) __VA_ARGS__
-#else
-# define ELF(...) /*_*/
-#endif
+#include "asm-common-amd64.h"
.text
@@ -200,6 +190,8 @@ _gcry_3des_amd64_crypt_block:
* %rsi: dst
* %rdx: src
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
pushq %rbp;
pushq %rbx;
pushq %r12;
@@ -208,7 +200,7 @@ _gcry_3des_amd64_crypt_block:
pushq %r15;
pushq %rsi; /*dst*/
- leaq .L_s1 RIP, SBOXES;
+ leaq .L_s1 rRIP, SBOXES;
read_block(%rdx, RL0, RR0);
initial_permutation(RL0, RR0);
@@ -277,6 +269,7 @@ _gcry_3des_amd64_crypt_block:
popq %rbx;
popq %rbp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_3des_amd64_crypt_block,.-_gcry_3des_amd64_crypt_block;)
@@ -473,7 +466,7 @@ _gcry_3des_amd64_crypt_blk3:
* RR0d, RL0d, RR1d, RL1d, RR2d, RL2d: 3 output blocks
*/
- leaq .L_s1 RIP, SBOXES;
+ leaq .L_s1 rRIP, SBOXES;
initial_permutation3(RL, RR);
@@ -547,6 +540,7 @@ _gcry_3des_amd64_cbc_dec:
* %rdx: src (3 blocks)
* %rcx: iv (64bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
pushq %rbp;
pushq %rbx;
@@ -610,6 +604,7 @@ _gcry_3des_amd64_cbc_dec:
popq %rbx;
popq %rbp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;)
@@ -623,6 +618,7 @@ _gcry_3des_amd64_ctr_enc:
* %rdx: src (3 blocks)
* %rcx: iv (64bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
pushq %rbp;
pushq %rbx;
@@ -688,6 +684,7 @@ _gcry_3des_amd64_ctr_enc:
popq %rbx;
popq %rbp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;)
@@ -701,6 +698,8 @@ _gcry_3des_amd64_cfb_dec:
* %rdx: src (3 blocks)
* %rcx: iv (64bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
pushq %rbp;
pushq %rbx;
pushq %r12;
@@ -763,6 +762,8 @@ _gcry_3des_amd64_cfb_dec:
popq %r12;
popq %rbx;
popq %rbp;
+
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_3des_amd64_cfb_dec,.-_gcry_3des_amd64_cfb_dec;)
diff --git a/cipher/des.c b/cipher/des.c
index 5c99f50d3..7801b08fc 100644
--- a/cipher/des.c
+++ b/cipher/des.c
@@ -772,23 +772,6 @@ extern void _gcry_3des_amd64_cfb_dec(const void *keys, byte *out,
#define TRIPLEDES_ECB_BURN_STACK (8 * sizeof(void *))
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
-static inline void
-call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
- const void *arg3, const void *arg4)
-{
- /* Call SystemV ABI function without storing non-volatile XMM registers,
- * as target function does not use vector instruction sets. */
- asm volatile ("callq *%0\n\t"
- : "+a" (fn),
- "+D" (arg1),
- "+S" (arg2),
- "+d" (arg3),
- "+c" (arg4)
- :
- : "cc", "memory", "r8", "r9", "r10", "r11");
-}
-#endif
/*
* Electronic Codebook Mode Triple-DES encryption/decryption of data
@@ -803,11 +786,7 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from,
keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_3des_amd64_crypt_block, keys, to, from, NULL);
-#else
_gcry_3des_amd64_crypt_block(keys, to, from);
-#endif
return 0;
}
@@ -815,31 +794,19 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from,
static inline void
tripledes_amd64_ctr_enc(const void *keys, byte *out, const byte *in, byte *ctr)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_3des_amd64_ctr_enc, keys, out, in, ctr);
-#else
_gcry_3des_amd64_ctr_enc(keys, out, in, ctr);
-#endif
}
static inline void
tripledes_amd64_cbc_dec(const void *keys, byte *out, const byte *in, byte *iv)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_3des_amd64_cbc_dec, keys, out, in, iv);
-#else
_gcry_3des_amd64_cbc_dec(keys, out, in, iv);
-#endif
}
static inline void
tripledes_amd64_cfb_dec(const void *keys, byte *out, const byte *in, byte *iv)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn (_gcry_3des_amd64_cfb_dec, keys, out, in, iv);
-#else
_gcry_3des_amd64_cfb_dec(keys, out, in, iv);
-#endif
}
#else /*USE_AMD64_ASM*/
diff --git a/cipher/rijndael-amd64.S b/cipher/rijndael-amd64.S
index b149e9485..798ff51af 100644
--- a/cipher/rijndael-amd64.S
+++ b/cipher/rijndael-amd64.S
@@ -23,17 +23,7 @@
#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_AES)
-#ifdef __PIC__
-# define RIP (%rip)
-#else
-# define RIP
-#endif
-
-#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
-# define ELF(...) __VA_ARGS__
-#else
-# define ELF(...) /*_*/
-#endif
+#include "asm-common-amd64.h"
.text
@@ -222,6 +212,8 @@ _gcry_aes_amd64_encrypt_block:
* %ecx: number of rounds.. 10, 12 or 14
* %r8: encryption tables
*/
+ ENTER_SYSV_FUNC_PARAMS_5
+
subq $(5 * 8), %rsp;
movq %rsi, (0 * 8)(%rsp);
movl %ecx, (1 * 8)(%rsp);
@@ -265,6 +257,8 @@ _gcry_aes_amd64_encrypt_block:
addq $(5 * 8), %rsp;
movl $(6 * 8), %eax;
+
+ EXIT_SYSV_FUNC
ret;
.align 4
@@ -382,6 +376,8 @@ _gcry_aes_amd64_decrypt_block:
* %ecx: number of rounds.. 10, 12 or 14
* %r8: decryption tables
*/
+ ENTER_SYSV_FUNC_PARAMS_5
+
subq $(5 * 8), %rsp;
movq %rsi, (0 * 8)(%rsp);
movl %ecx, (1 * 8)(%rsp);
@@ -426,6 +422,8 @@ _gcry_aes_amd64_decrypt_block:
addq $(5 * 8), %rsp;
movl $(6 * 8), %eax;
+
+ EXIT_SYSV_FUNC
ret;
.align 4
diff --git a/cipher/rijndael.c b/cipher/rijndael.c
index 548bfa099..df1363f28 100644
--- a/cipher/rijndael.c
+++ b/cipher/rijndael.c
@@ -740,27 +740,8 @@ 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. */
- const void *key = ctx->keyschenc;
- uintptr_t rounds = ctx->rounds;
- uintptr_t ret;
- asm volatile ("movq %[encT], %%r8\n\t"
- "callq *%[ret]\n\t"
- : [ret] "=a" (ret),
- "+D" (key),
- "+S" (bx),
- "+d" (ax),
- "+c" (rounds)
- : "0" (_gcry_aes_amd64_encrypt_block),
- [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
@@ -1123,27 +1104,8 @@ 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. */
- const void *key = ctx->keyschdec;
- uintptr_t rounds = ctx->rounds;
- uintptr_t ret;
- asm volatile ("movq %[dectabs], %%r8\n\t"
- "callq *%[ret]\n\t"
- : [ret] "=a" (ret),
- "+D" (key),
- "+S" (bx),
- "+d" (ax),
- "+c" (rounds)
- : "0" (_gcry_aes_amd64_decrypt_block),
- [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);
diff --git a/cipher/twofish-amd64.S b/cipher/twofish-amd64.S
index aa964e037..7a836463c 100644
--- a/cipher/twofish-amd64.S
+++ b/cipher/twofish-amd64.S
@@ -23,17 +23,7 @@
#if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_TWOFISH)
-#ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
-# define ELF(...) __VA_ARGS__
-#else
-# define ELF(...) /*_*/
-#endif
-
-#ifdef __PIC__
-# define RIP %rip
-#else
-# define RIP
-#endif
+#include "asm-common-amd64.h"
.text
@@ -181,6 +171,8 @@ _gcry_twofish_amd64_encrypt_block:
* %rsi: dst
* %rdx: src
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
subq $(3 * 8), %rsp;
movq %rsi, (0 * 8)(%rsp);
movq %rbp, (1 * 8)(%rsp);
@@ -211,6 +203,7 @@ _gcry_twofish_amd64_encrypt_block:
movq (1 * 8)(%rsp), %rbp;
addq $(3 * 8), %rsp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;)
@@ -224,6 +217,8 @@ _gcry_twofish_amd64_decrypt_block:
* %rsi: dst
* %rdx: src
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
subq $(3 * 8), %rsp;
movq %rsi, (0 * 8)(%rsp);
movq %rbp, (1 * 8)(%rsp);
@@ -254,6 +249,7 @@ _gcry_twofish_amd64_decrypt_block:
movq (1 * 8)(%rsp), %rbp;
addq $(3 * 8), %rsp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;)
@@ -530,6 +526,8 @@ _gcry_twofish_amd64_ctr_enc:
* %rdx: src (3 blocks)
* %rcx: iv (big endian, 128bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
subq $(8 * 8), %rsp;
movq %rbp, (0 * 8)(%rsp);
movq %rbx, (1 * 8)(%rsp);
@@ -599,6 +597,7 @@ _gcry_twofish_amd64_ctr_enc:
movq (5 * 8)(%rsp), %r15;
addq $(8 * 8), %rsp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_twofish_amd64_ctr_enc,.-_gcry_twofish_amd64_ctr_enc;)
@@ -612,6 +611,8 @@ _gcry_twofish_amd64_cbc_dec:
* %rdx: src (3 blocks)
* %rcx: iv (128bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
subq $(9 * 8), %rsp;
movq %rbp, (0 * 8)(%rsp);
movq %rbx, (1 * 8)(%rsp);
@@ -665,6 +666,7 @@ _gcry_twofish_amd64_cbc_dec:
movq (5 * 8)(%rsp), %r15;
addq $(9 * 8), %rsp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_twofish_amd64_cbc_dec,.-_gcry_twofish_amd64_cbc_dec;)
@@ -678,6 +680,8 @@ _gcry_twofish_amd64_cfb_dec:
* %rdx: src (3 blocks)
* %rcx: iv (128bit)
*/
+ ENTER_SYSV_FUNC_PARAMS_0_4
+
subq $(8 * 8), %rsp;
movq %rbp, (0 * 8)(%rsp);
movq %rbx, (1 * 8)(%rsp);
@@ -731,6 +735,7 @@ _gcry_twofish_amd64_cfb_dec:
movq (5 * 8)(%rsp), %r15;
addq $(8 * 8), %rsp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_twofish_amd64_cfb_dec,.-_gcry_twofish_amd64_cfb_dec;)
@@ -746,6 +751,8 @@ _gcry_twofish_amd64_ocb_enc:
* %r8 : checksum
* %r9 : L pointers (void *L[3])
*/
+ ENTER_SYSV_FUNC_PARAMS_6
+
subq $(8 * 8), %rsp;
movq %rbp, (0 * 8)(%rsp);
movq %rbx, (1 * 8)(%rsp);
@@ -838,6 +845,7 @@ _gcry_twofish_amd64_ocb_enc:
movq (5 * 8)(%rsp), %r15;
addq $(8 * 8), %rsp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_twofish_amd64_ocb_enc,.-_gcry_twofish_amd64_ocb_enc;)
@@ -853,6 +861,8 @@ _gcry_twofish_amd64_ocb_dec:
* %r8 : checksum
* %r9 : L pointers (void *L[3])
*/
+ ENTER_SYSV_FUNC_PARAMS_6
+
subq $(8 * 8), %rsp;
movq %rbp, (0 * 8)(%rsp);
movq %rbx, (1 * 8)(%rsp);
@@ -953,6 +963,7 @@ _gcry_twofish_amd64_ocb_dec:
movq (5 * 8)(%rsp), %r15;
addq $(8 * 8), %rsp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_twofish_amd64_ocb_dec,.-_gcry_twofish_amd64_ocb_dec;)
@@ -967,6 +978,8 @@ _gcry_twofish_amd64_ocb_auth:
* %rcx: checksum
* %r8 : L pointers (void *L[3])
*/
+ ENTER_SYSV_FUNC_PARAMS_5
+
subq $(8 * 8), %rsp;
movq %rbp, (0 * 8)(%rsp);
movq %rbx, (1 * 8)(%rsp);
@@ -1039,6 +1052,7 @@ _gcry_twofish_amd64_ocb_auth:
movq (5 * 8)(%rsp), %r15;
addq $(8 * 8), %rsp;
+ EXIT_SYSV_FUNC
ret;
ELF(.size _gcry_twofish_amd64_ocb_auth,.-_gcry_twofish_amd64_ocb_auth;)
diff --git a/cipher/twofish.c b/cipher/twofish.c
index 942e8d429..48feaae9f 100644
--- a/cipher/twofish.c
+++ b/cipher/twofish.c
@@ -829,145 +829,58 @@ extern void _gcry_twofish_amd64_ocb_auth(const TWOFISH_context *ctx,
const byte *abuf, byte *offset,
byte *checksum, const u64 Ls[3]);
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
-static inline void
-call_sysv_fn (const void *fn, const void *arg1, const void *arg2,
- const void *arg3, const void *arg4)
-{
- /* Call SystemV ABI function without storing non-volatile XMM registers,
- * as target function does not use vector instruction sets. */
- asm volatile ("callq *%0\n\t"
- : "+a" (fn),
- "+D" (arg1),
- "+S" (arg2),
- "+d" (arg3),
- "+c" (arg4)
- :
- : "cc", "memory", "r8", "r9", "r10", "r11");
-}
-
-static inline void
-call_sysv_fn5 (const void *fn, const void *arg1, const void *arg2,
- const void *arg3, const void *arg4, const void *arg5)
-{
- /* Call SystemV ABI function without storing non-volatile XMM registers,
- * as target function does not use vector instruction sets. */
- asm volatile ("movq %[arg5], %%r8\n\t"
- "callq *%0\n\t"
- : "+a" (fn),
- "+D" (arg1),
- "+S" (arg2),
- "+d" (arg3),
- "+c" (arg4)
- : [arg5] "g" (arg5)
- : "cc", "memory", "r8", "r9", "r10", "r11");
-}
-
-static inline void
-call_sysv_fn6 (const void *fn, const void *arg1, const void *arg2,
- const void *arg3, const void *arg4, const void *arg5,
- const void *arg6)
-{
- /* Call SystemV ABI function without storing non-volatile XMM registers,
- * as target function does not use vector instruction sets. */
- asm volatile ("movq %[arg5], %%r8\n\t"
- "movq %[arg6], %%r9\n\t"
- "callq *%0\n\t"
- : "+a" (fn),
- "+D" (arg1),
- "+S" (arg2),
- "+d" (arg3),
- "+c" (arg4)
- : [arg5] "g" (arg5),
- [arg6] "g" (arg6)
- : "cc", "memory", "r8", "r9", "r10", "r11");
-}
-#endif
-
static inline void
twofish_amd64_encrypt_block(const TWOFISH_context *c, byte *out, const byte *in)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn(_gcry_twofish_amd64_encrypt_block, c, out, in, NULL);
-#else
_gcry_twofish_amd64_encrypt_block(c, out, in);
-#endif
}
static inline void
twofish_amd64_decrypt_block(const TWOFISH_context *c, byte *out, const byte *in)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn(_gcry_twofish_amd64_decrypt_block, c, out, in, NULL);
-#else
_gcry_twofish_amd64_decrypt_block(c, out, in);
-#endif
}
static inline void
twofish_amd64_ctr_enc(const TWOFISH_context *c, byte *out, const byte *in,
byte *ctr)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn(_gcry_twofish_amd64_ctr_enc, c, out, in, ctr);
-#else
_gcry_twofish_amd64_ctr_enc(c, out, in, ctr);
-#endif
}
static inline void
twofish_amd64_cbc_dec(const TWOFISH_context *c, byte *out, const byte *in,
byte *iv)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn(_gcry_twofish_amd64_cbc_dec, c, out, in, iv);
-#else
_gcry_twofish_amd64_cbc_dec(c, out, in, iv);
-#endif
}
static inline void
twofish_amd64_cfb_dec(const TWOFISH_context *c, byte *out, const byte *in,
byte *iv)
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn(_gcry_twofish_amd64_cfb_dec, c, out, in, iv);
-#else
_gcry_twofish_amd64_cfb_dec(c, out, in, iv);
-#endif
}
static inline void
twofish_amd64_ocb_enc(const TWOFISH_context *ctx, byte *out, const byte *in,
byte *offset, byte *checksum, const u64 Ls[3])
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn6(_gcry_twofish_amd64_ocb_enc, ctx, out, in, offset, checksum, Ls);
-#else
_gcry_twofish_amd64_ocb_enc(ctx, out, in, offset, checksum, Ls);
-#endif
}
static inline void
twofish_amd64_ocb_dec(const TWOFISH_context *ctx, byte *out, const byte *in,
byte *offset, byte *checksum, const u64 Ls[3])
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn6(_gcry_twofish_amd64_ocb_dec, ctx, out, in, offset, checksum, Ls);
-#else
_gcry_twofish_amd64_ocb_dec(ctx, out, in, offset, checksum, Ls);
-#endif
}
static inline void
twofish_amd64_ocb_auth(const TWOFISH_context *ctx, const byte *abuf,
byte *offset, byte *checksum, const u64 Ls[3])
{
-#ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
- call_sysv_fn5(_gcry_twofish_amd64_ocb_auth, ctx, abuf, offset, checksum, Ls);
-#else
_gcry_twofish_amd64_ocb_auth(ctx, abuf, offset, checksum, Ls);
-#endif
}
#elif defined(USE_ARM_ASM)
More information about the Gcrypt-devel
mailing list