This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[csl-arm] Thumb-2 libgcc
- From: Paul Brook <paul at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 7 Feb 2006 20:05:20 +0000
- Subject: [csl-arm] Thumb-2 libgcc
The attached patch allows building libgcc as pure Thumb-2 code (ie. no Arm
mode code). It relies on a newish gas with unified assembler support, so may
need rethinking for mainline.
Tested on arm-none-eabi.
Applied to branches/csl/arm-4_1
Paul
2006-02-07 Paul Brook <paul@codesourcery.com>
* config/arm/lib1funcs.asm: Use unified assembly syntax. Assemble
"Arm" code as Thumb-2 where appropriate.
* config/arm/ieee754-df.S: Use unified assembly syntax for Arm code.
Add Thumb-2 code.
* config/arm/ieee754-df.S: Ditto.
* config/arm/libunwind.S: Ditto.
* config/arm/bpabi.S: Ditto.
Index: gcc/config/arm/ieee754-df.S
===================================================================
--- gcc/config/arm/ieee754-df.S (revision 110445)
+++ gcc/config/arm/ieee754-df.S (working copy)
@@ -88,23 +88,26 @@ ARM_FUNC_ALIAS aeabi_dsub subdf3
ARM_FUNC_START adddf3
ARM_FUNC_ALIAS aeabi_dadd adddf3
-1: stmfd sp!, {r4, r5, lr}
+1: push {r4, r5, lr}
@ Look for zeroes, equal values, INF, or NAN.
- mov r4, xh, lsl #1
- mov r5, yh, lsl #1
+ lsl r4, xh, #1
+ lsl r5, yh, #1
teq r4, r5
+ it eq
teqeq xl, yl
- orrnes ip, r4, xl
- orrnes ip, r5, yl
- mvnnes ip, r4, asr #21
- mvnnes ip, r5, asr #21
+ itttt ne
+ orrsne ip, r4, xl
+ orrsne ip, r5, yl
+ mvnsne ip, r4, asr #21
+ mvnsne ip, r5, asr #21
beq LSYM(Lad_s)
@ Compute exponent difference. Make largest exponent in r4,
@ corresponding arg in xh-xl, and positive exponent difference in r5.
- mov r4, r4, lsr #21
+ lsr r4, r4, #21
rsbs r5, r4, r5, lsr #21
+ it lt
rsblt r5, r5, #0
ble 1f
add r4, r4, r5
@@ -119,6 +122,7 @@ ARM_FUNC_ALIAS aeabi_dadd adddf3
@ already in xh-xl. We need up to 54 bit to handle proper rounding
@ of 0x1p54 - 1.1.
cmp r5, #54
+ it hi
RETLDM "r4, r5" hi
@ Convert mantissa to signed integer.
@@ -127,15 +131,27 @@ ARM_FUNC_ALIAS aeabi_dadd adddf3
mov ip, #0x00100000
orr xh, ip, xh, lsr #12
beq 1f
+#if defined(__thumb2__)
+ mov lr, #0
+ negs xl, xl
+ sbc xh, lr, xh
+#else
rsbs xl, xl, #0
rsc xh, xh, #0
+#endif
1:
tst yh, #0x80000000
mov yh, yh, lsl #12
orr yh, ip, yh, lsr #12
beq 1f
+#if defined(__thumb2__)
+ mov lr, #0
+ negs yl, yl
+ sbc yh, lr, yh
+#else
rsbs yl, yl, #0
rsc yh, yh, #0
+#endif
1:
@ If exponent == difference, one or both args were denormalized.
@ Since this is not common case, rescale them off line.
@@ -149,27 +165,35 @@ LSYM(Lad_x):
@ Shift yh-yl right per r5, add to xh-xl, keep leftover bits into ip.
rsbs lr, r5, #32
blt 1f
- mov ip, yl, lsl lr
- adds xl, xl, yl, lsr r5
+ lsl ip, yl, lr
+ shiftop adds xl xl yl lsr r5 yl
adc xh, xh, #0
- adds xl, xl, yh, lsl lr
- adcs xh, xh, yh, asr r5
+ shiftop adds xl xl yh lsl lr yl
+ shiftop adcs xh xh yh asr r5 yh
b 2f
1: sub r5, r5, #32
add lr, lr, #32
cmp yl, #1
- mov ip, yh, lsl lr
+ lsl ip, yh, lr
+ it cs
orrcs ip, ip, #2 @ 2 not 1, to allow lsr #1 later
- adds xl, xl, yh, asr r5
+ shiftop adds xl xl yh asr r5 yh
adcs xh, xh, yh, asr #31
2:
@ We now have a result in xh-xl-ip.
@ Keep absolute value in xh-xl-ip, sign in r5 (the n bit was set above)
and r5, xh, #0x80000000
bpl LSYM(Lad_p)
+#if defined(__thumb2__)
+ mov lr, #0
+ negs ip, ip
+ sbcs xl, lr, xl
+ sbc xh, lr, xh
+#else
rsbs ip, ip, #0
rscs xl, xl, #0
rsc xh, xh, #0
+#endif
@ Determine how to normalize the result.
LSYM(Lad_p):
@@ -195,7 +219,8 @@ LSYM(Lad_p):
@ Pack final result together.
LSYM(Lad_e):
cmp ip, #0x80000000
- moveqs ip, xl, lsr #1
+ it eq
+ movseq ip, xl, lsr #1
adcs xl, xl, #0
adc xh, xh, r4, lsl #20
orr xh, xh, r5
@@ -238,9 +263,11 @@ LSYM(Lad_l):
#else
teq xh, #0
+ itt eq
moveq xh, xl
moveq xl, #0
clz r3, xh
+ it eq
addeq r3, r3, #32
sub r3, r3, #11
@@ -256,20 +283,28 @@ LSYM(Lad_l):
@ since a register switch happened above.
add ip, r2, #20
rsb r2, r2, #12
- mov xl, xh, lsl ip
- mov xh, xh, lsr r2
+ lsl xl, xh, ip
+ lsr xh, xh, r2
b 3f
@ actually shift value left 1 to 20 bits, which might also represent
@ 32 to 52 bits if counting the register switch that happened earlier.
1: add r2, r2, #20
-2: rsble ip, r2, #32
- mov xh, xh, lsl r2
+2: it le
+ rsble ip, r2, #32
+ lsl xh, xh, r2
+#if defined(__thumb2__)
+ lsr yl, xl, ip
+ itt le
+ orrle xh, xh, yl
+#else
orrle xh, xh, xl, lsr ip
- movle xl, xl, lsl r2
+#endif
+ lslle xl, xl, r2
@ adjust exponent accordingly.
3: subs r4, r4, r3
+ ittt ge
addge xh, xh, r4, lsl #20
orrge xh, xh, r5
RETLDM "r4, r5" ge
@@ -285,23 +320,23 @@ LSYM(Lad_l):
@ shift result right of 1 to 20 bits, sign is in r5.
add r4, r4, #20
rsb r2, r4, #32
- mov xl, xl, lsr r4
- orr xl, xl, xh, lsl r2
- orr xh, r5, xh, lsr r4
+ lsr xl, xl, r4
+ shiftop orr xl xl xh lsl r2 yh
+ shiftop orr xh r5 xh lsr r4 yh
RETLDM "r4, r5"
@ shift result right of 21 to 31 bits, or left 11 to 1 bits after
@ a register switch from xh to xl.
1: rsb r4, r4, #12
rsb r2, r4, #32
- mov xl, xl, lsr r2
- orr xl, xl, xh, lsl r4
+ lsr xl, xl, r2
+ shiftop orr xl xl xh lsl r4 yh
mov xh, r5
RETLDM "r4, r5"
@ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
@ from xh to xl.
-2: mov xl, xh, lsr r4
+2: lsr xl, xh, r4
mov xh, r5
RETLDM "r4, r5"
@@ -310,6 +345,7 @@ LSYM(Lad_l):
LSYM(Lad_d):
teq r4, #0
eor yh, yh, #0x00100000
+ itte eq
eoreq xh, xh, #0x00100000
addeq r4, r4, #1
subne r5, r5, #1
@@ -318,15 +354,18 @@ LSYM(Lad_d):
LSYM(Lad_s):
mvns ip, r4, asr #21
- mvnnes ip, r5, asr #21
+ it ne
+ mvnsne ip, r5, asr #21
beq LSYM(Lad_i)
teq r4, r5
+ it eq
teqeq xl, yl
beq 1f
@ Result is x + 0.0 = x or 0.0 + y = y.
teq r4, #0
+ itt eq
moveq xh, yh
moveq xl, yl
RETLDM "r4, r5"
@@ -334,6 +373,7 @@ LSYM(Lad_s):
1: teq xh, yh
@ Result is x - x = 0.
+ ittt ne
movne xh, #0
movne xl, #0
RETLDM "r4, r5" ne
@@ -343,9 +383,11 @@ LSYM(Lad_s):
bne 2f
movs xl, xl, lsl #1
adcs xh, xh, xh
+ it cs
orrcs xh, xh, #0x80000000
RETLDM "r4, r5"
2: adds r4, r4, #(2 << 21)
+ itt cc
addcc xh, xh, #(1 << 20)
RETLDM "r4, r5" cc
and r5, xh, #0x80000000
@@ -365,13 +407,16 @@ LSYM(Lad_o):
@ otherwise return xh-xl (which is INF or -INF)
LSYM(Lad_i):
mvns ip, r4, asr #21
+ itte ne
movne xh, yh
movne xl, yl
- mvneqs ip, r5, asr #21
+ mvnseq ip, r5, asr #21
+ itt ne
movne yh, xh
movne yl, xl
orrs r4, xl, xh, lsl #12
- orreqs r5, yl, yh, lsl #12
+ itte eq
+ orrseq r5, yl, yh, lsl #12
teqeq xh, yh
orrne xh, xh, #0x00080000 @ quiet NAN
RETLDM "r4, r5"
@@ -385,9 +430,10 @@ ARM_FUNC_START floatunsidf
ARM_FUNC_ALIAS aeabi_ui2d floatunsidf
teq r0, #0
+ itt eq
moveq r1, #0
RETc(eq)
- stmfd sp!, {r4, r5, lr}
+ push {r4, r5, lr}
mov r4, #0x400 @ initial exponent
add r4, r4, #(52-1 - 1)
mov r5, #0 @ sign bit is 0
@@ -404,12 +450,14 @@ ARM_FUNC_START floatsidf
ARM_FUNC_ALIAS aeabi_i2d floatsidf
teq r0, #0
+ itt eq
moveq r1, #0
RETc(eq)
- stmfd sp!, {r4, r5, lr}
+ push {r4, r5, lr}
mov r4, #0x400 @ initial exponent
add r4, r4, #(52-1 - 1)
ands r5, r0, #0x80000000 @ sign bit in r5
+ it mi
rsbmi r0, r0, #0 @ absolute value
.ifnc xl, r0
mov xl, r0
@@ -427,17 +475,19 @@ ARM_FUNC_ALIAS aeabi_f2d extendsfdf2
mov xh, r2, asr #3 @ stretch exponent
mov xh, xh, rrx @ retrieve sign bit
mov xl, r2, lsl #28 @ retrieve remaining bits
- andnes r3, r2, #0xff000000 @ isolate exponent
+ itttt ne
+ andsne r3, r2, #0xff000000 @ isolate exponent
teqne r3, #0xff000000 @ if not 0, check if INF or NAN
eorne xh, xh, #0x38000000 @ fixup exponent otherwise.
RETc(ne) @ and return it.
teq r2, #0 @ if actually 0
+ ite ne
teqne r3, #0xff000000 @ or INF or NAN
RETc(eq) @ we are done already.
@ value was denormalized. We can normalize it now.
- stmfd sp!, {r4, r5, lr}
+ push {r4, r5, lr}
mov r4, #0x380 @ setup corresponding exponent
and r5, xh, #0x80000000 @ move sign bit in r5
bic xh, xh, #0x80000000
@@ -451,7 +501,10 @@ ARM_FUNC_ALIAS aeabi_ul2d floatundidf
orrs r2, r0, r1
#if !defined (__VFP_FP__) && !defined(__SOFTFP__)
+ itt eq
mvfeqd f0, #0.0
+#else
+ it eq
#endif
RETc(eq)
@@ -460,9 +513,9 @@ ARM_FUNC_ALIAS aeabi_ul2d floatundidf
@ we can return the result in f0 as well as in r0/r1 for backwards
@ compatibility.
adr ip, LSYM(f0_ret)
- stmfd sp!, {r4, r5, ip, lr}
+ push {r4, r5, ip, lr}
#else
- stmfd sp!, {r4, r5, lr}
+ push {r4, r5, lr}
#endif
mov r5, #0
@@ -473,7 +526,10 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
orrs r2, r0, r1
#if !defined (__VFP_FP__) && !defined(__SOFTFP__)
+ itt eq
mvfeqd f0, #0.0
+#else
+ it eq
#endif
RETc(eq)
@@ -482,15 +538,21 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
@ we can return the result in f0 as well as in r0/r1 for backwards
@ compatibility.
adr ip, LSYM(f0_ret)
- stmfd sp!, {r4, r5, ip, lr}
+ push {r4, r5, ip, lr}
#else
- stmfd sp!, {r4, r5, lr}
+ push {r4, r5, lr}
#endif
ands r5, ah, #0x80000000 @ sign bit in r5
bpl 2f
+#if defined(__thumb2__)
+ movs r4, #0
+ negs al, al
+ sbc ah, r4, ah
+#else
rsbs al, al, #0
rsc ah, ah, #0
+#endif
2:
mov r4, #0x400 @ initial exponent
add r4, r4, #(52-1 - 1)
@@ -508,16 +570,18 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
@ The value is too big. Scale it down a bit...
mov r2, #3
movs ip, ip, lsr #3
+ it ne
addne r2, r2, #3
movs ip, ip, lsr #3
+ it ne
addne r2, r2, #3
add r2, r2, ip, lsr #3
rsb r3, r2, #32
- mov ip, xl, lsl r3
- mov xl, xl, lsr r2
- orr xl, xl, xh, lsl r3
- mov xh, xh, lsr r2
+ lsl ip, xl, r3
+ lsr xl, xl, r2
+ shiftop orr xl xl xh lsl r3 lr
+ lsr xh, xh, r2
add r4, r4, r2
b LSYM(Lad_p)
@@ -526,7 +590,7 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
@ Legacy code expects the result to be returned in f0. Copy it
@ there as well.
LSYM(f0_ret):
- stmfd sp!, {r0, r1}
+ push {r0, r1}
ldfd f0, [sp], #8
RETLDM
@@ -543,13 +607,14 @@ LSYM(f0_ret):
ARM_FUNC_START muldf3
ARM_FUNC_ALIAS aeabi_dmul muldf3
- stmfd sp!, {r4, r5, r6, lr}
+ push {r4, r5, r6, lr}
@ Mask out exponents, trap any zero/denormal/INF/NAN.
mov ip, #0xff
orr ip, ip, #0x700
ands r4, ip, xh, lsr #20
- andnes r5, ip, yh, lsr #20
+ ittte ne
+ andsne r5, ip, yh, lsr #20
teqne r4, ip
teqne r5, ip
bleq LSYM(Lml_s)
@@ -565,7 +630,8 @@ ARM_FUNC_ALIAS aeabi_dmul muldf3
bic xh, xh, ip, lsl #21
bic yh, yh, ip, lsl #21
orrs r5, xl, xh, lsl #12
- orrnes r5, yl, yh, lsl #12
+ it ne
+ orrsne r5, yl, yh, lsl #12
orr xh, xh, #0x00100000
orr yh, yh, #0x00100000
beq LSYM(Lml_1)
@@ -646,6 +712,7 @@ ARM_FUNC_ALIAS aeabi_dmul muldf3
@ The LSBs in ip are only significant for the final rounding.
@ Fold them into lr.
teq ip, #0
+ it ne
orrne lr, lr, #1
@ Adjust result upon the MSB position.
@@ -666,12 +733,14 @@ ARM_FUNC_ALIAS aeabi_dmul muldf3
@ Check exponent range for under/overflow.
subs ip, r4, #(254 - 1)
+ it hi
cmphi ip, #0x700
bhi LSYM(Lml_u)
@ Round the result, merge final exponent.
cmp lr, #0x80000000
- moveqs lr, xl, lsr #1
+ it eq
+ movseq lr, xl, lsr #1
adcs xl, xl, #0
adc xh, xh, r4, lsl #20
RETLDM "r4, r5, r6"
@@ -683,7 +752,8 @@ LSYM(Lml_1):
orr xl, xl, yl
eor xh, xh, yh
subs r4, r4, ip, lsr #1
- rsbgts r5, r4, ip
+ ittt gt
+ rsbsgt r5, r4, ip
orrgt xh, xh, r4, lsl #20
RETLDM "r4, r5, r6" gt
@@ -698,6 +768,7 @@ LSYM(Lml_u):
@ Check if denormalized result is possible, otherwise return signed 0.
cmn r4, #(53 + 1)
+ ittt le
movle xl, #0
bicle xh, xh, #0x7fffffff
RETLDM "r4, r5, r6" le
@@ -712,14 +783,15 @@ LSYM(Lml_u):
@ shift result right of 1 to 20 bits, preserve sign bit, round, etc.
add r4, r4, #20
rsb r5, r4, #32
- mov r3, xl, lsl r5
- mov xl, xl, lsr r4
- orr xl, xl, xh, lsl r5
+ lsl r3, xl, r5
+ lsr xl, xl, r4
+ shiftop orr xl xl xh lsl r5 r2
and r2, xh, #0x80000000
bic xh, xh, #0x80000000
adds xl, xl, r3, lsr #31
- adc xh, r2, xh, lsr r4
+ shiftop adc xh r2 xh lsr r4 r6
orrs lr, lr, r3, lsl #1
+ it eq
biceq xl, xl, r3, lsr #31
RETLDM "r4, r5, r6"
@@ -727,27 +799,29 @@ LSYM(Lml_u):
@ a register switch from xh to xl. Then round.
1: rsb r4, r4, #12
rsb r5, r4, #32
- mov r3, xl, lsl r4
- mov xl, xl, lsr r5
- orr xl, xl, xh, lsl r4
+ lsl r3, xl, r4
+ lsr xl, xl, r5
+ shiftop orr xl xl xh lsl r4 r2
bic xh, xh, #0x7fffffff
adds xl, xl, r3, lsr #31
adc xh, xh, #0
orrs lr, lr, r3, lsl #1
+ it eq
biceq xl, xl, r3, lsr #31
RETLDM "r4, r5, r6"
@ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
@ from xh to xl. Leftover bits are in r3-r6-lr for rounding.
2: rsb r5, r4, #32
- orr lr, lr, xl, lsl r5
- mov r3, xl, lsr r4
- orr r3, r3, xh, lsl r5
- mov xl, xh, lsr r4
+ shiftop orr lr lr xl lsl r5 r2
+ lsr r3, xl, r4
+ shiftop orr r3 r3 xh lsl r5 r2
+ lsr xl, xh, r4
bic xh, xh, #0x7fffffff
- bic xl, xl, xh, lsr r4
+ shiftop bic xl xl xh lsr r4 r2
add xl, xl, r3, lsr #31
orrs lr, lr, r3, lsl #1
+ it eq
biceq xl, xl, r3, lsr #31
RETLDM "r4, r5, r6"
@@ -760,15 +834,18 @@ LSYM(Lml_d):
1: movs xl, xl, lsl #1
adc xh, xh, xh
tst xh, #0x00100000
+ it eq
subeq r4, r4, #1
beq 1b
orr xh, xh, r6
teq r5, #0
+ it ne
movne pc, lr
2: and r6, yh, #0x80000000
3: movs yl, yl, lsl #1
adc yh, yh, yh
tst yh, #0x00100000
+ it eq
subeq r5, r5, #1
beq 3b
orr yh, yh, r6
@@ -778,26 +855,29 @@ LSYM(Lml_s):
@ Isolate the INF and NAN cases away
teq r4, ip
and r5, ip, yh, lsr #20
+ it ne
teqne r5, ip
beq 1f
@ Here, one or more arguments are either denormalized or zero.
orrs r6, xl, xh, lsl #1
- orrnes r6, yl, yh, lsl #1
+ it ne
+ orrsne r6, yl, yh, lsl #1
bne LSYM(Lml_d)
@ Result is 0, but determine sign anyway.
LSYM(Lml_z):
eor xh, xh, yh
- bic xh, xh, #0x7fffffff
+ and xh, xh, #0x80000000
mov xl, #0
RETLDM "r4, r5, r6"
1: @ One or both args are INF or NAN.
orrs r6, xl, xh, lsl #1
+ itte eq
moveq xl, yl
moveq xh, yh
- orrnes r6, yl, yh, lsl #1
+ orrsne r6, yl, yh, lsl #1
beq LSYM(Lml_n) @ 0 * INF or INF * 0 -> NAN
teq r4, ip
bne 1f
@@ -806,6 +886,7 @@ LSYM(Lml_z):
1: teq r5, ip
bne LSYM(Lml_i)
orrs r6, yl, yh, lsl #12
+ itt ne
movne xl, yl
movne xh, yh
bne LSYM(Lml_n) @ <anything> * NAN -> NAN
@@ -834,13 +915,14 @@ LSYM(Lml_n):
ARM_FUNC_START divdf3
ARM_FUNC_ALIAS aeabi_ddiv divdf3
- stmfd sp!, {r4, r5, r6, lr}
+ push {r4, r5, r6, lr}
@ Mask out exponents, trap any zero/denormal/INF/NAN.
mov ip, #0xff
orr ip, ip, #0x700
ands r4, ip, xh, lsr #20
- andnes r5, ip, yh, lsr #20
+ ittte ne
+ andsne r5, ip, yh, lsr #20
teqne r4, ip
teqne r5, ip
bleq LSYM(Ldv_s)
@@ -871,6 +953,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
@ Ensure result will land to known bit position.
@ Apply exponent bias accordingly.
cmp r5, yh
+ it eq
cmpeq r6, yl
adc r4, r4, #(255 - 2)
add r4, r4, #0x300
@@ -889,6 +972,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
@ The actual division loop.
1: subs lr, r6, yl
sbcs lr, r5, yh
+ ittt cs
subcs r6, r6, yl
movcs r5, lr
orrcs xl, xl, ip
@@ -896,6 +980,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
mov yl, yl, rrx
subs lr, r6, yl
sbcs lr, r5, yh
+ ittt cs
subcs r6, r6, yl
movcs r5, lr
orrcs xl, xl, ip, lsr #1
@@ -903,6 +988,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
mov yl, yl, rrx
subs lr, r6, yl
sbcs lr, r5, yh
+ ittt cs
subcs r6, r6, yl
movcs r5, lr
orrcs xl, xl, ip, lsr #2
@@ -910,6 +996,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
mov yl, yl, rrx
subs lr, r6, yl
sbcs lr, r5, yh
+ ittt cs
subcs r6, r6, yl
movcs r5, lr
orrcs xl, xl, ip, lsr #3
@@ -936,18 +1023,21 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
2:
@ Be sure result starts in the high word.
tst xh, #0x00100000
+ itt eq
orreq xh, xh, xl
moveq xl, #0
3:
@ Check exponent range for under/overflow.
subs ip, r4, #(254 - 1)
+ it hi
cmphi ip, #0x700
bhi LSYM(Lml_u)
@ Round the result, merge final exponent.
subs ip, r5, yh
- subeqs ip, r6, yl
- moveqs ip, xl, lsr #1
+ itt eq
+ subseq ip, r6, yl
+ movseq ip, xl, lsr #1
adcs xl, xl, #0
adc xh, xh, r4, lsl #20
RETLDM "r4, r5, r6"
@@ -957,7 +1047,8 @@ LSYM(Ldv_1):
and lr, lr, #0x80000000
orr xh, lr, xh, lsr #12
adds r4, r4, ip, lsr #1
- rsbgts r5, r4, ip
+ ittt gt
+ rsbsgt r5, r4, ip
orrgt xh, xh, r4, lsl #20
RETLDM "r4, r5, r6" gt
@@ -976,6 +1067,7 @@ LSYM(Ldv_u):
LSYM(Ldv_s):
and r5, ip, yh, lsr #20
teq r4, ip
+ it eq
teqeq r5, ip
beq LSYM(Lml_n) @ INF/NAN / INF/NAN -> NAN
teq r4, ip
@@ -996,7 +1088,8 @@ LSYM(Ldv_s):
b LSYM(Lml_n) @ <anything> / NAN -> NAN
2: @ If both are nonzero, we need to normalize and resume above.
orrs r6, xl, xh, lsl #1
- orrnes r6, yl, yh, lsl #1
+ it ne
+ orrsne r6, yl, yh, lsl #1
bne LSYM(Lml_d)
@ One or both arguments are 0.
orrs r4, xl, xh, lsl #1
@@ -1035,14 +1128,17 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
mov ip, xh, lsl #1
mvns ip, ip, asr #21
mov ip, yh, lsl #1
- mvnnes ip, ip, asr #21
+ it ne
+ mvnsne ip, ip, asr #21
beq 3f
@ Test for equality.
@ Note that 0.0 is equal to -0.0.
2: orrs ip, xl, xh, lsl #1 @ if x == 0.0 or -0.0
- orreqs ip, yl, yh, lsl #1 @ and y == 0.0 or -0.0
+ ite eq
+ orrseq ip, yl, yh, lsl #1 @ and y == 0.0 or -0.0
teqne xh, yh @ or xh == yh
+ ittt eq
teqeq xl, yl @ and xl == yl
moveq r0, #0 @ then equal.
RETc(eq)
@@ -1054,10 +1150,13 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
teq xh, yh
@ Compare values if same sign
+ it pl
cmppl xh, yh
+ it eq
cmpeq xl, yl
@ Result:
+ ite cs
movcs r0, yh, asr #31
mvncc r0, yh, asr #31
orr r0, r0, #1
@@ -1100,14 +1199,15 @@ ARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmp
@ The status-returning routines are required to preserve all
@ registers except ip, lr, and cpsr.
-6: stmfd sp!, {r0, lr}
+6: push {r0, lr}
ARM_CALL cmpdf2
@ Set the Z flag correctly, and the C flag unconditionally.
- cmp r0, #0
+ cmp r0, #0
@ Clear the C flag if the return value was -1, indicating
@ that the first operand was smaller than the second.
- cmnmi r0, #0
- RETLDM "r0"
+ it mi
+ cmnmi r0, #0
+ RETLDM "r0"
FUNC_END aeabi_cdcmple
FUNC_END aeabi_cdcmpeq
@@ -1117,6 +1217,7 @@ ARM_FUNC_START aeabi_dcmpeq
str lr, [sp, #-8]!
ARM_CALL aeabi_cdcmple
+ ite eq
moveq r0, #1 @ Equal to.
movne r0, #0 @ Less than, greater than, or unordered.
RETLDM
@@ -1127,6 +1228,7 @@ ARM_FUNC_START aeabi_dcmplt
str lr, [sp, #-8]!
ARM_CALL aeabi_cdcmple
+ ite cc
movcc r0, #1 @ Less than.
movcs r0, #0 @ Equal to, greater than, or unordered.
RETLDM
@@ -1137,6 +1239,7 @@ ARM_FUNC_START aeabi_dcmple
str lr, [sp, #-8]!
ARM_CALL aeabi_cdcmple
+ ite ls
movls r0, #1 @ Less than or equal to.
movhi r0, #0 @ Greater than or unordered.
RETLDM
@@ -1147,6 +1250,7 @@ ARM_FUNC_START aeabi_dcmpge
str lr, [sp, #-8]!
ARM_CALL aeabi_cdrcmple
+ ite ls
movls r0, #1 @ Operand 2 is less than or equal to operand 1.
movhi r0, #0 @ Operand 2 greater than operand 1, or unordered.
RETLDM
@@ -1157,6 +1261,7 @@ ARM_FUNC_START aeabi_dcmpgt
str lr, [sp, #-8]!
ARM_CALL aeabi_cdrcmple
+ ite cc
movcc r0, #1 @ Operand 2 is less than operand 1.
movcs r0, #0 @ Operand 2 is greater than or equal to operand 1,
@ or they are unordered.
@@ -1211,7 +1316,8 @@ ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
orr r3, r3, #0x80000000
orr r3, r3, xl, lsr #21
tst xh, #0x80000000 @ the sign bit
- mov r0, r3, lsr r2
+ lsr r0, r3, r2
+ it ne
rsbne r0, r0, #0
RET
@@ -1221,6 +1327,7 @@ ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
2: orrs xl, xl, xh, lsl #12
bne 4f @ x is NAN.
3: ands r0, xh, #0x80000000 @ the sign bit
+ it eq
moveq r0, #0x7fffffff @ maximum signed positive si
RET
@@ -1251,7 +1358,7 @@ ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi
mov r3, xh, lsl #11
orr r3, r3, #0x80000000
orr r3, r3, xl, lsr #21
- mov r0, r3, lsr r2
+ lsr r0, r3, r2
RET
1: mov r0, #0
@@ -1278,8 +1385,9 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
@ check exponent range.
mov r2, xh, lsl #1
subs r3, r2, #((1023 - 127) << 21)
- subcss ip, r3, #(1 << 21)
- rsbcss ip, ip, #(254 << 21)
+ itt cs
+ subscs ip, r3, #(1 << 21)
+ rsbscs ip, ip, #(254 << 21)
bls 2f @ value is out of range
1: @ shift and round mantissa
@@ -1288,6 +1396,7 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
orr xl, ip, xl, lsr #29
cmp r2, #0x80000000
adc r0, xl, r3, lsl #2
+ it eq
biceq r0, r0, #1
RET
@@ -1297,6 +1406,7 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
@ check if denormalized value is possible
adds r2, r3, #(23 << 21)
+ itt lt
andlt r0, xh, #0x80000000 @ too small, return signed 0.
RETc(lt)
@@ -1305,13 +1415,14 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
mov r2, r2, lsr #21
rsb r2, r2, #24
rsb ip, r2, #32
- movs r3, xl, lsl ip
- mov xl, xl, lsr r2
+ lsls r3, xl, ip
+ lsr xl, xl, r2
+ it ne
orrne xl, xl, #1 @ fold r3 for rounding considerations.
mov r3, xh, lsl #11
mov r3, r3, lsr #11
- orr xl, xl, r3, lsl ip
- mov r3, r3, lsr r2
+ shiftop orr xl xl r3 lsl ip ip
+ lsr r3, r3, r2
mov r3, r3, lsl #1
b 1b
@@ -1319,6 +1430,7 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
mvns r3, r2, asr #21
bne 5f @ simple overflow
orrs r3, xl, xh, lsl #12
+ ittt ne
movne r0, #0x7f000000
orrne r0, r0, #0x00c00000
RETc(ne) @ return NAN
Index: gcc/config/arm/lib1funcs.asm
===================================================================
--- gcc/config/arm/lib1funcs.asm (revision 110445)
+++ gcc/config/arm/lib1funcs.asm (working copy)
@@ -29,6 +29,10 @@ the Free Software Foundation, 51 Frankli
Boston, MA 02110-1301, USA. */
/* ------------------------------------------------------------------------ */
+#if !defined(__thumb__)
+.syntax unified
+#endif
+
/* We need to know what prefix to add to function names. */
#ifndef __USER_LABEL_PREFIX__
@@ -186,7 +189,7 @@ LSYM(Lend_fde):
.ifc "\regs",""
ldr\cond lr, [sp], #8
.else
- ldm\cond\dirn sp!, {\regs, lr}
+ pop\cond {\regs, lr}
.endif
.ifnc "\unwind", ""
/* Mark LR as restored. */
@@ -194,14 +197,27 @@ LSYM(Lend_fde):
.endif
bx\cond lr
#else
+ /* Caller is responsible for providing IT instruction. */
.ifc "\regs",""
ldr\cond pc, [sp], #8
.else
- ldm\cond\dirn sp!, {\regs, pc}
+ pop\cond {\regs, pc}
.endif
#endif
.endm
+/* Perform an arithmetic operation with a variable shift operand. This
+ requires two instructions and a scratch register on Thumb-2. */
+#if defined(__thumb2__)
+.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
+ \shiftop \tmp, \src2, \shiftreg
+ \name \dest, \src1, \tmp
+.endm
+#else
+.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
+ \name \dest, \src1, \src2, \shiftop \shiftreg
+.endm
+#endif
.macro ARM_LDIV0 name
str lr, [sp, #-8]!
@@ -253,11 +269,13 @@ SYM (\name):
#ifdef __thumb__
#define THUMB_FUNC .thumb_func
#define THUMB_CODE .force_thumb
+#define THUMB_SYNTAX .syntax divided
#else
#define THUMB_FUNC
#define THUMB_CODE
+#define THUMB_SYNTAX
#endif
-
+
.macro FUNC_START name
.text
.globl SYM (__\name)
@@ -265,17 +283,32 @@ SYM (\name):
.align 0
THUMB_CODE
THUMB_FUNC
+ THUMB_SYNTAX
SYM (__\name):
.endm
/* Special function that will always be coded in ARM assembly, even if
in Thumb-only compilation. */
-#if defined(__INTERWORKING_STUBS__)
+#if defined(__thumb2__)
+
+/* For Thumb-2 we build everything in thumb mode. */
+.macro ARM_FUNC_START name
+ FUNC_START \name
+ .syntax unified
+.endm
+#define EQUIV .thumb_set
+.macro ARM_CALL name
+ bl __\name
+.endm
+
+#elif defined(__INTERWORKING_STUBS__)
+
.macro ARM_FUNC_START name
FUNC_START \name
bx pc
nop
+ .syntax unified
.arm
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
directly from other local arm routines. */
@@ -287,12 +320,15 @@ _L__\name:
.macro ARM_CALL name
bl _L__\name
.endm
-#else
+
+#else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
+
.macro ARM_FUNC_START name
.text
.globl SYM (__\name)
TYPE (__\name)
.align 0
+ .syntax unified
.arm
SYM (__\name):
.endm
@@ -300,6 +336,7 @@ SYM (__\name):
.macro ARM_CALL name
bl __\name
.endm
+
#endif
.macro FUNC_ALIAS new old
@@ -1176,6 +1213,10 @@ LSYM(Lover12):
#endif /* L_call_via_rX */
+/* Don't bother with the old interworking routines for Thumb-2. */
+/* ??? Maybe only omit these on v7m. */
+#ifndef __thumb2__
+
#if defined L_interwork_call_via_rX
/* These labels & instructions are used by the Arm/Thumb interworking code,
@@ -1300,6 +1341,7 @@ LSYM(Lchange_\register):
SIZE (_interwork_call_via_lr)
#endif /* L_interwork_call_via_rX */
+#endif /* !__thumb2__ */
#endif /* Arch supports thumb. */
#ifndef __symbian__
Index: gcc/config/arm/libunwind.S
===================================================================
--- gcc/config/arm/libunwind.S (revision 110445)
+++ gcc/config/arm/libunwind.S (working copy)
@@ -43,7 +43,14 @@ ARM_FUNC_START restore_core_regs
this. */
add r1, r0, #52
ldmia r1, {r3, r4, r5} /* {sp, lr, pc}. */
-#ifdef __INTERWORKING__
+#if defined(__thumb2__)
+ /* Thumb-2 doesn't allow sp in a load-multiple instruction, so push
+ the target address onto the target stack. This is safe as
+ we're always returning to somewhere further up the call stack. */
+ mov ip, r3
+ mov lr, r4
+ str r5, [ip, #-4]!
+#elif defined(__INTERWORKING__)
/* Restore pc into ip. */
mov r2, r5
stmfd sp!, {r2, r3, r4}
@@ -52,8 +59,12 @@ ARM_FUNC_START restore_core_regs
#endif
/* Don't bother restoring ip. */
ldmia r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp}
+#if defined(__thumb2__)
+ /* Pop the return address off the target stack. */
+ mov sp, ip
+ pop {pc}
+#elif defined(__INTERWORKING__)
/* Pop the three registers we pushed earlier. */
-#ifdef __INTERWORKING__
ldmfd sp, {ip, sp, lr}
bx ip
#else
@@ -82,7 +93,13 @@ ARM_FUNC_START gnu_Unwind_Save_VFP
ARM_FUNC_START \name
/* Create a phase2_vrs structure. */
/* Split reg push in two to ensure the correct value for sp. */
+#if defined(__thumb2__)
+ mov ip, sp
+ push {lr} /* PC is ignored. */
+ push {ip, lr} /* Push original SP and LR. */
+#else
stmfd sp!, {sp, lr, pc}
+#endif
stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip}
/* Demand-save flags, plus an extra word for alignment. */
@@ -91,7 +108,7 @@ ARM_FUNC_START gnu_Unwind_Save_VFP
/* Point r1 at the block. Pass r[0..nargs) unchanged. */
add r\nargs, sp, #4
-#if defined(__thumb__)
+#if defined(__thumb__) && !defined(__thumb2__)
/* Switch back to thumb mode to avoid interworking hassle. */
adr ip, .L1_\name
orr ip, ip, #1
Index: gcc/config/arm/ieee754-sf.S
===================================================================
--- gcc/config/arm/ieee754-sf.S (revision 110445)
+++ gcc/config/arm/ieee754-sf.S (working copy)
@@ -71,36 +71,42 @@ ARM_FUNC_ALIAS aeabi_fadd addsf3
1: @ Look for zeroes, equal values, INF, or NAN.
movs r2, r0, lsl #1
- movnes r3, r1, lsl #1
+ itttt ne
+ movsne r3, r1, lsl #1
teqne r2, r3
- mvnnes ip, r2, asr #24
- mvnnes ip, r3, asr #24
+ mvnsne ip, r2, asr #24
+ mvnsne ip, r3, asr #24
beq LSYM(Lad_s)
@ Compute exponent difference. Make largest exponent in r2,
@ corresponding arg in r0, and positive exponent difference in r3.
mov r2, r2, lsr #24
rsbs r3, r2, r3, lsr #24
+ itttt gt
addgt r2, r2, r3
eorgt r1, r0, r1
eorgt r0, r1, r0
eorgt r1, r0, r1
+ it lt
rsblt r3, r3, #0
@ If exponent difference is too large, return largest argument
@ already in r0. We need up to 25 bit to handle proper rounding
@ of 0x1p25 - 1.1.
cmp r3, #25
+ it hi
RETc(hi)
@ Convert mantissa to signed integer.
tst r0, #0x80000000
orr r0, r0, #0x00800000
bic r0, r0, #0xff000000
+ it ne
rsbne r0, r0, #0
tst r1, #0x80000000
orr r1, r1, #0x00800000
bic r1, r1, #0xff000000
+ it ne
rsbne r1, r1, #0
@ If exponent == difference, one or both args were denormalized.
@@ -114,15 +120,21 @@ LSYM(Lad_x):
@ Shift and add second arg to first arg in r0.
@ Keep leftover bits into r1.
- adds r0, r0, r1, asr r3
+ shiftop adds r0 r0 r1 asr r3 ip
rsb r3, r3, #32
- mov r1, r1, lsl r3
+ lsl r1, r1, r3
@ Keep absolute value in r0-r1, sign in r3 (the n bit was set above)
and r3, r0, #0x80000000
bpl LSYM(Lad_p)
+#if defined(__thumb2__)
+ mov ip, #0
+ negs r1, r1
+ sbc r0, ip, r0
+#else
rsbs r1, r1, #0
rsc r0, r0, #0
+#endif
@ Determine how to normalize the result.
LSYM(Lad_p):
@@ -147,6 +159,7 @@ LSYM(Lad_p):
LSYM(Lad_e):
cmp r1, #0x80000000
adc r0, r0, r2, lsl #23
+ it eq
biceq r0, r0, #1
orr r0, r0, r3
RET
@@ -185,16 +198,23 @@ LSYM(Lad_l):
clz ip, r0
sub ip, ip, #8
subs r2, r2, ip
- mov r0, r0, lsl ip
+ lsl r0, r0, ip
#endif
@ Final result with sign
@ If exponent negative, denormalize result.
+ itet ge
addge r0, r0, r2, lsl #23
rsblt r2, r2, #0
orrge r0, r0, r3
+#if defined(__thumb2__)
+ itt lt
+ lsrlt r0, r0, r2
+ orrlt r0, r3, r0
+#else
orrlt r0, r3, r0, lsr r2
+#endif
RET
@ Fixup and adjust bit position for denormalized arguments.
@@ -202,6 +222,7 @@ LSYM(Lad_l):
LSYM(Lad_d):
teq r2, #0
eor r1, r1, #0x00800000
+ itte eq
eoreq r0, r0, #0x00800000
addeq r2, r2, #1
subne r3, r3, #1
@@ -211,7 +232,8 @@ LSYM(Lad_s):
mov r3, r1, lsl #1
mvns ip, r2, asr #24
- mvnnes ip, r3, asr #24
+ it ne
+ mvnsne ip, r3, asr #24
beq LSYM(Lad_i)
teq r2, r3
@@ -219,12 +241,14 @@ LSYM(Lad_s):
@ Result is x + 0.0 = x or 0.0 + y = y.
teq r2, #0
+ it eq
moveq r0, r1
RET
1: teq r0, r1
@ Result is x - x = 0.
+ itt ne
movne r0, #0
RETc(ne)
@@ -232,9 +256,11 @@ LSYM(Lad_s):
tst r2, #0xff000000
bne 2f
movs r0, r0, lsl #1
+ it cs
orrcs r0, r0, #0x80000000
RET
2: adds r2, r2, #(2 << 24)
+ itt cc
addcc r0, r0, #(1 << 23)
RETc(cc)
and r3, r0, #0x80000000
@@ -253,11 +279,13 @@ LSYM(Lad_o):
@ otherwise return r0 (which is INF or -INF)
LSYM(Lad_i):
mvns r2, r2, asr #24
+ itet ne
movne r0, r1
- mvneqs r3, r3, asr #24
+ mvnseq r3, r3, asr #24
movne r1, r0
movs r2, r0, lsl #9
- moveqs r3, r1, lsl #9
+ itte eq
+ movseq r3, r1, lsl #9
teqeq r0, r1
orrne r0, r0, #0x00400000 @ quiet NAN
RET
@@ -278,9 +306,11 @@ ARM_FUNC_START floatsisf
ARM_FUNC_ALIAS aeabi_i2f floatsisf
ands r3, r0, #0x80000000
+ it mi
rsbmi r0, r0, #0
1: movs ip, r0
+ it eq
RETc(eq)
@ Add initial exponent to sign
@@ -302,7 +332,10 @@ ARM_FUNC_ALIAS aeabi_ul2f floatundisf
orrs r2, r0, r1
#if !defined (__VFP_FP__) && !defined(__SOFTFP__)
+ itt eq
mvfeqs f0, #0.0
+#else
+ it eq
#endif
RETc(eq)
@@ -314,14 +347,23 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
orrs r2, r0, r1
#if !defined (__VFP_FP__) && !defined(__SOFTFP__)
+ itt eq
mvfeqs f0, #0.0
+#else
+ it eq
#endif
RETc(eq)
ands r3, ah, #0x80000000 @ sign bit in r3
bpl 1f
+#if defined(__thumb2__)
+ movs r2, #0
+ negs al, al
+ sbc ah, r2, ah
+#else
rsbs al, al, #0
rsc ah, ah, #0
+#endif
1:
#if !defined (__VFP_FP__) && !defined(__SOFTFP__)
@ For hard FPA code we want to return via the tail below so that
@@ -332,12 +374,14 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
#endif
movs ip, ah
+ ittt eq
moveq ip, al
moveq ah, al
moveq al, #0
@ Add initial exponent to sign
orr r3, r3, #((127 + 23 + 32) << 23)
+ it eq
subeq r3, r3, #(32 << 23)
2: sub r3, r3, #(1 << 23)
@@ -345,15 +389,19 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
mov r2, #23
cmp ip, #(1 << 16)
+ itt hs
movhs ip, ip, lsr #16
subhs r2, r2, #16
cmp ip, #(1 << 8)
+ itt hs
movhs ip, ip, lsr #8
subhs r2, r2, #8
cmp ip, #(1 << 4)
+ itt hs
movhs ip, ip, lsr #4
subhs r2, r2, #4
cmp ip, #(1 << 2)
+ ite hs
subhs r2, r2, #2
sublo r2, r2, ip, lsr #1
subs r2, r2, ip, lsr #3
@@ -368,19 +416,21 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
sub r3, r3, r2, lsl #23
blt 3f
- add r3, r3, ah, lsl r2
- mov ip, al, lsl r2
+ shiftop add r3 r3 ah lsl r2 ip
+ lsl ip, al, r2
rsb r2, r2, #32
cmp ip, #0x80000000
- adc r0, r3, al, lsr r2
+ shiftop adc r0 r3 al lsr r2 r2
+ it eq
biceq r0, r0, #1
RET
3: add r2, r2, #32
- mov ip, ah, lsl r2
+ lsl ip, ah, r2
rsb r2, r2, #32
orrs al, al, ip, lsl #1
- adc r0, r3, ah, lsr r2
+ shiftop adc r0 r3 ah lsr r2 r2
+ it eq
biceq r0, r0, ip, lsr #31
RET
@@ -408,7 +458,8 @@ ARM_FUNC_ALIAS aeabi_fmul mulsf3
@ Mask out exponents, trap any zero/denormal/INF/NAN.
mov ip, #0xff
ands r2, ip, r0, lsr #23
- andnes r3, ip, r1, lsr #23
+ ittt ne
+ andsne r3, ip, r1, lsr #23
teqne r2, ip
teqne r3, ip
beq LSYM(Lml_s)
@@ -424,7 +475,8 @@ LSYM(Lml_x):
@ If power of two, branch to a separate path.
@ Make up for final alignment.
movs r0, r0, lsl #9
- movnes r1, r1, lsl #9
+ it ne
+ movsne r1, r1, lsl #9
beq LSYM(Lml_1)
mov r3, #0x08000000
orr r0, r3, r0, lsr #5
@@ -436,7 +488,7 @@ LSYM(Lml_x):
and r3, ip, #0x80000000
@ Well, no way to make it shorter without the umull instruction.
- stmfd sp!, {r3, r4, r5}
+ push {r3, r4, r5}
mov r4, r0, lsr #16
mov r5, r1, lsr #16
bic r0, r0, r4, lsl #16
@@ -447,7 +499,7 @@ LSYM(Lml_x):
mla r0, r4, r1, r0
adds r3, r3, r0, lsl #16
adc r1, ip, r0, lsr #16
- ldmfd sp!, {r0, r4, r5}
+ pop {r0, r4, r5}
#else
@@ -461,6 +513,7 @@ LSYM(Lml_x):
@ Adjust result upon the MSB position.
cmp r1, #(1 << 23)
+ ittt cc
movcc r1, r1, lsl #1
orrcc r1, r1, r3, lsr #31
movcc r3, r3, lsl #1
@@ -476,6 +529,7 @@ LSYM(Lml_x):
@ Round the result, merge final exponent.
cmp r3, #0x80000000
adc r0, r0, r2, lsl #23
+ it eq
biceq r0, r0, #1
RET
@@ -483,11 +537,13 @@ LSYM(Lml_x):
LSYM(Lml_1):
teq r0, #0
and ip, ip, #0x80000000
+ it eq
moveq r1, r1, lsl #9
orr r0, ip, r0, lsr #9
orr r0, r0, r1, lsr #9
subs r2, r2, #127
- rsbgts r3, r2, #255
+ ittt gt
+ rsbsgt r3, r2, #255
orrgt r0, r0, r2, lsl #23
RETc(gt)
@@ -502,18 +558,20 @@ LSYM(Lml_u):
@ Check if denormalized result is possible, otherwise return signed 0.
cmn r2, #(24 + 1)
+ itt le
bicle r0, r0, #0x7fffffff
RETc(le)
@ Shift value right, round, etc.
rsb r2, r2, #0
movs r1, r0, lsl #1
- mov r1, r1, lsr r2
+ lsr r1, r1, r2
rsb r2, r2, #32
- mov ip, r0, lsl r2
+ lsl ip, r0, r2
movs r0, r1, rrx
adc r0, r0, #0
orrs r3, r3, ip, lsl #1
+ it eq
biceq r0, r0, ip, lsr #31
RET
@@ -522,14 +580,16 @@ LSYM(Lml_u):
LSYM(Lml_d):
teq r2, #0
and ip, r0, #0x80000000
-1: moveq r0, r0, lsl #1
+1: ittt eq
+ moveq r0, r0, lsl #1
tsteq r0, #0x00800000
subeq r2, r2, #1
beq 1b
orr r0, r0, ip
teq r3, #0
and ip, r1, #0x80000000
-2: moveq r1, r1, lsl #1
+2: ittt eq
+ moveq r1, r1, lsl #1
tsteq r1, #0x00800000
subeq r3, r3, #1
beq 2b
@@ -540,12 +600,14 @@ LSYM(Lml_s):
@ Isolate the INF and NAN cases away
and r3, ip, r1, lsr #23
teq r2, ip
+ it ne
teqne r3, ip
beq 1f
@ Here, one or more arguments are either denormalized or zero.
bics ip, r0, #0x80000000
- bicnes ip, r1, #0x80000000
+ it ne
+ bicsne ip, r1, #0x80000000
bne LSYM(Lml_d)
@ Result is 0, but determine sign anyway.
@@ -556,6 +618,7 @@ LSYM(Lml_z):
1: @ One or both args are INF or NAN.
teq r0, #0x0
+ itett ne
teqne r0, #0x80000000
moveq r0, r1
teqne r1, #0x0
@@ -568,6 +631,7 @@ LSYM(Lml_z):
1: teq r3, ip
bne LSYM(Lml_i)
movs r3, r1, lsl #9
+ it ne
movne r0, r1
bne LSYM(Lml_n) @ <anything> * NAN -> NAN
@@ -597,7 +661,8 @@ ARM_FUNC_ALIAS aeabi_fdiv divsf3
@ Mask out exponents, trap any zero/denormal/INF/NAN.
mov ip, #0xff
ands r2, ip, r0, lsr #23
- andnes r3, ip, r1, lsr #23
+ ittt ne
+ andsne r3, ip, r1, lsr #23
teqne r2, ip
teqne r3, ip
beq LSYM(Ldv_s)
@@ -624,25 +689,31 @@ LSYM(Ldv_x):
@ Ensure result will land to known bit position.
@ Apply exponent bias accordingly.
cmp r3, r1
+ it cc
movcc r3, r3, lsl #1
adc r2, r2, #(127 - 2)
@ The actual division loop.
mov ip, #0x00800000
1: cmp r3, r1
+ itt cs
subcs r3, r3, r1
orrcs r0, r0, ip
cmp r3, r1, lsr #1
+ itt cs
subcs r3, r3, r1, lsr #1
orrcs r0, r0, ip, lsr #1
cmp r3, r1, lsr #2
+ itt cs
subcs r3, r3, r1, lsr #2
orrcs r0, r0, ip, lsr #2
cmp r3, r1, lsr #3
+ itt cs
subcs r3, r3, r1, lsr #3
orrcs r0, r0, ip, lsr #3
movs r3, r3, lsl #4
- movnes ip, ip, lsr #4
+ it ne
+ movsne ip, ip, lsr #4
bne 1b
@ Check exponent for under/overflow.
@@ -652,6 +723,7 @@ LSYM(Ldv_x):
@ Round the result, merge final exponent.
cmp r3, r1
adc r0, r0, r2, lsl #23
+ it eq
biceq r0, r0, #1
RET
@@ -660,7 +732,8 @@ LSYM(Ldv_1):
and ip, ip, #0x80000000
orr r0, ip, r0, lsr #9
adds r2, r2, #127
- rsbgts r3, r2, #255
+ ittt gt
+ rsbsgt r3, r2, #255
orrgt r0, r0, r2, lsl #23
RETc(gt)
@@ -674,14 +747,16 @@ LSYM(Ldv_1):
LSYM(Ldv_d):
teq r2, #0
and ip, r0, #0x80000000
-1: moveq r0, r0, lsl #1
+1: ittt eq
+ moveq r0, r0, lsl #1
tsteq r0, #0x00800000
subeq r2, r2, #1
beq 1b
orr r0, r0, ip
teq r3, #0
and ip, r1, #0x80000000
-2: moveq r1, r1, lsl #1
+2: ittt eq
+ moveq r1, r1, lsl #1
tsteq r1, #0x00800000
subeq r3, r3, #1
beq 2b
@@ -707,7 +782,8 @@ LSYM(Ldv_s):
b LSYM(Lml_n) @ <anything> / NAN -> NAN
2: @ If both are nonzero, we need to normalize and resume above.
bics ip, r0, #0x80000000
- bicnes ip, r1, #0x80000000
+ it ne
+ bicsne ip, r1, #0x80000000
bne LSYM(Ldv_d)
@ One or both arguments are zero.
bics r2, r0, #0x80000000
@@ -759,18 +835,24 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
mov r2, r0, lsl #1
mov r3, r1, lsl #1
mvns ip, r2, asr #24
- mvnnes ip, r3, asr #24
+ it ne
+ mvnsne ip, r3, asr #24
beq 3f
@ Compare values.
@ Note that 0.0 is equal to -0.0.
2: orrs ip, r2, r3, lsr #1 @ test if both are 0, clear C flag
+ it ne
teqne r0, r1 @ if not 0 compare sign
- subpls r0, r2, r3 @ if same sign compare values, set r0
+ it pl
+ subspl r0, r2, r3 @ if same sign compare values, set r0
@ Result:
+ it hi
movhi r0, r1, asr #31
+ it lo
mvnlo r0, r1, asr #31
+ it ne
orrne r0, r0, #1
RET
@@ -806,14 +888,15 @@ ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmp
@ The status-returning routines are required to preserve all
@ registers except ip, lr, and cpsr.
-6: stmfd sp!, {r0, r1, r2, r3, lr}
+6: push {r0, r1, r2, r3, lr}
ARM_CALL cmpsf2
@ Set the Z flag correctly, and the C flag unconditionally.
- cmp r0, #0
+ cmp r0, #0
@ Clear the C flag if the return value was -1, indicating
@ that the first operand was smaller than the second.
- cmnmi r0, #0
- RETLDM "r0, r1, r2, r3"
+ it mi
+ cmnmi r0, #0
+ RETLDM "r0, r1, r2, r3"
FUNC_END aeabi_cfcmple
FUNC_END aeabi_cfcmpeq
@@ -823,6 +906,7 @@ ARM_FUNC_START aeabi_fcmpeq
str lr, [sp, #-8]!
ARM_CALL aeabi_cfcmple
+ ite eq
moveq r0, #1 @ Equal to.
movne r0, #0 @ Less than, greater than, or unordered.
RETLDM
@@ -833,6 +917,7 @@ ARM_FUNC_START aeabi_fcmplt
str lr, [sp, #-8]!
ARM_CALL aeabi_cfcmple
+ ite cc
movcc r0, #1 @ Less than.
movcs r0, #0 @ Equal to, greater than, or unordered.
RETLDM
@@ -843,6 +928,7 @@ ARM_FUNC_START aeabi_fcmple
str lr, [sp, #-8]!
ARM_CALL aeabi_cfcmple
+ ite ls
movls r0, #1 @ Less than or equal to.
movhi r0, #0 @ Greater than or unordered.
RETLDM
@@ -853,6 +939,7 @@ ARM_FUNC_START aeabi_fcmpge
str lr, [sp, #-8]!
ARM_CALL aeabi_cfrcmple
+ ite ls
movls r0, #1 @ Operand 2 is less than or equal to operand 1.
movhi r0, #0 @ Operand 2 greater than operand 1, or unordered.
RETLDM
@@ -863,6 +950,7 @@ ARM_FUNC_START aeabi_fcmpgt
str lr, [sp, #-8]!
ARM_CALL aeabi_cfrcmple
+ ite cc
movcc r0, #1 @ Operand 2 is less than operand 1.
movcs r0, #0 @ Operand 2 is greater than or equal to operand 1,
@ or they are unordered.
@@ -914,7 +1002,8 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
mov r3, r0, lsl #8
orr r3, r3, #0x80000000
tst r0, #0x80000000 @ the sign bit
- mov r0, r3, lsr r2
+ lsr r0, r3, r2
+ it ne
rsbne r0, r0, #0
RET
@@ -926,6 +1015,7 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
movs r2, r0, lsl #9
bne 4f @ r0 is NAN.
3: ands r0, r0, #0x80000000 @ the sign bit
+ it eq
moveq r0, #0x7fffffff @ the maximum signed positive si
RET
@@ -954,7 +1044,7 @@ ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi
@ scale the value
mov r3, r0, lsl #8
orr r3, r3, #0x80000000
- mov r0, r3, lsr r2
+ lsr r0, r3, r2
RET
1: mov r0, #0
Index: gcc/config/arm/bpabi.S
===================================================================
--- gcc/config/arm/bpabi.S (revision 110445)
+++ gcc/config/arm/bpabi.S (working copy)
@@ -44,7 +44,8 @@
ARM_FUNC_START aeabi_lcmp
subs ip, xxl, yyl
sbcs ip, xxh, yyh
- subeqs ip, xxl, yyl
+ it eq
+ subseq ip, xxl, yyl
mov r0, ip
RET
FUNC_END aeabi_lcmp
@@ -55,12 +56,18 @@ ARM_FUNC_START aeabi_lcmp
ARM_FUNC_START aeabi_ulcmp
cmp xxh, yyh
+ it lo
movlo r0, #-1
+ it hi
movhi r0, #1
+ it ne
RETc(ne)
cmp xxl, yyl
+ it lo
movlo r0, #-1
+ it hi
movhi r0, #1
+ it eq
moveq r0, #0
RET
FUNC_END aeabi_ulcmp
@@ -71,11 +78,16 @@ ARM_FUNC_START aeabi_ulcmp
ARM_FUNC_START aeabi_ldivmod
sub sp, sp, #8
- stmfd sp!, {sp, lr}
+#if defined(__thumb2__)
+ mov ip, sp
+ push {ip, lr}
+#else
+ push {sp, lr}
+#endif
bl SYM(__gnu_ldivmod_helper) __PLT__
ldr lr, [sp, #4]
add sp, sp, #8
- ldmfd sp!, {r2, r3}
+ pop {r2, r3}
RET
#endif /* L_aeabi_ldivmod */
@@ -84,11 +96,16 @@ ARM_FUNC_START aeabi_ldivmod
ARM_FUNC_START aeabi_uldivmod
sub sp, sp, #8
- stmfd sp!, {sp, lr}
+#if defined(__thumb2__)
+ mov ip, sp
+ push {ip, lr}
+#else
+ push {sp, lr}
+#endif
bl SYM(__gnu_uldivmod_helper) __PLT__
ldr lr, [sp, #4]
add sp, sp, #8
- ldmfd sp!, {r2, r3}
+ pop {r2, r3}
RET
#endif /* L_aeabi_divmod */