Blame sysdeps/sparc/sysdep.h

Packit 6c4009
/* Copyright (C) 2011-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#define _SYSDEPS_SYSDEP_H 1
Packit 6c4009
#include <bits/hwcap.h>
Packit 6c4009
Packit 6c4009
#ifdef	__ASSEMBLER__
Packit 6c4009
Packit 6c4009
#define SPARC_PIC_THUNK(reg)						\
Packit 6c4009
	.ifndef __sparc_get_pc_thunk.reg;				\
Packit 6c4009
	.section .text.__sparc_get_pc_thunk.reg,"axG",@progbits,__sparc_get_pc_thunk.reg,comdat; \
Packit 6c4009
	.align	 32;							\
Packit 6c4009
	.weak	 __sparc_get_pc_thunk.reg;				\
Packit 6c4009
	.hidden	 __sparc_get_pc_thunk.reg;				\
Packit 6c4009
	.type	 __sparc_get_pc_thunk.reg, #function;			\
Packit 6c4009
__sparc_get_pc_thunk.reg:		   				\
Packit 6c4009
	jmp	%o7 + 8;						\
Packit 6c4009
	 add	%o7, %reg, %##reg;					\
Packit 6c4009
	.previous;							\
Packit 6c4009
	.endif;
Packit 6c4009
Packit 6c4009
/* The "-4" and "+4" offsets against _GLOBAL_OFFSET_TABLE_ are
Packit 6c4009
   critical since they represent the offset from the thunk call to the
Packit 6c4009
   instruction containing the _GLOBAL_OFFSET_TABLE_ reference.
Packit 6c4009
   Therefore these instructions cannot be moved around without
Packit 6c4009
   appropriate adjustments to those offsets.
Packit 6c4009
Packit 6c4009
   Furthermore, these expressions are special in another regard.  When
Packit 6c4009
   the assembler sees a reference to _GLOBAL_OFFSET_TABLE_ inside of
Packit 6c4009
   a %hi() or %lo(), it emits a PC-relative relocation.  This causes
Packit 6c4009
   R_SPARC_HI22 to turn into R_SPARC_PC22, and R_SPARC_LO10 to turn into
Packit 6c4009
   R_SPARC_PC10, respectively.
Packit 6c4009
Packit 6c4009
   Even when v9 we use a call sequence instead of using "rd %pc" because
Packit 6c4009
   RDPC is extremely expensive and incurs a full pipeline flush.  */
Packit 6c4009
Packit 6c4009
#define SPARC_PIC_THUNK_CALL(reg)					\
Packit 6c4009
	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %##reg;			\
Packit 6c4009
	call	__sparc_get_pc_thunk.reg;				\
Packit 6c4009
	 or	%##reg, %lo(_GLOBAL_OFFSET_TABLE_+4), %##reg;
Packit 6c4009
Packit 6c4009
#define SETUP_PIC_REG(reg)						\
Packit 6c4009
	SPARC_PIC_THUNK(reg)						\
Packit 6c4009
	SPARC_PIC_THUNK_CALL(reg)
Packit 6c4009
Packit 6c4009
#define SETUP_PIC_REG_LEAF(reg, tmp)					\
Packit 6c4009
	SPARC_PIC_THUNK(reg)						\
Packit 6c4009
	mov	%o7, %##tmp;		      				\
Packit 6c4009
	SPARC_PIC_THUNK_CALL(reg);					\
Packit 6c4009
	mov	%##tmp, %o7;
Packit 6c4009
Packit 6c4009
#undef ENTRY
Packit 6c4009
#define ENTRY(name)			\
Packit 6c4009
	.align	4;			\
Packit 6c4009
	.global	C_SYMBOL_NAME(name);	\
Packit 6c4009
	.type	name, @function;	\
Packit 6c4009
C_LABEL(name)				\
Packit 6c4009
	cfi_startproc;
Packit 6c4009
Packit 6c4009
#undef END
Packit 6c4009
#define END(name)			\
Packit 6c4009
	cfi_endproc;			\
Packit 6c4009
	.size name, . - name
Packit 6c4009
Packit 6c4009
#undef LOC
Packit 6c4009
#define LOC(name)  .L##name
Packit 6c4009
Packit 6c4009
#endif	/* __ASSEMBLER__ */