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>
* tree-optimize.c: New file.
......
......@@ -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 */
......@@ -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 ^
.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
#else
# ifdef __THUMB_INTERWORK__
#elif (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
# 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.
pop { r1 }
bx r1
# 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.
ldr lr, [sp], #4
bx lr
RETLDM
.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.
#if defined (__INTERWORKING__)
pop { r1 }
bx r1
#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
......@@ -150,6 +191,23 @@ SYM (\name):
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 */
/* ------------------------------------------------------------------------ */
......@@ -724,8 +778,7 @@ LSYM(Lover12):
.code 32
.globl _arm_return
_arm_return:
ldmia r13!, {r12}
bx r12
RETLDM
.code 16
.macro interwork register
......@@ -737,10 +790,10 @@ _arm_return:
nop
.code 32
.globl .Lchange_\register
.Lchange_\register:
.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
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
......
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