aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-30 15:55:18 +0000
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-30 15:55:18 +0000
commit4d18cf6fecb88fd80dfca215a926f7c01df6668e (patch)
tree349af1b7d66c6e55be23a479deec8f89cb9d734b /gcc/config
parentd4e272bb7bde1d10e863ec5742cdbfaa46798a02 (diff)
2003-08-30 Richard Earnshaw <rearnsha@arm.com>
Nicolas Pitre <nico@cam.org> * arm/lib1funcs.asm (RETCOND): Delete. (RETLDM): New assembler macro. Use it for returning with ldm/ldr. (ARM_LDIV0, THUMB_LDIV0): Collapse multiple definitions. (__ARM_ARCH__): Move here from ieee754-?f.S. (RET, RETc): Clean up definitions. (DIV_FUNC_END): Renamed from FUNC_END. All uses changed. (FUNC_END): New macro that marks the end of any function. (ARM_FUNC_START): New macro that allows an assembler routine to be implemented in ARM code even if a Thumb-only build. Unconditionally include ieee754-?f.S. * arm/ieee754-df.S: Delete macros moved to lib1funcs.asm. Mark ends of functions. Split into separate conditionally-compiled units. Use RETLDM to return from routines. * arm/ieee754-sf.S: Similarly. * t-arm-elf (LIB1ASMFUNCS): Remove _ieee754_dp and _ieee754_sp. Add _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 _fixsfsi and _fixunssfsi. * arm/ieee754-df.S (__muldf3): Fix bug when result of a multiplication underflows to zero. (__adddf3): Fix bug when using VFP ordering on little-endian processors. (__fixdfsi): Use rrx to extract the carry into a register instead of MRS instruction. Optimize later use of result. * arm/ieee754-sf.S (__fixsfsi): Likewise. (__fixunssfsi): Use a better sequence for handling negative-or-zero. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70949 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/ieee754-df.S285
-rw-r--r--gcc/config/arm/ieee754-sf.S106
-rw-r--r--gcc/config/arm/lib1funcs.asm183
-rw-r--r--gcc/config/arm/t-arm-elf6
4 files changed, 256 insertions, 324 deletions
diff --git a/gcc/config/arm/ieee754-df.S b/gcc/config/arm/ieee754-df.S
index 9a00dcea25e..2d5f487ff60 100644
--- a/gcc/config/arm/ieee754-df.S
+++ b/gcc/config/arm/ieee754-df.S
@@ -40,33 +40,6 @@
* if necessary without impacting performances.
*/
-@ This selects the minimum architecture level required.
-#undef __ARM_ARCH__
-#define __ARM_ARCH__ 3
-
-#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
- || defined(__ARM_ARCH_4T__)
-#undef __ARM_ARCH__
-/* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
- long multiply instructions. That includes v3M. */
-#define __ARM_ARCH__ 4
-#endif
-
-#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
- || defined(__ARM_ARCH_5TE__)
-#undef __ARM_ARCH__
-#define __ARM_ARCH__ 5
-#endif
-
-#if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
-#undef RET
-#undef RETc
-#define RET bx lr
-#define RETc(x) bx##x lr
-#if (__ARM_ARCH__ == 4) && (defined(__thumb__) || defined(__THUMB_INTERWORK__))
-#define __FP_INTERWORKING__
-#endif
-#endif
@ For FPA, float words are always big-endian.
@ For VFP, floats words follow the memory system mode.
@@ -83,24 +56,19 @@
#endif
-#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
-.macro ARM_FUNC_START name
- FUNC_START \name
- bx pc
- nop
- .arm
-.endm
-#else
-.macro ARM_FUNC_START name
- FUNC_START \name
-.endm
-#endif
+#ifdef L_negdf2
ARM_FUNC_START negdf2
@ flip sign bit
eor xh, xh, #0x80000000
RET
+ FUNC_END negdf2
+
+#endif
+
+#ifdef L_addsubdf3
+
ARM_FUNC_START subdf3
@ flip sign bit of second arg
eor yh, yh, #0x80000000
@@ -155,12 +123,7 @@ ARM_FUNC_START adddf3
@ already in xh-xl. We need up to 54 bit to handle proper rounding
@ of 0x1p54 - 1.1.
cmp r5, #(54 << 20)
-#ifdef __FP_INTERWORKING__
- ldmhifd sp!, {r4, r5, lr}
- bxhi lr
-#else
- ldmhifd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5" hi
@ Convert mantissa to signed integer.
tst xh, #0x80000000
@@ -227,9 +190,9 @@ LSYM(Lad_x):
LSYM(Lad_p):
cmp xh, #0x00100000
bcc LSYM(Lad_l)
- cmp r0, #0x00200000
+ cmp xh, #0x00200000
bcc LSYM(Lad_r0)
- cmp r0, #0x00400000
+ cmp xh, #0x00400000
bcc LSYM(Lad_r1)
@ Result needs to be shifted right.
@@ -268,14 +231,10 @@ LSYM(Lad_e):
bic xh, xh, #0x00300000
orr xh, xh, r4
orr xh, xh, r5
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5"
-LSYM(Lad_l): @ Result must be shifted left and exponent adjusted.
+LSYM(Lad_l):
+ @ Result must be shifted left and exponent adjusted.
@ No rounding necessary since ip will always be 0.
#if __ARM_ARCH__ < 5
@@ -351,12 +310,7 @@ LSYM(Lad_l): @ Result must be shifted left and exponent adjusted.
mov xl, xl, lsr r4
orr xl, xl, xh, lsl r2
orr xh, r5, xh, lsr r4
-#ifdef __FP_INTERWORKING
- ldmfd sp!, {r4, r5, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, pc}RETCOND
-#endif
+ 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.
@@ -365,23 +319,13 @@ LSYM(Lad_l): @ Result must be shifted left and exponent adjusted.
mov xl, xl, lsr r2
orr xl, xl, xh, lsl r4
mov xh, r5
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, pc}RETCOND
-#endif
+ 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
mov xh, r5
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5"
@ Adjust exponents for denormalized arguments.
LSYM(Lad_d):
@@ -407,12 +351,7 @@ LSYM(Lad_o):
orr xh, r5, #0x7f000000
orr xh, xh, #0x00f00000
mov xl, #0
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5"
@ At least one of x or y is INF/NAN.
@ if xh-xl != INF/NAN: return yh-yl (which is INF/NAN)
@@ -425,24 +364,17 @@ LSYM(Lad_i):
movne xh, yh
movne xl, yl
teqeq r5, ip
-#ifdef __FP_INTERWORKING__
- ldmnefd sp!, {r4, r5, lr}
- bxne lr
-#else
- ldmnefd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5" ne
+
orrs r4, xl, xh, lsl #12
orreqs r4, yl, yh, lsl #12
teqeq xh, yh
orrne xh, r5, #0x00080000
movne xl, #0
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5"
+ FUNC_END subdf3
+ FUNC_END adddf3
ARM_FUNC_START floatunsidf
teq r0, #0
@@ -456,6 +388,7 @@ ARM_FUNC_START floatunsidf
mov xh, #0
b LSYM(Lad_l)
+ FUNC_END floatunsidf
ARM_FUNC_START floatsidf
teq r0, #0
@@ -470,6 +403,7 @@ ARM_FUNC_START floatsidf
mov xh, #0
b LSYM(Lad_l)
+ FUNC_END floatsidf
ARM_FUNC_START extendsfdf2
movs r2, r0, lsl #1
@@ -495,6 +429,11 @@ ARM_FUNC_START extendsfdf2
bic xh, xh, #0x80000000
b LSYM(Lad_l)
+ FUNC_END extendsfdf2
+
+#endif /* L_addsubdf3 */
+
+#ifdef L_muldivdf3
ARM_FUNC_START muldf3
@@ -656,12 +595,7 @@ LSYM(Lml_x):
@ Add final exponent.
bic xh, xh, #0x00300000
orr xh, xh, r4, lsl #1
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, r6, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ RETLDM "r4, r5, r6"
@ Result is 0, but determine sign anyway.
LSYM(Lml_z):
@@ -669,23 +603,14 @@ LSYM(Lml_z):
LSYM(Ldv_z):
bic xh, xh, #0x7fffffff
mov xl, #0
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, r6, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ RETLDM "r4, r5, r6"
@ Check if denormalized result is possible, otherwise return signed 0.
LSYM(Lml_u):
cmn r4, #(53 << 19)
movle xl, #0
-#ifdef __FP_INTERWORKING__
- ldmlefd sp!, {r4, r5, r6, lr}
- bxle lr
-#else
- ldmlefd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ bicle xh, xh, #0x7fffffff
+ RETLDM "r4, r5, r6" le
@ Find out proper shift value.
LSYM(Lml_r):
@@ -709,12 +634,7 @@ LSYM(Lml_r):
teq lr, #0
teqeq r3, #0x80000000
biceq xl, xl, #1
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, r6, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ RETLDM "r4, r5, r6"
@ shift result right of 21 to 31 bits, or left 11 to 1 bits after
@ a register switch from xh to xl. Then round.
@@ -729,12 +649,7 @@ LSYM(Lml_r):
teq lr, #0
teqeq r3, #0x80000000
biceq xl, xl, #1
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, r6, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ 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.
@@ -749,12 +664,7 @@ LSYM(Lml_r):
orrs r6, r6, lr
teqeq r3, #0x80000000
biceq xl, xl, #1
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, r6, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ RETLDM "r4, r5, r6"
@ One or both arguments are denormalized.
@ Scale them leftwards and preserve sign bit.
@@ -804,24 +714,15 @@ LSYM(Lml_o):
orr xh, xh, #0x7f000000
orr xh, xh, #0x00f00000
mov xl, #0
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, r6, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ RETLDM "r4, r5, r6"
@ Return NAN.
LSYM(Lml_n):
mov xh, #0x7f000000
orr xh, xh, #0x00f80000
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, r6, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ RETLDM "r4, r5, r6"
+ FUNC_END muldf3
ARM_FUNC_START divdf3
@@ -961,12 +862,7 @@ LSYM(Ldv_x):
@ Add exponent to result.
bic xh, xh, #0x00100000
orr xh, xh, r4, lsl #1
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, r6, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ RETLDM "r4, r5, r6"
@ Division by 0x1p*: shortcut a lot of code.
LSYM(Ldv_1):
@@ -978,12 +874,8 @@ LSYM(Ldv_1):
bge LSYM(Lml_o)
cmp r4, #0
orrgt xh, xh, r4, lsl #1
-#ifdef __FP_INTERWORKING__
- ldmgtfd sp!, {r4, r5, r6, lr}
- bxgt lr
-#else
- ldmgtfd sp!, {r4, r5, r6, pc}RETCOND
-#endif
+ RETLDM "r4, r5, r6" gt
+
cmn r4, #(53 << 19)
ble LSYM(Ldv_z)
orr xh, xh, #0x00100000
@@ -1042,6 +934,11 @@ LSYM(Ldv_s):
bne LSYM(Lml_z) @ 0 / <non_zero> -> 0
b LSYM(Lml_n) @ 0 / 0 -> NAN
+ FUNC_END divdf3
+
+#endif /* L_muldivdf3 */
+
+#ifdef L_cmpdf2
FUNC_START gedf2
ARM_FUNC_START gtdf2
@@ -1076,23 +973,13 @@ ARM_FUNC_START cmpdf2
teqne xh, yh @ or xh == yh
teqeq xl, yl @ and xl == yl
moveq r0, #0 @ then equal.
-#ifdef __FP_INTERWORKING__
- ldmeqfd sp!, {r4, r5, lr}
- bxeq lr
-#else
- ldmeqfd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5" eq
@ Check for sign difference.
teq xh, yh
movmi r0, xh, asr #31
orrmi r0, r0, #1
-#ifdef __FP_INTERWORKING__
- ldmmifd sp!, {r4, r5, lr}
- bxmi lr
-#else
- ldmmifd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5" mi
@ Compare exponents.
cmp r4, r5
@@ -1104,12 +991,7 @@ ARM_FUNC_START cmpdf2
movcs r0, yh, asr #31
mvncc r0, yh, asr #31
orr r0, r0, #1
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5"
@ Look for a NAN.
3: teq r4, lr
@@ -1121,13 +1003,19 @@ ARM_FUNC_START cmpdf2
orrs yl, yl, yh, lsl #12
beq 2b @ y is not NAN
5: mov r0, ip @ return unordered code from ip
-#ifdef __FP_INTERWORKING__
- ldmfd sp!, {r4, r5, lr}
- bx lr
-#else
- ldmfd sp!, {r4, r5, pc}RETCOND
-#endif
+ RETLDM "r4, r5"
+ FUNC_END gedf2
+ FUNC_END gtdf2
+ FUNC_END ledf2
+ FUNC_END ltdf2
+ FUNC_END nedf2
+ FUNC_END eqdf2
+ FUNC_END cmpdf2
+
+#endif /* L_cmpdf2 */
+
+#ifdef L_unorddf2
ARM_FUNC_START unorddf2
str lr, [sp, #-4]!
@@ -1144,35 +1032,22 @@ ARM_FUNC_START unorddf2
orrs yl, yl, yh, lsl #12
bne 3f @ y is NAN
2: mov r0, #0 @ arguments are ordered.
-#ifdef __FP_INTERWORKING__
- ldr lr, [sp], #4
- bx lr
-#elif defined (__APCS_26__)
- ldmia sp!, {pc}^
-#else
- ldr pc, [sp], #4
-#endif
+ RETLDM
+
3: mov r0, #1 @ arguments are unordered.
-#ifdef __FP_INTERWORKING__
- ldr lr, [sp], #4
- bx lr
-#elif defined (__APCS_26__)
- ldmia sp!, {pc}^
-#else
- ldr pc, [sp], #4
-#endif
+ RETLDM
+
+ FUNC_END unorddf2
+#endif /* L_unorddf2 */
+
+#ifdef L_fixdfsi
ARM_FUNC_START fixdfsi
orrs ip, xl, xh, lsl #1
beq 1f @ value is 0.
- @ preserve C flag (the actual sign)
-#ifdef __APCS_26__
- mov r3, pc
-#else
- mrs r3, cpsr
-#endif
+ mov r3, r3, rrx @ preserve C flag (the actual sign)
@ check exponent range.
mov ip, #0x7f000000
@@ -1192,8 +1067,8 @@ ARM_FUNC_START fixdfsi
orr ip, ip, #0x80000000
orr ip, ip, xl, lsr #21
mov r2, r2, lsr #20
+ tst r3, #0x80000000 @ the sign bit
mov r0, ip, lsr r2
- tst r3, #0x20000000 @ the sign bit
rsbne r0, r0, #0
RET
@@ -1202,18 +1077,19 @@ ARM_FUNC_START fixdfsi
2: orrs xl, xl, xh, lsl #12
bne 4f @ r0 is NAN.
-3: tst r3, #0x20000000 @ the sign bit
+3: ands r0, r3, #0x80000000 @ the sign bit
moveq r0, #0x7fffffff @ maximum signed positive si
- movne r0, #0x80000000 @ maximum signed negative si
RET
4: mov r0, #0 @ How should we convert NAN?
RET
+ FUNC_END fixdfsi
+
ARM_FUNC_START fixunsdfsi
orrs ip, xl, xh, lsl #1
- beq 1b @ value is 0
- bcs 1b @ value is negative
+ movcss r0, #0 @ value is negative
+ RETc(eq) @ or 0 (xl, xh overlap r0)
@ check exponent range.
mov ip, #0x7f000000
@@ -1241,6 +1117,11 @@ ARM_FUNC_START fixunsdfsi
2: mov r0, #0xffffffff @ maximum unsigned si
RET
+ FUNC_END fixunsdfsi
+
+#endif /* L_fixunsdfdi */
+
+#ifdef L_truncdfsf2
ARM_FUNC_START truncdfsf2
orrs r2, xl, xh, lsl #1
@@ -1328,4 +1209,6 @@ ARM_FUNC_START truncdfsf2
and xh, xh, #0x80000000
b 5b
+ FUNC_END truncdfsf2
+#endif /* L_truncdfsf2 */
diff --git a/gcc/config/arm/ieee754-sf.S b/gcc/config/arm/ieee754-sf.S
index 88ded2931bf..904b536f2ff 100644
--- a/gcc/config/arm/ieee754-sf.S
+++ b/gcc/config/arm/ieee754-sf.S
@@ -38,50 +38,17 @@
* if necessary without impacting performances.
*/
-@ This selects the minimum architecture level required.
-#undef __ARM_ARCH__
-#define __ARM_ARCH__ 3
-
-#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
- || defined(__ARM_ARCH_4T__)
-#undef __ARM_ARCH__
-/* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
- long multiply instructions. That includes v3M. */
-#define __ARM_ARCH__ 4
-#endif
+#ifdef L_negsf2
-#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
- || defined(__ARM_ARCH_5TE__)
-#undef __ARM_ARCH__
-#define __ARM_ARCH__ 5
-#endif
+ARM_FUNC_START negsf2
+ eor r0, r0, #0x80000000 @ flip sign bit
+ RET
-#if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
-#undef RET
-#undef RETc
-#define RET bx lr
-#define RETc(x) bx##x lr
-#if (__ARM_ARCH__ == 4) && (defined(__thumb__) || defined(__THUMB_INTERWORK__))
-#define __FP_INTERWORKING__
-#endif
-#endif
+ FUNC_END negsf2
-#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
-.macro ARM_FUNC_START name
- FUNC_START \name
- bx pc
- nop
- .arm
-.endm
-#else
-.macro ARM_FUNC_START name
- FUNC_START \name
-.endm
#endif
-ARM_FUNC_START negsf2
- eor r0, r0, #0x80000000 @ flip sign bit
- RET
+#ifdef L_addsubsf3
ARM_FUNC_START subsf3
eor r1, r1, #0x80000000 @ flip sign bit of second arg
@@ -291,6 +258,8 @@ LSYM(Lad_i):
orrne r0, r3, #0x00400000 @ NAN
RET
+ FUNC_END addsf3
+ FUNC_END subsf3
ARM_FUNC_START floatunsisf
mov r3, #0
@@ -321,6 +290,12 @@ ARM_FUNC_START floatsisf
add r2, r2, #(2 << 23)
b LSYM(Lad_p)
+ FUNC_END floatsisf
+ FUNC_END floatunsisf
+
+#endif /* L_addsubsf3 */
+
+#ifdef L_muldivsf3
ARM_FUNC_START mulsf3
@@ -509,6 +484,7 @@ LSYM(Lml_n):
orr r0, r0, #0x00c00000
RET
+ FUNC_END mulsf3
ARM_FUNC_START divsf3
@@ -659,6 +635,11 @@ LSYM(Ldv_s):
bne LSYM(Lml_z) @ 0 / <non_zero> -> 0
b LSYM(Lml_n) @ 0 / 0 -> NAN
+ FUNC_END divsf3
+
+#endif /* L_muldivsf3 */
+
+#ifdef L_cmpsf2
FUNC_START gesf2
ARM_FUNC_START gtsf2
@@ -723,6 +704,17 @@ ARM_FUNC_START cmpsf2
5: mov r0, r3 @ return unordered code from r3.
RET
+ FUNC_END gesf2
+ FUNC_END gtsf2
+ FUNC_END lesf2
+ FUNC_END ltsf2
+ FUNC_END nesf2
+ FUNC_END eqsf2
+ FUNC_END cmpsf2
+
+#endif /* L_cmpsf2 */
+
+#ifdef L_unordsf2
ARM_FUNC_START unordsf2
mov ip, #0xff000000
@@ -741,16 +733,17 @@ ARM_FUNC_START unordsf2
3: mov r0, #1 @ arguments are unordered.
RET
+ FUNC_END unordsf2
+
+#endif /* L_unordsf2 */
+
+#ifdef L_fixsfsi
ARM_FUNC_START fixsfsi
movs r0, r0, lsl #1
RETc(eq) @ value is 0.
- @ preserve C flag (the actual sign)
-#ifdef __APCS_26__
- mov r1, pc
-#else
- mrs r1, cpsr
-#endif
+
+ mov r1, r1, rrx @ preserve C flag (the actual sign)
@ check exponent range.
and r2, r0, #0xff000000
@@ -764,8 +757,8 @@ ARM_FUNC_START fixsfsi
orr r0, r0, #0x80000000
mov r2, r2, lsr #24
rsb r2, r2, #(127 + 31)
+ tst r1, #0x80000000 @ the sign bit
mov r0, r0, lsr r2
- tst r1, #0x20000000 @ the sign bit
rsbne r0, r0, #0
RET
@@ -773,20 +766,24 @@ ARM_FUNC_START fixsfsi
bne 2f
movs r0, r0, lsl #8
bne 3f @ r0 is NAN.
-2: tst r1, #0x20000000 @ the sign bit
+2: ands r0, r1, #0x80000000 @ the sign bit
moveq r0, #0x7fffffff @ the maximum signed positive si
- movne r0, #0x80000000 @ the maximum signed negative si
RET
3: mov r0, #0 @ What should we convert NAN to?
RET
+ FUNC_END fixsfsi
+
+#endif /* L_fixsfsi */
+
+#ifdef L_fixunssfsi
ARM_FUNC_START fixunssfsi
movs r0, r0, lsl #1
- RETc(eq) @ value is 0.
- movcs r0, #0
- RETc(cs) @ value is negative.
+ movcss r0, #0 @ value is negative...
+ RETc(eq) @ ... or 0.
+
@ check exponent range.
and r2, r0, #0xff000000
@@ -806,8 +803,13 @@ ARM_FUNC_START fixunssfsi
1: teq r2, #0xff000000
bne 2f
movs r0, r0, lsl #8
- bne 3b @ r0 is NAN.
+ bne 3f @ r0 is NAN.
2: mov r0, #0xffffffff @ maximum unsigned si
RET
+3: mov r0, #0 @ What should we convert NAN to?
+ RET
+
+ FUNC_END fixunssfsi
+#endif /* L_fixunssfsi */
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
index f587bc2969e..34cf986d03e 100644
--- a/gcc/config/arm/lib1funcs.asm
+++ b/gcc/config/arm/lib1funcs.asm
@@ -61,66 +61,107 @@ Boston, MA 02111-1307, USA. */
/* Function end macros. Variants for 26 bit APCS and interworking. */
+@ This selects the minimum architecture level required.
+#define __ARM_ARCH__ 3
+
+#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
+ || defined(__ARM_ARCH_4T__)
+/* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
+ long multiply instructions. That includes v3M. */
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 4
+#endif
+
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+ || defined(__ARM_ARCH_5TE__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 5
+#endif
+
+/* How to return from a function call depends on the architecture variant. */
+
#ifdef __APCS_26__
+
# define RET movs pc, lr
# define RETc(x) mov##x##s pc, lr
-# define RETCOND ^
+
+#elif (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
+
+# define RET bx lr
+# define RETc(x) bx##x lr
+
+# if (__ARM_ARCH__ == 4) \
+ && (defined(__thumb__) || defined(__THUMB_INTERWORK__))
+# define __INTERWORKING__
+# endif
+
+#else
+
+# define RET mov pc, lr
+# define RETc(x) mov##x pc, lr
+
+#endif
+
+/* Don't pass dirn, it's there just to get token pasting right. */
+
+.macro RETLDM regs=, cond=, dirn=ia
+#ifdef __APCS_26__
+ .ifc "\regs",""
+ ldm\cond\dirn sp!, {pc}^
+ .else
+ ldm\cond\dirn sp!, {\regs, pc}^
+ .endif
+#elif defined (__INTERWORKING__)
+ .ifc "\regs",""
+ ldr\cond lr, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, lr}
+ .endif
+ bx\cond lr
+#else
+ .ifc "\regs",""
+ ldr\cond pc, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, pc}
+ .endif
+#endif
+.endm
+
+
.macro ARM_LDIV0
LSYM(Ldiv0):
str lr, [sp, #-4]!
bl SYM (__div0) __PLT__
mov r0, #0 @ About as wrong as it could be.
- ldmia sp!, {pc}^
+ RETLDM
.endm
-#else
-# ifdef __THUMB_INTERWORK__
-# define RET bx lr
-# define RETc(x) bx##x lr
+
+
.macro THUMB_LDIV0
LSYM(Ldiv0):
push { lr }
bl SYM (__div0)
mov r0, #0 @ About as wrong as it could be.
+#if defined (__INTERWORKING__)
pop { r1 }
bx r1
-.endm
-.macro ARM_LDIV0
-LSYM(Ldiv0):
- str lr, [sp, #-4]!
- bl SYM (__div0) __PLT__
- mov r0, #0 @ About as wrong as it could be.
- ldr lr, [sp], #4
- bx lr
-.endm
-# else
-# define RET mov pc, lr
-# define RETc(x) mov##x pc, lr
-.macro THUMB_LDIV0
-LSYM(Ldiv0):
- push { lr }
- bl SYM (__div0)
- mov r0, #0 @ About as wrong as it could be.
+#else
pop { pc }
-.endm
-.macro ARM_LDIV0
-LSYM(Ldiv0):
- str lr, [sp, #-4]!
- bl SYM (__div0) __PLT__
- mov r0, #0 @ About as wrong as it could be.
- ldmia sp!, {pc}
-.endm
-# endif
-# define RETCOND
#endif
+.endm
.macro FUNC_END name
+ SIZE (__\name)
+.endm
+
+.macro DIV_FUNC_END name
LSYM(Ldiv0):
#ifdef __thumb__
THUMB_LDIV0
#else
ARM_LDIV0
#endif
- SIZE (__\name)
+ FUNC_END \name
.endm
.macro THUMB_FUNC_START name
@@ -149,7 +190,24 @@ SYM (\name):
THUMB_FUNC
SYM (__\name):
.endm
-
+
+/* Special function that will always be coded in ARM assembly, even if
+ in Thumb-only compilation. */
+
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+.macro ARM_FUNC_START name
+ FUNC_START \name
+ bx pc
+ nop
+ .arm
+_L__\name: /* A hook to tell gdb that we've switched to ARM */
+.endm
+#else
+.macro ARM_FUNC_START name
+ FUNC_START \name
+.endm
+#endif
+
/* Register aliases. */
work .req r4 @ XXXX is this safe ?
@@ -452,7 +510,7 @@ LSYM(Lgot_result):
#endif /* ARM version */
- FUNC_END udivsi3
+ DIV_FUNC_END udivsi3
#endif /* L_udivsi3 */
/* ------------------------------------------------------------------------ */
@@ -493,7 +551,7 @@ LSYM(Lover10):
#endif /* ARM version. */
- FUNC_END umodsi3
+ DIV_FUNC_END umodsi3
#endif /* L_umodsi3 */
/* ------------------------------------------------------------------------ */
@@ -555,7 +613,7 @@ LSYM(Lover12):
#endif /* ARM version */
- FUNC_END divsi3
+ DIV_FUNC_END divsi3
#endif /* L_divsi3 */
/* ------------------------------------------------------------------------ */
@@ -616,7 +674,7 @@ LSYM(Lover12):
#endif /* ARM version */
- FUNC_END modsi3
+ DIV_FUNC_END modsi3
#endif /* L_modsi3 */
/* ------------------------------------------------------------------------ */
@@ -626,7 +684,7 @@ LSYM(Lover12):
RET
- SIZE (__div0)
+ FUNC_END div0
#endif /* L_divmodsi_tools */
/* ------------------------------------------------------------------------ */
@@ -639,22 +697,18 @@ LSYM(Lover12):
#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
#define __NR_kill (__NR_SYSCALL_BASE+ 37)
+ .code 32
FUNC_START div0
stmfd sp!, {r1, lr}
swi __NR_getpid
cmn r0, #1000
- ldmhsfd sp!, {r1, pc}RETCOND @ not much we can do
+ RETLDM r1 hs
mov r1, #SIGFPE
swi __NR_kill
-#ifdef __THUMB_INTERWORK__
- ldmfd sp!, {r1, lr}
- bx lr
-#else
- ldmfd sp!, {r1, pc}RETCOND
-#endif
+ RETLDM r1
- SIZE (__div0)
+ FUNC_END div0
#endif /* L_dvmd_lnx */
/* ------------------------------------------------------------------------ */
@@ -723,24 +777,23 @@ LSYM(Lover12):
.code 32
.globl _arm_return
-_arm_return:
- ldmia r13!, {r12}
- bx r12
+_arm_return:
+ RETLDM
.code 16
-.macro interwork register
- .code 16
+.macro interwork register
+ .code 16
THUMB_FUNC_START _interwork_call_via_\register
- bx pc
+ bx pc
nop
-
- .code 32
- .globl .Lchange_\register
-.Lchange_\register:
+
+ .code 32
+ .globl LSYM(Lchange_\register)
+LSYM(Lchange_\register):
tst \register, #1
- stmeqdb r13!, {lr}
+ streq lr, [sp, #-4]!
adreq lr, _arm_return
bx \register
@@ -783,16 +836,6 @@ _arm_return:
#endif /* L_interwork_call_via_rX */
-#ifdef L_ieee754_dp
- /* These functions are coded in ARM state, even when called from
- Thumb. */
- .arm
#include "ieee754-df.S"
-#endif
-
-#ifdef L_ieee754_sp
- /* These functions are coded in ARM state, even when called from
- Thumb. */
- .arm
#include "ieee754-sf.S"
-#endif
+
diff --git a/gcc/config/arm/t-arm-elf b/gcc/config/arm/t-arm-elf
index 7b0b86754d4..1b8f719b949 100644
--- a/gcc/config/arm/t-arm-elf
+++ b/gcc/config/arm/t-arm-elf
@@ -1,5 +1,9 @@
LIB1ASMSRC = arm/lib1funcs.asm
-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func _call_via_rX _interwork_call_via_rX _ieee754_dp _ieee754_sp
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func \
+ _call_via_rX _interwork_call_via_rX \
+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi \
+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
+ _fixsfsi _fixunssfsi
MULTILIB_OPTIONS = marm/mthumb
MULTILIB_DIRNAMES = arm thumb