assert(GV && "C++ constructor pointer was not a GlobalValue!");
const MCExpr *E = MCSymbolRefExpr::Create(getSymbol(GV),
- (Subtarget->isTargetDarwin()
- ? MCSymbolRefExpr::VK_None
- : MCSymbolRefExpr::VK_ARM_TARGET1),
+ (Subtarget->isTargetELF()
+ ? MCSymbolRefExpr::VK_ARM_TARGET1
+ : MCSymbolRefExpr::VK_None),
OutContext);
OutStreamer.EmitValue(E, Size);
}
void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
- if (Subtarget->isTargetDarwin()) {
+ if (Subtarget->isTargetMachO()) {
Reloc::Model RelocM = TM.getRelocationModel();
if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
// Declare all the text sections up front (before the DWARF sections
void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
- if (Subtarget->isTargetDarwin()) {
+ if (Subtarget->isTargetMachO()) {
// All darwin targets use mach-o.
const TargetLoweringObjectFileMachO &TLOFMacho =
static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV,
unsigned char TargetFlags) {
- bool isIndirect = Subtarget->isTargetDarwin() &&
+ bool isIndirect = Subtarget->isTargetMachO() &&
(TargetFlags & ARMII::MO_NONLAZY) &&
Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
if (!isIndirect)
// On Darwin, const-pool entries may get the "FOO$non_lazy_ptr" mangling, so
// flag the global as MO_NONLAZY.
- unsigned char TF = Subtarget->isTargetDarwin() ? ARMII::MO_NONLAZY : 0;
+ unsigned char TF = Subtarget->isTargetMachO() ? ARMII::MO_NONLAZY : 0;
MCSym = GetARMGVSymbol(GV, TF);
} else if (ACPV->isMachineBasicBlock()) {
const MachineBasicBlock *MBB = cast<ARMConstantPoolMBB>(ACPV)->getMBB();
case ARM::TRAP: {
// Non-Darwin binutils don't yet support the "trap" mnemonic.
// FIXME: Remove this special case when they do.
- if (!Subtarget->isTargetDarwin()) {
+ if (!Subtarget->isTargetMachO()) {
//.long 0xe7ffdefe @ trap
uint32_t Val = 0xe7ffdefeUL;
OutStreamer.AddComment("trap");
case ARM::tTRAP: {
// Non-Darwin binutils don't yet support the "trap" mnemonic.
// FIXME: Remove this special case when they do.
- if (!Subtarget->isTargetDarwin()) {
+ if (!Subtarget->isTargetMachO()) {
//.short 57086 @ trap
uint16_t Val = 0xdefe;
OutStreamer.AddComment("trap");
virtual unsigned getISAEncoding() LLVM_OVERRIDE {
// ARM/Darwin adds ISA to the DWARF info for each function.
- if (!Subtarget->isTargetDarwin())
+ if (!Subtarget->isTargetMachO())
return 0;
return Subtarget->isThumb() ?
ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm;
ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMSubtarget &sti)
: ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC), STI(sti),
- FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11),
+ FramePtr((STI.isTargetMachO() || STI.isThumb()) ? ARM::R7 : ARM::R11),
BasePtr(ARM::R6) {
}
(const TargetRegisterClass*)&ARM::GPRRegClass;
unsigned DestReg = createResultReg(RC);
- // FastISel TLS support on non-Darwin is broken, punt to SelectionDAG.
+ // FastISel TLS support on non-MachO is broken, punt to SelectionDAG.
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
bool IsThreadLocal = GVar && GVar->isThreadLocal();
- if (!Subtarget->isTargetDarwin() && IsThreadLocal) return 0;
+ if (!Subtarget->isTargetMachO() && IsThreadLocal) return 0;
// Use movw+movt when possible, it avoids constant pool entries.
// Non-darwin targets only support static movt relocations in FastISel.
if (Subtarget->useMovt() &&
- (Subtarget->isTargetDarwin() || RelocM == Reloc::Static)) {
+ (Subtarget->isTargetMachO() || RelocM == Reloc::Static)) {
unsigned Opc;
unsigned char TF = 0;
- if (Subtarget->isTargetDarwin())
+ if (Subtarget->isTargetMachO())
TF = ARMII::MO_NONLAZY;
switch (RelocM) {
const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>();
// Thumb2 support on iOS; ARM support on iOS, Linux and NaCl.
bool UseFastISel = false;
- UseFastISel |= Subtarget->isTargetIOS() && !Subtarget->isThumb1Only();
+ UseFastISel |= Subtarget->isTargetMachO() && !Subtarget->isThumb1Only();
UseFastISel |= Subtarget->isTargetLinux() && !Subtarget->isThumb();
UseFastISel |= Subtarget->isTargetNaCl() && !Subtarget->isThumb();
case ARM::R12:
if (Reg == FramePtr)
FramePtrSpillFI = FI;
- if (STI.isTargetIOS())
+ if (STI.isTargetMachO())
GPRCS2Size += 4;
else
GPRCS1Size += 4;
// Jump to label or value in register.
if (RetOpcode == ARM::TCRETURNdi) {
unsigned TCOpcode = STI.isThumb() ?
- (STI.isTargetIOS() ? ARM::tTAILJMPd : ARM::tTAILJMPdND) :
+ (STI.isTargetMachO() ? ARM::tTAILJMPd : ARM::tTAILJMPdND) :
ARM::TAILJMPd;
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(TCOpcode));
if (JumpTarget.isGlobal())
unsigned LastReg = 0;
for (; i != 0; --i) {
unsigned Reg = CSI[i-1].getReg();
- if (!(Func)(Reg, STI.isTargetIOS())) continue;
+ if (!(Func)(Reg, STI.isTargetMachO())) continue;
// D-registers in the aligned area DPRCS2 are NOT spilled here.
if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
bool DeleteRet = false;
for (; i != 0; --i) {
unsigned Reg = CSI[i-1].getReg();
- if (!(Func)(Reg, STI.isTargetIOS())) continue;
+ if (!(Func)(Reg, STI.isTargetMachO())) continue;
// The aligned reloads from area DPRCS2 are not inserted here.
if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
if (Spilled) {
NumGPRSpills++;
- if (!STI.isTargetIOS()) {
+ if (!STI.isTargetMachO()) {
if (Reg == ARM::LR)
LRSpilled = true;
CS1Spilled = true;
break;
}
} else {
- if (!STI.isTargetIOS()) {
+ if (!STI.isTargetMachO()) {
UnspilledCS1GPRs.push_back(Reg);
continue;
}
}
static TargetLoweringObjectFile *createTLOF(TargetMachine &TM) {
- if (TM.getSubtarget<ARMSubtarget>().isTargetDarwin())
+ if (TM.getSubtarget<ARMSubtarget>().isTargetMachO())
return new TargetLoweringObjectFileMachO();
return new ARMElfTargetObjectFile();
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
- if (Subtarget->isTargetIOS()) {
+ if (Subtarget->isTargetMachO()) {
// Uses VFP for Thumb libfuncs if available.
if (Subtarget->isThumb() && Subtarget->hasVFP2() &&
Subtarget->hasARMOps()) {
setLibcallName(RTLIB::SRL_I128, 0);
setLibcallName(RTLIB::SRA_I128, 0);
- if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetDarwin()) {
+ if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetMachO()) {
// Double-precision floating-point arithmetic helper functions
// RTABI chapter 4.1.2, Table 2
setLibcallName(RTLIB::ADD_F64, "__aeabi_dadd");
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
- if (!Subtarget->isTargetDarwin()) {
- // Non-Darwin platforms may return values in these registers via the
+ if (!Subtarget->isTargetMachO()) {
+ // Non-MachO platforms may return values in these registers via the
// personality function.
setExceptionPointerRegister(ARM::R0);
setExceptionSelectorRegister(ARM::R1);
const GlobalValue *GV = G->getGlobal();
isDirect = true;
bool isExt = GV->isDeclaration() || GV->isWeakForLinker();
- bool isStub = (isExt && Subtarget->isTargetDarwin()) &&
+ bool isStub = (isExt && Subtarget->isTargetMachO()) &&
getTargetMachine().getRelocationModel() != Reloc::Static;
isARMFunc = !Subtarget->isThumb() || isStub;
// ARM call to a local ARM function is predicable.
isLocalARMFunc = !Subtarget->isThumb() && (!isExt || !ARMInterworking);
// tBX takes a register source operand.
if (isStub && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
- assert(Subtarget->isTargetDarwin() && "WrapperPIC use on non-Darwin?");
+ assert(Subtarget->isTargetMachO() && "WrapperPIC use on non-MachO?");
Callee = DAG.getNode(ARMISD::WrapperPIC, dl, getPointerTy(),
DAG.getTargetGlobalAddress(GV, dl, getPointerTy()));
} else {
}
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
isDirect = true;
- bool isStub = Subtarget->isTargetDarwin() &&
+ bool isStub = Subtarget->isTargetMachO() &&
getTargetMachine().getRelocationModel() != Reloc::Static;
isARMFunc = !Subtarget->isThumb() || isStub;
// tBX takes a register source operand.
EVT VT = Op.getValueType();
SDLoc dl(Op); // FIXME probably not meaningful
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
- unsigned FrameReg = (Subtarget->isThumb() || Subtarget->isTargetDarwin())
+ unsigned FrameReg = (Subtarget->isThumb() || Subtarget->isTargetMachO())
? ARM::R7 : ARM::R11;
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
while (Depth--)
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
case ISD::GlobalAddress:
- return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) :
+ return Subtarget->isTargetMachO() ? LowerGlobalAddressDarwin(Op, DAG) :
LowerGlobalAddressELF(Op, DAG);
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
case ISD::SELECT: return LowerSELECT(Op, DAG);
AssemblerPredicate<"!ModeThumb", "arm-mode">;
def IsIOS : Predicate<"Subtarget->isTargetIOS()">;
def IsNotIOS : Predicate<"!Subtarget->isTargetIOS()">;
+def IsMachO : Predicate<"Subtarget->isTargetMachO()">;
+def IsNotMachO : Predicate<"!Subtarget->isTargetMachO()">;
def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
def UseNaClTrap : Predicate<"Subtarget->useNaClTrap()">,
AssemblerPredicate<"FeatureNaClTrap", "NaCl">;
(tBX GPR:$dst, (ops 14, zero_reg))>,
Requires<[IsThumb]>, Sched<[WriteBr]>;
}
- // tTAILJMPd: IOS version uses a Thumb2 branch (no Thumb1 tail calls
- // on IOS), so it's in ARMInstrThumb2.td.
- // Non-IOS version:
+ // tTAILJMPd: MachO version uses a Thumb2 branch (no Thumb1 tail calls
+ // on MachO), so it's in ARMInstrThumb2.td.
+ // Non-MachO version:
let Uses = [SP] in {
def tTAILJMPdND : tPseudoExpand<(outs),
(ins t_brtarget:$dst, pred:$p),
4, IIC_Br, [],
(tB t_brtarget:$dst, pred:$p)>,
- Requires<[IsThumb, IsNotIOS]>, Sched<[WriteBr]>;
+ Requires<[IsThumb, IsNotMachO]>, Sched<[WriteBr]>;
}
}
let AsmMatchConverter = "cvtThumbBranches";
}
-// Tail calls. The IOS version of thumb tail calls uses a t2 branch, so
+// Tail calls. The MachO version of thumb tail calls uses a t2 branch, so
// it goes here.
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
// IOS version.
(ins uncondbrtarget:$dst, pred:$p),
4, IIC_Br, [],
(t2B uncondbrtarget:$dst, pred:$p)>,
- Requires<[IsThumb2, IsIOS]>, Sched<[WriteBr]>;
+ Requires<[IsThumb2, IsMachO]>, Sched<[WriteBr]>;
}
// IT block
SDValue Src, SDValue Size,
unsigned Align, bool isVolatile,
MachinePointerInfo DstPtrInfo) const {
- // Use default for non-AAPCS (or Darwin) subtargets
- if (!Subtarget->isAAPCS_ABI() || Subtarget->isTargetDarwin())
+ // Use default for non-AAPCS (or MachO) subtargets
+ if (!Subtarget->isAAPCS_ABI() || Subtarget->isTargetMachO())
return SDValue();
const ARMTargetLowering &TLI =
case Triple::EABIHF:
case Triple::GNUEABI:
case Triple::GNUEABIHF:
+ case Triple::MachO:
TargetABI = ARM_ABI_AAPCS;
break;
default:
UseMovt = hasV6T2Ops() && ArmUseMOVT;
- if (!isTargetIOS()) {
- IsR9Reserved = ReserveR9;
- } else {
+ if (isTargetMachO()) {
IsR9Reserved = ReserveR9 | !HasV6Ops;
- SupportsTailCall = !getTargetTriple().isOSVersionLT(5, 0);
- }
+ SupportsTailCall = !isTargetIOS() || !getTargetTriple().isOSVersionLT(5, 0);
+ } else
+ IsR9Reserved = ReserveR9;
if (!isThumb() || hasThumb2())
PostRAScheduler = true;
// The above behavior is consistent with GCC.
AllowsUnalignedMem = (
(hasV7Ops() && (isTargetLinux() || isTargetNaCl())) ||
- (hasV6Ops() && isTargetDarwin()));
+ (hasV6Ops() && isTargetMachO()));
break;
case StrictAlign:
AllowsUnalignedMem = false;
if (GV->isDeclaration() && !GV->isMaterializable())
isDecl = true;
- if (!isTargetDarwin()) {
+ if (!isTargetMachO()) {
// Extra load is needed for all externally visible.
if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
return false;
bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
+
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
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SourceMgr.h"
StringRef TT, StringRef CPU) {
Triple TheTriple(TT);
- if (TheTriple.isOSDarwin()) {
+ if (TheTriple.isOSBinFormatMachO()) {
MachO::CPUSubTypeARM CS =
StringSwitch<MachO::CPUSubTypeARM>(TheTriple.getArchName())
.Cases("armv4t", "thumbv4t", MachO::CPU_SUBTYPE_ARM_V4T)
bool isThumb2() const {
return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
}
- bool isTargetDarwin() const {
+ bool isTargetMachO() const {
Triple TT(STI.getTargetTriple());
- return TT.isOSDarwin();
+ return TT.isOSBinFormatMachO();
}
unsigned getMachineSoImmOpValue(unsigned SoImm) const;
switch (ARM16Expr->getKind()) {
default: llvm_unreachable("Unsupported ARMFixup");
case ARMMCExpr::VK_ARM_HI16:
- if (!isTargetDarwin() && EvaluateAsPCRel(E))
+ if (!isTargetMachO() && EvaluateAsPCRel(E))
Kind = MCFixupKind(isThumb2()
? ARM::fixup_t2_movt_hi16_pcrel
: ARM::fixup_arm_movt_hi16_pcrel);
: ARM::fixup_arm_movt_hi16);
break;
case ARMMCExpr::VK_ARM_LO16:
- if (!isTargetDarwin() && EvaluateAsPCRel(E))
+ if (!isTargetMachO() && EvaluateAsPCRel(E))
Kind = MCFixupKind(isThumb2()
? ARM::fixup_t2_movw_lo16_pcrel
: ARM::fixup_arm_movw_lo16_pcrel);
// it's just a plain immediate expression, and those evaluate to
// the lower 16 bits of the expression regardless of whether
// we have a movt or a movw.
- if (!isTargetDarwin() && EvaluateAsPCRel(E))
+ if (!isTargetMachO() && EvaluateAsPCRel(E))
Kind = MCFixupKind(isThumb2()
? ARM::fixup_t2_movw_lo16_pcrel
: ARM::fixup_arm_movw_lo16_pcrel);
static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
Triple TheTriple(TT);
- if (TheTriple.isOSDarwin())
+ if (TheTriple.isOSBinFormatMachO())
return new ARMMCAsmInfoDarwin();
return new ARMELFMCAsmInfo();
bool NoExecStack) {
Triple TheTriple(TT);
- if (TheTriple.isOSDarwin())
+ if (TheTriple.isOSBinFormatMachO())
return createMachOStreamer(Ctx, MAB, OS, Emitter, false);
if (TheTriple.isOSWindows()) {
case ARM::R11:
if (Reg == FramePtr)
FramePtrSpillFI = FI;
- if (STI.isTargetIOS())
+ if (STI.isTargetMachO())
GPRCS2Size += 4;
else
GPRCS1Size += 4;
StringRef CPU) {
Triple TheTriple(TT);
- if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
+ if (TheTriple.isOSBinFormatMachO())
return new DarwinX86_32AsmBackend(T, MRI, CPU,
TheTriple.isMacOSX() &&
!TheTriple.isMacOSXVersionLT(10, 7));
StringRef CPU) {
Triple TheTriple(TT);
- if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) {
+ if (TheTriple.isOSBinFormatMachO()) {
MachO::CPUSubTypeX86 CS =
StringSwitch<MachO::CPUSubTypeX86>(TheTriple.getArchName())
.Case("x86_64h", MachO::CPU_SUBTYPE_X86_64_H)
bool is64Bit = TheTriple.getArch() == Triple::x86_64;
MCAsmInfo *MAI;
- if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) {
+ if (TheTriple.isOSBinFormatMachO()) {
if (is64Bit)
MAI = new X86_64MCAsmInfoDarwin(TheTriple);
else
bool NoExecStack) {
Triple TheTriple(TT);
- if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
+ if (TheTriple.isOSBinFormatMachO())
return createMachOStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll);
if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
-; RUN: llc -mtriple=thumbv6m-apple-darwin-eabi -relocation-model=pic -o - %s | FileCheck %s --check-prefix=CHECK-THUMB-PIC
-; RUN: llc -mtriple=arm-apple-darwin-eabi -relocation-model=pic -o - %s | FileCheck %s --check-prefix=CHECK-ARM-PIC
-; RUN: llc -mtriple=thumbv6m-apple-darwin-eabi -relocation-model=dynamic-no-pic -o - %s | FileCheck %s --check-prefix=CHECK-DYNAMIC
-; RUN: llc -mtriple=arm-apple-darwin-eabi -relocation-model=dynamic-no-pic -o - %s | FileCheck %s --check-prefix=CHECK-DYNAMIC
-; RUN: llc -mtriple=thumbv6m-apple-darwin-eabi -relocation-model=static -o - %s | FileCheck %s --check-prefix=CHECK-STATIC
-; RUN: llc -mtriple=arm-apple-darwin-eabi -relocation-model=static -o - %s | FileCheck %s --check-prefix=CHECK-STATIC
+; RUN: llc -mtriple=thumbv6m-apple-none-macho -relocation-model=pic -o - %s | FileCheck %s --check-prefix=CHECK-THUMB-PIC
+; RUN: llc -mtriple=arm-apple-none-macho -relocation-model=pic -o - %s | FileCheck %s --check-prefix=CHECK-ARM-PIC
+; RUN: llc -mtriple=thumbv6m-apple-none-macho -relocation-model=dynamic-no-pic -o - %s | FileCheck %s --check-prefix=CHECK-DYNAMIC
+; RUN: llc -mtriple=arm-apple-none-macho -relocation-model=dynamic-no-pic -o - %s | FileCheck %s --check-prefix=CHECK-DYNAMIC
+; RUN: llc -mtriple=thumbv6m-apple-none-macho -relocation-model=static -o - %s | FileCheck %s --check-prefix=CHECK-STATIC
+; RUN: llc -mtriple=arm-apple-none-macho -relocation-model=static -o - %s | FileCheck %s --check-prefix=CHECK-STATIC
@var = global [16 x i32] zeroinitializer
declare void @bar(i32*)
-; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=thumbv7-apple-darwin
-; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=thumbv7-linux-gnueabi
+; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=thumbv7-apple-darwin
+; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=armv7-linux-gnueabi
; rdar://9515076
; (Make sure this doesn't crash.)
-; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=armv7-apple-darwin | FileCheck %s --check-prefix=DARWIN-ARM
+; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=DARWIN-ARM
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=armv7-linux-gnueabi | FileCheck %s --check-prefix=LINUX-ARM
-; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefix=DARWIN-THUMB2
+; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=DARWIN-THUMB2
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=thumbv7-linux-gnueabi | FileCheck %s --check-prefix=LINUX-THUMB2
define i8* @frameaddr_index0() nounwind {
; DARWIN-ARM-LABEL: frameaddr_index1:
; DARWIN-ARM: push {r7}
; DARWIN-ARM: mov r7, sp
-; DARWIN-ARM: mov r0, r7
-; DARWIN-ARM: ldr r0, [r0]
+; DARWIN-ARM: ldr r0, [r7]
; DARWIN-THUMB2-LABEL: frameaddr_index1:
; DARWIN-THUMB2: str r7, [sp, #-4]!
; DARWIN-THUMB2: mov r7, sp
-; DARWIN-THUMB2: mov r0, r7
-; DARWIN-THUMB2: ldr r0, [r0]
+; DARWIN-THUMB2: ldr r0, [r7]
; LINUX-ARM-LABEL: frameaddr_index1:
; LINUX-ARM: push {r11}
; DARWIN-ARM-LABEL: frameaddr_index3:
; DARWIN-ARM: push {r7}
; DARWIN-ARM: mov r7, sp
-; DARWIN-ARM: mov r0, r7
-; DARWIN-ARM: ldr r0, [r0]
+; DARWIN-ARM: ldr r0, [r7]
; DARWIN-ARM: ldr r0, [r0]
; DARWIN-ARM: ldr r0, [r0]
; DARWIN-THUMB2-LABEL: frameaddr_index3:
; DARWIN-THUMB2: str r7, [sp, #-4]!
; DARWIN-THUMB2: mov r7, sp
-; DARWIN-THUMB2: mov r0, r7
-; DARWIN-THUMB2: ldr r0, [r0]
+; DARWIN-THUMB2: ldr r0, [r7]
; DARWIN-THUMB2: ldr r0, [r0]
; DARWIN-THUMB2: ldr r0, [r0]
-; RUN: llc -mtriple=thumbv7-apple-darwin-eabi < %s | FileCheck %s
-; RUN: llc -mtriple=thumbv6m-apple-darwin-eabi -disable-fp-elim < %s | FileCheck %s --check-prefix=CHECK-T1
+; RUN: llc -mtriple=thumbv7-apple-none-macho < %s | FileCheck %s
+; RUN: llc -mtriple=thumbv6m-apple-none-macho -disable-fp-elim < %s | FileCheck %s --check-prefix=CHECK-T1
; RUN: llc -mtriple=thumbv7-apple-darwin-ios -disable-fp-elim < %s | FileCheck %s --check-prefix=CHECK-IOS
define void @check_simple() minsize {
; CHECK-LABEL: check_simple:
-; CHECK: push.w {r7, r8, r9, r10, r11, lr}
+; CHECK: push {r3, r4, r5, r6, r7, lr}
; CHECK-NOT: sub sp, sp,
; ...
; CHECK-NOT: add sp, sp,
-; CHECK: pop.w {r0, r1, r2, r3, r11, pc}
+; CHECK: pop {r0, r1, r2, r3, r7, pc}
; CHECK-T1-LABEL: check_simple:
; CHECK-T1: push {r3, r4, r5, r6, r7, lr}
define void @check_simple_too_big() minsize {
; CHECK-LABEL: check_simple_too_big:
-; CHECK: push.w {r11, lr}
+; CHECK: push {r7, lr}
; CHECK: sub sp,
; ...
; CHECK: add sp,
-; CHECK: pop.w {r11, pc}
+; CHECK: pop {r7, pc}
%var = alloca i8, i32 64
call void @bar(i8* %var)
ret void
; folded in except that doing so would clobber the value being returned.
define i64 @check_no_return_clobber() minsize {
; CHECK-LABEL: check_no_return_clobber:
-; CHECK: push.w {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
+; CHECK: push {r1, r2, r3, r4, r5, r6, r7, lr}
; CHECK-NOT: sub sp,
; ...
-; CHECK: add sp, #40
-; CHECK: pop.w {r11, pc}
+; CHECK: add sp, #24
+; CHECK: pop {r7, pc}
; Just to keep iOS FileCheck within previous function:
; CHECK-IOS-LABEL: check_no_return_clobber:
- %var = alloca i8, i32 40
+ %var = alloca i8, i32 20
call void @bar(i8* %var)
ret i64 0
}
; We want the epilogue to be the only thing in a basic block so that we hit
; the correct edge-case (first inst in block is correct one to adjust).
ret void
-}
\ No newline at end of file
+}
; RUN: llc -mtriple=arm-none-none-eabi -mcpu=cortex-a15 -o - %s | FileCheck --check-prefix=CHECK-A %s
; RUN: llc -mtriple=thumb-none-none-eabi -mcpu=cortex-a15 -o - %s | FileCheck --check-prefix=CHECK-A-THUMB %s
-; RUN: llc -mtriple=thumb-apple-darwin -mcpu=cortex-m3 -o - %s | FileCheck --check-prefix=CHECK-M %s
+; RUN: llc -mtriple=thumb-apple-none-macho -mcpu=cortex-m3 -o - %s | FileCheck --check-prefix=CHECK-M %s
declare arm_aapcscc void @bar()
; Normal AAPCS function (r0-r3 pushed onto stack by hardware, lr set to
; appropriate sentinel so no special return needed).
+; CHECK-M-LABEL: irq_fn:
; CHECK-M: push {r4, r7, lr}
; CHECK-M: add r7, sp, #4
-; CHECK-M: sub sp, #4
; CHECK-M: mov r4, sp
+; CHECK-M: bic r4, r4, #7
; CHECK-M: mov sp, r4
; CHECK-M: blx _bar
; CHECK-M: subs r4, r7, #4
; CHECK-A: pop {r0, r1, r2, r3, r4, r5, r6, r7, r11, lr}
; CHECK-A: subs pc, lr, #4
+; CHECK-A-THUMB-LABEL: fiq_fn:
+; CHECK-M-LABEL: fiq_fn:
%val = load volatile [16 x i32]* @bigvar
store volatile [16 x i32] %val, [16 x i32]* @bigvar
ret void
-; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s
-; RUN: llc < %s -mtriple=armv4t-apple-darwin | FileCheck %s -check-prefix=V4T
+; RUN: llc < %s -mtriple=armv7-apple-ios3.0 | FileCheck %s
+; RUN: llc < %s -mtriple=armv4t-apple-ios3.0 | FileCheck %s -check-prefix=V4T
@X = external global [0 x i32] ; <[0 x i32]*> [#uses=5]
; RUN: llc < %s -mtriple=armv7-apple-ios -o - | FileCheck %s
-; RUN: llc < %s -mtriple=thumbv7m-darwin-eabi -o - | FileCheck %s --check-prefix=DARWIN
+; RUN: llc < %s -mtriple=thumbv7m-none-macho -o - | FileCheck %s --check-prefix=DARWIN
; RUN: llc < %s -mtriple=arm-none-eabi -o - | FileCheck --check-prefix=EABI %s
; RUN: llc < %s -mtriple=arm-none-eabihf -o - | FileCheck --check-prefix=EABI %s
--- /dev/null
+; RUN: llc -mtriple=thumbv7m-none-macho %s -o - -relocation-model=pic -disable-fp-elim | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NON-FAST
+; RUN: llc -mtriple=thumbv7m-none-macho -O0 %s -o - -relocation-model=pic -disable-fp-elim | FileCheck %s
+; RUN: llc -mtriple=thumbv7m-none-macho -filetype=obj %s -o /dev/null
+
+ ; Bare-metal should probably "declare" segments just like normal MachO
+; CHECK: __picsymbolstub4
+; CHECK: __StaticInit
+; CHECK: __text
+
+@var = external global i32
+
+define i32 @test_litpool() minsize {
+; CHECK-LABEL: test_litpool:
+ %val = load i32* @var
+ ret i32 %val
+
+ ; Lit-pool entries need to produce a "$non_lazy_ptr" version of the symbol.
+; CHECK: LCPI0_0:
+; CHECK-NEXT: .long L_var$non_lazy_ptr-(LPC0_0+4)
+}
+
+define i32 @test_movw_movt() {
+; CHECK-LABEL: test_movw_movt:
+ %val = load i32* @var
+ ret i32 %val
+
+ ; movw/movt should also address their symbols MachO-style
+; CHECK: movw [[RTMP:r[0-9]+]], :lower16:(L_var$non_lazy_ptr-(LPC1_0+4))
+; CHECK: movt [[RTMP]], :upper16:(L_var$non_lazy_ptr-(LPC1_0+4))
+; CHECK: LPC1_0:
+; CHECK: add [[RTMP]], pc
+}
+
+declare void @llvm.trap()
+
+define void @test_trap() {
+; CHECK-LABEL: test_trap:
+
+ ; Bare-metal MachO gets compiled on top of normal MachO toolchain which
+ ; understands trap natively.
+ call void @llvm.trap()
+; CHECK: trap
+
+ ret void
+}
+
+define i32 @test_frame_ptr() {
+; CHECK-LABEL: test_frame_ptr:
+ call void @test_trap()
+
+ ; Frame pointer is r7 as for Darwin
+; CHECK: mov r7, sp
+ ret i32 42
+}
+
+%big_arr = type [8 x i32]
+define void @test_two_areas(%big_arr* %addr) {
+; CHECK-LABEL: test_two_areas:
+ %val = load %big_arr* %addr
+ call void @test_trap()
+ store %big_arr %val, %big_arr* %addr
+
+ ; This goes with the choice of r7 as FP (largely). FP and LR have to be stored
+ ; consecutively on the stack for the frame record to be valid, which means we
+ ; need the 2 register-save areas employed by iOS.
+; CHECK-NON-FAST: push {r4, r5, r6, r7, lr}
+; CHECK-NON-FAST: push.w {r8, r9, r10, r11}
+; ...
+; CHECK-NON-FAST: pop.w {r8, r9, r10, r11}
+; CHECK-NON-FAST: pop {r4, r5, r6, r7, pc}
+ ret void
+}
+
+define void @test_tail_call() {
+; CHECK-LABEL: test_tail_call:
+ tail call void @test_trap()
+
+ ; Tail calls should be available and use Thumb2 branch.
+; CHECK: b.w _test_trap
+ ret void
+}
+
+define float @test_softfloat_calls(float %in) {
+; CHECK-LABEL: test_softfloat_calls:
+ %sum = fadd float %in, %in
+
+ ; Soft-float calls should be GNU-style rather than RTABI and should not be the
+ ; *vfp variants used for ARMv6 iOS.
+; CHECK: blx ___addsf3{{$}}
+ ret float %sum
+}
+
+ ; Even bare-metal PIC needs GOT-like behaviour, in principle. Depends a bit on
+ ; the use-case of course, but LLVM doesn't know what that is.
+; CHECK: non_lazy_symbol_pointers
+; CHECK: L_var$non_lazy_ptr:
+; CHECK-NEXT: .indirect_symbol _var
+
+ ; All MachO objects should have this to give the linker leeway in removing
+ ; dead code.
+; CHECK: .subsections_via_symbols