mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 04:50:07 +00:00
ARM_BX_ALIGN_LOG2
This commit is contained in:
parent
ccffb2a2db
commit
bb48a26acf
@ -1,5 +1,9 @@
|
||||
2013-03-13 Roland McGrath <roland@hack.frob.com>
|
||||
|
||||
* sysdeps/arm/arm-features.h (ARM_BX_ALIGN_LOG2): New macro.
|
||||
* sysdeps/arm/memcpy.S: Respect ARM_BX_ALIGN_LOG2.
|
||||
* sysdeps/arm/memmove.S: Likewise.
|
||||
|
||||
* sysdeps/arm/add_n.S: Include <arm-features.h>.
|
||||
[ARM_ALWAYS_BX]: Don't pop into pc.
|
||||
|
||||
|
@ -40,4 +40,17 @@
|
||||
that instructions using pc as a destination register must never be used,
|
||||
so a "bx" (or "blx") instruction is always required. */
|
||||
|
||||
/* The log2 of the minimum alignment required for an address that
|
||||
is the target of a computed branch (i.e. a "bx" instruction).
|
||||
A more-specific arm-features.h file may define this to set a more
|
||||
stringent requirement.
|
||||
|
||||
Using this only makes sense for code in ARM mode (where instructions
|
||||
always have a fixed size of four bytes), or for Thumb-mode code that is
|
||||
specifically aligning all the related branch targets to match (since
|
||||
Thumb instructions might be either two or four bytes). */
|
||||
#ifndef ARM_BX_ALIGN_LOG2
|
||||
# define ARM_BX_ALIGN_LOG2 2
|
||||
#endif
|
||||
|
||||
#endif /* arm-features.h */
|
||||
|
@ -91,9 +91,9 @@ ENTRY(memcpy)
|
||||
CALGN( adr r4, 6f )
|
||||
CALGN( subs r2, r2, r3 ) @ C gets set
|
||||
#ifndef ARM_ALWAYS_BX
|
||||
CALGN( add pc, r4, ip )
|
||||
CALGN( add pc, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2))
|
||||
#else
|
||||
CALGN( add r4, r4, ip )
|
||||
CALGN( add r4, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2))
|
||||
CALGN( bx r4 )
|
||||
#endif
|
||||
|
||||
@ -115,39 +115,56 @@ ENTRY(memcpy)
|
||||
5: ands ip, r2, #28
|
||||
rsb ip, ip, #32
|
||||
#ifndef ARM_ALWAYS_BX
|
||||
addne pc, pc, ip @ C is always clear here
|
||||
/* C is always clear here. */
|
||||
addne pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
|
||||
b 7f
|
||||
#else
|
||||
beq 7f
|
||||
push {r10}
|
||||
cfi_adjust_cfa_offset (4)
|
||||
cfi_rel_offset (r10, 0)
|
||||
add r10, pc, ip
|
||||
add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
|
||||
bx r10
|
||||
#endif
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
6: nop
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r3, [r1], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r4, [r1], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r5, [r1], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r6, [r1], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r7, [r1], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r8, [r1], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr lr, [r1], #4
|
||||
|
||||
#ifndef ARM_ALWAYS_BX
|
||||
add pc, pc, ip
|
||||
add pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
|
||||
nop
|
||||
#else
|
||||
add r10, pc, ip
|
||||
add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
|
||||
bx r10
|
||||
#endif
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
nop
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r3, [r0], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r4, [r0], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r5, [r0], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r6, [r0], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r7, [r0], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r8, [r0], #4
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str lr, [r0], #4
|
||||
|
||||
#ifdef ARM_ALWAYS_BX
|
||||
|
@ -107,9 +107,9 @@ ENTRY(memmove)
|
||||
CALGN( adr r4, 6f )
|
||||
CALGN( subs r2, r2, ip ) @ C is set here
|
||||
#ifndef ARM_ALWAYS_BX
|
||||
CALGN( add pc, r4, ip )
|
||||
CALGN( add pc, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2))
|
||||
#else
|
||||
CALGN( add r4, r4, ip )
|
||||
CALGN( add r4, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2))
|
||||
CALGN( bx r4 )
|
||||
#endif
|
||||
|
||||
@ -131,39 +131,56 @@ ENTRY(memmove)
|
||||
5: ands ip, r2, #28
|
||||
rsb ip, ip, #32
|
||||
#ifndef ARM_ALWAYS_BX
|
||||
addne pc, pc, ip @ C is always clear here
|
||||
/* C is always clear here. */
|
||||
addne pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
|
||||
b 7f
|
||||
#else
|
||||
beq 7f
|
||||
push {r10}
|
||||
cfi_adjust_cfa_offset (4)
|
||||
cfi_rel_offset (r10, 0)
|
||||
add r10, pc, ip
|
||||
add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
|
||||
bx r10
|
||||
#endif
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
6: nop
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r3, [r1, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r4, [r1, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r5, [r1, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r6, [r1, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r7, [r1, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr r8, [r1, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
ldr lr, [r1, #-4]!
|
||||
|
||||
#ifndef ARM_ALWAYS_BX
|
||||
add pc, pc, ip
|
||||
add pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
|
||||
nop
|
||||
#else
|
||||
add r10, pc, ip
|
||||
add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
|
||||
bx r10
|
||||
#endif
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
nop
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r3, [r0, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r4, [r0, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r5, [r0, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r6, [r0, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r7, [r0, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str r8, [r0, #-4]!
|
||||
.p2align ARM_BX_ALIGN_LOG2
|
||||
str lr, [r0, #-4]!
|
||||
|
||||
#ifdef ARM_ALWAYS_BX
|
||||
|
Loading…
Reference in New Issue
Block a user