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