X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/2cb17e021884f46af033c31a4deb5f60714c3997..6a024d24d97cb5d42c0091571735475b849f59f4:/base/asm-common.h diff --git a/base/asm-common.h b/base/asm-common.h index 083643e7..8e51ea39 100644 --- a/base/asm-common.h +++ b/base/asm-common.h @@ -1,6 +1,6 @@ /// -*- mode: asm; asm-comment-char: ?/ -*- /// -/// Fancy SIMD implementation of Salsa20 +/// Common definitions for asesembler source files /// /// (c) 2015 Straylight/Edgeware /// @@ -62,17 +62,24 @@ #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); \ @@ -143,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 @@ -423,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 @@ -547,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= @@ -864,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 ///-------------------------------------------------------------------------- @@ -892,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