Commit 496b84c8 by Richard Earnshaw Committed by Richard Earnshaw

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
parent 88d032eb
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> 2003-08-29 Richard Henderson <rth@redhat.com>
* tree-optimize.c: New file. * tree-optimize.c: New file.
......
...@@ -38,50 +38,17 @@ ...@@ -38,50 +38,17 @@
* if necessary without impacting performances. * if necessary without impacting performances.
*/ */
@ This selects the minimum architecture level required. #ifdef L_negsf2
#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__) \ ARM_FUNC_START negsf2
|| defined(__ARM_ARCH_5TE__) eor r0, r0, #0x80000000 @ flip sign bit
#undef __ARM_ARCH__ RET
#define __ARM_ARCH__ 5
#endif
#if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__) FUNC_END negsf2
#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
#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 #endif
ARM_FUNC_START negsf2 #ifdef L_addsubsf3
eor r0, r0, #0x80000000 @ flip sign bit
RET
ARM_FUNC_START subsf3 ARM_FUNC_START subsf3
eor r1, r1, #0x80000000 @ flip sign bit of second arg eor r1, r1, #0x80000000 @ flip sign bit of second arg
...@@ -291,6 +258,8 @@ LSYM(Lad_i): ...@@ -291,6 +258,8 @@ LSYM(Lad_i):
orrne r0, r3, #0x00400000 @ NAN orrne r0, r3, #0x00400000 @ NAN
RET RET
FUNC_END addsf3
FUNC_END subsf3
ARM_FUNC_START floatunsisf ARM_FUNC_START floatunsisf
mov r3, #0 mov r3, #0
...@@ -321,6 +290,12 @@ ARM_FUNC_START floatsisf ...@@ -321,6 +290,12 @@ ARM_FUNC_START floatsisf
add r2, r2, #(2 << 23) add r2, r2, #(2 << 23)
b LSYM(Lad_p) b LSYM(Lad_p)
FUNC_END floatsisf
FUNC_END floatunsisf
#endif /* L_addsubsf3 */
#ifdef L_muldivsf3
ARM_FUNC_START mulsf3 ARM_FUNC_START mulsf3
...@@ -509,6 +484,7 @@ LSYM(Lml_n): ...@@ -509,6 +484,7 @@ LSYM(Lml_n):
orr r0, r0, #0x00c00000 orr r0, r0, #0x00c00000
RET RET
FUNC_END mulsf3
ARM_FUNC_START divsf3 ARM_FUNC_START divsf3
...@@ -659,6 +635,11 @@ LSYM(Ldv_s): ...@@ -659,6 +635,11 @@ LSYM(Ldv_s):
bne LSYM(Lml_z) @ 0 / <non_zero> -> 0 bne LSYM(Lml_z) @ 0 / <non_zero> -> 0
b LSYM(Lml_n) @ 0 / 0 -> NAN b LSYM(Lml_n) @ 0 / 0 -> NAN
FUNC_END divsf3
#endif /* L_muldivsf3 */
#ifdef L_cmpsf2
FUNC_START gesf2 FUNC_START gesf2
ARM_FUNC_START gtsf2 ARM_FUNC_START gtsf2
...@@ -723,6 +704,17 @@ ARM_FUNC_START cmpsf2 ...@@ -723,6 +704,17 @@ ARM_FUNC_START cmpsf2
5: mov r0, r3 @ return unordered code from r3. 5: mov r0, r3 @ return unordered code from r3.
RET 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 ARM_FUNC_START unordsf2
mov ip, #0xff000000 mov ip, #0xff000000
...@@ -741,16 +733,17 @@ ARM_FUNC_START unordsf2 ...@@ -741,16 +733,17 @@ ARM_FUNC_START unordsf2
3: mov r0, #1 @ arguments are unordered. 3: mov r0, #1 @ arguments are unordered.
RET RET
FUNC_END unordsf2
#endif /* L_unordsf2 */
#ifdef L_fixsfsi
ARM_FUNC_START fixsfsi ARM_FUNC_START fixsfsi
movs r0, r0, lsl #1 movs r0, r0, lsl #1
RETc(eq) @ value is 0. RETc(eq) @ value is 0.
@ preserve C flag (the actual sign)
#ifdef __APCS_26__ mov r1, r1, rrx @ preserve C flag (the actual sign)
mov r1, pc
#else
mrs r1, cpsr
#endif
@ check exponent range. @ check exponent range.
and r2, r0, #0xff000000 and r2, r0, #0xff000000
...@@ -764,8 +757,8 @@ ARM_FUNC_START fixsfsi ...@@ -764,8 +757,8 @@ ARM_FUNC_START fixsfsi
orr r0, r0, #0x80000000 orr r0, r0, #0x80000000
mov r2, r2, lsr #24 mov r2, r2, lsr #24
rsb r2, r2, #(127 + 31) rsb r2, r2, #(127 + 31)
tst r1, #0x80000000 @ the sign bit
mov r0, r0, lsr r2 mov r0, r0, lsr r2
tst r1, #0x20000000 @ the sign bit
rsbne r0, r0, #0 rsbne r0, r0, #0
RET RET
...@@ -773,20 +766,24 @@ ARM_FUNC_START fixsfsi ...@@ -773,20 +766,24 @@ ARM_FUNC_START fixsfsi
bne 2f bne 2f
movs r0, r0, lsl #8 movs r0, r0, lsl #8
bne 3f @ r0 is NAN. 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 moveq r0, #0x7fffffff @ the maximum signed positive si
movne r0, #0x80000000 @ the maximum signed negative si
RET RET
3: mov r0, #0 @ What should we convert NAN to? 3: mov r0, #0 @ What should we convert NAN to?
RET RET
FUNC_END fixsfsi
#endif /* L_fixsfsi */
#ifdef L_fixunssfsi
ARM_FUNC_START fixunssfsi ARM_FUNC_START fixunssfsi
movs r0, r0, lsl #1 movs r0, r0, lsl #1
RETc(eq) @ value is 0. movcss r0, #0 @ value is negative...
movcs r0, #0 RETc(eq) @ ... or 0.
RETc(cs) @ value is negative.
@ check exponent range. @ check exponent range.
and r2, r0, #0xff000000 and r2, r0, #0xff000000
...@@ -806,8 +803,13 @@ ARM_FUNC_START fixunssfsi ...@@ -806,8 +803,13 @@ ARM_FUNC_START fixunssfsi
1: teq r2, #0xff000000 1: teq r2, #0xff000000
bne 2f bne 2f
movs r0, r0, lsl #8 movs r0, r0, lsl #8
bne 3b @ r0 is NAN. bne 3f @ r0 is NAN.
2: mov r0, #0xffffffff @ maximum unsigned si 2: mov r0, #0xffffffff @ maximum unsigned si
RET RET
3: mov r0, #0 @ What should we convert NAN to?
RET
FUNC_END fixunssfsi
#endif /* L_fixunssfsi */
...@@ -61,66 +61,107 @@ Boston, MA 02111-1307, USA. */ ...@@ -61,66 +61,107 @@ Boston, MA 02111-1307, USA. */
/* Function end macros. Variants for 26 bit APCS and interworking. */ /* 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__ #ifdef __APCS_26__
# define RET movs pc, lr # define RET movs pc, lr
# define RETc(x) mov##x##s pc, lr # define RETc(x) mov##x##s pc, lr
# define RETCOND ^
.macro ARM_LDIV0 #elif (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
LSYM(Ldiv0):
str lr, [sp, #-4]!
bl SYM (__div0) __PLT__
mov r0, #0 @ About as wrong as it could be.
ldmia sp!, {pc}^
.endm
#else
# ifdef __THUMB_INTERWORK__
# define RET bx lr # define RET bx lr
# define RETc(x) bx##x lr # define RETc(x) bx##x lr
.macro THUMB_LDIV0
LSYM(Ldiv0): # if (__ARM_ARCH__ == 4) \
push { lr } && (defined(__thumb__) || defined(__THUMB_INTERWORK__))
bl SYM (__div0) # define __INTERWORKING__
mov r0, #0 @ About as wrong as it could be. # endif
pop { r1 }
bx r1 #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 .endm
.macro ARM_LDIV0 .macro ARM_LDIV0
LSYM(Ldiv0): LSYM(Ldiv0):
str lr, [sp, #-4]! str lr, [sp, #-4]!
bl SYM (__div0) __PLT__ bl SYM (__div0) __PLT__
mov r0, #0 @ About as wrong as it could be. mov r0, #0 @ About as wrong as it could be.
ldr lr, [sp], #4 RETLDM
bx lr
.endm .endm
# else
# define RET mov pc, lr
# define RETc(x) mov##x pc, lr
.macro THUMB_LDIV0 .macro THUMB_LDIV0
LSYM(Ldiv0): LSYM(Ldiv0):
push { lr } push { lr }
bl SYM (__div0) bl SYM (__div0)
mov r0, #0 @ About as wrong as it could be. mov r0, #0 @ About as wrong as it could be.
#if defined (__INTERWORKING__)
pop { r1 }
bx r1
#else
pop { pc } 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 #endif
.endm
.macro FUNC_END name .macro FUNC_END name
SIZE (__\name)
.endm
.macro DIV_FUNC_END name
LSYM(Ldiv0): LSYM(Ldiv0):
#ifdef __thumb__ #ifdef __thumb__
THUMB_LDIV0 THUMB_LDIV0
#else #else
ARM_LDIV0 ARM_LDIV0
#endif #endif
SIZE (__\name) FUNC_END \name
.endm .endm
.macro THUMB_FUNC_START name .macro THUMB_FUNC_START name
...@@ -150,6 +191,23 @@ SYM (\name): ...@@ -150,6 +191,23 @@ SYM (\name):
SYM (__\name): SYM (__\name):
.endm .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. */ /* Register aliases. */
work .req r4 @ XXXX is this safe ? work .req r4 @ XXXX is this safe ?
...@@ -452,7 +510,7 @@ LSYM(Lgot_result): ...@@ -452,7 +510,7 @@ LSYM(Lgot_result):
#endif /* ARM version */ #endif /* ARM version */
FUNC_END udivsi3 DIV_FUNC_END udivsi3
#endif /* L_udivsi3 */ #endif /* L_udivsi3 */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
...@@ -493,7 +551,7 @@ LSYM(Lover10): ...@@ -493,7 +551,7 @@ LSYM(Lover10):
#endif /* ARM version. */ #endif /* ARM version. */
FUNC_END umodsi3 DIV_FUNC_END umodsi3
#endif /* L_umodsi3 */ #endif /* L_umodsi3 */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
...@@ -555,7 +613,7 @@ LSYM(Lover12): ...@@ -555,7 +613,7 @@ LSYM(Lover12):
#endif /* ARM version */ #endif /* ARM version */
FUNC_END divsi3 DIV_FUNC_END divsi3
#endif /* L_divsi3 */ #endif /* L_divsi3 */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
...@@ -616,7 +674,7 @@ LSYM(Lover12): ...@@ -616,7 +674,7 @@ LSYM(Lover12):
#endif /* ARM version */ #endif /* ARM version */
FUNC_END modsi3 DIV_FUNC_END modsi3
#endif /* L_modsi3 */ #endif /* L_modsi3 */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
...@@ -626,7 +684,7 @@ LSYM(Lover12): ...@@ -626,7 +684,7 @@ LSYM(Lover12):
RET RET
SIZE (__div0) FUNC_END div0
#endif /* L_divmodsi_tools */ #endif /* L_divmodsi_tools */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
...@@ -639,22 +697,18 @@ LSYM(Lover12): ...@@ -639,22 +697,18 @@ LSYM(Lover12):
#define __NR_getpid (__NR_SYSCALL_BASE+ 20) #define __NR_getpid (__NR_SYSCALL_BASE+ 20)
#define __NR_kill (__NR_SYSCALL_BASE+ 37) #define __NR_kill (__NR_SYSCALL_BASE+ 37)
.code 32
FUNC_START div0 FUNC_START div0
stmfd sp!, {r1, lr} stmfd sp!, {r1, lr}
swi __NR_getpid swi __NR_getpid
cmn r0, #1000 cmn r0, #1000
ldmhsfd sp!, {r1, pc}RETCOND @ not much we can do RETLDM r1 hs
mov r1, #SIGFPE mov r1, #SIGFPE
swi __NR_kill swi __NR_kill
#ifdef __THUMB_INTERWORK__ RETLDM r1
ldmfd sp!, {r1, lr}
bx lr
#else
ldmfd sp!, {r1, pc}RETCOND
#endif
SIZE (__div0) FUNC_END div0
#endif /* L_dvmd_lnx */ #endif /* L_dvmd_lnx */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
...@@ -724,8 +778,7 @@ LSYM(Lover12): ...@@ -724,8 +778,7 @@ LSYM(Lover12):
.code 32 .code 32
.globl _arm_return .globl _arm_return
_arm_return: _arm_return:
ldmia r13!, {r12} RETLDM
bx r12
.code 16 .code 16
.macro interwork register .macro interwork register
...@@ -737,10 +790,10 @@ _arm_return: ...@@ -737,10 +790,10 @@ _arm_return:
nop nop
.code 32 .code 32
.globl .Lchange_\register .globl LSYM(Lchange_\register)
.Lchange_\register: LSYM(Lchange_\register):
tst \register, #1 tst \register, #1
stmeqdb r13!, {lr} streq lr, [sp, #-4]!
adreq lr, _arm_return adreq lr, _arm_return
bx \register bx \register
...@@ -783,16 +836,6 @@ _arm_return: ...@@ -783,16 +836,6 @@ _arm_return:
#endif /* L_interwork_call_via_rX */ #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" #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" #include "ieee754-sf.S"
#endif
LIB1ASMSRC = arm/lib1funcs.asm 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_OPTIONS = marm/mthumb
MULTILIB_DIRNAMES = arm thumb MULTILIB_DIRNAMES = arm thumb
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment