Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
ARM: Use movw/movt more when available
  • Loading branch information
Roland McGrath committed Oct 22, 2014
1 parent b5af929 commit 8c2b1ed
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 69 deletions.
27 changes: 27 additions & 0 deletions ChangeLog
@@ -1,3 +1,30 @@
2014-10-22 Roland McGrath <roland@hack.frob.com>

* sysdeps/arm/__longjmp.S [NEED_HWCAP] [IS_IN_rtld]: Use LDST_PCREL
macro to get at the _rt_local_ro field.
[NEED_HWCAP] [!IS_IN_rtld]: Use LDR_GLOBAL to get at _rtld_global_ro
([PIC] case) or _dl_hwcap ([!PIC] case).
* sysdeps/arm/setjmp.S: Likewise.

* config.h.in (ARM_PCREL_MOVW_OK): New macro.
* sysdeps/arm/configure.ac: New check to define it.
* sysdeps/arm/configure: Regenerated.
* sysdeps/arm/sysdep.h [__ASSEMBLER__]: Include <arm-features.h>.
(LDST_INDEXED_NOINDEX, LDST_INDEXED_INDEX): New macros.
(LDST_INDEXED, LDST_PC_INDEXED): New macros, differing definitions
depending on [ARM_NO_INDEX_REGISTER] and [__thumb2__].
(LDST_PCREL) [!__thumb2__ && ARCH_HAS_T2 && ARM_PCREL_MOVW_OK]:
Use move/movt pair instead of a load.
(LDST_GLOBAL): Macro removed.
(LDR_GLOBAL): New macro replaces it.
(LDR_HIDDEN): New macro.
(PTR_MANGLE_LOAD): Use LDR_GLOBAL rather than LDST_GLOBAL.
Use LDR_HIDDEN instead for __pointer_chk_guard_local.

* setjmp/tst-setjmp-static.c: New file.
* setjmp/Makefile (tests): Add it.
(tests-static): New variable.

2014-10-22 Maciej W. Rozycki <macro@codesourcery.com>

