Avoid VFP HWCAP check in setjmp/longjmp and getcontext/setcontext when compiled without __SOFTFP__ defined.

This commit is contained in:
Roland McGrath 2012-08-09 11:51:05 -07:00
parent a4ca519518
commit 6dcf80c782
5 changed files with 114 additions and 102 deletions

View file

@ -1,5 +1,11 @@
2012-08-09 Roland McGrath <roland@hack.frob.com>
* sysdeps/arm/__longjmp.S: Use .Lxxx rather than Lxxx for local labels.
[__SOFTFP__]: Conditionalize HWCAP_ARM_VFP check on this.
* sysdeps/arm/setjmp.S: Likewise.
* sysdeps/unix/sysv/linux/arm/getcontext.S: Likewise.
* sysdeps/unix/sysv/linux/arm/setcontext.S: Likewise.
* sysdeps/arm/arm-features.h: New file.
* sysdeps/unix/sysv/linux/arm/arm-features.h: New file.
* sysdeps/arm/fclrexcpt.c: Use ARM_HAVE_VFP instead of hwcap bits.

View file

@ -1,6 +1,5 @@
/* longjmp for ARM.
Copyright (C) 1997, 1998, 2005, 2006, 2009, 2010
Free Software Foundation, Inc.
Copyright (C) 1997-2012 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
@ -48,26 +47,28 @@ ENTRY (__longjmp)
cfi_restore (lr)
#ifdef IS_IN_rtld
ldr a2, 1f
ldr a3, Lrtld_local_ro
ldr a2, 1f
ldr a3, .Lrtld_local_ro
0: add a2, pc, a2
add a2, a2, a3
ldr a2, [a2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
#else
#ifdef PIC
ldr a2, 1f
ldr a3, Lrtld_global_ro
ldr a2, 1f
ldr a3, .Lrtld_global_ro
0: add a2, pc, a2
ldr a2, [a2, a3]
ldr a2, [a2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
#else
ldr a2, Lhwcap
ldr a2, .Lhwcap
ldr a2, [a2, #0]
#endif
#endif
#ifdef __SOFTFP__
tst a2, #HWCAP_ARM_VFP
beq Lno_vfp
beq .Lno_vfp
#endif
/* Restore the VFP registers. */
/* Following instruction is vldmia ip!, {d8-d15}. */
@ -76,10 +77,10 @@ ENTRY (__longjmp)
ldr a3, [ip], #4
/* Following instruction is fmxr fpscr, a3. */
mcr p10, 7, a3, cr1, cr0, 0
Lno_vfp:
.Lno_vfp:
tst a2, #HWCAP_ARM_IWMMXT
beq Lno_iwmmxt
beq .Lno_iwmmxt
/* Restore the call-preserved iWMMXt registers. */
/* Following instructions are wldrd wr10, [ip], #8 (etc.) */
@ -89,21 +90,21 @@ Lno_vfp:
ldcl p1, cr13, [r12], #8
ldcl p1, cr14, [r12], #8
ldcl p1, cr15, [r12], #8
Lno_iwmmxt:
.Lno_iwmmxt:
DO_RET(lr)
#ifdef IS_IN_rtld
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8
Lrtld_local_ro:
.Lrtld_local_ro:
.long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
#else
#ifdef PIC
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8
Lrtld_global_ro:
.Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
#else
Lhwcap:
.Lhwcap:
.long C_SYMBOL_NAME(_dl_hwcap)
#endif
#endif

View file

