symm/rijndael-x86ish-aesni.S: Move setup of endswap table after prologue.
[catacomb] / base / asm-common.h
CommitLineData
1a0c09c4
MW
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
f8e509a9
MW
30// Some useful variables.
31 .L$_subsec = 0
32
33// Literal pools done the hard way.
34#define _LIT .text .L$_subsec + 1
35#define _ENDLIT .text .L$_subsec
6c54cbd3 36#define _LTORG .L$_subsec = .L$_subsec + 2; .text .L$_subsec
f8e509a9 37
1a0c09c4
MW
38// Announcing an external function.
39#define FUNC(name) \
40 .globl F(name); \
41 TYPE_FUNC(name); \
8a1aa284 42 .macro ENDFUNC; _ENDFUNC(name); .endm; \
1a0c09c4
MW
43 FUNC_PREHOOK(name); \
44F(name): \
45 FUNC_POSTHOOK(name)
46
47// Marking the end of a function.
48#define _ENDFUNC(name) \
49 .purgem ENDFUNC; \
50 SIZE_OBJ(name); \
f8e509a9 51 ENDFUNC_HOOK(name); \
6c54cbd3 52 _LTORG
1a0c09c4 53
8ae4c946
MW
54// Make a helper function, if necessary.
55#define AUXFN(name) \
56 .ifndef .L$_auxfn_def.name; \
57 .text 7128; \
58 .macro _ENDAUXFN; _ENDAUXFN_TAIL(name); .endm; \
59 FUNC_PREHOOK(name); \
60name:
61#define _ENDAUXFN_TAIL(name) \
62 .purgem _ENDAUXFN; \
63 .text .L$_subsec; \
64 .L$_auxfn_def.name = 1
65#define ENDAUXFN _ENDAUXFN; .endif
66
1a0c09c4
MW
67///--------------------------------------------------------------------------
68/// ELF-specific hacking.
69
70#if __ELF__
71
72#if __PIC__ || __PIE__
73# define WANT_PIC 1
74#endif
75
76#define TYPE_FUNC(name) .type name, STT_FUNC
77
78#define SIZE_OBJ(name) .size name, . - name
79
80#endif
81
82///--------------------------------------------------------------------------
0f23f75f
MW
83/// Windows-specific hacking.
84
85#if ABI_WIN
1a0c09c4
MW
86
87#if CPUFAM_X86
0f23f75f
MW
88# define F(name) _##name
89#endif
90
91#endif
92
93///--------------------------------------------------------------------------
94/// x86- and amd64-specific hacking.
95///
96/// It's (slightly) easier to deal with both of these in one go.
97
98#if CPUFAM_X86 || CPUFAM_AMD64
1a0c09c4
MW
99
100// Set the function hooks.
101#define FUNC_PREHOOK(_) .balign 16
102
103// Don't use the wretched AT&T syntax. It's festooned with pointless
104// punctuation, and all of the data movement is backwards. Ugh!
105 .intel_syntax noprefix
106
107// Call external subroutine at ADDR, possibly via PLT.
8a1aa284 108.macro callext addr
1a0c09c4
MW
109#if WANT_PIC
110 call \addr@PLT
111#else
112 call \addr
113#endif
8a1aa284 114.endm
1a0c09c4
MW
115
116// Do I need to arrange a spare GOT register?
117#if WANT_PIC && CPUFAM_X86
118# define NEED_GOT 1
119#endif
120#define GOTREG ebx // Not needed in AMD64 so don't care.
121
122// Maybe load GOT address into GOT.
8a1aa284 123.macro ldgot got=GOTREG
0f23f75f 124#if WANT_PIC && CPUFAM_X86
8ae4c946 125 AUXFN(_ldgot.\got)
1a0c09c4
MW
126 mov \got, [esp]
127 ret
8ae4c946
MW
128 ENDAUXFN
129 call _ldgot.\got
130 add \got, offset _GLOBAL_OFFSET_TABLE_
1a0c09c4 131#endif
8a1aa284 132.endm
1a0c09c4
MW
133
134// Load address of external symbol ADDR into REG, maybe using GOT.
8a1aa284 135.macro leaext reg, addr, got=GOTREG
1a0c09c4 136#if WANT_PIC
0f23f75f 137# if CPUFAM_X86
1a0c09c4 138 mov \reg, [\got + \addr@GOT]
0f23f75f
MW
139# endif
140# if CPUFAM_AMD64
141 mov \reg, \addr@GOTPCREL[rip]
142# endif
1a0c09c4 143#else
0f23f75f 144# if CPUFAM_X86
1a0c09c4 145 mov \reg, offset \addr
0f23f75f
MW
146# endif
147# if CPUFAM_AMD64
148 lea \reg, \addr[rip]
149# endif
1a0c09c4 150#endif
8a1aa284 151.endm
1a0c09c4
MW
152
153// Address expression (possibly using a base register, and a displacement)
154// referring to ADDR, which is within our module, maybe using GOT.
155#define INTADDR(...) INTADDR__0(__VA_ARGS__, GOTREG, dummy)
156#define INTADDR__0(addr, got, ...) INTADDR__1(addr, got)
0f23f75f
MW
157#if CPUFAM_AMD64
158# define INTADDR__1(addr, got) addr + rip
159#elif WANT_PIC
1a0c09c4
MW
160# define INTADDR__1(addr, got) got + addr@GOTOFF
161#else
162# define INTADDR__1(addr, got) addr
163#endif
164
165#endif
166
167///--------------------------------------------------------------------------
61bd904b
MW
168/// ARM-specific hacking.
169
59d86860 170#if CPUFAM_ARMEL
61bd904b 171
9f6eb05d
MW
172// ARM/Thumb mode things. Use ARM by default.
173#define ARM .arm; .L$_pcoff = 8
174#define THUMB .thumb; .L$_pcoff = 4
175 ARM
176
61bd904b
MW
177// Set the function hooks.
178#define FUNC_PREHOOK(_) .balign 4
179#define ENDFUNC_HOOK(name) .ltorg
180
181// Call external subroutine at ADDR, possibly via PLT.
8a1aa284 182.macro callext addr, cond=
61bd904b
MW
183#if WANT_PIC
184 bl\cond \addr(PLT)
185#else
186 bl\cond \addr
187#endif
8a1aa284 188.endm
61bd904b
MW
189
190// Do I need to arrange a spare GOT register?
191#if WANT_PIC
192# define NEED_GOT 1
193#endif
194#define GOTREG r9
195
196// Maybe load GOT address into GOT.
8a1aa284 197.macro ldgot cond=, got=GOTREG
61bd904b 198#if WANT_PIC
adca2a18
MW
199 ldr\cond \got, .L$_ldgot$\@
200.L$_ldgot_pc$\@:
2d03a881 201 add\cond \got, pc, \got
8a1aa284 202 _LIT
adca2a18
MW
203 .balign 4
204.L$_ldgot$\@:
9f6eb05d 205 .word _GLOBAL_OFFSET_TABLE_ - .L$_ldgot_pc$\@ - .L$_pcoff
8a1aa284 206 _ENDLIT
61bd904b 207#endif
8a1aa284 208.endm
61bd904b
MW
209
210// Load address of external symbol ADDR into REG, maybe using GOT.
8a1aa284 211.macro leaext reg, addr, cond=, got=GOTREG
61bd904b 212#if WANT_PIC
adca2a18 213 ldr\cond \reg, .L$_leaext$\@
2d03a881 214 ldr\cond \reg, [\got, \reg]
8a1aa284 215 _LIT
adca2a18
MW
216 .balign 4
217.L$_leaext$\@:
218 .word \addr(GOT)
8a1aa284 219 _ENDLIT
61bd904b 220#else
2d03a881 221 ldr\cond \reg, =\addr
61bd904b 222#endif
8a1aa284 223.endm
61bd904b 224
0c53ac58 225// Load address of external symbol ADDR into REG directly.
8a1aa284 226.macro leaextq reg, addr, cond=
0c53ac58
MW
227#if WANT_PIC
228 ldr\cond \reg, .L$_leaextq$\@
229.L$_leaextq_pc$\@:
9f6eb05d 230 .if .L$_pcoff == 8
0c53ac58 231 ldr\cond \reg, [pc, \reg]
9f6eb05d
MW
232 .else
233 add\cond \reg, pc
234 ldr\cond \reg, [\reg]
235 .endif
8a1aa284 236 _LIT
0c53ac58
MW
237 .balign 4
238.L$_leaextq$\@:
9f6eb05d 239 .word \addr(GOT_PREL) + (. - .L$_leaextq_pc$\@ - .L$_pcoff)
8a1aa284 240 _ENDLIT
0c53ac58
MW
241#else
242 ldr\cond \reg, =\addr
243#endif
8a1aa284 244.endm
0c53ac58 245
61bd904b
MW
246#endif
247
248///--------------------------------------------------------------------------
1a0c09c4
MW
249/// Final stuff.
250
251// Default values for the various hooks.
252#ifndef FUNC_PREHOOK
253# define FUNC_PREHOOK(name)
254#endif
255#ifndef FUNC_POSTHOOK
256# define FUNC_POSTHOOK(name)
257#endif
258#ifndef ENDFUNC_HOOK
259# define ENDFUNC_HOOK(name)
260#endif
261
262#ifndef F
263# define F(name) name
264#endif
265
266#ifndef TYPE_FUNC
267# define TYPE_FUNC(name)
268#endif
269
270#ifndef SIZE_OBJ
271# define SIZE_OBJ(name)
272#endif
273
274///----- That's all, folks --------------------------------------------------