1 /* Assembly macros for 32-bit PowerPC. 2 Copyright (C) 1999-2021 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #include <sysdeps/powerpc/sysdep.h> 20 21 #ifdef __ASSEMBLER__ 22 23 /* If compiled for profiling, call `_mcount' at the start of each 24 function. */ 25 #ifdef PROF 26 /* The mcount code relies on a the return address being on the stack 27 to locate our caller and so it can restore it; so store one just 28 for its benefit. */ 29 # define CALL_MCOUNT \ 30 mflr r0; \ 31 stw r0,4(r1); \ 32 cfi_offset (lr, 4); \ 33 bl JUMPTARGET(_mcount); 34 #else /* PROF */ 35 # define CALL_MCOUNT /* Do nothing. */ 36 #endif /* PROF */ 37 38 #define ENTRY(name) \ 39 .globl C_SYMBOL_NAME(name); \ 40 .type C_SYMBOL_NAME(name),@function; \ 41 .align ALIGNARG(2); \ 42 C_LABEL(name) \ 43 cfi_startproc; \ 44 CALL_MCOUNT 45 46 #define ENTRY_TOCLESS(name) ENTRY(name) 47 48 /* helper macro for accessing the 32-bit powerpc GOT. */ 49 50 #define SETUP_GOT_ACCESS(regname,GOT_LABEL) \ 51 bcl 20,31,GOT_LABEL ; \ 52 GOT_LABEL: ; \ 53 mflr (regname) 54 55 #define EALIGN_W_0 /* No words to insert. */ 56 #define EALIGN_W_1 nop 57 #define EALIGN_W_2 nop;nop 58 #define EALIGN_W_3 nop;nop;nop 59 #define EALIGN_W_4 EALIGN_W_3;nop 60 #define EALIGN_W_5 EALIGN_W_4;nop 61 #define EALIGN_W_6 EALIGN_W_5;nop 62 #define EALIGN_W_7 EALIGN_W_6;nop 63 64 /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes 65 past a 2^align boundary. */ 66 #ifdef PROF 67 # define EALIGN(name, alignt, words) \ 68 .globl C_SYMBOL_NAME(name); \ 69 .type C_SYMBOL_NAME(name),@function; \ 70 .align ALIGNARG(2); \ 71 C_LABEL(name) \ 72 cfi_startproc; \ 73 CALL_MCOUNT \ 74 b 0f; \ 75 .align ALIGNARG(alignt); \ 76 EALIGN_W_##words; \ 77 0: 78 #else /* PROF */ 79 # define EALIGN(name, alignt, words) \ 80 .globl C_SYMBOL_NAME(name); \ 81 .type C_SYMBOL_NAME(name),@function; \ 82 .align ALIGNARG(alignt); \ 83 EALIGN_W_##words; \ 84 C_LABEL(name) \ 85 cfi_startproc; 86 #endif 87 88 #undef END 89 #define END(name) \ 90 cfi_endproc; \ 91 ASM_SIZE_DIRECTIVE(name) 92 93 #define DO_CALL(syscall) \ 94 li 0,syscall; \ 95 DO_CALL_SC 96 97 #define DO_CALL_SC \ 98 sc 99 100 #undef JUMPTARGET 101 #ifdef PIC 102 # define JUMPTARGET(name) name##@plt 103 #else 104 # define JUMPTARGET(name) name 105 #endif 106 107 #if defined SHARED && defined PIC && !defined NO_HIDDEN 108 # undef HIDDEN_JUMPTARGET 109 # define HIDDEN_JUMPTARGET(name) __GI_##name##@local 110 #endif 111 112 #define TAIL_CALL_SYSCALL_ERROR \ 113 b __syscall_error@local 114 115 #define PSEUDO(name, syscall_name, args) \ 116 .section ".text"; \ 117 ENTRY (name) \ 118 DO_CALL (SYS_ify (syscall_name)); 119 120 #define RET_SC \ 121 bnslr+; 122 123 #define PSEUDO_RET \ 124 RET_SC; \ 125 TAIL_CALL_SYSCALL_ERROR 126 #define ret PSEUDO_RET 127 128 #undef PSEUDO_END 129 #define PSEUDO_END(name) \ 130 END (name) 131 132 #define PSEUDO_NOERRNO(name, syscall_name, args) \ 133 .section ".text"; \ 134 ENTRY (name) \ 135 DO_CALL (SYS_ify (syscall_name)); 136 137 #define PSEUDO_RET_NOERRNO \ 138 blr 139 #define ret_NOERRNO PSEUDO_RET_NOERRNO 140 141 #undef PSEUDO_END_NOERRNO 142 #define PSEUDO_END_NOERRNO(name) \ 143 END (name) 144 145 #define PSEUDO_ERRVAL(name, syscall_name, args) \ 146 .section ".text"; \ 147 ENTRY (name) \ 148 DO_CALL (SYS_ify (syscall_name)); 149 150 #define PSEUDO_RET_ERRVAL \ 151 blr 152 #define ret_ERRVAL PSEUDO_RET_ERRVAL 153 154 #undef PSEUDO_END_ERRVAL 155 #define PSEUDO_END_ERRVAL(name) \ 156 END (name) 157 158 /* Local labels stripped out by the linker. */ 159 #undef L 160 #define L(x) .L##x 161 162 #define XGLUE(a,b) a##b 163 #define GLUE(a,b) XGLUE (a,b) 164 #define GENERATE_GOT_LABEL(name) GLUE (.got_label, name) 165 166 /* Label in text section. */ 167 #define C_TEXT(name) name 168 169 /* Read the value of member from rtld_global_ro. */ 170 #ifdef PIC 171 # ifdef SHARED 172 # if IS_IN (rtld) 173 /* Inside ld.so we use the local alias to avoid runtime GOT 174 relocations. */ 175 # define __GLRO(rOUT, rGOT, member, offset) \ 176 lwz rOUT,_rtld_local_ro@got(rGOT); \ 177 lwz rOUT,offset(rOUT) 178 # else 179 # define __GLRO(rOUT, rGOT, member, offset) \ 180 lwz rOUT,_rtld_global_ro@got(rGOT); \ 181 lwz rOUT,offset(rOUT) 182 # endif 183 # else 184 # define __GLRO(rOUT, rGOT, member, offset) \ 185 lwz rOUT,member@got(rGOT); \ 186 lwz rOUT,0(rOUT) 187 # endif 188 #else 189 /* Position-dependent code does not require access to the GOT. */ 190 # define __GLRO(rOUT, rGOT, member, offset) \ 191 lis rOUT,(member)@ha; \ 192 lwz rOUT,(member)@l(rOUT) 193 #endif /* PIC */ 194 195 #endif /* __ASSEMBLER__ */ 196