mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-23 16:06:24 +00:00
ARM: match GCC's behaviour for builtins
GCC changes the CC between the user-code and the builtins based on the value of `-target` rather than `-mfloat-abi`. When a HF target is used, the VFP variant of the AAPCS CC is used. Otherwise, the AAPCS variant is used. In all cases, the AEABI functions use the AAPCS CC. Adjust the calling convention based on the target. Resolves PR30543! llvm-svn: 291909
This commit is contained in:
parent
1e799942b3
commit
6ef45916c6
@ -97,171 +97,6 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
void ARMTargetLowering::InitLibcallCallingConvs() {
|
||||
// The builtins on ARM always use AAPCS, irrespective of wheter C is AAPCS or
|
||||
// AAPCS_VFP.
|
||||
for (const auto LC : {
|
||||
RTLIB::SHL_I16,
|
||||
RTLIB::SHL_I32,
|
||||
RTLIB::SHL_I64,
|
||||
RTLIB::SHL_I128,
|
||||
RTLIB::SRL_I16,
|
||||
RTLIB::SRL_I32,
|
||||
RTLIB::SRL_I64,
|
||||
RTLIB::SRL_I128,
|
||||
RTLIB::SRA_I16,
|
||||
RTLIB::SRA_I32,
|
||||
RTLIB::SRA_I64,
|
||||
RTLIB::SRA_I128,
|
||||
RTLIB::MUL_I8,
|
||||
RTLIB::MUL_I16,
|
||||
RTLIB::MUL_I32,
|
||||
RTLIB::MUL_I64,
|
||||
RTLIB::MUL_I128,
|
||||
RTLIB::MULO_I32,
|
||||
RTLIB::MULO_I64,
|
||||
RTLIB::MULO_I128,
|
||||
RTLIB::SDIV_I8,
|
||||
RTLIB::SDIV_I16,
|
||||
RTLIB::SDIV_I32,
|
||||
RTLIB::SDIV_I64,
|
||||
RTLIB::SDIV_I128,
|
||||
RTLIB::UDIV_I8,
|
||||
RTLIB::UDIV_I16,
|
||||
RTLIB::UDIV_I32,
|
||||
RTLIB::UDIV_I64,
|
||||
RTLIB::UDIV_I128,
|
||||
RTLIB::SREM_I8,
|
||||
RTLIB::SREM_I16,
|
||||
RTLIB::SREM_I32,
|
||||
RTLIB::SREM_I64,
|
||||
RTLIB::SREM_I128,
|
||||
RTLIB::UREM_I8,
|
||||
RTLIB::UREM_I16,
|
||||
RTLIB::UREM_I32,
|
||||
RTLIB::UREM_I64,
|
||||
RTLIB::UREM_I128,
|
||||
RTLIB::SDIVREM_I8,
|
||||
RTLIB::SDIVREM_I16,
|
||||
RTLIB::SDIVREM_I32,
|
||||
RTLIB::SDIVREM_I64,
|
||||
RTLIB::SDIVREM_I128,
|
||||
RTLIB::UDIVREM_I8,
|
||||
RTLIB::UDIVREM_I16,
|
||||
RTLIB::UDIVREM_I32,
|
||||
RTLIB::UDIVREM_I64,
|
||||
RTLIB::UDIVREM_I128,
|
||||
RTLIB::NEG_I32,
|
||||
RTLIB::NEG_I64,
|
||||
RTLIB::ADD_F32,
|
||||
RTLIB::ADD_F64,
|
||||
RTLIB::ADD_F80,
|
||||
RTLIB::ADD_F128,
|
||||
RTLIB::SUB_F32,
|
||||
RTLIB::SUB_F64,
|
||||
RTLIB::SUB_F80,
|
||||
RTLIB::SUB_F128,
|
||||
RTLIB::MUL_F32,
|
||||
RTLIB::MUL_F64,
|
||||
RTLIB::MUL_F80,
|
||||
RTLIB::MUL_F128,
|
||||
RTLIB::DIV_F32,
|
||||
RTLIB::DIV_F64,
|
||||
RTLIB::DIV_F80,
|
||||
RTLIB::DIV_F128,
|
||||
RTLIB::POWI_F32,
|
||||
RTLIB::POWI_F64,
|
||||
RTLIB::POWI_F80,
|
||||
RTLIB::POWI_F128,
|
||||
RTLIB::FPEXT_F64_F128,
|
||||
RTLIB::FPEXT_F32_F128,
|
||||
RTLIB::FPEXT_F32_F64,
|
||||
RTLIB::FPEXT_F16_F32,
|
||||
RTLIB::FPROUND_F32_F16,
|
||||
RTLIB::FPROUND_F64_F16,
|
||||
RTLIB::FPROUND_F80_F16,
|
||||
RTLIB::FPROUND_F128_F16,
|
||||
RTLIB::FPROUND_F64_F32,
|
||||
RTLIB::FPROUND_F80_F32,
|
||||
RTLIB::FPROUND_F128_F32,
|
||||
RTLIB::FPROUND_F80_F64,
|
||||
RTLIB::FPROUND_F128_F64,
|
||||
RTLIB::FPTOSINT_F32_I32,
|
||||
RTLIB::FPTOSINT_F32_I64,
|
||||
RTLIB::FPTOSINT_F32_I128,
|
||||
RTLIB::FPTOSINT_F64_I32,
|
||||
RTLIB::FPTOSINT_F64_I64,
|
||||
RTLIB::FPTOSINT_F64_I128,
|
||||
RTLIB::FPTOSINT_F80_I32,
|
||||
RTLIB::FPTOSINT_F80_I64,
|
||||
RTLIB::FPTOSINT_F80_I128,
|
||||
RTLIB::FPTOSINT_F128_I32,
|
||||
RTLIB::FPTOSINT_F128_I64,
|
||||
RTLIB::FPTOSINT_F128_I128,
|
||||
RTLIB::FPTOUINT_F32_I32,
|
||||
RTLIB::FPTOUINT_F32_I64,
|
||||
RTLIB::FPTOUINT_F32_I128,
|
||||
RTLIB::FPTOUINT_F64_I32,
|
||||
RTLIB::FPTOUINT_F64_I64,
|
||||
RTLIB::FPTOUINT_F64_I128,
|
||||
RTLIB::FPTOUINT_F80_I32,
|
||||
RTLIB::FPTOUINT_F80_I64,
|
||||
RTLIB::FPTOUINT_F80_I128,
|
||||
RTLIB::FPTOUINT_F128_I32,
|
||||
RTLIB::FPTOUINT_F128_I64,
|
||||
RTLIB::FPTOUINT_F128_I128,
|
||||
RTLIB::SINTTOFP_I32_F32,
|
||||
RTLIB::SINTTOFP_I32_F64,
|
||||
RTLIB::SINTTOFP_I32_F80,
|
||||
RTLIB::SINTTOFP_I32_F128,
|
||||
RTLIB::SINTTOFP_I64_F32,
|
||||
RTLIB::SINTTOFP_I64_F64,
|
||||
RTLIB::SINTTOFP_I64_F80,
|
||||
RTLIB::SINTTOFP_I64_F128,
|
||||
RTLIB::SINTTOFP_I128_F32,
|
||||
RTLIB::SINTTOFP_I128_F64,
|
||||
RTLIB::SINTTOFP_I128_F80,
|
||||
RTLIB::SINTTOFP_I128_F128,
|
||||
RTLIB::UINTTOFP_I32_F32,
|
||||
RTLIB::UINTTOFP_I32_F64,
|
||||
RTLIB::UINTTOFP_I32_F80,
|
||||
RTLIB::UINTTOFP_I32_F128,
|
||||
RTLIB::UINTTOFP_I64_F32,
|
||||
RTLIB::UINTTOFP_I64_F64,
|
||||
RTLIB::UINTTOFP_I64_F80,
|
||||
RTLIB::UINTTOFP_I64_F128,
|
||||
RTLIB::UINTTOFP_I128_F32,
|
||||
RTLIB::UINTTOFP_I128_F64,
|
||||
RTLIB::UINTTOFP_I128_F80,
|
||||
RTLIB::UINTTOFP_I128_F128,
|
||||
RTLIB::OEQ_F32,
|
||||
RTLIB::OEQ_F64,
|
||||
RTLIB::OEQ_F128,
|
||||
RTLIB::UNE_F32,
|
||||
RTLIB::UNE_F64,
|
||||
RTLIB::UNE_F128,
|
||||
RTLIB::OGE_F32,
|
||||
RTLIB::OGE_F64,
|
||||
RTLIB::OGE_F128,
|
||||
RTLIB::OLT_F32,
|
||||
RTLIB::OLT_F64,
|
||||
RTLIB::OLT_F128,
|
||||
RTLIB::OLE_F32,
|
||||
RTLIB::OLE_F64,
|
||||
RTLIB::OLE_F128,
|
||||
RTLIB::OGT_F32,
|
||||
RTLIB::OGT_F64,
|
||||
RTLIB::OGT_F128,
|
||||
RTLIB::UO_F32,
|
||||
RTLIB::UO_F64,
|
||||
RTLIB::UO_F128,
|
||||
RTLIB::O_F32,
|
||||
RTLIB::O_F64,
|
||||
RTLIB::O_F128,
|
||||
})
|
||||
setLibcallCallingConv(LC, CallingConv::ARM_AAPCS);
|
||||
}
|
||||
|
||||
// The APCS parameter registers.
|
||||
static const MCPhysReg GPRArgRegs[] = {
|
||||
ARM::R0, ARM::R1, ARM::R2, ARM::R3
|
||||
@ -349,7 +184,22 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
|
||||
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
|
||||
|
||||
InitLibcallCallingConvs();
|
||||
if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetIOS() &&
|
||||
!Subtarget->isTargetWatchOS()) {
|
||||
const auto &E = Subtarget->getTargetTriple().getEnvironment();
|
||||
|
||||
bool IsHFTarget = E == Triple::EABIHF || E == Triple::GNUEABIHF ||
|
||||
E == Triple::MuslEABIHF;
|
||||
// Windows is a special case. Technically, we will replace all of the "GNU"
|
||||
// calls with calls to MSVCRT if appropriate and adjust the calling
|
||||
// convention then.
|
||||
IsHFTarget = IsHFTarget || Subtarget->isTargetWindows();
|
||||
|
||||
for (int LCID = 0; LCID < RTLIB::UNKNOWN_LIBCALL; ++LCID)
|
||||
setLibcallCallingConv(static_cast<RTLIB::Libcall>(LCID),
|
||||
IsHFTarget ? CallingConv::ARM_AAPCS_VFP
|
||||
: CallingConv::ARM_AAPCS);
|
||||
}
|
||||
|
||||
if (Subtarget->isTargetMachO()) {
|
||||
// Uses VFP for Thumb libfuncs if available.
|
||||
|
@ -538,8 +538,6 @@ class InstrItineraryData;
|
||||
|
||||
bool HasStandaloneRem = true;
|
||||
|
||||
void InitLibcallCallingConvs();
|
||||
|
||||
void addTypeForNEON(MVT VT, MVT PromotedLdStVT, MVT PromotedBitwiseVT);
|
||||
void addDRTypeForNEON(MVT VT);
|
||||
void addQRTypeForNEON(MVT VT);
|
||||
|
@ -18,7 +18,7 @@ declare double @llvm.powi.f64(double %Val, i32 %power)
|
||||
define double @powi_d(double %a, i32 %b) {
|
||||
; CHECK-LABEL: powi_d:
|
||||
; SOFT: {{(bl|b)}} __powidf2
|
||||
; HARD: bl __powidf2
|
||||
; HARD: b __powidf2
|
||||
%1 = call double @llvm.powi.f64(double %a, i32 %b)
|
||||
ret double %1
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ declare float @llvm.powi.f32(float %Val, i32 %power)
|
||||
define float @powi_f(float %a, i32 %b) {
|
||||
; CHECK-LABEL: powi_f:
|
||||
; SOFT: bl __powisf2
|
||||
; HARD: bl __powisf2
|
||||
; HARD: b __powisf2
|
||||
%1 = call float @llvm.powi.f32(float %a, i32 %b)
|
||||
ret float %1
|
||||
}
|
||||
|
41
llvm/test/CodeGen/Thumb2/intrinsics-cc.ll
Normal file
41
llvm/test/CodeGen/Thumb2/intrinsics-cc.ll
Normal file
@ -0,0 +1,41 @@
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-eabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-eabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-eabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-eabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
|
||||
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-gnueabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-gnueabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-gnueabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-gnueabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
|
||||
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-musleabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-musleabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-musleabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD
|
||||
; RUN: llc -mtriple thumbv7-unknown-none-musleabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
|
||||
|
||||
declare float @llvm.powi.f32(float, i32)
|
||||
|
||||
define float @f(float %f, i32 %i) {
|
||||
entry:
|
||||
%0 = call float @llvm.powi.f32(float %f, i32 %i)
|
||||
ret float %0
|
||||
}
|
||||
|
||||
; CHECK-MATCH: b __powisf2
|
||||
; CHECK-MISMATCH: bl __powisf2
|
||||
; CHECK-TO-SOFT: vmov s0, r0
|
||||
; CHECK-TO-HARD: vmov r0, s0
|
||||
|
||||
declare double @llvm.powi.f64(double, i32)
|
||||
|
||||
define double @g(double %d, i32 %i) {
|
||||
entry:
|
||||
%0 = call double @llvm.powi.f64(double %d, i32 %i)
|
||||
ret double %0
|
||||
}
|
||||
|
||||
; CHECK-MATCH: b __powidf2
|
||||
; CHECK-MISMATCH: bl __powidf2
|
||||
; CHECK-TO-SOFT: vmov d0, r0, r1
|
||||
; CHECK-TO-HARD: vmov r0, r1, d0
|
||||
|
Loading…
Reference in New Issue
Block a user