forked from OSchip/llvm-project
[builtins] Deduplicate __eqsf2 and __gtsf2 via macro
The only difference between __eqsf2 and __gtsf2 is whether they return 1 or -1 on NaN. Rather than duplicating all the code, use a macro to define the function twice and use an argument to decide whether to negate the return value. Differential Revision: https://reviews.llvm.org/D61919 llvm-svn: 361207
This commit is contained in:
parent
1a5cc629de
commit
48140db797
|
@ -37,14 +37,13 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
.syntax unified
|
||||
.text
|
||||
DEFINE_CODE_STATE
|
||||
|
||||
@ int __eqsf2(float a, float b)
|
||||
.macro COMPARESF2_FUNCTION name:req handle_nan:req
|
||||
@ int \name(float a, float b)
|
||||
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__eqsf2)
|
||||
DEFINE_COMPILERRT_FUNCTION(\name)
|
||||
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmov r0, s0
|
||||
vmov r1, s1
|
||||
|
@ -112,9 +111,9 @@ DEFINE_COMPILERRT_FUNCTION(__eqsf2)
|
|||
// b < 0 ? 1 : -1. Same if a and b have the opposite sign (ignoring Nan).
|
||||
movs r0, #1
|
||||
lsrs r1, #31
|
||||
bne LOCAL_LABEL(CHECK_NAN)
|
||||
bne LOCAL_LABEL(CHECK_NAN\@)
|
||||
negs r0, r0
|
||||
b LOCAL_LABEL(CHECK_NAN)
|
||||
b LOCAL_LABEL(CHECK_NAN\@)
|
||||
1:
|
||||
#else
|
||||
it lo
|
||||
|
@ -130,7 +129,7 @@ DEFINE_COMPILERRT_FUNCTION(__eqsf2)
|
|||
// Here both have the same sign and absA > absB.
|
||||
movs r0, #1
|
||||
lsrs r1, #31
|
||||
beq LOCAL_LABEL(CHECK_NAN)
|
||||
beq LOCAL_LABEL(CHECK_NAN\@)
|
||||
negs r0, r0
|
||||
1:
|
||||
#else
|
||||
|
@ -151,7 +150,7 @@ DEFINE_COMPILERRT_FUNCTION(__eqsf2)
|
|||
// Finally, we need to deal with NaNs. If either argument is NaN, replace
|
||||
// the value in r0 with 1.
|
||||
#if defined(USE_THUMB_1)
|
||||
LOCAL_LABEL(CHECK_NAN):
|
||||
LOCAL_LABEL(CHECK_NAN\@):
|
||||
movs r6, #0xff
|
||||
lsls r6, #24
|
||||
cmp r2, r6
|
||||
|
@ -159,17 +158,32 @@ LOCAL_LABEL(CHECK_NAN):
|
|||
cmp r3, r6
|
||||
1:
|
||||
bls 2f
|
||||
movs r0, #1
|
||||
\handle_nan
|
||||
2:
|
||||
pop {r6, pc}
|
||||
#else
|
||||
cmp r2, #0xff000000
|
||||
ite ls
|
||||
cmpls r3, #0xff000000
|
||||
movhi r0, #1
|
||||
\handle_nan
|
||||
JMP(lr)
|
||||
#endif
|
||||
END_COMPILERRT_FUNCTION(__eqsf2)
|
||||
END_COMPILERRT_FUNCTION(\name)
|
||||
.endm
|
||||
|
||||
.syntax unified
|
||||
.text
|
||||
DEFINE_CODE_STATE
|
||||
|
||||
.macro __eqsf2_handle_nan
|
||||
#if defined(USE_THUMB_1)
|
||||
movs r0, #1
|
||||
#else
|
||||
movhi r0, #1
|
||||
#endif
|
||||
.endm
|
||||
|
||||
COMPARESF2_FUNCTION __eqsf2, __eqsf2_handle_nan
|
||||
|
||||
DEFINE_COMPILERRT_FUNCTION_ALIAS(__lesf2, __eqsf2)
|
||||
DEFINE_COMPILERRT_FUNCTION_ALIAS(__ltsf2, __eqsf2)
|
||||
|
@ -180,77 +194,16 @@ DEFINE_COMPILERRT_FUNCTION_ALIAS(__nesf2, __eqsf2)
|
|||
DEFINE_COMPILERRT_FUNCTION_ALIAS(__cmpsf2, __lesf2)
|
||||
#endif
|
||||
|
||||
@ int __gtsf2(float a, float b)
|
||||
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__gtsf2)
|
||||
// Identical to the preceding except in that we return -1 for NaN values.
|
||||
// Given that the two paths share so much code, one might be tempted to
|
||||
// unify them; however, the extra code needed to do so makes the code size
|
||||
// to performance tradeoff very hard to justify for such small functions.
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmov r0, s0
|
||||
vmov r1, s1
|
||||
#endif
|
||||
.macro __gtsf2_handle_nan
|
||||
#if defined(USE_THUMB_1)
|
||||
push {r6, lr}
|
||||
lsls r2, r0, #1
|
||||
lsls r3, r1, #1
|
||||
lsrs r6, r3, #1
|
||||
orrs r6, r2
|
||||
beq 1f
|
||||
movs r6, r0
|
||||
eors r6, r1
|
||||
1:
|
||||
bmi 2f
|
||||
subs r0, r2, r3
|
||||
2:
|
||||
bhs 3f
|
||||
movs r0, #1
|
||||
lsrs r1, #31
|
||||
bne LOCAL_LABEL(CHECK_NAN_2)
|
||||
negs r0, r0
|
||||
b LOCAL_LABEL(CHECK_NAN_2)
|
||||
3:
|
||||
bls 4f
|
||||
movs r0, #1
|
||||
lsrs r1, #31
|
||||
beq LOCAL_LABEL(CHECK_NAN_2)
|
||||
negs r0, r0
|
||||
4:
|
||||
LOCAL_LABEL(CHECK_NAN_2):
|
||||
movs r6, #0xff
|
||||
lsls r6, #24
|
||||
cmp r2, r6
|
||||
bhi 5f
|
||||
cmp r3, r6
|
||||
5:
|
||||
bls 6f
|
||||
movs r0, #1
|
||||
negs r0, r0
|
||||
6:
|
||||
pop {r6, pc}
|
||||
#else
|
||||
mov r2, r0, lsl #1
|
||||
mov r3, r1, lsl #1
|
||||
orrs r12, r2, r3, lsr #1
|
||||
it ne
|
||||
eorsne r12, r0, r1
|
||||
it pl
|
||||
subspl r0, r2, r3
|
||||
it lo
|
||||
mvnlo r0, r1, asr #31
|
||||
it hi
|
||||
movhi r0, r1, asr #31
|
||||
it ne
|
||||
orrne r0, r0, #1
|
||||
cmp r2, #0xff000000
|
||||
ite ls
|
||||
cmpls r3, #0xff000000
|
||||
movhi r0, #-1
|
||||
JMP(lr)
|
||||
#endif
|
||||
END_COMPILERRT_FUNCTION(__gtsf2)
|
||||
.endm
|
||||
|
||||
COMPARESF2_FUNCTION __gtsf2, __gtsf2_handle_nan
|
||||
|
||||
DEFINE_COMPILERRT_FUNCTION_ALIAS(__gesf2, __gtsf2)
|
||||
|
||||
|
|
Loading…
Reference in New Issue