[BZ #17485]
Expand Down
3 changes: 3 additions & 0 deletions config.h.in
Expand Up @@ -243,6 +243,9 @@
/* The ARM hard-float ABI is being used. */
#undef HAVE_ARM_PCS_VFP

/* The ARM movw/movt instructions using PC-relative relocs work right. */
#define ARM_PCREL_MOVW_OK 0

/* The pt_chown binary is being built and used by grantpt. */
#define HAVE_PT_CHOWN 0

Expand Down
3 changes: 2 additions & 1 deletion setjmp/Makefile
Expand Up @@ -28,7 +28,8 @@ routines := setjmp sigjmp bsd-setjmp bsd-_setjmp \
longjmp __longjmp jmp-unwind

tests := tst-setjmp jmpbug bug269-setjmp tst-setjmp-fp \
tst-sigsetjmp
tst-sigsetjmp tst-setjmp-static
tests-static := tst-setjmp-static


include ../Rules
Expand Down
1 change: 1 addition & 0 deletions setjmp/tst-setjmp-static.c
@@ -0,0 +1 @@
#include "tst-setjmp.c"
35 changes: 6 additions & 29 deletions sysdeps/arm/__longjmp.S
Expand Up @@ -77,21 +77,15 @@ ENTRY (__longjmp)

#ifdef NEED_HWCAP
# ifdef IS_IN_rtld
ldr a4, 1f
ldr a3, .Lrtld_local_ro
0: add a4, pc, a4
add a4, a4, a3
ldr a4, [a4, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
LDST_PCREL (ldr, a4, a3, \
C_SYMBOL_NAME(_rtld_local_ro) \
+ RTLD_GLOBAL_RO_DL_HWCAP_OFFSET)
# else
# ifdef PIC
ldr a4, 1f
ldr a3, .Lrtld_global_ro
0: add a4, pc, a4
ldr a4, [a4, a3]
ldr a4, [a4, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
LDR_GLOBAL (a4, a3, C_SYMBOL_NAME(_rtld_global_ro), \
RTLD_GLOBAL_RO_DL_HWCAP_OFFSET)
# else
ldr a4, .Lhwcap
ldr a4, [a4, #0]
LDR_GLOBAL (a4, a3, C_SYMBOL_NAME(_dl_hwcap), 0)
# endif
# endif
#endif
Expand Down Expand Up @@ -138,21 +132,4 @@ ENTRY (__longjmp)

DO_RET(lr)

#ifdef NEED_HWCAP
# ifdef IS_IN_rtld
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS
.Lrtld_local_ro:
.long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
# else
# ifdef PIC
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS
.Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
# else
.Lhwcap:
.long C_SYMBOL_NAME(_dl_hwcap)
# endif
# endif
#endif

END (__longjmp)
52 changes: 50 additions & 2 deletions sysdeps/arm/configure
Expand Up @@ -150,8 +150,8 @@ else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifdef __ARM_PCS_VFP
yes
#endif
yes
#endif

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
Expand Down Expand Up @@ -211,6 +211,54 @@ else
have-arm-tls-desc = no"
fi

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PC-relative relocs in movw/movt work properly" >&5
$as_echo_n "checking whether PC-relative relocs in movw/movt work properly... " >&6; }
if ${libc_cv_arm_pcrel_movw+:} false; then :
$as_echo_n "(cached) " >&6
else

cat > conftest.s <<\EOF
.syntax unified
.arm
.arch armv7-a

.text
.globl foo
.type foo,%function
foo: movw r0, #:lower16:symbol - 1f - 8
movt r0, #:upper16:symbol - 1f - 8
1: add r0, pc
@ And now a case with a local symbol.
movw r0, #:lower16:3f - 2f - 8
movt r0, #:upper16:3f - 2f - 8
2: add r0, pc
bx lr

.data
.globl symbol
.hidden symbol
symbol: .long 23
3: .long 17
EOF
libc_cv_arm_pcrel_movw=no
${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
-nostartfiles -nostdlib -shared \
-o conftest.so conftest.s 1>&5 2>&5 &&
LC_ALL=C $READELF -dr conftest.so > conftest.dr 2>&5 &&
{
cat conftest.dr 1>&5
fgrep 'TEXTREL
R_ARM_NONE' conftest.dr > /dev/null || libc_cv_arm_pcrel_movw=yes
}
rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_arm_pcrel_movw" >&5
$as_echo "$libc_cv_arm_pcrel_movw" >&6; }
if test $libc_cv_arm_pcrel_movw = yes; then
$as_echo "#define ARM_PCREL_MOVW_OK 1" >>confdefs.h

fi

libc_cv_gcc_unwind_find_fde=no

# Remove -fno-unwind-tables that was added in sysdeps/arm/preconfigure.ac.
Expand Down
44 changes: 42 additions & 2 deletions sysdeps/arm/configure.ac
Expand Up @@ -17,8 +17,8 @@ dnl it. Until we do, don't define it.
AC_CACHE_CHECK([whether the compiler is using the ARM hard-float ABI],
[libc_cv_arm_pcs_vfp],
[AC_EGREP_CPP(yes,[#ifdef __ARM_PCS_VFP
yes
#endif
yes
#endif
], libc_cv_arm_pcs_vfp=yes, libc_cv_arm_pcs_vfp=no)])
if test $libc_cv_arm_pcs_vfp = yes; then
AC_DEFINE(HAVE_ARM_PCS_VFP)
Expand All @@ -40,6 +40,46 @@ else
LIBC_CONFIG_VAR([have-arm-tls-desc], [no])
fi

AC_CACHE_CHECK([whether PC-relative relocs in movw/movt work properly],
libc_cv_arm_pcrel_movw, [
cat > conftest.s <<\EOF
.syntax unified
.arm
.arch armv7-a
.text
.globl foo
.type foo,%function
foo: movw r0, #:lower16:symbol - 1f - 8
movt r0, #:upper16:symbol - 1f - 8
1: add r0, pc
@ And now a case with a local symbol.
movw r0, #:lower16:3f - 2f - 8
movt r0, #:upper16:3f - 2f - 8
2: add r0, pc
bx lr
.data
.globl symbol
.hidden symbol
symbol: .long 23
3: .long 17
EOF
libc_cv_arm_pcrel_movw=no
${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
-nostartfiles -nostdlib -shared \
-o conftest.so conftest.s 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD &&
LC_ALL=C $READELF -dr conftest.so > conftest.dr 2>&AS_MESSAGE_LOG_FD &&
{
cat conftest.dr 1>&AS_MESSAGE_LOG_FD
fgrep 'TEXTREL
R_ARM_NONE' conftest.dr > /dev/null || libc_cv_arm_pcrel_movw=yes
}
rm -f conftest*])
if test $libc_cv_arm_pcrel_movw = yes; then
AC_DEFINE([ARM_PCREL_MOVW_OK])
fi

libc_cv_gcc_unwind_find_fde=no

# Remove -fno-unwind-tables that was added in sysdeps/arm/preconfigure.ac.
Expand Down
35 changes: 6 additions & 29 deletions sysdeps/arm/setjmp.S
Expand Up @@ -58,21 +58,15 @@ ENTRY (__sigsetjmp)
#ifdef NEED_HWCAP
/* Check if we have a VFP unit. */
# ifdef IS_IN_rtld
ldr a3, 1f
ldr a4, .Lrtld_local_ro
0: add a3, pc, a3
add a3, a3, a4
ldr a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
LDST_PCREL (ldr, a3, a4, \
C_SYMBOL_NAME(_rtld_local_ro) \
+ RTLD_GLOBAL_RO_DL_HWCAP_OFFSET)
# else
# ifdef PIC
ldr a3, 1f
ldr a4, .Lrtld_global_ro
0: add a3, pc, a3
ldr a3, [a3, a4]
ldr a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
LDR_GLOBAL (a3, a4, C_SYMBOL_NAME(_rtld_global_ro), \
RTLD_GLOBAL_RO_DL_HWCAP_OFFSET)
# else
ldr a3, .Lhwcap
ldr a3, [a3, #0]
LDR_GLOBAL (a3, a4, C_SYMBOL_NAME(_dl_hwcap), 0)
# endif
# endif
#endif
Expand Down Expand Up @@ -114,23 +108,6 @@ ENTRY (__sigsetjmp)
/* Make a tail call to __sigjmp_save; it takes the same args. */
B PLTJMP(C_SYMBOL_NAME(__sigjmp_save))

#ifdef NEED_HWCAP
# ifdef IS_IN_rtld
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS
.Lrtld_local_ro:
.long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
# else
# ifdef PIC
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS
.Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
# else
.Lhwcap:
.long C_SYMBOL_NAME(_dl_hwcap)
# endif
# endif
#endif

END (__sigsetjmp)

hidden_def (__sigsetjmp)

0 comments on commit 8c2b1ed

Please sign in to comment.