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