math/Makefile.am, symm/Makefile.am: Use `--no-install' on oddball tests.
[catacomb] / base / asm-common.h
index 4a0a420..8e51ea3 100644 (file)
@@ -1,6 +1,6 @@
 /// -*- mode: asm; asm-comment-char: ?/ -*-
 ///
-/// Fancy SIMD implementation of Salsa20
+/// Common definitions for asesembler source files
 ///
 /// (c) 2015 Straylight/Edgeware
 ///
 #endif
 #define DATA .data
 
-// Announcing an external function.
-#define FUNC(name)                                                     \
-       .globl  F(name);                                                \
+// Announcing an internal function.
+#define INTFUNC(name)                                                  \
        TYPE_FUNC(name);                                                \
        .macro ENDFUNC; _ENDFUNC(name); .endm;                          \
+       .L$_prologue_p = 0; .L$_frameptr_p = 0;                         \
        FUNC_PREHOOK(name);                                             \
-F(name):                                                               \
+name:                                                                  \
        FUNC_POSTHOOK(name)
 
+// Announcing an external function.
+#define FUNC(name)                                                     \
+       .globl  F(name);                                                \
+INTFUNC(F(name))
+
 // Marking the end of a function.
 #define _ENDFUNC(name)                                                 \
+       .if ~ .L$_prologue_p; .error "Missing `endprologue'"; .endif;   \
+       .if .L$_frameptr_p; .purgem dropfp; .endif;                     \
        .purgem ENDFUNC;                                                \
        SIZE_OBJ(name);                                                 \
        ENDFUNC_HOOK(name);                                             \
@@ -124,6 +131,14 @@ name:
 
 #if CPUFAM_X86 || CPUFAM_AMD64
 
+// Word size.
+#if CPUFAM_X86
+#  define WORDSZ 4
+#endif
+#if CPUFAM_AMD64
+#  define WORDSZ 8
+#endif
+
 // Set the function hooks.
 #define FUNC_PREHOOK(_) .balign 16
 
@@ -135,6 +150,11 @@ name:
 // `.seh_pushreg' and friends, and `.seh_endprologue'.
 #endif
 
+#if __ELF__
+#  define FUNC_POSTHOOK(_) .cfi_startproc
+#  define ENDFUNC_HOOK(_) .cfi_endproc
+#endif
+
 // Don't use the wretched AT&T syntax.  It's festooned with pointless
 // punctuation, and all of the data movement is backwards.  Ugh!
        .intel_syntax noprefix
@@ -415,6 +435,101 @@ name:
 #endif
 #define WHOLE(reg) _REGFORM(reg, r)
 
+// Stack management and unwinding.
+.macro setfp   fp, offset = 0
+  .if \offset == 0
+       mov     \fp, R_sp(r)
+#if __ELF__
+         .cfi_def_cfa_register \fp
+#endif
+#if ABI_WIN && CPUFAM_AMD64
+         .seh_setframe \fp, 0
+#endif
+  .else
+       lea     \fp, [R_sp(r) + \offset]
+#if __ELF__
+         .cfi_def_cfa_register \fp
+         .cfi_adjust_cfa_offset -\offset
+#endif
+#if ABI_WIN && CPUFAM_AMD64
+         .seh_setframe \fp, \offset
+#endif
+  .endif
+       .L$_frameptr_p = -1
+       .macro dropfp; _dropfp  \fp, \offset; .endm
+.endm
+
+.macro _dropfp fp, offset = 0
+  .if \offset == 0
+       mov     R_sp(r), \fp
+#if __ELF__
+         .cfi_def_cfa_register R_sp(r)
+#endif
+  .else
+       lea     R_sp(r), [\fp - \offset]
+#if __ELF__
+         .cfi_def_cfa_register R_sp(r)
+         .cfi_adjust_cfa_offset +\offset
+#endif
+  .endif
+       .L$_frameptr_p = 0
+       .purgem dropfp
+.endm
+
+.macro stalloc n
+       sub     R_sp(r), \n
+#if __ELF__
+         .cfi_adjust_cfa_offset +\n
+#endif
+#if ABI_WIN && CPUFAM_AMD64
+         .seh_stackalloc \n
+#endif
+.endm
+
+.macro stfree  n
+       add     R_sp(r), \n
+#if __ELF__
+         .cfi_adjust_cfa_offset -\n
+#endif
+.endm
+
+.macro pushreg r
+       push    \r
+#if __ELF__
+         .cfi_adjust_cfa_offset +WORDSZ
+         .cfi_rel_offset \r, 0
+#endif
+#if ABI_WIN && CPUFAM_AMD64
+         .seh_pushreg \r
+#endif
+.endm
+
+.macro popreg  r
+       pop     \r
+#if __ELF__
+         .cfi_adjust_cfa_offset -WORDSZ
+         .cfi_restore \r
+#endif
+.endm
+
+.macro savexmm r, offset
+       movdqa  [R_sp(r) + \offset], \r
+#if ABI_WIN && CPUFAM_AMD64
+         .seh_savexmm \r, \offset
+#endif
+.endm
+
+.macro rstrxmm r, offset
+       movdqa  \r, [R_sp(r) + \offset]
+.endm
+
+.macro endprologue
+#if ABI_WIN && CPUFAM_AMD64
+         .seh_endprologue
+#endif
+       .L$_prologue_p = -1
+.endm
+
 #endif
 
 #if CPUFAM_X86
