mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 19:08:21 +08:00
ARM: Start moving runtime libcall configuration out of TargetLowering (#142617)
These Module level triple checks implemented in the Subtarget are kind of a pain and we should probably get rid of all of them in across all targets, and stick to a consistent set of names.
This commit is contained in:
@@ -917,6 +917,34 @@ public:
|
||||
isOSBinFormatELF();
|
||||
}
|
||||
|
||||
// ARM EABI is the bare-metal EABI described in ARM ABI documents and
|
||||
// can be accessed via -target arm-none-eabi. This is NOT GNUEABI.
|
||||
// FIXME: Add a flag for bare-metal for that target and set Triple::EABI
|
||||
// even for GNUEABI, so we can make a distinction here and still conform to
|
||||
// the EABI on GNU (and Android) mode. This requires change in Clang, too.
|
||||
// FIXME: The Darwin exception is temporary, while we move users to
|
||||
// "*-*-*-macho" triples as quickly as possible.
|
||||
bool isTargetAEABI() const {
|
||||
return (getEnvironment() == Triple::EABI ||
|
||||
getEnvironment() == Triple::EABIHF) &&
|
||||
!isOSDarwin() && !isOSWindows();
|
||||
}
|
||||
|
||||
bool isTargetGNUAEABI() const {
|
||||
return (getEnvironment() == Triple::GNUEABI ||
|
||||
getEnvironment() == Triple::GNUEABIT64 ||
|
||||
getEnvironment() == Triple::GNUEABIHF ||
|
||||
getEnvironment() == Triple::GNUEABIHFT64) &&
|
||||
!isOSDarwin() && !isOSWindows();
|
||||
}
|
||||
|
||||
bool isTargetMuslAEABI() const {
|
||||
return (getEnvironment() == Triple::MuslEABI ||
|
||||
getEnvironment() == Triple::MuslEABIHF ||
|
||||
getEnvironment() == Triple::OpenHOS) &&
|
||||
!isOSDarwin() && !isOSWindows();
|
||||
}
|
||||
|
||||
/// Tests whether the target is T32.
|
||||
bool isArmT32() const {
|
||||
switch (getSubArch()) {
|
||||
|
||||
@@ -31,6 +31,56 @@ static void setAArch64LibcallNames(RuntimeLibcallsInfo &Info,
|
||||
}
|
||||
}
|
||||
|
||||
static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT) {
|
||||
// Register based DivRem for AEABI (RTABI 4.2)
|
||||
if (TT.isTargetAEABI() || TT.isAndroid() || TT.isTargetGNUAEABI() ||
|
||||
TT.isTargetMuslAEABI() || TT.isOSWindows()) {
|
||||
if (TT.isOSWindows()) {
|
||||
const struct {
|
||||
const RTLIB::Libcall Op;
|
||||
const char *const Name;
|
||||
const CallingConv::ID CC;
|
||||
} LibraryCalls[] = {
|
||||
{RTLIB::SDIVREM_I8, "__rt_sdiv", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::SDIVREM_I16, "__rt_sdiv", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::SDIVREM_I32, "__rt_sdiv", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::SDIVREM_I64, "__rt_sdiv64", CallingConv::ARM_AAPCS},
|
||||
|
||||
{RTLIB::UDIVREM_I8, "__rt_udiv", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::UDIVREM_I16, "__rt_udiv", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::UDIVREM_I32, "__rt_udiv", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::UDIVREM_I64, "__rt_udiv64", CallingConv::ARM_AAPCS},
|
||||
};
|
||||
|
||||
for (const auto &LC : LibraryCalls) {
|
||||
Info.setLibcallName(LC.Op, LC.Name);
|
||||
Info.setLibcallCallingConv(LC.Op, LC.CC);
|
||||
}
|
||||
} else {
|
||||
const struct {
|
||||
const RTLIB::Libcall Op;
|
||||
const char *const Name;
|
||||
const CallingConv::ID CC;
|
||||
} LibraryCalls[] = {
|
||||
{RTLIB::SDIVREM_I8, "__aeabi_idivmod", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::SDIVREM_I16, "__aeabi_idivmod", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::SDIVREM_I32, "__aeabi_idivmod", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::SDIVREM_I64, "__aeabi_ldivmod", CallingConv::ARM_AAPCS},
|
||||
|
||||
{RTLIB::UDIVREM_I8, "__aeabi_uidivmod", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::UDIVREM_I16, "__aeabi_uidivmod", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::UDIVREM_I32, "__aeabi_uidivmod", CallingConv::ARM_AAPCS},
|
||||
{RTLIB::UDIVREM_I64, "__aeabi_uldivmod", CallingConv::ARM_AAPCS},
|
||||
};
|
||||
|
||||
for (const auto &LC : LibraryCalls) {
|
||||
Info.setLibcallName(LC.Op, LC.Name);
|
||||
Info.setLibcallCallingConv(LC.Op, LC.CC);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Set default libcall names. If a target wants to opt-out of a libcall it
|
||||
/// should be placed here.
|
||||
void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
|
||||
@@ -298,8 +348,9 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
|
||||
|
||||
if (TT.getArch() == Triple::ArchType::aarch64)
|
||||
setAArch64LibcallNames(*this, TT);
|
||||
|
||||
if (TT.getArch() == Triple::ArchType::avr) {
|
||||
else if (TT.isARM() || TT.isThumb())
|
||||
setARMLibcallNames(*this, TT);
|
||||
else if (TT.getArch() == Triple::ArchType::avr) {
|
||||
// Division rtlib functions (not supported), use divmod functions instead
|
||||
setLibcallName(RTLIB::SDIV_I8, nullptr);
|
||||
setLibcallName(RTLIB::SDIV_I16, nullptr);
|
||||
|
||||
@@ -1275,50 +1275,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
setOperationAction(ISD::UREM, MVT::i64, Custom);
|
||||
HasStandaloneRem = false;
|
||||
|
||||
if (Subtarget->isTargetWindows()) {
|
||||
const struct {
|
||||
const RTLIB::Libcall Op;
|
||||
const char * const Name;
|
||||
const CallingConv::ID CC;
|
||||
} LibraryCalls[] = {
|
||||
{ RTLIB::SDIVREM_I8, "__rt_sdiv", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::SDIVREM_I16, "__rt_sdiv", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::SDIVREM_I32, "__rt_sdiv", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::SDIVREM_I64, "__rt_sdiv64", CallingConv::ARM_AAPCS },
|
||||
|
||||
{ RTLIB::UDIVREM_I8, "__rt_udiv", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::UDIVREM_I16, "__rt_udiv", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::UDIVREM_I32, "__rt_udiv", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::UDIVREM_I64, "__rt_udiv64", CallingConv::ARM_AAPCS },
|
||||
};
|
||||
|
||||
for (const auto &LC : LibraryCalls) {
|
||||
setLibcallName(LC.Op, LC.Name);
|
||||
setLibcallCallingConv(LC.Op, LC.CC);
|
||||
}
|
||||
} else {
|
||||
const struct {
|
||||
const RTLIB::Libcall Op;
|
||||
const char * const Name;
|
||||
const CallingConv::ID CC;
|
||||
} LibraryCalls[] = {
|
||||
{ RTLIB::SDIVREM_I8, "__aeabi_idivmod", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::SDIVREM_I16, "__aeabi_idivmod", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::SDIVREM_I32, "__aeabi_idivmod", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::SDIVREM_I64, "__aeabi_ldivmod", CallingConv::ARM_AAPCS },
|
||||
|
||||
{ RTLIB::UDIVREM_I8, "__aeabi_uidivmod", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::UDIVREM_I16, "__aeabi_uidivmod", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::UDIVREM_I32, "__aeabi_uidivmod", CallingConv::ARM_AAPCS },
|
||||
{ RTLIB::UDIVREM_I64, "__aeabi_uldivmod", CallingConv::ARM_AAPCS },
|
||||
};
|
||||
|
||||
for (const auto &LC : LibraryCalls) {
|
||||
setLibcallName(LC.Op, LC.Name);
|
||||
setLibcallCallingConv(LC.Op, LC.CC);
|
||||
}
|
||||
}
|
||||
|
||||
setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
|
||||
setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
|
||||
|
||||
@@ -348,31 +348,11 @@ public:
|
||||
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
|
||||
bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
|
||||
|
||||
// ARM EABI is the bare-metal EABI described in ARM ABI documents and
|
||||
// can be accessed via -target arm-none-eabi. This is NOT GNUEABI.
|
||||
// FIXME: Add a flag for bare-metal for that target and set Triple::EABI
|
||||
// even for GNUEABI, so we can make a distinction here and still conform to
|
||||
// the EABI on GNU (and Android) mode. This requires change in Clang, too.
|
||||
// FIXME: The Darwin exception is temporary, while we move users to
|
||||
// "*-*-*-macho" triples as quickly as possible.
|
||||
bool isTargetAEABI() const {
|
||||
return (TargetTriple.getEnvironment() == Triple::EABI ||
|
||||
TargetTriple.getEnvironment() == Triple::EABIHF) &&
|
||||
!isTargetDarwin() && !isTargetWindows();
|
||||
}
|
||||
bool isTargetGNUAEABI() const {
|
||||
return (TargetTriple.getEnvironment() == Triple::GNUEABI ||
|
||||
TargetTriple.getEnvironment() == Triple::GNUEABIT64 ||
|
||||
TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
|
||||
TargetTriple.getEnvironment() == Triple::GNUEABIHFT64) &&
|
||||
!isTargetDarwin() && !isTargetWindows();
|
||||
}
|
||||
bool isTargetMuslAEABI() const {
|
||||
return (TargetTriple.getEnvironment() == Triple::MuslEABI ||
|
||||
TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
|
||||
TargetTriple.getEnvironment() == Triple::OpenHOS) &&
|
||||
!isTargetDarwin() && !isTargetWindows();
|
||||
}
|
||||
bool isTargetAEABI() const { return TargetTriple.isTargetAEABI(); }
|
||||
|
||||
bool isTargetGNUAEABI() const { return TargetTriple.isTargetGNUAEABI(); }
|
||||
|
||||
bool isTargetMuslAEABI() const { return TargetTriple.isTargetMuslAEABI(); }
|
||||
|
||||
// ARM Targets that support EHABI exception handling standard
|
||||
// Darwin uses SjLj. Other targets might need more checks.
|
||||
|
||||
Reference in New Issue
Block a user