Make the ARM ABI selectable via SubtargetFeature.

This patch makes it possible to select the ABI with -mattr. It will be used to
forward clang's -target-abi option to llvm's CodeGen.

llvm-svn: 198304
This commit is contained in:
Rafael Espindola 2014-01-02 13:40:08 +00:00
parent d4993032a9
commit d89b16dcb8
4 changed files with 61 additions and 14 deletions

View File

@ -255,6 +255,14 @@ def ProcKrait : SubtargetFeature<"krait", "ARMProcFamily", "Krait",
FeatureHWDiv,
FeatureHWDivARM]>;
def FeatureAPCS : SubtargetFeature<"apcs", "TargetABI", "ARM_ABI_APCS",
"Use the APCS ABI">;
def FeatureAAPCS : SubtargetFeature<"aapcs", "TargetABI", "ARM_ABI_AAPCS",
"Use the AAPCS ABI">;
class ProcNoItin<string Name, list<SubtargetFeature> Features>
: Processor<Name, NoItineraries, Features>;

View File

@ -83,7 +83,7 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
, CPUString(CPU)
, TargetTriple(TT)
, Options(Options)
, TargetABI(ARM_ABI_APCS) {
, TargetABI(ARM_ABI_UNKNOWN) {
initializeEnvironment();
resetSubtargetFeatures(CPU, FS);
}
@ -189,18 +189,22 @@ void ARMSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) {
// Initialize scheduling itinerary for the specified CPU.
InstrItins = getInstrItineraryForCPU(CPUString);
switch (TargetTriple.getEnvironment()) {
case Triple::Android:
case Triple::EABI:
case Triple::EABIHF:
case Triple::GNUEABI:
case Triple::GNUEABIHF:
TargetABI = ARM_ABI_AAPCS;
break;
default:
if (isTargetIOS() && isMClass())
if (TargetABI == ARM_ABI_UNKNOWN) {
switch (TargetTriple.getEnvironment()) {
case Triple::Android:
case Triple::EABI:
case Triple::EABIHF:
case Triple::GNUEABI:
case Triple::GNUEABIHF:
TargetABI = ARM_ABI_AAPCS;
break;
break;
default:
if (isTargetIOS() && isMClass())
TargetABI = ARM_ABI_AAPCS;
else
TargetABI = ARM_ABI_APCS;
break;
}
}
if (isAAPCS_ABI())

View File

@ -217,6 +217,7 @@ protected:
public:
enum {
ARM_ABI_UNKNOWN,
ARM_ABI_APCS,
ARM_ABI_AAPCS // ARM EABI
} TargetABI;
@ -326,8 +327,14 @@ public:
TargetTriple.getEnvironment() == Triple::EABIHF;
}
bool isAPCS_ABI() const { return TargetABI == ARM_ABI_APCS; }
bool isAAPCS_ABI() const { return TargetABI == ARM_ABI_AAPCS; }
bool isAPCS_ABI() const {
assert(TargetABI != ARM_ABI_UNKNOWN);
return TargetABI == ARM_ABI_APCS;
}
bool isAAPCS_ABI() const {
assert(TargetABI != ARM_ABI_UNKNOWN);
return TargetABI == ARM_ABI_AAPCS;
}
bool isThumb() const { return InThumbMode; }
bool isThumb1Only() const { return InThumbMode && !HasThumb2; }

View File

@ -0,0 +1,28 @@
; RUN: llc -mtriple=arm-linux < %s | FileCheck %s --check-prefix=APCS
; RUN: llc -mtriple=arm-linux -mattr=apcs < %s | \
; RUN: FileCheck %s --check-prefix=APCS
; RUN: llc -mtriple=arm-linux-gnueabi -mattr=apcs < %s | \
; RUN: FileCheck %s --check-prefix=APCS
; RUN: llc -mtriple=arm-linux-gnueabi < %s | FileCheck %s --check-prefix=AAPCS
; RUN: llc -mtriple=arm-linux-gnueabi -mattr=aapcs < %s | \
; RUN: FileCheck %s --check-prefix=AAPCS
; RUN: llc -mtriple=arm-linux-gnu -mattr=aapcs < %s | \
; RUN: FileCheck %s --check-prefix=AAPCS
; The stack is 8 byte aligned on AAPCS and 4 on APCS, so we should get a BIC
; only on APCS.
define void @g() {
; APCS: sub sp, sp, #8
; APCS: bic sp, sp, #7
; AAPCS: sub sp, sp, #8
; AAPCS-NOT: bic
%c = alloca i8, align 8
call void @f(i8* %c)
ret void
}
declare void @f(i8*)