@@ -539,8 +654,8 @@ name:
        ARM
 
 // Set the function hooks.
-#define FUNC_PREHOOK(_) .balign 4
-#define ENDFUNC_HOOK(name) .ltorg
+#define FUNC_PREHOOK(_) .balign 4; .fnstart
+#define ENDFUNC_HOOK(_) .fnend; .ltorg
 
 // Call external subroutine at ADDR, possibly via PLT.
 .macro callext addr, cond=
@@ -856,6 +971,182 @@ name:
 // Macros for converting vldm/vstm ranges.
 #define QQ(qlo, qhi) D0(qlo)-D1(qhi)
 
+// Stack management and unwinding.
+.macro setfp   fp, offset = 0
+  .if \offset == 0
+       mov     \fp, sp
+         .setfp \fp, sp
+  .else
+       add     \fp, sp, #\offset
+         .setfp \fp, sp, #\offset
+  .endif
+       .macro dropfp; _dropfp  \fp, \offset; .endm
+       .L$_frameptr_p = -1
+.endm
+
+.macro _dropfp fp, offset = 0
+  .if \offset == 0
+       mov     sp, \fp
+  .else
+       sub     sp, \fp, #\offset
+  .endif
+       .purgem dropfp
+       .L$_frameptr_p = 0
+.endm
+
+.macro stalloc n
+       sub     sp, sp, #\n
+         .pad #\n
+.endm
+
+.macro stfree  n
+       add     sp, sp, #\n
+         .pad #-\n
+.endm
+
+.macro pushreg rr:vararg
+       stmfd   sp!, {\rr}
+         .save {\rr}
+.endm
+
+.macro popreg  rr:vararg
+       ldmfd   sp!, {\rr}
+.endm
+
+.macro pushvfp rr:vararg
+       vstmdb  sp!, {\rr}
+         .vsave {\rr}
+.endm
+
+.macro popvfp rr:vararg
+       vldmia  sp!, {\rr}
+.endm
+
+.macro endprologue
+.endm
+
+// No need for prologue markers on ARM.
+#define FUNC_POSTHOOK(_) .L$_prologue_p = -1
+
+#endif
+
+///--------------------------------------------------------------------------
+/// AArch64-specific hacking.
+
+#if CPUFAM_ARM64
+
+// Set the function hooks.
+#define FUNC_PREHOOK(_) .balign 4
+#define FUNC_POSTHOOK(_) .cfi_startproc; .L$_prologue_p = -1
+#define ENDFUNC_HOOK(_) .cfi_endproc
+
+// Call external subroutine at ADDR, possibly via PLT.
+.macro callext addr
+       bl      \addr
+.endm
+
+// Load address of external symbol ADDR into REG.
+.macro leaext  reg, addr
+#if WANT_PIC
+       adrp    \reg, :got:\addr
+       ldr     \reg, [\reg, #:got_lo12:\addr]
+#else
+       adrp    \reg, \addr
+       add     \reg, \reg, #:lo12:\addr
+#endif
+.endm
+
+// Stack management and unwinding.
+.macro setfp   fp, offset = 0
+  // If you're just going through the motions with a fixed-size stack frame,
+  // then you want to say `add x29, sp, #OFFSET' directly, which will avoid
+  // pointlessly restoring sp later.
+  .if \offset == 0
+       mov     \fp, sp
+         .cfi_def_cfa_register \fp
+  .else
+       add     \fp, sp, #\offset
+         .cfi_def_cfa_register \fp
+         .cfi_adjust_cfa_offset -\offset
+  .endif
+       .macro dropfp; _dropfp  \fp, \offset; .endm
+       .L$_frameptr_p = -1
+.endm
+
+.macro _dropfp fp, offset = 0
+  .if \offset == 0
+       mov     sp, \fp
+         .cfi_def_cfa_register sp
+  .else
+       sub     sp, \fp, #\offset
+         .cfi_def_cfa_register sp
+         .cfi_adjust_cfa_offset +\offset
+  .endif
+       .purgem dropfp
+       .L$_frameptr_p = 0
+.endm
+
+.macro stalloc n
+       sub     sp, sp, #\n
+         .cfi_adjust_cfa_offset +\n
+.endm
+
+.macro stfree  n
+       add     sp, sp, #\n
+         .cfi_adjust_cfa_offset -\n
+.endm
+
+.macro pushreg x, y=
+  .ifeqs "\y", ""
+       str     \x, [sp, #-16]!
+         .cfi_adjust_cfa_offset +16
+         .cfi_rel_offset \x, 0
+  .else
+       stp     \x, \y, [sp, #-16]!
+         .cfi_adjust_cfa_offset +16
+         .cfi_rel_offset \x, 0
+         .cfi_rel_offset \y, 8
+  .endif
+.endm
+
+.macro popreg  x, y=
+  .ifeqs "\y", ""
+       ldr     \x, [sp], #16
+         .cfi_restore \x
+         .cfi_adjust_cfa_offset -16
+  .else
+       ldp     \x, \y, [sp], #16
+         .cfi_restore \x
+         .cfi_restore \y
+         .cfi_adjust_cfa_offset -16
+  .endif
+.endm
+
+.macro savereg x, y, z=
+  .ifeqs "\z", ""
+       str     \x, [sp, #\y]
+         .cfi_rel_offset \x, \y
+  .else
+       stp     \x, \y, [sp, #\z]
+         .cfi_rel_offset \x, \z
+         .cfi_rel_offset \y, \z + 8
+  .endif
+.endm
+
+.macro rstrreg x, y, z=
+  .ifeqs "\z", ""
+       ldr     \x, [sp, #\y]
+         .cfi_restore \x
+  .else
+       ldp     \x, \y, [sp, #\z]
+         .cfi_restore \x
+         .cfi_restore \y
+  .endif
+.endm
+
+.macro endprologue
+.endm
+
 #endif
 
 ///--------------------------------------------------------------------------
@@ -863,13 +1154,13 @@ name:
 
 // Default values for the various hooks.
 #ifndef FUNC_PREHOOK
-#  define FUNC_PREHOOK(name)
+#  define FUNC_PREHOOK(_)
 #endif
 #ifndef FUNC_POSTHOOK
-#  define FUNC_POSTHOOK(name)
+#  define FUNC_POSTHOOK(_)
 #endif
 #ifndef ENDFUNC_HOOK
-#  define ENDFUNC_HOOK(name)
+#  define ENDFUNC_HOOK(_)
 #endif
 
 #ifndef F
@@ -884,7 +1175,7 @@ name:
 #  define SIZE_OBJ(name)
 #endif
 
-#if __ELF__ && defined(WANT_EXECUTABLE_STACK)
+#if __ELF__ && !defined(WANT_EXECUTABLE_STACK)
        .pushsection .note.GNU-stack, "", _SECTTY(progbits)
        .popsection
 #endif