123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /* Assembly macros for 64-bit PowerPC.
- Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
- #ifdef __ELF__
- #ifdef __ASSEMBLER__
- /* Support macros for CALL_MCOUNT. */
- .macro SAVE_ARG NARG
- .if \NARG
- SAVE_ARG \NARG-1
- std 2+\NARG,-72+8*(\NARG)(1)
- .endif
- .endm
- .macro REST_ARG NARG
- .if \NARG
- REST_ARG \NARG-1
- ld 2+\NARG,40+8*(\NARG)(1)
- .endif
- .endm
- /* If compiled for profiling, call `_mcount' at the start of each function.
- see ppc-mcount.S for more details. */
- .macro CALL_MCOUNT NARG
- #ifdef PROF
- mflr r0
- SAVE_ARG \NARG
- std r0,16(r1)
- stdu r1,-112(r1)
- bl JUMPTARGET (_mcount)
- ld r0,128(r1)
- REST_ARG \NARG
- addi r1,r1,112
- mtlr r0
- #endif
- .endm
- #ifdef USE_PPC64_OVERLAPPING_OPD
- # define OPD_ENT(name) .quad BODY_LABEL (name), .TOC.@tocbase
- #else
- # define OPD_ENT(name) .quad BODY_LABEL (name), .TOC.@tocbase, 0
- #endif
- #define ENTRY_1(name) \
- .section ".text"; \
- .type BODY_LABEL(name),@function; \
- .globl name; \
- .section ".opd","aw"; \
- .align 3; \
- name##: OPD_ENT (name); \
- .previous;
- #ifdef HAVE_ASM_GLOBAL_DOT_NAME
- # define DOT_LABEL(X) .##X
- # define BODY_LABEL(X) .##X
- # define ENTRY_2(name) \
- .globl BODY_LABEL(name); \
- ENTRY_1(name) \
- .size name, 24;
- # define END_2(name) \
- .size BODY_LABEL(name),.-BODY_LABEL(name);
- #else
- # define DOT_LABEL(X) X
- # define BODY_LABEL(X) .LY##X
- # define ENTRY_2(name) \
- .type name,@function; \
- ENTRY_1(name)
- # define END_2(name) \
- .size name,.-BODY_LABEL(name); \
- .size BODY_LABEL(name),.-BODY_LABEL(name);
- #endif
- #define ENTRY(name) \
- ENTRY_2(name) \
- .align ALIGNARG(2); \
- BODY_LABEL(name): \
- cfi_startproc;
- #define EALIGN_W_0 /* No words to insert. */
- #define EALIGN_W_1 nop
- #define EALIGN_W_2 nop;nop
- #define EALIGN_W_3 nop;nop;nop
- #define EALIGN_W_4 EALIGN_W_3;nop
- #define EALIGN_W_5 EALIGN_W_4;nop
- #define EALIGN_W_6 EALIGN_W_5;nop
- #define EALIGN_W_7 EALIGN_W_6;nop
- /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
- past a 2^alignt boundary. */
- #define EALIGN(name, alignt, words) \
- ENTRY_2(name) \
- .align ALIGNARG(alignt); \
- EALIGN_W_##words; \
- BODY_LABEL(name): \
- cfi_startproc;
- /* Local labels stripped out by the linker. */
- #undef L
- #define L(x) .L##x
- #define tostring(s) #s
- #define stringify(s) tostring(s)
- #define XGLUE(a,b) a##b
- #define GLUE(a,b) XGLUE(a,b)
- #define LT_LABEL(name) GLUE(.LT,name)
- #define LT_LABELSUFFIX(name,suffix) GLUE(GLUE(.LT,name),suffix)
- /* Support Traceback tables */
- #define TB_ASM 0x000c000000000000
- #define TB_GLOBALLINK 0x0000800000000000
- #define TB_IS_EPROL 0x0000400000000000
- #define TB_HAS_TBOFF 0x0000200000000000
- #define TB_INT_PROC 0x0000100000000000
- #define TB_HAS_CTL 0x0000080000000000
- #define TB_TOCLESS 0x0000040000000000
- #define TB_FP_PRESENT 0x0000020000000000
- #define TB_LOG_ABORT 0x0000010000000000
- #define TB_INT_HANDL 0x0000008000000000
- #define TB_NAME_PRESENT 0x0000004000000000
- #define TB_USES_ALLOCA 0x0000002000000000
- #define TB_SAVES_CR 0x0000000200000000
- #define TB_SAVES_LR 0x0000000100000000
- #define TB_STORES_BC 0x0000000080000000
- #define TB_FIXUP 0x0000000040000000
- #define TB_FP_SAVED(fprs) (((fprs) & 0x3f) << 24)
- #define TB_GPR_SAVED(gprs) (((fprs) & 0x3f) << 16)
- #define TB_FIXEDPARMS(parms) (((parms) & 0xff) << 8)
- #define TB_FLOATPARMS(parms) (((parms) & 0x7f) << 1)
- #define TB_PARMSONSTK 0x0000000000000001
- #define PPC_HIGHER(v) (((v) >> 32) & 0xffff)
- #define TB_DEFAULT TB_ASM | TB_HAS_TBOFF | TB_NAME_PRESENT
- #define TRACEBACK(name) \
- LT_LABEL(name): ; \
- .long 0 ; \
- .quad TB_DEFAULT ; \
- .long LT_LABEL(name)-BODY_LABEL(name) ; \
- .short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
- LT_LABELSUFFIX(name,_name_start): ;\
- .ascii stringify(name) ; \
- LT_LABELSUFFIX(name,_name_end): ; \
- .align 2 ;
- #define TRACEBACK_MASK(name,mask) \
- LT_LABEL(name): ; \
- .long 0 ; \
- .quad TB_DEFAULT | mask ; \
- .long LT_LABEL(name)-BODY_LABEL(name) ; \
- .short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
- LT_LABELSUFFIX(name,_name_start): ;\
- .ascii stringify(name) ; \
- LT_LABELSUFFIX(name,_name_end): ; \
- .align 2 ;
- /* END generates Traceback tables */
- #undef END
- #define END(name) \
- cfi_endproc; \
- TRACEBACK(name) \
- END_2(name)
- /* This form supports more informative traceback tables */
- #define END_GEN_TB(name,mask) \
- cfi_endproc; \
- TRACEBACK_MASK(name,mask) \
- END_2(name)
- #define DO_CALL(syscall) \
- li 0,syscall; \
- sc
- /* ppc64 is always PIC */
- #undef JUMPTARGET
- #define JUMPTARGET(name) DOT_LABEL(name)
- #define PSEUDO(name, syscall_name, args) \
- .section ".text"; \
- ENTRY (name) \
- DO_CALL (SYS_ify (syscall_name));
- #define PSEUDO_RET \
- bnslr+; \
- b JUMPTARGET(__syscall_error)
- #define ret PSEUDO_RET
- #undef PSEUDO_END
- #define PSEUDO_END(name) \
- END (name)
- #define PSEUDO_NOERRNO(name, syscall_name, args) \
- .section ".text"; \
- ENTRY (name) \
- DO_CALL (SYS_ify (syscall_name));
- #define PSEUDO_RET_NOERRNO \
- blr
- #define ret_NOERRNO PSEUDO_RET_NOERRNO
- #undef PSEUDO_END_NOERRNO
- #define PSEUDO_END_NOERRNO(name) \
- END (name)
- #define PSEUDO_ERRVAL(name, syscall_name, args) \
- .section ".text"; \
- ENTRY (name) \
- DO_CALL (SYS_ify (syscall_name));
- #define PSEUDO_RET_ERRVAL \
- blr
- #define ret_ERRVAL PSEUDO_RET_ERRVAL
- #undef PSEUDO_END_ERRVAL
- #define PSEUDO_END_ERRVAL(name) \
- END (name)
- #else /* !__ASSEMBLER__ */
- #ifdef USE_PPC64_OVERLAPPING_OPD
- # define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase;"
- #else
- # define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase, 0;"
- #endif
- #ifdef HAVE_ASM_GLOBAL_DOT_NAME
- # define DOT_PREFIX "."
- # define BODY_PREFIX "."
- # define ENTRY_2(name) \
- ".globl " BODY_PREFIX #name ";\n" \
- ".size " #name ", 24;"
- # define END_2(name) \
- ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
- #else
- # define DOT_PREFIX ""
- # define BODY_PREFIX ".LY"
- # define ENTRY_2(name) ".type " #name ",@function;"
- # define END_2(name) \
- ".size " #name ",.-" BODY_PREFIX #name ";\n" \
- ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
- #endif
- #endif /* __ASSEMBLER__ */
- #endif /* __ELF__ */
|