1 // Assembly language support for arm64 CPU.
2 // Bruno Haible 1999-05-29
3 
4 // Copyright (C) 1999-2021 Bruno Haible <bruno@clisp.org>
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
18 
19 // In order not to have to maintain several copies of the assembly language
20 // code, we use some macros which expand into the correct syntax.
21 // These macros are:
22 //   C(name)
23 //           This expands to the name of the C variable or function `name'.
24 //           On Unix BSD systems, this prepends an underscore.
25 //   L(label)
26 //           This expands to the name of a local label, having the name `label'.
27 //           On Unix ELF systems, where there is no underscore, names beginning
28 //           with an alphabetic character are automatically exported, so this
29 //           prepends a dot. Note that when defining a label, the `:' must
30 //           be inside the parentheses, not outside, because otherwise some
31 //           ANSI C preprocessor inserts a space between the label and the `:',
32 //           and some assemblers don't like this.
33 //   GOTPAGE(variable)
34 //           This expands to a second argument for the 'adrp' instruction.
35 //   GOTPAGEOFF(variable)
36 //           This expands to an offset, to be used with GOTPAGE(variable).
37 //   GOTINDIR(register)
38 //           This expands to an indirect load instruction, on platforms which
39 //           use a "large" memory model.
40 //   PAGE(function)
41 //           This expands to a second argument for the 'adrp' instruction.
42 //   PAGEOFF(function)
43 //           This expands to an offset, to be used with PAGE(function).
44 //   DECLARE_FUNCTION(name)
45 //           Declare `name' to be a global function. When assembly language
46 //           code is compiled into a shared library, ELF linkers need to know
47 //           which symbols are functions.
48 //   FUNBEGIN(name)
49 //           Start the assembly language code for the C function `name'.
50 //   FUNEND(name)
51 //           End the assembly language code for the C function 'name'.
52 
53 #ifdef ASM_UNDERSCORE
54 #define C(entrypoint) _##entrypoint
55 #define L(label) L##label
56 #else
57 #define C(entrypoint) entrypoint
58 #define L(label) .L##label
59 #endif
60 
61 #if defined __APPLE__ && defined __MACH__
62 #define GOTPAGE(variable) variable@GOTPAGE
63 #define GOTPAGEOFF(variable) variable@GOTPAGEOFF
64 #define GOTINDIR(register) ldr register,[register]
65 #define PAGE(function) function@PAGE
66 #define PAGEOFF(function) function@PAGEOFF
67 #else
68 #define GOTPAGE(variable) variable
69 #define GOTPAGEOFF(variable) $:lo12:variable
70 #define GOTINDIR(register)
71 #define PAGE(function) function
72 #define PAGEOFF(function) $:lo12:function
73 #endif
74 
75 // When assembly language code is compiled into a shared library, ELF linkers
76 // need to know which symbols are functions.
77 #if defined(__ELF__) || !(defined(ASM_UNDERSCORE) || (defined __APPLE__ && defined __MACH__))
78 #define DECLARE_FUNCTION(name) .type C(name),%function
79 #define FUNEND(name) .size C(name),.-C(name)
80 #else
81 #define DECLARE_FUNCTION(name)
82 #define FUNEND(name)
83 #endif
84 #define FUNBEGIN(name) C(name):
85