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>;
, CPUString(CPU)
, TargetTriple(TT)
, Options(Options)
- , TargetABI(ARM_ABI_APCS) {
+ , TargetABI(ARM_ABI_UNKNOWN) {
initializeEnvironment();
resetSubtargetFeatures(CPU, 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())
public:
enum {
+ ARM_ABI_UNKNOWN,
ARM_ABI_APCS,
ARM_ABI_AAPCS // ARM EABI
} TargetABI;
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; }
--- /dev/null
+; 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*)