diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-11 02:50:14 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-11 02:50:14 +0000 |
commit | 30e9913fe6eb2f1c2519cfeacdf9100ccb26cbb7 (patch) | |
tree | 8ecb27f99fc899aec528b0cc2ea297f10080750c /gcc/config/arm/ieee754-sf.S | |
parent | e042bf99fa1f08ea70f276bd0b65ebade5c10aba (diff) | |
download | gcc-30e9913fe6eb2f1c2519cfeacdf9100ccb26cbb7.tar.gz |
* configure.in (arm*-*-eabi*): New target.
* configure: Regenerate.
* configure.ac (arm*-*-eabi*): New target.
(arm*-*-symbianelf*): Likewise.
* configure: Regenerated.
* config.gcc (arm*-*-eabi*): New target.
* defaults.h (TARGET_LIBGCC_FUNCS): New macro.
(TARGET_LIB_INT_CMP_BIASED): Likewise.
* expmed.c (expand_divmod): Try a two-valued divmod function as a
last resort.
* gthr.h: Remove bogus tokens at end of #pragma.
* optabs.c (expand_twoval_binop_libfunc): New function.
(prepare_cmp_insn): Handle the !TARGET_LIB_INT_CMP_BIASED case.
(prepare_float_lib_cmp): Try reversing the condition.
(debug_optab_libfuncs): New function.
* optabs.h (expand_twoval_binop_libfunc): Declare.
* config/arm/arm.c (arm_init_libfuncs): New function.
(arm_compute_initial_eliminatino_offset): Return HOST_WIDE_INT.
(TARGET_INIT_LIBFUNCS): Define it.
* config/arm/arm.h (TARGET_BPABI): New macro.
* config/arm/arm-protos.h
(arm_compute_initial_elimination_offset): Return HOST_WIDE_INT.
* config/arm/bpabi.S: New file.
* config/arm/bpabi.c: Likewise.
* config/arm/bpabi.h: Likewise.
* config/arm/ieee754-df.S (__aeabi_dneg): New function or alias.
(__aeabi_drsub): Likewise.
(__aeabi_dsub): Likewise.
(__aeabi_dadd): Likewise.
(__aeabi_ui2d): Likewise.
(__aeabi_i2d): Likewise.
(__aeabi_f2d): Likewise.
(__aeabi_dmul): Likewise.
(__aeabi_ddiv): Likewise.
(__aeabi_cdrcmple): Likewise.
(__aeabi_cdcmpeq): Likewise.
(__aeabi_cdcmple): Likewise.
(__aeabi_dcmpeq): Likewise.
(__aeabi_dcmplt): Likewise.
(__aeabi_dcmple): Likewise.
(__aeabi_dcmpge): Likewise.
(__aeabi_dcmpgt): Likewise.
(__aeabi_dcmpun): Likewise.
(__aeabi_d2iz): Likewise.
(__aeabi_d2uiz): Likewise.
(__aeabi_d2f): Likewise.
* config/arm/ieee754-sf.S (__aeabi_fneg): New function or alias.
(__aeabi_frsub): Likewise.
(__aeabi_fsub): Likewise.
(__aeabi_fadd): Likewise.
(__aeabi_ui2f): Likewise.
(__aeabi_i2f): Likewise.
(__aeabi_fmul): Likewise.
(__aeabi_fdiv): Likewise.
(__aeabi_cfrcmple): Likewise.
(__aeabi_cfcmpeq): Likewise.
(__aeabi_cfcmple): Likewise.
(__aeabi_fcmpeq): Likewise.
(__aeabi_fcmplt): Likewise.
(__aeabi_fcmple): Likewise.
(__aeabi_fcmpge): Likewise.
(__aeabi_fcmpgt): Likewise.
(__aeabi_fcmpun): Likewise.
(__aeabi_f2iz): Likewise.
(__aeabi_f2uiz): Likewise.
* config/arm/lib1funcs.asm (ARM_CALL): New macro.
(__aeabi_uidivmod): New function or alias.
(__aeabi_idivmod): Likewise.
(__aeabi_idiv0): Likewise.
(__aeabi_ldiv0): Likewise.
(__aeabi_llsr): Likewise.
(__aeabi_lasr): Likewise.
(__aeabi_llsl): Likewise.
(bpabi.S): Include it.
* config/arm/libgcc-bpabi.ver: New file.
* config/arm/symbian.h (ARM_DEFAULT_ABI): Remove.
(LINK_SPEC): Remove.
* config/arm/t-arm-elf (LIB1ASMFUNCS): Add __aeabi_lcmp and
__aeabi_ulcmp.
* config/arm/t-bpabi: New file.
* doc/tm.texi (TARGET_LIBGCC_FUNCS): New entry.
(TARGET_LIB_INT_CMP_BIASED): Likewise.
* gcc.dg/testsuite/gcc.dg/arm-eabi1.c: New test.
* gcc.dg/dll-2.c: Fix dg-require syntax.
* gcc.misc-tests/arm-isr.c (abort): Declare.
(exit): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85788 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/arm/ieee754-sf.S')
-rw-r--r-- | gcc/config/arm/ieee754-sf.S | 150 |
1 files changed, 139 insertions, 11 deletions
diff --git a/gcc/config/arm/ieee754-sf.S b/gcc/config/arm/ieee754-sf.S index 5c972452954..627fd7231d3 100644 --- a/gcc/config/arm/ieee754-sf.S +++ b/gcc/config/arm/ieee754-sf.S @@ -41,23 +41,34 @@ #ifdef L_negsf2 ARM_FUNC_START negsf2 +ARM_FUNC_ALIAS aeabi_fneg negsf2 + eor r0, r0, #0x80000000 @ flip sign bit RET + FUNC_END aeabi_fneg FUNC_END negsf2 #endif #ifdef L_addsubsf3 +ARM_FUNC_START aeabi_frsub + + eor r0, r0, #0x80000000 @ flip sign bit of first arg + b 1f + ARM_FUNC_START subsf3 +ARM_FUNC_ALIAS aeabi_fsub subsf3 + eor r1, r1, #0x80000000 @ flip sign bit of second arg #if defined(__thumb__) && !defined(__THUMB_INTERWORK__) b 1f @ Skip Thumb-code prologue #endif ARM_FUNC_START addsf3 - +ARM_FUNC_ALIAS aeabi_fadd addsf3 + 1: @ Compare both args, return zero if equal but the sign. eor r2, r0, r1 teq r2, #0x80000000 @@ -258,14 +269,21 @@ LSYM(Lad_i): orrne r0, r3, #0x00400000 @ NAN RET + FUNC_END aeabi_frsub + FUNC_END aeabi_fadd FUNC_END addsf3 + FUNC_END aeabi_fsub FUNC_END subsf3 ARM_FUNC_START floatunsisf +ARM_FUNC_ALIAS aeabi_ui2f floatunsisf + mov r3, #0 b 1f ARM_FUNC_START floatsisf +ARM_FUNC_ALIAS aeabi_i2f floatsisf + ands r3, r0, #0x80000000 rsbmi r0, r0, #0 @@ -290,7 +308,9 @@ ARM_FUNC_START floatsisf add r2, r2, #(2 << 23) b LSYM(Lad_p) + FUNC_END aeabi_i2f FUNC_END floatsisf + FUNC_END aeabi_ui2f FUNC_END floatunsisf #endif /* L_addsubsf3 */ @@ -298,7 +318,8 @@ ARM_FUNC_START floatsisf #ifdef L_muldivsf3 ARM_FUNC_START mulsf3 - +ARM_FUNC_ALIAS aeabi_fmul mulsf3 + @ Mask out exponents. mov ip, #0xff000000 and r2, r0, ip, lsr #1 @@ -485,10 +506,12 @@ LSYM(Lml_n): orr r0, r0, #0x00c00000 RET + FUNC_END aeabi_fmul FUNC_END mulsf3 ARM_FUNC_START divsf3 - +ARM_FUNC_ALIAS aeabi_fdiv divsf3 + @ Mask out exponents. mov ip, #0xff000000 and r2, r0, ip, lsr #1 @@ -636,12 +659,28 @@ LSYM(Ldv_s): bne LSYM(Lml_z) @ 0 / <non_zero> -> 0 b LSYM(Lml_n) @ 0 / 0 -> NAN + FUNC_END aeabi_fdiv FUNC_END divsf3 #endif /* L_muldivsf3 */ #ifdef L_cmpsf2 + @ The return value in r0 is + @ + @ 0 if the operands are equal + @ 1 if the first operand is greater than the second, or + @ the operands are unordered and the operation is + @ CMP, LT, LE, NE, or EQ. + @ -1 if the first operand is less than the second, or + @ the operands are unordered and the operation is GT + @ or GE. + @ + @ The Z flag will be set iff the operands are equal. + @ + @ The following registers are clobbered by this function: + @ ip, r0, r1, r2, r3 + ARM_FUNC_START gtsf2 ARM_FUNC_ALIAS gesf2 gtsf2 mov r3, #-1 @@ -657,24 +696,31 @@ ARM_FUNC_ALIAS nesf2 cmpsf2 ARM_FUNC_ALIAS eqsf2 cmpsf2 mov r3, #1 @ how should we specify unordered here? -1: @ Trap any INF/NAN first. - mov ip, #0xff000000 + @ Both Inf and NaN have an exponent of 255. Therefore, we + @ compute (r1 & 0x8f80000) || (r2 & 0x8f8000). +1: mov ip, #0xff000000 and r2, r1, ip, lsr #1 teq r2, ip, lsr #1 and r2, r0, ip, lsr #1 teqne r2, ip, lsr #1 beq 3f - @ Test for equality. - @ Note that 0.0 is equal to -0.0. + @ Test for equality. The representations of +0.0 and -0.0 + @ have all bits set to zero, except for the sign bit. Since + @ 0.0 is equal to -0.0, we begin by testing + @ ((r0 | r1) & ~0x8000000). 2: orr r3, r0, r1 + @ If the result of the bitwise and is zero, then the Z flag + @ will be set. In any case, the C flag will be set. bics r3, r3, #0x80000000 @ either 0.0 or -0.0 teqne r0, r1 @ or both the same + @ If the Z flag is set, the two operands were equal. Return zero. moveq r0, #0 RETc(eq) - @ Check for sign difference. The N flag is set if it is the case. - @ If so, return sign of r0. + @ Check for sign difference. The N flag is set (due to the + @ use of teq above) if the sign bit is set on exactly one + @ of the operands. Return the sign of the first operand. movmi r0, r0, asr #31 orrmi r0, r0, #1 RETc(mi) @@ -686,12 +732,24 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2 @ Compare mantissa if exponents are equal moveq r0, r0, lsl #9 cmpeq r0, r1, lsl #9 + + @ We know the operands cannot be equal at this point, so the + @ Z flag is clear. The C flag is set if the first operand has + @ the greater exponent, or the exponents are equal and the + @ first operand has the greater mantissa. Therefore, if the C + @ flag is set, the first operand is greater iff the sign is + @ positive. These next two instructions will put zero in + @ r0 if the first operand is greater, and -1 if the second + @ operand is greater. movcs r0, r1, asr #31 mvncc r0, r1, asr #31 + @ If r0 is 0, the first operand is greater, so return 1. Leave + @ -1 unchanged. orr r0, r0, #1 RET - @ Look for a NAN. + @ We know that at least one argument is either Inf or NaN. + @ Look for a NaN. 3: and r2, r1, ip, lsr #1 teq r2, ip, lsr #1 bne 4f @@ -702,7 +760,8 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2 bne 2b movs ip, r0, lsl #9 beq 2b @ r0 is not NAN -5: mov r0, r3 @ return unordered code from r3. +5: @ The Z flag is clear at this point. + mov r0, r3 @ return unordered code from r3. RET FUNC_END gesf2 @@ -713,11 +772,75 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2 FUNC_END eqsf2 FUNC_END cmpsf2 +ARM_FUNC_START aeabi_cfrcmple + mov ip, r0 + mov r0, r1 + mov r1, ip + b 6f + +ARM_FUNC_START aeabi_cfcmpeq +ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq + @ The status-returning routines are required to preserve all + @ registers except ip, lr, and cpsr. +6: stmfd sp!, {r0, r1, r2, r3, lr} + ARM_CALL cmpsf2 + @ Set the Z flag correctly, and the C flag unconditionally. + cmp r0, #0 + @ Clear the C flag if the return value was -1, indicating + @ that the first operand was smaller than the second. + cmnmi r0, #0 + RETLDM "r0, r1, r2, r3" + FUNC_END aeabi_cfcmple + FUNC_END aeabi_cfcmpeq + +ARM_FUNC_START aeabi_fcmpeq + str lr, [sp, #-4]! + ARM_CALL aeabi_cfcmple + moveq r0, #1 @ Equal to. + movne r0, #0 @ Less than, greater than, or unordered. + RETLDM + FUNC_END aeabi_fcmpeq + +ARM_FUNC_START aeabi_fcmplt + str lr, [sp, #-4]! + ARM_CALL aeabi_cfcmple + movcc r0, #1 @ Less than. + movcs r0, #0 @ Equal to, greater than, or unordered. + RETLDM + FUNC_END aeabi_fcmplt + +ARM_FUNC_START aeabi_fcmple + str lr, [sp, #-4]! + ARM_CALL aeabi_cfcmple + movls r0, #1 @ Less than or equal to. + movhi r0, #0 @ Greater than or unordered. + RETLDM + FUNC_END aeabi_fcmple + +ARM_FUNC_START aeabi_fcmpge + str lr, [sp, #-4]! + ARM_CALL aeabi_cfrcmple + movls r0, #1 @ Operand 2 is less than or equal to operand 1. + movhi r0, #0 @ Operand 2 greater than operand 1, or unordered. + RETLDM + FUNC_END aeabi_fcmpge + +ARM_FUNC_START aeabi_fcmpgt + str lr, [sp, #-4]! + ARM_CALL aeabi_cfrcmple + movcc r0, #1 @ Operand 2 is less than operand 1. + movcs r0, #0 @ Operand 2 is greater than or equal to operand 1, + @ or they are unordered. + RETLDM + FUNC_END aeabi_fcmpgt + #endif /* L_cmpsf2 */ #ifdef L_unordsf2 ARM_FUNC_START unordsf2 +ARM_FUNC_ALIAS aeabi_fcmpun unordsf2 + mov ip, #0xff000000 and r2, r1, ip, lsr #1 teq r2, ip, lsr #1 @@ -734,6 +857,7 @@ ARM_FUNC_START unordsf2 3: mov r0, #1 @ arguments are unordered. RET + FUNC_END aeabi_fcmpun FUNC_END unordsf2 #endif /* L_unordsf2 */ @@ -741,6 +865,7 @@ ARM_FUNC_START unordsf2 #ifdef L_fixsfsi ARM_FUNC_START fixsfsi +ARM_FUNC_ALIAS aeabi_f2iz fixsfsi movs r0, r0, lsl #1 RETc(eq) @ value is 0. @@ -774,6 +899,7 @@ ARM_FUNC_START fixsfsi 3: mov r0, #0 @ What should we convert NAN to? RET + FUNC_END aeabi_f2iz FUNC_END fixsfsi #endif /* L_fixsfsi */ @@ -781,6 +907,7 @@ ARM_FUNC_START fixsfsi #ifdef L_fixunssfsi ARM_FUNC_START fixunssfsi +ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi movs r0, r0, lsl #1 movcss r0, #0 @ value is negative... RETc(eq) @ ... or 0. @@ -811,6 +938,7 @@ ARM_FUNC_START fixunssfsi 3: mov r0, #0 @ What should we convert NAN to? RET + FUNC_END aeabi_f2uiz FUNC_END fixunssfsi #endif /* L_fixunssfsi */ |