OSDN Git Service

2003-08-30 Richard Earnshaw <rearnsha@arm.com>
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 30 Aug 2003 15:55:18 +0000 (15:55 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 30 Aug 2003 15:55:18 +0000 (15:55 +0000)
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

gcc/ChangeLog
gcc/config/arm/ieee754-df.S
gcc/config/arm/ieee754-sf.S
gcc/config/arm/lib1funcs.asm
gcc/config/arm/t-arm-elf

index fdabb62..59f4389 100644 (file)
@@ -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.
index 9a00dce..2d5f487 100644 (file)
  * 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.
 #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 */
index 88ded29..904b536 100644 (file)
  * 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 */
index f587bc2..34cf986 100644 (file)
@@ -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
+
index 7b0b867..1b8f719 100644 (file)
@@ -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