1 /// -*- mode: asm; asm-comment-char: ?/ -*-
3 /// Fancy SIMD implementation of Salsa20
5 /// (c) 2015 Straylight/Edgeware
8 ///----- Licensing notice ---------------------------------------------------
10 /// This file is part of Catacomb.
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.
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.
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.
27 ///--------------------------------------------------------------------------
28 /// General definitions.
30 // Some useful variables.
33 // Literal pools done the hard way.
34 #define _LIT .text .L$_subsec + 1
35 #define _ENDLIT .text .L$_subsec
36 #define _LTORG .L$_subsec = .L$_subsec + 2; .text .L$_subsec
38 // Announcing an external function.
42 .macro ENDFUNC; _ENDFUNC(name); .endm; \
47 // Marking the end of a function.
48 #define _ENDFUNC(name) \
54 // Make a helper function, if necessary.
56 .ifndef .L$_auxfn_def.name; \
58 .macro _ENDAUXFN; _ENDAUXFN_TAIL(name); .endm; \
61 #define _ENDAUXFN_TAIL(name) \
64 .L$_auxfn_def.name = 1
65 #define ENDAUXFN _ENDAUXFN; .endif
67 ///--------------------------------------------------------------------------
68 /// ELF-specific hacking.
72 #if __PIC__ || __PIE__
76 #define TYPE_FUNC(name) .type name, STT_FUNC
78 #define SIZE_OBJ(name) .size name, . - name
82 ///--------------------------------------------------------------------------
83 /// Windows-specific hacking.
88 # define F(name) _##name
93 ///--------------------------------------------------------------------------
94 /// x86- and amd64-specific hacking.
96 /// It's (slightly) easier to deal with both of these in one go.
98 #if CPUFAM_X86 || CPUFAM_AMD64
100 // Set the function hooks.
101 #define FUNC_PREHOOK(_) .balign 16
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
107 // Call external subroutine at ADDR, possibly via PLT.
116 // Do I need to arrange a spare GOT register?
117 #if WANT_PIC && CPUFAM_X86
120 #define GOTREG ebx // Not needed in AMD64 so don't care.
122 // Maybe load GOT address into GOT.
123 .macro ldgot got
=GOTREG
124 #if WANT_PIC && CPUFAM_X86
130 add \got
, offset _GLOBAL_OFFSET_TABLE_
134 // Load address of external symbol ADDR into REG, maybe using GOT.
135 .macro leaext reg
, addr
, got
=GOTREG
138 mov
\reg
, [\got
+ \addr@GOT
]
141 mov
\reg
, \addr@GOTPCREL
[rip
]
145 mov
\reg
, offset
\addr
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)
158 # define INTADDR__1(addr, got) addr + rip
160 # define INTADDR__1(addr, got) got + addr@GOTOFF
162 # define INTADDR__1(addr, got) addr
167 ///--------------------------------------------------------------------------
168 /// ARM-specific hacking.
172 // ARM/Thumb mode things. Use ARM by default.
173 #define ARM .arm; .L$_pcoff = 8
174 #define THUMB .thumb; .L$_pcoff = 4
177 // Set the function hooks.
178 #define FUNC_PREHOOK(_) .balign 4
179 #define ENDFUNC_HOOK(name) .ltorg
181 // Call external subroutine at ADDR, possibly via PLT.
182 .macro callext addr
, cond
=
190 // Do I need to arrange a spare GOT register?
196 // Maybe load GOT address into GOT.
197 .macro ldgot cond
=, got
=GOTREG
199 ldr\cond \got
, .L$_ldgot$\@
201 add\cond \got
, pc
, \got
205 .word _GLOBAL_OFFSET_TABLE_
- .L$_ldgot_pc$\@
- .L$_pcoff
210 // Load address of external symbol ADDR into REG, maybe using GOT.
211 .macro leaext reg
, addr
, cond
=, got
=GOTREG
213 ldr\cond
\reg
, .L$_leaext$\@
214 ldr\cond
\reg
, [\got
, \reg
]
221 ldr\cond
\reg
, =\addr
225 // Load address of external symbol ADDR into REG directly.
226 .macro leaextq reg
, addr
, cond
=
228 ldr\cond
\reg
, .L$_leaextq$\@
231 ldr\cond
\reg
, [pc
, \reg
]
234 ldr\cond
\reg
, [\reg
]
239 .word
\addr
(GOT_PREL
) + (. - .L$_leaextq_pc$\@
- .L$_pcoff
)
242 ldr\cond
\reg
, =\addr
248 ///--------------------------------------------------------------------------
251 // Default values for the various hooks.
253 # define FUNC_PREHOOK(name)
255 #ifndef FUNC_POSTHOOK
256 # define FUNC_POSTHOOK(name)
259 # define ENDFUNC_HOOK(name)
263 # define F(name) name
267 # define TYPE_FUNC(name)
271 # define SIZE_OBJ(name)
274 ///----- That's all, folks --------------------------------------------------