diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2003-08-30 15:55:18 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2003-08-30 15:55:18 +0000 |
commit | 496b84c8edb6289c1e9e24c8c69ae2f63d1bcd13 (patch) | |
tree | 349af1b7d66c6e55be23a479deec8f89cb9d734b | |
parent | 88d032eb1ef92c51e155131e30ce8411673bdec6 (diff) | |
download | gcc-496b84c8edb6289c1e9e24c8c69ae2f63d1bcd13.zip gcc-496b84c8edb6289c1e9e24c8c69ae2f63d1bcd13.tar.gz gcc-496b84c8edb6289c1e9e24c8c69ae2f63d1bcd13.tar.bz2 |
lib1funcs.asm (RETCOND): Delete.
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.
Co-Authored-By: Nicolas Pitre <nico@cam.org>
From-SVN: r70949
-rw-r--r-- | gcc/ChangeLog | 32 | ||||
-rw-r--r-- | gcc/config/arm/ieee754-df.S | 285 | ||||
-rw-r--r-- | gcc/config/arm/ieee754-sf.S | 106 | ||||
-rw-r--r-- | gcc/config/arm/lib1funcs.asm | 183 | ||||
-rw-r--r-- | gcc/config/arm/t-arm-elf | 6 |
5 files changed, 288 insertions, 324 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fdabb62..59f4389 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,35 @@ +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. + 2003-08-29 Richard Henderson <rth@redhat.com> * tree-optimize.c: New file. diff --git a/gcc/config/arm/ieee754-df.S b/gcc/config/arm/ieee754-df.S index 9a00dce..2d5f487 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 88ded29..904b536 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 f587bc2..34cf986 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 7b0b867..1b8f719 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 |