This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch roland/arm-sfi-macros created. glibc-2.17-386-ga964748
- From: roland at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 12 Mar 2013 18:52:29 -0000
- Subject: GNU C Library master sources branch roland/arm-sfi-macros created. glibc-2.17-386-ga964748
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, roland/arm-sfi-macros has been created
at a964748c46453c7b9d7959a0af4a85143aee91b6 (commit)
- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a964748c46453c7b9d7959a0af4a85143aee91b6
commit a964748c46453c7b9d7959a0af4a85143aee91b6
Author: Roland McGrath <roland@hack.frob.com>
Date: Tue Mar 12 10:57:50 2013 -0700
ARM: sfi_sp assembler macro
diff --git a/ports/ChangeLog.arm b/ports/ChangeLog.arm
index 5d773b9..7ecc0fe 100644
--- a/ports/ChangeLog.arm
+++ b/ports/ChangeLog.arm
@@ -1,5 +1,8 @@
2013-03-12 Roland McGrath <roland@hack.frob.com>
+ * sysdeps/arm/sysdep.h [!ARM_SFI_MACROS] (sfi_sp): New macro.
+ * sysdeps/arm/__longjmp.S: Use it.
+
* sysdeps/arm/sysdep.h [!ARM_SFI_MACROS]
(ARM_SFI_MACROS): Define it.
(sfi_breg, sfi_pld): New assembler macros.
diff --git a/ports/sysdeps/arm/__longjmp.S b/ports/sysdeps/arm/__longjmp.S
index 2936a44..8de9fa1 100644
--- a/ports/sysdeps/arm/__longjmp.S
+++ b/ports/sysdeps/arm/__longjmp.S
@@ -36,7 +36,7 @@ ENTRY (__longjmp)
cfi_undefined (r4)
CHECK_SP (r4)
#endif
- sfi_breg ip, \
+ sfi_sp sfi_breg ip, \
ldmia \B!, JMP_BUF_REGLIST
cfi_restore (v1)
cfi_restore (v2)
diff --git a/ports/sysdeps/arm/sysdep.h b/ports/sysdeps/arm/sysdep.h
index 4917805..83df7eb 100644
--- a/ports/sysdeps/arm/sysdep.h
+++ b/ports/sysdeps/arm/sysdep.h
@@ -250,6 +250,11 @@
pld [\basereg, \offset]
.endm
+/* This macro precedes any instruction that directly changes the SP.
+ It's not needed for push/pop or for any kind of load or store that
+ implicitly changes the SP via the ! syntax. */
+# define sfi_sp /* Nothing to do. */
+
# endif
#endif /* __ASSEMBLER__ */
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=daf6cee2c620833723b1a10e83f0bae0cd92204d
commit daf6cee2c620833723b1a10e83f0bae0cd92204d
Author: Roland McGrath <roland@hack.frob.com>
Date: Tue Mar 12 10:45:51 2013 -0700
ARM: sfi_breg assembler macro
diff --git a/ports/ChangeLog.arm b/ports/ChangeLog.arm
index 8536181..5d773b9 100644
--- a/ports/ChangeLog.arm
+++ b/ports/ChangeLog.arm
@@ -1,3 +1,23 @@
+2013-03-12 Roland McGrath <roland@hack.frob.com>
+
+ * sysdeps/arm/sysdep.h [!ARM_SFI_MACROS]
+ (ARM_SFI_MACROS): Define it.
+ (sfi_breg, sfi_pld): New assembler macros.
+ * sysdeps/arm/__longjmp.S: Use them for all memory references not
+ through the pc or sp registers.
+ * sysdeps/arm/add_n.S: Likewise.
+ * sysdeps/arm/addmul_1.S: Likewise.
+ * sysdeps/arm/arm-mcount.S: Likewise.
+ * sysdeps/arm/armv6/rawmemchr.S: Likewise.
+ * sysdeps/arm/armv6/strchr.S: Likewise.
+ * sysdeps/arm/armv6/strcpy.S: Likewise.
+ * sysdeps/arm/armv6/strlen.S: Likewise.
+ * sysdeps/arm/armv6/strrchr.S: Likewise.
+ * sysdeps/arm/memset.S: Likewise.
+ * sysdeps/arm/setjmp.S: Likewise.
+ * sysdeps/arm/strlen.S: Likewise.
+ * sysdeps/arm/submul_1.S: Likewise.
+
2013-03-11 Joseph Myers <joseph@codesourcery.com>
* sysdeps/arm/preconfigure.in: Add comment about
diff --git a/ports/sysdeps/arm/__longjmp.S b/ports/sysdeps/arm/__longjmp.S
index becba93..2936a44 100644
--- a/ports/sysdeps/arm/__longjmp.S
+++ b/ports/sysdeps/arm/__longjmp.S
@@ -31,11 +31,13 @@ ENTRY (__longjmp)
moveq r0, #1 /* can't let setjmp() return zero! */
#ifdef CHECK_SP
- ldr r4, [ip, #32] /* jmpbuf's sp */
+ sfi_breg ip, \
+ ldr r4, [\B, #32] /* jmpbuf's sp */
cfi_undefined (r4)
CHECK_SP (r4)
#endif
- ldmia ip!, JMP_BUF_REGLIST
+ sfi_breg ip, \
+ ldmia \B!, JMP_BUF_REGLIST
cfi_restore (v1)
cfi_restore (v2)
cfi_restore (v3)
@@ -79,9 +81,11 @@ ENTRY (__longjmp)
/* Restore the VFP registers. */
/* Following instruction is vldmia ip!, {d8-d15}. */
- ldc p11, cr8, [r12], #64
+ sfi_breg r12, \
+ ldc p11, cr8, [\B], #64
/* Restore the floating-point status register. */
- ldr a3, [ip], #4
+ sfi_breg ip, \
+ ldr a3, [\B], #4
/* Following instruction is fmxr fpscr, a3. */
mcr p10, 7, a3, cr1, cr0, 0
.Lno_vfp:
@@ -92,12 +96,18 @@ ENTRY (__longjmp)
/* Restore the call-preserved iWMMXt registers. */
/* Following instructions are wldrd wr10, [ip], #8 (etc.) */
- ldcl p1, cr10, [r12], #8
- ldcl p1, cr11, [r12], #8
- ldcl p1, cr12, [r12], #8
- ldcl p1, cr13, [r12], #8
- ldcl p1, cr14, [r12], #8
- ldcl p1, cr15, [r12], #8
+ sfi_breg r12, \
+ ldcl p1, cr10, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr11, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr12, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr13, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr14, [\B], #8
+ sfi_breg r12, \
+ ldcl p1, cr15, [\B], #8
.Lno_iwmmxt:
#endif
diff --git a/ports/sysdeps/arm/add_n.S b/ports/sysdeps/arm/add_n.S
index 119a994..bbc6b8b 100644
--- a/ports/sysdeps/arm/add_n.S
+++ b/ports/sysdeps/arm/add_n.S
@@ -51,31 +51,40 @@ ENTRY (FUNC)
add lr, r1, r3, lsl #2 /* compute end src1 */
beq 1f
- ldr r4, [r1], #4 /* do one to make count even */
- ldr r5, [r2], #4
+ sfi_breg r1, \
+ ldr r4, [\B], #4 /* do one to make count even */
+ sfi_breg r2, \
+ ldr r5, [\B], #4
OPC r4, r4, r5
teq r1, lr /* end of count? (preserve carry) */
- str r4, [r0], #4
+ sfi_breg r0, \
+ str r4, [\B], #4
beq 9f
1:
tst r3, #2 /* count & 2 == 2? */
beq 2f
- ldm r1!, { r4, r5 } /* do two to make count 0 mod 4 */
- ldm r2!, { r6, r7 }
+ sfi_breg r1, \
+ ldm \B!, { r4, r5 } /* do two to make count 0 mod 4 */
+ sfi_breg r2, \
+ ldm \B!, { r6, r7 }
OPC r4, r4, r6
OPC r5, r5, r7
teq r1, lr /* end of count? */
- stm r0!, { r4, r5 }
+ sfi_breg r0, \
+ stm \B!, { r4, r5 }
beq 9f
2:
- ldm r1!, { r3, r5, r7, r10 } /* do four each loop */
- ldm r2!, { r4, r6, r8, ip }
+ sfi_breg r1, \
+ ldm \B!, { r3, r5, r7, r10 } /* do four each loop */
+ sfi_breg r2, \
+ ldm \B!, { r4, r6, r8, ip }
OPC r3, r3, r4
OPC r5, r5, r6
OPC r7, r7, r8
OPC r10, r10, ip
teq r1, lr
- stm r0!, { r3, r5, r7, r10 }
+ sfi_breg r0, \
+ stm \B!, { r3, r5, r7, r10 }
bne 2b
9:
diff --git a/ports/sysdeps/arm/addmul_1.S b/ports/sysdeps/arm/addmul_1.S
index 09153d2..d204c88 100644
--- a/ports/sysdeps/arm/addmul_1.S
+++ b/ports/sysdeps/arm/addmul_1.S
@@ -37,16 +37,21 @@ ENTRY (__mpn_addmul_1)
cfi_rel_offset (r6, 8)
cfi_rel_offset (r7, 12)
- ldr r6, [r1], #4
- ldr r5, [r0]
+ sfi_breg r1, \
+ ldr r6, [\B], #4
+ sfi_breg r0, \
+ ldr r5, [\B]
mov r4, #0 /* init carry in */
b 1f
0:
- ldr r6, [r1], #4 /* load next ul */
+ sfi_breg r1, \
+ ldr r6, [\B], #4 /* load next ul */
adds r7, r4, r5 /* (out, c) = cl + lpl */
- ldr r5, [r0, #4] /* load next rl */
+ sfi_breg r0, \
+ ldr r5, [\B, #4] /* load next rl */
adc r4, ip, #0 /* cl = hpl + c */
- str r7, [r0], #4
+ sfi_breg r0, \
+ str r7, [\B], #4
1:
mov ip, #0 /* zero-extend rl */
umlal r5, ip, r6, r3 /* (hpl, lpl) = ul * vl + rl */
@@ -54,7 +59,8 @@ ENTRY (__mpn_addmul_1)
bne 0b
adds r4, r4, r5 /* (out, c) = cl + llpl */
- str r4, [r0]
+ sfi_breg r0, \
+ str r4, [\B]
adc r0, ip, #0 /* return hpl + c */
pop { r4, r5, r6, r7 }
diff --git a/ports/sysdeps/arm/arm-mcount.S b/ports/sysdeps/arm/arm-mcount.S
index 8ad0779..f61e978 100644
--- a/ports/sysdeps/arm/arm-mcount.S
+++ b/ports/sysdeps/arm/arm-mcount.S
@@ -79,7 +79,8 @@ ENTRY(_mcount)
cfi_rel_offset (lr, 20)
movs r0, fp
ittt ne
- ldrne r0, [r0, #-4]
+ sfi_breg r0, \
+ ldrne r0, [\B, #-4]
movsne r1, lr
blne __mcount_internal
#if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)
diff --git a/ports/sysdeps/arm/armv6/rawmemchr.S b/ports/sysdeps/arm/armv6/rawmemchr.S
index 7877bcf..b5e4a16 100644
--- a/ports/sysdeps/arm/armv6/rawmemchr.S
+++ b/ports/sysdeps/arm/armv6/rawmemchr.S
@@ -25,7 +25,8 @@ ENTRY (__rawmemchr)
@ r0 = start of string
@ r1 = character to match
@ returns a pointer to the match, which must be present.
- ldrb r2, [r0] @ load first byte asap
+ sfi_breg r0, \
+ ldrb r2, [\B] @ load first byte asap
@ To cater to long strings, we want to search through a few
@ characters until we reach an aligned pointer. To cater to
@@ -41,7 +42,8 @@ ENTRY (__rawmemchr)
bxeq lr
@ Loop until we find ...
-1: ldrb r2, [r0, #1]!
+1: sfi_breg r0, \
+ ldrb r2, [\B, #1]!
subs r3, r3, #1 @ ... the alignment point
it ne
cmpne r2, r1 @ ... or C
@@ -54,15 +56,16 @@ ENTRY (__rawmemchr)
add r0, r0, #1
@ So now we're aligned.
- ldrd r2, r3, [r0], #8
+ sfi_breg r0, \
+ ldrd r2, r3, [\B], #8
orr r1, r1, r1, lsl #8 @ Replicate C to all bytes
#ifdef ARCH_HAS_T2
movw ip, #0x0101
- pld [r0, #64]
+ sfi_pld r0, #64
movt ip, #0x0101
#else
ldr ip, =0x01010101
- pld [r0, #64]
+ sfi_pld r0, #64
#endif
orr r1, r1, r1, lsl #16
@@ -74,10 +77,11 @@ ENTRY (__rawmemchr)
eor r3, r3, r1
uqsub8 r2, ip, r2 @ Find C
uqsub8 r3, ip, r3
- pld [r0, #128]
+ sfi_pld r0, #128
orrs r3, r3, r2 @ Test both words for found
it eq
- ldrdeq r2, r3, [r0], #8
+ sfi_breg r0, \
+ ldrdeq r2, r3, [\B], #8
beq 2b
@ Found something. Disambiguate between first and second words.
diff --git a/ports/sysdeps/arm/armv6/strchr.S b/ports/sysdeps/arm/armv6/strchr.S
index c856283..936c2be 100644
--- a/ports/sysdeps/arm/armv6/strchr.S
+++ b/ports/sysdeps/arm/armv6/strchr.S
@@ -25,7 +25,8 @@ ENTRY (strchr)
@ r0 = start of string
@ r1 = character to match
@ returns NULL for no match, or a pointer to the match
- ldrb r2, [r0] @ load the first byte asap
+ sfi_breg r0, \
+ ldrb r2, [\B] @ load the first byte asap
uxtb r1, r1
@ To cater to long strings, we want to search through a few
@@ -42,7 +43,8 @@ ENTRY (strchr)
beq 99f
@ Loop until we find ...
-1: ldrb r2, [r0, #1]!
+1: sfi_breg r0, \
+ ldrb r2, [\B, #1]!
subs r3, r3, #1 @ ... the aligment point
it ne
cmpne r2, r1 @ ... or the character
@@ -65,15 +67,16 @@ ENTRY (strchr)
cfi_rel_offset (r6, 8)
cfi_rel_offset (r7, 12)
- ldrd r2, r3, [r0], #8
+ sfi_breg r0, \
+ ldrd r2, r3, [\B], #8
orr r1, r1, r1, lsl #8 @ Replicate C to all bytes
#ifdef ARCH_HAS_T2
movw ip, #0x0101
- pld [r0, #64]
+ sfi_pld r0, #64
movt ip, #0x0101
#else
ldr ip, =0x01010101
- pld [r0, #64]
+ sfi_pld r0, #64
#endif
orr r1, r1, r1, lsl #16
@@ -87,13 +90,14 @@ ENTRY (strchr)
uqsub8 r5, ip, r3
eor r7, r3, r1
uqsub8 r6, ip, r6 @ Find C
- pld [r0, #128] @ Prefetch 2 lines ahead
+ sfi_pld r0, #128 @ Prefetch 2 lines ahead
uqsub8 r7, ip, r7
orr r4, r4, r6 @ Combine found for EOS and C
orr r5, r5, r7
orrs r6, r4, r5 @ Combine the two words
it eq
- ldrdeq r2, r3, [r0], #8
+ sfi_breg r0, \
+ ldrdeq r2, r3, [\B], #8
beq 2b
@ Found something. Disambiguate between first and second words.
diff --git a/ports/sysdeps/arm/armv6/strcpy.S b/ports/sysdeps/arm/armv6/strcpy.S
index 41f6443..cd13ff7 100644
--- a/ports/sysdeps/arm/armv6/strcpy.S
+++ b/ports/sysdeps/arm/armv6/strcpy.S
@@ -44,8 +44,8 @@ ENTRY (strcpy)
@ Signal strcpy with DEST in IP.
mov ip, r0
0:
- pld [r0]
- pld [r1]
+ sfi_pld r0
+ sfi_pld r1
@ To cater to long strings, we want 8 byte alignment in the source.
@ To cater to small strings, we don't want to start that right away.
@@ -54,9 +54,11 @@ ENTRY (strcpy)
rsb r3, r3, #16
@ Loop until we find ...
-1: ldrb r2, [r1], #1
+1: sfi_breg r1, \
+ ldrb r2, [\B], #1
subs r3, r3, #1 @ ... the alignment point
- strb r2, [r0], #1
+ sfi_breg r0, \
+ strb r2, [\B], #1
it ne
cmpne r2, #0 @ ... or EOS
bne 1b
@@ -66,9 +68,10 @@ ENTRY (strcpy)
beq .Lreturn
@ Load the next two words asap
- ldrd r2, r3, [r1], #8
- pld [r0, #64]
- pld [r1, #64]
+ sfi_breg r1, \
+ ldrd r2, r3, [\B], #8
+ sfi_pld r0, #64
+ sfi_pld r1, #64
@ For longer strings, we actaully need a stack frame.
push { r4, r5, r6, r7 }
@@ -96,15 +99,18 @@ ENTRY (strcpy)
.balign 16
2: uqsub8 r4, r7, r2 @ Find EOS
uqsub8 r5, r7, r3
- pld [r1, #128]
+ sfi_pld r1, #128
cmp r4, #0 @ EOS in first word?
- pld [r0, #128]
+ sfi_pld r0, #128
bne 3f
- str r2, [r0], #4
+ sfi_breg r0, \
+ str r2, [\B], #4
cmp r5, #0 @ EOS in second word?
bne 4f
- str r3, [r0], #4
- ldrd r2, r3, [r1], #8
+ sfi_breg r0, \
+ str r3, [\B], #4
+ sfi_breg r1, \
+ ldrd r2, r3, [\B], #8
b 2b
3: sub r1, r1, #4 @ backup to first word
@@ -114,9 +120,11 @@ ENTRY (strcpy)
@ Note that we generally back up and re-read source bytes,
@ but we'll not re-write dest bytes.
.Lbyte_loop:
- ldrb r2, [r1], #1
+ sfi_breg r1, \
+ ldrb r2, [\B], #1
cmp r2, #0
- strb r2, [r0], #1
+ sfi_breg r0, \
+ strb r2, [\B], #1
bne .Lbyte_loop
pop { r4, r5, r6, r7 }
@@ -161,7 +169,8 @@ ENTRY (strcpy)
@ Store a few bytes from the first word.
@ At the same time we align r0 and shift out bytes from r2.
.rept 4-\unalign
- strb r2, [r0], #1
+ sfi_breg r0, \
+ strb r2, [\B], #1
lsr r2, r2, #8
.endr
#ifdef __ARMEB__
@@ -176,20 +185,23 @@ ENTRY (strcpy)
orr r2, r2, r3, lsh_gt #(\unalign*8)
@ Save leftover bytes from the two words
lsh_ls r6, r3, #((4-\unalign)*8)
- str r2, [r0], #4
+ sfi_breg r0, \
+ str r2, [\B], #4
@ The "real" start of the unaligned copy loop.
- ldrd r2, r3, [r1], #8 @ Load 8 more bytes
+ sfi_breg r1, \
+ ldrd r2, r3, [\B], #8 @ Load 8 more bytes
uqsub8 r4, r7, r2 @ Find EOS
- pld [r1, #128]
+ sfi_pld r1, #128
uqsub8 r5, r7, r3
- pld [r0, #128]
+ sfi_pld r0, #128
mvns r4, r4 @ EOS in first word?
bne 3f
@ Combine the leftover and the first word
orr r6, r6, r2, lsh_gt #(\unalign*8)
@ Discard used bytes from the first word.
lsh_ls r2, r2, #((4-\unalign)*8)
- str r6, [r0], #4
+ sfi_breg r0, \
+ str r6, [\B], #4
b 1b
@ Found EOS in one of the words; adjust backward
3: sub r1, r1, #4
@@ -200,7 +212,8 @@ ENTRY (strcpy)
rev r2, r2
#endif
.rept \unalign
- strb r2, [r0], #1
+ sfi_breg r0, \
+ strb r2, [\B], #1
lsr r2, r2, #8
.endr
b .Lbyte_loop
diff --git a/ports/sysdeps/arm/armv6/strlen.S b/ports/sysdeps/arm/armv6/strlen.S
index a53d414..59ff6b5 100644
--- a/ports/sysdeps/arm/armv6/strlen.S
+++ b/ports/sysdeps/arm/armv6/strlen.S
@@ -23,7 +23,8 @@
ENTRY (strlen)
@ r0 = start of string
- ldrb r2, [r0] @ load the first byte asap
+ sfi_breg r0, \
+ ldrb r2, [\B] @ load the first byte asap
@ To cater to long strings, we want to search through a few
@ characters until we reach an aligned pointer. To cater to
@@ -38,7 +39,8 @@ ENTRY (strlen)
beq 99f
@ Loop until we find ...
-1: ldrb r2, [r0, #1]!
+1: sfi_breg r0, \
+ ldrb r2, [\B, #1]!
subs r3, r3, #1 @ ... the aligment point
it ne
cmpne r2, #0 @ ... or EOS
@@ -50,14 +52,15 @@ ENTRY (strlen)
add r0, r0, #1
@ So now we're aligned.
- ldrd r2, r3, [r0], #8
+ sfi_breg r0, \
+ ldrd r2, r3, [\B], #8
#ifdef ARCH_HAS_T2
movw ip, #0x0101
- pld [r0, #64]
+ sfi_pld r0, #64
movt ip, #0x0101
#else
ldr ip, =0x01010101
- pld [r0, #64]
+ sfi_pld r0, #64
#endif
@ Loop searching for EOS, 8 bytes at a time.
@@ -67,10 +70,11 @@ ENTRY (strlen)
.balign 16
2: uqsub8 r2, ip, r2 @ Find EOS
uqsub8 r3, ip, r3
- pld [r0, #128] @ Prefetch 2 lines ahead
+ sfi_pld r0, #128 @ Prefetch 2 lines ahead
orrs r3, r3, r2 @ Combine the two words
it eq
- ldrdeq r2, r3, [r0], #8
+ sfi_breg r0, \
+ ldrdeq r2, r3, [\B], #8
beq 2b
@ Found something. Disambiguate between first and second words.
diff --git a/ports/sysdeps/arm/armv6/strrchr.S b/ports/sysdeps/arm/armv6/strrchr.S
index ddd4f7f..e40df90 100644
--- a/ports/sysdeps/arm/armv6/strrchr.S
+++ b/ports/sysdeps/arm/armv6/strrchr.S
@@ -33,7 +33,8 @@ ENTRY (strrchr)
@ Loop a few times until we're aligned.
tst r3, #7
beq 2f
-1: ldrb r2, [r3], #1
+1: sfi_breg r3, \
+ ldrb r2, [\B], #1
cmp r2, r1 @ Find the character
it eq
subeq r0, r3, #1
@@ -64,7 +65,8 @@ ENTRY (strrchr)
@ Loop searching for EOS and C, 8 bytes at a time.
@ Any time we find a match in a word, we copy the address of
@ the word to r0, and the found bits to r2.
-3: ldrd r4, r5, [r3], #8
+3: sfi_breg r3, \
+ ldrd r4, r5, [\B], #8
@ Subtracting (unsigned saturating) from 1 means result of 1 for
@ any byte that was originally zero and 0 otherwise. Therefore
@ we consider the lsb of each byte the "found" bit.
diff --git a/ports/sysdeps/arm/memset.S b/ports/sysdeps/arm/memset.S
index 5e055ad..a28cdc6 100644
--- a/ports/sysdeps/arm/memset.S
+++ b/ports/sysdeps/arm/memset.S
@@ -32,7 +32,8 @@ ENTRY(memset)
1:
tst r3, #3 @ aligned yet?
- strbne r1, [r3], #1
+ sfi_breg r3, \
+ strbne r1, [\B], #1
subne r2, r2, #1
bne 1b
@@ -43,25 +44,33 @@ ENTRY(memset)
1:
subs r2, r2, #8
- stmiacs r3!, {r1, ip} @ store up to 32 bytes per loop iteration
+ sfi_breg r3, \
+ stmiacs \B!, {r1, ip} @ store up to 32 bytes per loop iteration
subscs r2, r2, #8
- stmiacs r3!, {r1, ip}
+ sfi_breg r3, \
+ stmiacs \B!, {r1, ip}
subscs r2, r2, #8
- stmiacs r3!, {r1, ip}
+ sfi_breg r3, \
+ stmiacs \B!, {r1, ip}
subscs r2, r2, #8
- stmiacs r3!, {r1, ip}
+ sfi_breg r3, \
+ stmiacs \B!, {r1, ip}
bcs 1b
and r2, r2, #7
2:
subs r2, r2, #1 @ store up to 4 bytes per loop iteration
- strbcs r1, [r3], #1
+ sfi_breg r3, \
+ strbcs r1, [\B], #1
subscs r2, r2, #1
- strbcs r1, [r3], #1
+ sfi_breg r3, \
+ strbcs r1, [\B], #1
subscs r2, r2, #1
- strbcs r1, [r3], #1
+ sfi_breg r3, \
+ strbcs r1, [\B], #1
subscs r2, r2, #1
- strbcs r1, [r3], #1
+ sfi_breg r3, \
+ strbcs r1, [\B], #1
bcs 2b
DO_RET(lr)
diff --git a/ports/sysdeps/arm/setjmp.S b/ports/sysdeps/arm/setjmp.S
index c41a1ba..f750470 100644
--- a/ports/sysdeps/arm/setjmp.S
+++ b/ports/sysdeps/arm/setjmp.S
@@ -27,7 +27,8 @@ ENTRY (__sigsetjmp)
mov ip, r0
/* Save registers */
- stmia ip!, JMP_BUF_REGLIST
+ sfi_breg ip, \
+ stmia \B!, JMP_BUF_REGLIST
#if !defined ARM_ASSUME_NO_IWMMXT || defined __SOFTFP__
# define NEED_HWCAP 1
@@ -64,11 +65,13 @@ ENTRY (__sigsetjmp)
Don't use VFP instructions directly because this code
is used in non-VFP multilibs. */
/* Following instruction is vstmia ip!, {d8-d15}. */
- stc p11, cr8, [ip], #64
+ sfi_breg ip, \
+ stc p11, cr8, [\B], #64
/* Store the floating-point status register. */
/* Following instruction is vmrs a4, fpscr. */
mrc p10, 7, a4, cr1, cr0, 0
- str a4, [ip], #4
+ sfi_breg ip, \
+ str a4, [\B], #4
.Lno_vfp:
#ifndef ARM_ASSUME_NO_IWMMXT
@@ -77,12 +80,18 @@ ENTRY (__sigsetjmp)
/* Save the call-preserved iWMMXt registers. */
/* Following instructions are wstrd wr10, [ip], #8 (etc.) */
- stcl p1, cr10, [r12], #8
- stcl p1, cr11, [r12], #8
- stcl p1, cr12, [r12], #8
- stcl p1, cr13, [r12], #8
- stcl p1, cr14, [r12], #8
- stcl p1, cr15, [r12], #8
+ sfi_breg r12, \
+ stcl p1, cr10, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr11, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr12, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr13, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr14, [\B], #8
+ sfi_breg r12, \
+ stcl p1, cr15, [\B], #8
.Lno_iwmmxt:
#endif
diff --git a/ports/sysdeps/arm/strlen.S b/ports/sysdeps/arm/strlen.S
index fef62cf..7d358a7 100644
--- a/ports/sysdeps/arm/strlen.S
+++ b/ports/sysdeps/arm/strlen.S
@@ -30,7 +30,8 @@
ENTRY(strlen)
bic r1, r0, $3 @ addr of word containing first byte
- ldr r2, [r1], $4 @ get the first word
+ sfi_breg r1, \
+ ldr r2, [\B], $4 @ get the first word
ands r3, r0, $3 @ how many bytes are duff?
rsb r0, r3, $0 @ get - that number into counter.
beq Laligned @ skip into main check routine if no
@@ -54,7 +55,8 @@ Laligned: @ here, we have a word in r2. Does it
tstne r2, $0x00ff0000 @
tstne r2, $0xff000000 @
addne r0, r0, $4 @ if not, the string is 4 bytes longer
- ldrne r2, [r1], $4 @ and we continue to the next word
+ sfi_breg r1, \
+ ldrne r2, [\B], $4 @ and we continue to the next word
bne Laligned @
Llastword: @ drop through to here once we find a
#ifdef __ARMEB__
diff --git a/ports/sysdeps/arm/submul_1.S b/ports/sysdeps/arm/submul_1.S
index 3805eca..2d17490 100644
--- a/ports/sysdeps/arm/submul_1.S
+++ b/ports/sysdeps/arm/submul_1.S
@@ -37,19 +37,24 @@ ENTRY (__mpn_submul_1)
cfi_rel_offset (r6, 8)
cfi_rel_offset (r7, 12)
- ldr r6, [r1], #4
- ldr r7, [r0]
+ sfi_breg r1, \
+ ldr r6, [\B], #4
+ sfi_breg r0, \
+ ldr r7, [\B]
mov r4, #0 /* init carry in */
b 1f
0:
- ldr r6, [r1], #4 /* load next ul */
+ sfi_breg r1, \
+ ldr r6, [\B], #4 /* load next ul */
adds r5, r5, r4 /* (lpl, c) = lpl + cl */
adc r4, ip, #0 /* cl = hpl + c */
subs r5, r7, r5 /* (lpl, !c) = rl - lpl */
- ldr r7, [r0, #4] /* load next rl */
+ sfi_breg r0, \
+ ldr r7, [\B, #4] /* load next rl */
it cc
addcc r4, r4, #1 /* cl += !c */
- str r5, [r0], #4
+ sfi_breg r0, \
+ str r5, [\B], #4
1:
umull r5, ip, r6, r3 /* (hpl, lpl) = ul * vl */
subs r2, r2, #1
@@ -58,7 +63,8 @@ ENTRY (__mpn_submul_1)
adds r5, r5, r4 /* (lpl, c) = lpl + cl */
adc r4, ip, #0 /* cl = hpl + c */
subs r5, r7, r5 /* (lpl, !c) = rl - lpl */
- str r5, [r0], #4
+ sfi_breg r0, \
+ str r5, [\B], #4
it cc
addcc r4, r4, #1 /* cl += !c */
mov r0, r4 /* return carry */
diff --git a/ports/sysdeps/arm/sysdep.h b/ports/sysdeps/arm/sysdep.h
index 4a7a13f..4917805 100644
--- a/ports/sysdeps/arm/sysdep.h
+++ b/ports/sysdeps/arm/sysdep.h
@@ -210,6 +210,48 @@
cfi_restore_state
# endif /* ARCH_HAS_HARD_TP */
+# ifndef ARM_SFI_MACROS
+# define ARM_SFI_MACROS 1
+/* This assembly macro is prepended to any load/store instruction,
+ pulling the base register out of the addressing mode syntax and
+ making it the first operand of the macro. For example:
+ ldr r0, [r1]
+ becomes:
+ sfi_breg r1, ldr r0, [\B]
+ The \B stands in for the base register that is the first operand
+ to the macro, so we can avoid error-prone repetition of the base
+ register in two places on the line.
+
+ This is used for all memory access through a base register other
+ than PC or SP. It's intended to support SFI schemes such as
+ Native Client, where the OS will enforce that all load/store
+ instructions use a special form. In any such configuration,
+ another sysdep.h file will have defined ARM_SFI_MACROS and
+ provided its own assembly macros with the same interface. */
+
+ .macro sfi_breg basereg, insn, operands:vararg
+ .macro _sfi_breg_doit B
+ \insn \operands
+ .endm
+ _sfi_breg_doit \basereg
+ .purgem _sfi_breg_doit
+ .endm
+
+/* This assembly macro replaces the "pld" instruction.
+ The syntax:
+ sfi_pld REGISTER, #OFFSET
+ is exactly equivalent to:
+ sfi_breg REGISTER, pld [\B, #OFFSET]
+ (and ", #OFFSET" is optional). We have a separate macro
+ only to work around a bug in GAS versions prior to 2.23.2,
+ that misparses the sfi_breg macro expansion in this case. */
+
+ .macro sfi_pld basereg, offset=#0
+ pld [\basereg, \offset]
+ .endm
+
+# endif
+
#endif /* __ASSEMBLER__ */
/* This number is the offset from the pc at the current location. */
-----------------------------------------------------------------------
hooks/post-receive
--
GNU C Library master sources