X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/6c54cbd34173e835f82887f61d606c2a63356972..645fcce0830342b644cc16e71e28790c838d9415:/base/asm-common.h?ds=sidebyside diff --git a/base/asm-common.h b/base/asm-common.h index 8ab0bc0a..e5e0f2f2 100644 --- a/base/asm-common.h +++ b/base/asm-common.h @@ -35,6 +35,26 @@ #define _ENDLIT .text .L$_subsec #define _LTORG .L$_subsec = .L$_subsec + 2; .text .L$_subsec +// ELF section types. +#if __ELF__ +# if CPUFAM_ARMEL +# define _SECTTY(ty) %ty +# else +# define _SECTTY(ty) @ty +# endif +#endif + +// Section selection. +#define TEXT .text .L$_subsec +#if ABI_WIN +# define RODATA .section .rdata, "dr" +#elif __ELF__ +# define RODATA .section .rodata, "a", _SECTTY(progbits) +#else +# define RODATA TEXT +#endif +#define DATA .data + // Announcing an external function. #define FUNC(name) \ .globl F(name); \ @@ -51,6 +71,19 @@ F(name): \ ENDFUNC_HOOK(name); \ _LTORG +// Make a helper function, if necessary. +#define AUXFN(name) \ + .ifndef .L$_auxfn_def.name; \ + .text 7128; \ + .macro _ENDAUXFN; _ENDAUXFN_TAIL(name); .endm; \ + FUNC_PREHOOK(name); \ +name: +#define _ENDAUXFN_TAIL(name) \ + .purgem _ENDAUXFN; \ + .text .L$_subsec; \ + .L$_auxfn_def.name = 1 +#define ENDAUXFN _ENDAUXFN; .endif + ///-------------------------------------------------------------------------- /// ELF-specific hacking. @@ -87,6 +120,14 @@ F(name): \ // Set the function hooks. #define FUNC_PREHOOK(_) .balign 16 +// On Windows, arrange to install stack-unwinding data. +#if CPUFAM_AMD64 && ABI_WIN +# define FUNC_POSTHOOK(name) .seh_proc name +# define ENDFUNC_HOOK(_) .seh_endproc +// Procedures are expected to invoke `.seh_setframe' if necessary, and +// `.seh_pushreg' and friends, and `.seh_endprologue'. +#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 @@ -109,18 +150,12 @@ F(name): \ // Maybe load GOT address into GOT. .macro ldgot got=GOTREG #if WANT_PIC && CPUFAM_X86 - call _where_am_i.\got - add \got, offset _GLOBAL_OFFSET_TABLE_ -#endif -.endm - -// Maybe build a helper subroutine for `ldgot GOT'. -.macro gotaux got=GOTREG -#if WANT_PIC && CPUFAM_X86 - .align 16 -_where_am_i.\got : + AUXFN(_ldgot.\got) mov \got, [esp] ret + ENDAUXFN + call _ldgot.\got + add \got, offset _GLOBAL_OFFSET_TABLE_ #endif .endm @@ -155,6 +190,123 @@ _where_am_i.\got : # define INTADDR__1(addr, got) addr #endif +// Permutations for SIMD instructions. SHUF(D, C, B, A) is an immediate, +// suitable for use in `pshufd' or `shufpd', which copies element D +// (0 <= D < 4) of the source to element 3 of the destination, element C to +// element 2, element B to element 1, and element A to element 0. +#define SHUF(d, c, b, a) (64*(d) + 16*(c) + 4*(b) + (a)) + +#endif + +#if CPUFAM_X86 + +.macro _reg.0 + // Stash GP registers and establish temporary stack frame. + pushfd + push eax + push ecx + push edx + push ebp + mov ebp, esp + and esp, ~15 + sub esp, 512 + fxsave [esp] +.endm + +.macro _reg.1 +.endm + +.macro _reg.2 +.endm + +.macro _reg.3 fmt + // Print FMT and the other established arguments. + lea eax, .L$_reg$msg.\@ + push eax + call printf + jmp .L$_reg$cont.\@ +.L$_reg$msg.\@: + .ascii ";; \fmt\n\0" +.L$_reg$cont.\@: + mov eax, ebp + and eax, ~15 + sub eax, 512 + fxrstor [eax] + mov esp, ebp + pop ebp + pop edx + pop ecx + pop eax + popfd +.endm + +.macro msg msg + _reg.0 + _reg.1 + _reg.2 + _reg.3 "\msg" +.endm + +.macro reg r, msg + _reg.0 + .ifeqs "\r", "esp" + lea eax, [ebp + 20] + push eax + .else + .ifeqs "\r", "ebp" + push [ebp] + .else + push \r + .endif + .endif + _reg.1 + _reg.2 + _reg.3 "\msg: \r = %08x" +.endm + +.macro xmmreg r, msg + _reg.0 + _reg.1 + _reg.2 + movdqu xmm0, \r + pshufd xmm0, xmm0, 0x1b + sub esp, 16 + movdqa [esp], xmm0 + _reg.3 "\msg: \r = %08x %08x %08x %08x" +.endm + +.macro mmreg r, msg + _reg.0 + _reg.1 + _reg.2 + pshufw \r, \r, 0x4e + sub esp, 8 + movq [esp], \r + _reg.3 "\msg: \r = %08x %08x" +.endm + +.macro freg i, msg + _reg.0 + _reg.1 + _reg.2 + finit + fldt [esp + 32 + 16*\i] + sub esp, 12 + fstpt [esp] + _reg.3 "\msg: st(\i) = %.20Lg" +.endm + +.macro fxreg i, msg + _reg.0 + _reg.1 + _reg.2 + finit + fldt [esp + 32 + 16*\i] + sub esp, 12 + fstpt [esp] + _reg.3 "\msg: st(\i) = %La" +.endm + #endif ///-------------------------------------------------------------------------- @@ -264,4 +416,9 @@ _where_am_i.\got : # define SIZE_OBJ(name) #endif +#if __ELF__ && defined(WANT_EXECUTABLE_STACK) + .pushsection .note.GNU-stack, "", _SECTTY(progbits) + .popsection +#endif + ///----- That's all, folks --------------------------------------------------