Preprocess the assembler files.
[catacomb] / base / asm-common.h
1 /// -*- mode: asm; asm-comment-char: ?/ -*-
2 ///
3 /// Fancy SIMD implementation of Salsa20
4 ///
5 /// (c) 2015 Straylight/Edgeware
6 ///
7
8 ///----- Licensing notice ---------------------------------------------------
9 ///
10 /// This file is part of Catacomb.
11 ///
12 /// Catacomb is free software; you can redistribute it and/or modify
13 /// it under the terms of the GNU Library General Public License as
14 /// published by the Free Software Foundation; either version 2 of the
15 /// License, or (at your option) any later version.
16 ///
17 /// Catacomb is distributed in the hope that it will be useful,
18 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 /// GNU Library General Public License for more details.
21 ///
22 /// You should have received a copy of the GNU Library General Public
23 /// License along with Catacomb; if not, write to the Free
24 /// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 /// MA 02111-1307, USA.
26
27 ///--------------------------------------------------------------------------
28 /// General definitions.
29
30 // Announcing an external function.
31 #define FUNC(name) \
32 .globl F(name); \
33 TYPE_FUNC(name); \
34 .macro ENDFUNC; _ENDFUNC(name); .endm; \
35 FUNC_PREHOOK(name); \
36 F(name): \
37 FUNC_POSTHOOK(name)
38
39 // Marking the end of a function.
40 #define _ENDFUNC(name) \
41 .purgem ENDFUNC; \
42 SIZE_OBJ(name); \
43 ENDFUNC_HOOK(name)
44
45 ///--------------------------------------------------------------------------
46 /// ELF-specific hacking.
47
48 #if __ELF__
49
50 #if __PIC__ || __PIE__
51 # define WANT_PIC 1
52 #endif
53
54 #define TYPE_FUNC(name) .type name, STT_FUNC
55
56 #define SIZE_OBJ(name) .size name, . - name
57
58 #endif
59
60 ///--------------------------------------------------------------------------
61 /// x86-specific hacking.
62
63 #if CPUFAM_X86
64
65 // Set the function hooks.
66 #define FUNC_PREHOOK(_) .balign 16
67
68 // Don't use the wretched AT&T syntax. It's festooned with pointless
69 // punctuation, and all of the data movement is backwards. Ugh!
70 .intel_syntax noprefix
71
72 // Call external subroutine at ADDR, possibly via PLT.
73 .macro callext addr
74 #if WANT_PIC
75 call \addr@PLT
76 #else
77 call \addr
78 #endif
79 .endm
80
81 // Do I need to arrange a spare GOT register?
82 #if WANT_PIC && CPUFAM_X86
83 # define NEED_GOT 1
84 #endif
85 #define GOTREG ebx // Not needed in AMD64 so don't care.
86
87 // Maybe load GOT address into GOT.
88 .macro ldgot got=GOTREG
89 #if WANT_PIC
90 call _where_am_i.\got
91 add \got, offset _GLOBAL_OFFSET_TABLE_
92 #endif
93 .endm
94
95 // Maybe build a helper subroutine for `ldgot GOT'.
96 .macro gotaux got=GOTREG
97 #if WANT_PIC
98 .align 16
99 _where_am_i.\got :
100 mov \got, [esp]
101 ret
102 #endif
103 .endm
104
105 // Load address of external symbol ADDR into REG, maybe using GOT.
106 .macro leaext reg, addr, got=GOTREG
107 #if WANT_PIC
108 mov \reg, [\got + \addr@GOT]
109 #else
110 mov \reg, offset \addr
111 #endif
112 .endm
113
114 // Address expression (possibly using a base register, and a displacement)
115 // referring to ADDR, which is within our module, maybe using GOT.
116 #define INTADDR(...) INTADDR__0(__VA_ARGS__, GOTREG, dummy)
117 #define INTADDR__0(addr, got, ...) INTADDR__1(addr, got)
118 #if WANT_PIC
119 # define INTADDR__1(addr, got) got + addr@GOTOFF
120 #else
121 # define INTADDR__1(addr, got) addr
122 #endif
123
124 #endif
125
126 ///--------------------------------------------------------------------------
127 /// Final stuff.
128
129 // Default values for the various hooks.
130 #ifndef FUNC_PREHOOK
131 # define FUNC_PREHOOK(name)
132 #endif
133 #ifndef FUNC_POSTHOOK
134 # define FUNC_POSTHOOK(name)
135 #endif
136 #ifndef ENDFUNC_HOOK
137 # define ENDFUNC_HOOK(name)
138 #endif
139
140 #ifndef F
141 # define F(name) name
142 #endif
143
144 #ifndef TYPE_FUNC
145 # define TYPE_FUNC(name)
146 #endif
147
148 #ifndef SIZE_OBJ
149 # define SIZE_OBJ(name)
150 #endif
151
152 ///----- That's all, folks --------------------------------------------------