@ -1,5 +1,5 @@
/* setjmp for ARM.
Copyright (C) 1997, 1998, 2005, 2006, 2008 Free Software Foundation, Inc.
Copyright (C) 1997-2012 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
@ -31,25 +31,27 @@ ENTRY (__sigsetjmp)
/* Check if we have a VFP unit. */
#ifdef IS_IN_rtld
ldr a3, 1f
ldr a4, Lrtld_local_ro
ldr a4, .Lrtld_local_ro
0: add a3, pc, a3
add a3, a3, a4
ldr a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
#else
#ifdef PIC
ldr a3, 1f
ldr a4, Lrtld_global_ro
ldr a4, .Lrtld_global_ro
0: add a3, pc, a3
ldr a3, [a3, a4]
ldr a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
#else
ldr a3, Lhwcap
ldr a3, .Lhwcap
ldr a3, [a3, #0]
#endif
#endif
#ifdef __SOFTFP__
tst a3, #HWCAP_ARM_VFP
beq Lno_vfp
beq .Lno_vfp
#endif
/* Store the VFP registers.
Don't use VFP instructions directly because this code
@ -60,10 +62,10 @@ ENTRY (__sigsetjmp)
/* Following instruction is vmrs a4, fpscr. */
mrc p10, 7, a4, cr1, cr0, 0
str a4, [ip], #4
Lno_vfp:
.Lno_vfp:
tst a3, #HWCAP_ARM_IWMMXT
beq Lno_iwmmxt
beq .Lno_iwmmxt
/* Save the call-preserved iWMMXt registers. */
/* Following instructions are wstrd wr10, [ip], #8 (etc.) */
@ -73,22 +75,22 @@ Lno_vfp:
stcl p1, cr13, [r12], #8
stcl p1, cr14, [r12], #8
stcl p1, cr15, [r12], #8
Lno_iwmmxt:
.Lno_iwmmxt:
/* Make a tail call to __sigjmp_save; it takes the same args. */
B PLTJMP(C_SYMBOL_NAME(__sigjmp_save))
#ifdef IS_IN_rtld
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8
Lrtld_local_ro:
.Lrtld_local_ro:
.long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
#else
#ifdef PIC
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8
Lrtld_global_ro:
.Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
#else
Lhwcap:
.Lhwcap:
.long C_SYMBOL_NAME(_dl_hwcap)
#endif
#endif

View file

@ -41,54 +41,56 @@ ENTRY(__getcontext)
/* Save ucontext_t * across the next call. */
mov r4, r0
/* __sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */
mov r0, #SIG_BLOCK
mov r1, #0
add r2, r4, #UCONTEXT_SIGMASK
bl PLTJMP(__sigprocmask)
/* Store FP regs. Much of the FP code is copied from arm/setjmp.S. */
#ifdef PIC
ldr r2, 1f
ldr r1, Lrtld_global_ro
ldr r2, 1f
ldr r1, .Lrtld_global_ro
0: add r2, pc, r2
ldr r2, [r2, r1]
ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
ldr r2, [r2, r1]
ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
#else
ldr r2, Lhwcap
ldr r2, [r2, #0]
ldr r2, .Lhwcap
ldr r2, [r2, #0]
#endif
add r0, r4, #UCONTEXT_REGSPACE
tst r2, #HWCAP_ARM_VFP
beq Lno_vfp
#ifdef __SOFTFP__
tst r2, #HWCAP_ARM_VFP
beq .Lno_vfp
#endif
/* Store the VFP registers.
Don't use VFP instructions directly because this code
is used in non-VFP multilibs. */
/* Following instruction is vstmia r0!, {d8-d15}. */
stc p11, cr8, [r0], #64
/* Store the floating-point status register. */
/* Following instruction is vmrs r1, fpscr. */
mrc p10, 7, r1, cr1, cr0, 0
str r1, [r0], #4
Lno_vfp:
/* Store the VFP registers.
Don't use VFP instructions directly because this code
is used in non-VFP multilibs. */
/* Following instruction is vstmia r0!, {d8-d15}. */
stc p11, cr8, [r0], #64
/* Store the floating-point status register. */
/* Following instruction is vmrs r1, fpscr. */
mrc p10, 7, r1, cr1, cr0, 0
str r1, [r0], #4
.Lno_vfp:
tst r2, #HWCAP_ARM_IWMMXT
beq Lno_iwmmxt
tst r2, #HWCAP_ARM_IWMMXT
beq .Lno_iwmmxt
/* Save the call-preserved iWMMXt registers. */
/* Following instructions are wstrd wr10, [r0], #8 (etc.) */
stcl p1, cr10, [r0], #8
stcl p1, cr11, [r0], #8
stcl p1, cr12, [r0], #8
stcl p1, cr13, [r0], #8
stcl p1, cr14, [r0], #8
stcl p1, cr15, [r0], #8
Lno_iwmmxt:
/* Save the call-preserved iWMMXt registers. */
/* Following instructions are wstrd wr10, [r0], #8 (etc.) */
stcl p1, cr10, [r0], #8
stcl p1, cr11, [r0], #8
stcl p1, cr12, [r0], #8
stcl p1, cr13, [r0], #8
stcl p1, cr14, [r0], #8
stcl p1, cr15, [r0], #8
.Lno_iwmmxt:
/* Restore the clobbered R4 and LR. */
ldr r14, [r4, #MCONTEXT_ARM_LR]
@ -102,11 +104,11 @@ END(__getcontext)
#ifdef PIC
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8
Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
.Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
#else
Lhwcap:
.long C_SYMBOL_NAME(_dl_hwcap)
.Lhwcap:
.long C_SYMBOL_NAME(_dl_hwcap)
#endif

View file

@ -29,40 +29,42 @@ ENTRY(__setcontext)
mov r4, r0
add r0, r0, #UCONTEXT_REGSPACE
/* Restore the VFP registers. Copied from arm/__longjmp.S. */
/* Restore the VFP registers. Copied from arm/__longjmp.S. */
#ifdef PIC
ldr r2, 1f
ldr r1, Lrtld_global_ro
ldr r2, 1f
ldr r1, .Lrtld_global_ro
0: add r2, pc, r2
ldr r2, [r2, r1]
ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
ldr r2, [r2, r1]
ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
#else
ldr r2, Lhwcap
ldr r2, [r2, #0]
ldr r2, .Lhwcap
ldr r2, [r2, #0]
#endif
tst r2, #HWCAP_ARM_VFP
beq Lno_vfp_sc
#ifdef __SOFTFP__
tst r2, #HWCAP_ARM_VFP
beq .Lno_vfp_sc
#endif
/* Following instruction is vldmia r0!, {d8-d15}. */
ldc p11, cr8, [r0], #64
/* Restore the floating-point status register. */
ldr r1, [r0], #4
/* Following instruction is fmxr fpscr, r1. */
mcr p10, 7, r1, cr1, cr0, 0
Lno_vfp_sc:
tst r2, #HWCAP_ARM_IWMMXT
beq Lno_iwmmxt_sc
/* Following instruction is vldmia r0!, {d8-d15}. */
ldc p11, cr8, [r0], #64
/* Restore the floating-point status register. */
ldr r1, [r0], #4
/* Following instruction is fmxr fpscr, r1. */
mcr p10, 7, r1, cr1, cr0, 0
.Lno_vfp_sc:
tst r2, #HWCAP_ARM_IWMMXT
beq .Lno_iwmmxt_sc
/* Restore the call-preserved iWMMXt registers. */
/* Following instructions are wldrd wr10, [r0], #8 (etc.) */
ldcl p1, cr10, [r0], #8
ldcl p1, cr11, [r0], #8
ldcl p1, cr12, [r0], #8
ldcl p1, cr13, [r0], #8
ldcl p1, cr14, [r0], #8
ldcl p1, cr15, [r0], #8
Lno_iwmmxt_sc:
/* Restore the call-preserved iWMMXt registers. */
/* Following instructions are wldrd wr10, [r0], #8 (etc.) */
ldcl p1, cr10, [r0], #8
ldcl p1, cr11, [r0], #8
ldcl p1, cr12, [r0], #8
ldcl p1, cr13, [r0], #8
ldcl p1, cr14, [r0], #8
ldcl p1, cr15, [r0], #8
.Lno_iwmmxt_sc:
/* Now bring back the signal status. */
mov r0, #SIG_SETMASK
@ -70,12 +72,12 @@ Lno_iwmmxt_sc:
mov r2, #0
bl PLTJMP(__sigprocmask)
/* Loading r0-r3 makes makecontext easier. */
add r14, r4, #MCONTEXT_ARM_R0
ldmia r14, {r0-r12}
ldr r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)]
add r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0)
ldmia r14, {r14, pc}
/* Loading r0-r3 makes makecontext easier. */
add r14, r4, #MCONTEXT_ARM_R0
ldmia r14, {r0-r12}
ldr r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)]
add r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0)
ldmia r14, {r14, pc}
END(setcontext)
weak_alias(__setcontext, setcontext)
@ -83,19 +85,18 @@ weak_alias(__setcontext, setcontext)
/* Called when a makecontext() context returns. Start the
context in R4 or fall through to exit(). */
ENTRY(__startcontext)
movs r0, r4
bne PLTJMP(__setcontext)
movs r0, r4
bne PLTJMP(__setcontext)
@ New context was 0 - exit
b PLTJMP(HIDDEN_JUMPTARGET(_exit))
@ New context was 0 - exit
b PLTJMP(HIDDEN_JUMPTARGET(_exit))
END(__startcontext)
#ifdef PIC
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8
Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
.Lrtld_global_ro:
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
#else
Lhwcap:
.long C_SYMBOL_NAME(_dl_hwcap)
.Lhwcap:
.long C_SYMBOL_NAME(_dl_hwcap)
#endif