aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/TargetLoweringBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringBase.cpp')
-rw-r--r--llvm/lib/CodeGen/TargetLoweringBase.cpp106
1 files changed, 73 insertions, 33 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 85b148a..0a077b7 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -609,37 +609,79 @@ RTLIB::Libcall RTLIB::getMEMSET_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize) {
}
}
-void RTLIB::initCmpLibcallCCs(ISD::CondCode *CmpLibcallCCs) {
- std::fill(CmpLibcallCCs, CmpLibcallCCs + RTLIB::UNKNOWN_LIBCALL,
- ISD::SETCC_INVALID);
- CmpLibcallCCs[RTLIB::OEQ_F32] = ISD::SETEQ;
- CmpLibcallCCs[RTLIB::OEQ_F64] = ISD::SETEQ;
- CmpLibcallCCs[RTLIB::OEQ_F128] = ISD::SETEQ;
- CmpLibcallCCs[RTLIB::OEQ_PPCF128] = ISD::SETEQ;
- CmpLibcallCCs[RTLIB::UNE_F32] = ISD::SETNE;
- CmpLibcallCCs[RTLIB::UNE_F64] = ISD::SETNE;
- CmpLibcallCCs[RTLIB::UNE_F128] = ISD::SETNE;
- CmpLibcallCCs[RTLIB::UNE_PPCF128] = ISD::SETNE;
- CmpLibcallCCs[RTLIB::OGE_F32] = ISD::SETGE;
- CmpLibcallCCs[RTLIB::OGE_F64] = ISD::SETGE;
- CmpLibcallCCs[RTLIB::OGE_F128] = ISD::SETGE;
- CmpLibcallCCs[RTLIB::OGE_PPCF128] = ISD::SETGE;
- CmpLibcallCCs[RTLIB::OLT_F32] = ISD::SETLT;
- CmpLibcallCCs[RTLIB::OLT_F64] = ISD::SETLT;
- CmpLibcallCCs[RTLIB::OLT_F128] = ISD::SETLT;
- CmpLibcallCCs[RTLIB::OLT_PPCF128] = ISD::SETLT;
- CmpLibcallCCs[RTLIB::OLE_F32] = ISD::SETLE;
- CmpLibcallCCs[RTLIB::OLE_F64] = ISD::SETLE;
- CmpLibcallCCs[RTLIB::OLE_F128] = ISD::SETLE;
- CmpLibcallCCs[RTLIB::OLE_PPCF128] = ISD::SETLE;
- CmpLibcallCCs[RTLIB::OGT_F32] = ISD::SETGT;
- CmpLibcallCCs[RTLIB::OGT_F64] = ISD::SETGT;
- CmpLibcallCCs[RTLIB::OGT_F128] = ISD::SETGT;
- CmpLibcallCCs[RTLIB::OGT_PPCF128] = ISD::SETGT;
- CmpLibcallCCs[RTLIB::UO_F32] = ISD::SETNE;
- CmpLibcallCCs[RTLIB::UO_F64] = ISD::SETNE;
- CmpLibcallCCs[RTLIB::UO_F128] = ISD::SETNE;
- CmpLibcallCCs[RTLIB::UO_PPCF128] = ISD::SETNE;
+ISD::CondCode TargetLoweringBase::getSoftFloatCmpLibcallPredicate(
+ RTLIB::LibcallImpl Impl) const {
+ switch (Impl) {
+ case RTLIB::__aeabi_dcmpeq__une:
+ case RTLIB::__aeabi_fcmpeq__une:
+ // Usage in the eq case, so we have to invert the comparison.
+ return ISD::SETEQ;
+ case RTLIB::__aeabi_dcmpeq__oeq:
+ case RTLIB::__aeabi_fcmpeq__oeq:
+ // Normal comparison to boolean value.
+ return ISD::SETNE;
+ case RTLIB::__aeabi_dcmplt:
+ case RTLIB::__aeabi_dcmple:
+ case RTLIB::__aeabi_dcmpge:
+ case RTLIB::__aeabi_dcmpgt:
+ case RTLIB::__aeabi_dcmpun:
+ case RTLIB::__aeabi_fcmplt:
+ case RTLIB::__aeabi_fcmple:
+ case RTLIB::__aeabi_fcmpge:
+ case RTLIB::__aeabi_fcmpgt:
+ /// The AEABI versions return a typical boolean value, so we can compare
+ /// against the integer result as simply != 0.
+ return ISD::SETNE;
+ default:
+ break;
+ }
+
+ // Assume libgcc/compiler-rt behavior. Most of the cases are really aliases of
+ // each other, and return a 3-way comparison style result of -1, 0, or 1
+ // depending on lt/eq/gt.
+ //
+ // FIXME: It would be cleaner to directly express this as a 3-way comparison
+ // soft FP libcall instead of individual compares.
+ RTLIB::Libcall LC = RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(Impl);
+ switch (LC) {
+ case RTLIB::OEQ_F32:
+ case RTLIB::OEQ_F64:
+ case RTLIB::OEQ_F128:
+ case RTLIB::OEQ_PPCF128:
+ return ISD::SETEQ;
+ case RTLIB::UNE_F32:
+ case RTLIB::UNE_F64:
+ case RTLIB::UNE_F128:
+ case RTLIB::UNE_PPCF128:
+ return ISD::SETNE;
+ case RTLIB::OGE_F32:
+ case RTLIB::OGE_F64:
+ case RTLIB::OGE_F128:
+ case RTLIB::OGE_PPCF128:
+ return ISD::SETGE;
+ case RTLIB::OLT_F32:
+ case RTLIB::OLT_F64:
+ case RTLIB::OLT_F128:
+ case RTLIB::OLT_PPCF128:
+ return ISD::SETLT;
+ case RTLIB::OLE_F32:
+ case RTLIB::OLE_F64:
+ case RTLIB::OLE_F128:
+ case RTLIB::OLE_PPCF128:
+ return ISD::SETLE;
+ case RTLIB::OGT_F32:
+ case RTLIB::OGT_F64:
+ case RTLIB::OGT_F128:
+ case RTLIB::OGT_PPCF128:
+ return ISD::SETGT;
+ case RTLIB::UO_F32:
+ case RTLIB::UO_F64:
+ case RTLIB::UO_F128:
+ case RTLIB::UO_PPCF128:
+ return ISD::SETNE;
+ default:
+ llvm_unreachable("not a compare libcall");
+ }
}
/// NOTE: The TargetMachine owns TLOF.
@@ -678,8 +720,6 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm)
MinCmpXchgSizeInBits = 0;
SupportsUnalignedAtomics = false;
-
- RTLIB::initCmpLibcallCCs(CmpLibcallCCs);
}
// Define the virtual destructor out-of-line to act as a key method to anchor