summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-06 21:05:42 +0000
committerkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-06 21:05:42 +0000
commitb357350a6768b959e173ad5efac567952d0ab695 (patch)
tree2f843135c4d43d5b5800a73c36c047389dbf4f97
parent4b49a15a48aaa5bdb5754c8c2aacab5eac777a96 (diff)
downloadgcc-b357350a6768b959e173ad5efac567952d0ab695.tar.gz
* config/arm/lib1funcs.asm (ARM_DIV_BODY): Add Thumb-2 implementation.
(udivsi3, aeabi_uidivmod, divsi3, aeabi_idivmod): Only use Thumb-1 implementation on ARMv6-M. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150545 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arm/lib1funcs.asm63
2 files changed, 60 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 578b682403e..24920f02fae 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2009-08-06 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/lib1funcs.asm (ARM_DIV_BODY): Add Thumb-2 implementation.
+ (udivsi3, aeabi_uidivmod, divsi3, aeabi_idivmod): Only use Thumb-1
+ implementation on ARMv6-M.
+
2009-08-06 Richard Earnshaw <rearnsha@arm.com>
* doc/extend.texi (pcs): Document new attribute for ARM.
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
index 03446f8d03b..9f7cc63e469 100644
--- a/gcc/config/arm/lib1funcs.asm
+++ b/gcc/config/arm/lib1funcs.asm
@@ -446,6 +446,27 @@ pc .req r15
#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
+#if defined (__thumb2__)
+ clz \curbit, \dividend
+ clz \result, \divisor
+ sub \curbit, \result, \curbit
+ rsb \curbit, \curbit, #31
+ adr \result, 1f
+ add \curbit, \result, \curbit, lsl #4
+ mov \result, #0
+ mov pc, \curbit
+.p2align 3
+1:
+ .set shift, 32
+ .rept 32
+ .set shift, shift - 1
+ cmp.w \dividend, \divisor, lsl #shift
+ nop.n
+ adc.w \result, \result, \result
+ it cs
+ subcs.w \dividend, \dividend, \divisor, lsl #shift
+ .endr
+#else
clz \curbit, \dividend
clz \result, \divisor
sub \curbit, \result, \curbit
@@ -461,6 +482,7 @@ pc .req r15
adc \result, \result, \result
subcs \dividend, \dividend, \divisor, lsl #shift
.endr
+#endif
#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
#if __ARM_ARCH__ >= 5
@@ -508,18 +530,23 @@ pc .req r15
@ Division loop
1: cmp \dividend, \divisor
+ do_it hs, t
subhs \dividend, \dividend, \divisor
orrhs \result, \result, \curbit
cmp \dividend, \divisor, lsr #1
+ do_it hs, t
subhs \dividend, \dividend, \divisor, lsr #1
orrhs \result, \result, \curbit, lsr #1
cmp \dividend, \divisor, lsr #2
+ do_it hs, t
subhs \dividend, \dividend, \divisor, lsr #2
orrhs \result, \result, \curbit, lsr #2
cmp \dividend, \divisor, lsr #3
+ do_it hs, t
subhs \dividend, \dividend, \divisor, lsr #3
orrhs \result, \result, \curbit, lsr #3
cmp \dividend, #0 @ Early termination?
+ do_it hs, t
movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
movne \divisor, \divisor, lsr #4
bne 1b
@@ -808,11 +835,11 @@ LSYM(Lgot_result):
/* ------------------------------------------------------------------------ */
#ifdef L_udivsi3
+#if defined(__ARM_ARCH_6M__)
+
FUNC_START udivsi3
FUNC_ALIAS aeabi_uidiv udivsi3
-#ifdef __thumb__
-
cmp divisor, #0
beq LSYM(Ldiv0)
mov curbit, #1
@@ -828,9 +855,13 @@ LSYM(Lgot_result):
pop { work }
RET
-#else /* ARM version. */
+#else /* ARM version/Thumb-2. */
+
+ ARM_FUNC_START udivsi3
+ ARM_FUNC_ALIAS aeabi_uidiv udivsi3
subs r2, r1, #1
+ do_it eq
RETc(eq)
bcc LSYM(Ldiv0)
cmp r0, r1
@@ -843,7 +874,8 @@ LSYM(Lgot_result):
mov r0, r2
RET
-11: moveq r0, #1
+11: do_it eq, e
+ moveq r0, #1
movne r0, #0
RET
@@ -856,8 +888,8 @@ LSYM(Lgot_result):
DIV_FUNC_END udivsi3
+#if defined(__ARM_ARCH_6M__)
FUNC_START aeabi_uidivmod
-#ifdef __thumb__
push {r0, r1, lr}
bl SYM(__udivsi3)
POP {r1, r2, r3}
@@ -865,6 +897,7 @@ FUNC_START aeabi_uidivmod
sub r1, r1, r2
bx r3
#else
+ARM_FUNC_START aeabi_uidivmod
stmfd sp!, { r0, r1, lr }
bl SYM(__udivsi3)
ldmfd sp!, { r1, r2, lr }
@@ -919,10 +952,11 @@ LSYM(Lover10):
/* ------------------------------------------------------------------------ */
#ifdef L_divsi3
+#if defined(__ARM_ARCH_6M__)
+
FUNC_START divsi3
FUNC_ALIAS aeabi_idiv divsi3
-#ifdef __thumb__
cmp divisor, #0
beq LSYM(Ldiv0)
@@ -954,15 +988,20 @@ LSYM(Lover12):
pop { work }
RET
-#else /* ARM version. */
+#else /* ARM/Thumb-2 version. */
+ ARM_FUNC_START divsi3
+ ARM_FUNC_ALIAS aeabi_idiv divsi3
+
cmp r1, #0
eor ip, r0, r1 @ save the sign of the result.
beq LSYM(Ldiv0)
+ do_it mi
rsbmi r1, r1, #0 @ loops below use unsigned.
subs r2, r1, #1 @ division by 1 or -1 ?
beq 10f
movs r3, r0
+ do_it mi
rsbmi r3, r0, #0 @ positive dividend value
cmp r3, r1
bls 11f
@@ -972,14 +1011,18 @@ LSYM(Lover12):
ARM_DIV_BODY r3, r1, r0, r2
cmp ip, #0
+ do_it mi
rsbmi r0, r0, #0
RET
10: teq ip, r0 @ same sign ?
+ do_it mi
rsbmi r0, r0, #0
RET
-11: movlo r0, #0
+11: do_it lo
+ movlo r0, #0
+ do_it eq,t
moveq r0, ip, asr #31
orreq r0, r0, #1
RET
@@ -988,6 +1031,7 @@ LSYM(Lover12):
cmp ip, #0
mov r0, r3, lsr r2
+ do_it mi
rsbmi r0, r0, #0
RET
@@ -995,8 +1039,8 @@ LSYM(Lover12):
DIV_FUNC_END divsi3
+#if defined(__ARM_ARCH_6M__)
FUNC_START aeabi_idivmod
-#ifdef __thumb__
push {r0, r1, lr}
bl SYM(__divsi3)
POP {r1, r2, r3}
@@ -1004,6 +1048,7 @@ FUNC_START aeabi_idivmod
sub r1, r1, r2
bx r3
#else
+ARM_FUNC_START aeabi_idivmod
stmfd sp!, { r0, r1, lr }
bl SYM(__divsi3)
ldmfd sp!, { r1, r2, lr }