aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r--lib/Target/ARM/ARM.h21
-rw-r--r--lib/Target/ARM/ARM.td8
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp189
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.h23
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp2
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp11
-rw-r--r--lib/Target/ARM/ARMCallingConv.td10
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp1
-rw-r--r--lib/Target/ARM/ARMConstantPoolValue.h3
-rw-r--r--lib/Target/ARM/ARMExpandPseudoInsts.cpp172
-rw-r--r--lib/Target/ARM/ARMFastISel.cpp5
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp84
-rw-r--r--lib/Target/ARM/ARMFrameLowering.h3
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp137
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp407
-rw-r--r--lib/Target/ARM/ARMISelLowering.h15
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td208
-rw-r--r--lib/Target/ARM/ARMInstrNaCl.td145
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td12
-rw-r--r--lib/Target/ARM/ARMLoadStoreOptimizer.cpp22
-rw-r--r--lib/Target/ARM/ARMMCInstLower.cpp54
-rw-r--r--lib/Target/ARM/ARMNaClHeaders.cpp192
-rw-r--r--lib/Target/ARM/ARMNaClRewritePass.cpp755
-rw-r--r--lib/Target/ARM/ARMNaClRewritePass.h36
-rw-r--r--lib/Target/ARM/ARMSelectionDAGInfo.cpp2
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp18
-rw-r--r--lib/Target/ARM/ARMSubtarget.h19
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp23
-rw-r--r--lib/Target/ARM/ARMTargetMachine.h7
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.cpp2
-rw-r--r--lib/Target/ARM/CMakeLists.txt2
-rw-r--r--lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp65
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp35
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp7
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp5
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCNaCl.cpp329
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCNaCl.h19
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp27
-rw-r--r--lib/Target/ARM/MCTargetDesc/CMakeLists.txt1
39 files changed, 2970 insertions, 106 deletions
diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h
index 1446bbbb8e..0ac92f1ee8 100644
--- a/lib/Target/ARM/ARM.h
+++ b/lib/Target/ARM/ARM.h
@@ -20,6 +20,9 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/Target/TargetMachine.h"
+// @LOCALMOD (for LowerARMMachineInstrToMCInstPCRel)
+#include "llvm/MC/MCSymbol.h"
+
namespace llvm {
class ARMAsmPrinter;
@@ -44,9 +47,27 @@ FunctionPass *createMLxExpansionPass();
FunctionPass *createThumb2ITBlockPass();
FunctionPass *createThumb2SizeReductionPass();
+/* @LOCALMOD-START */
+FunctionPass *createARMNaClRewritePass();
+/* @LOCALMOD-END */
+
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
ARMAsmPrinter &AP);
+
+/* @LOCALMOD-START */
+// Used to lower the pc-relative MOVi16PIC / MOVTi16PIC pseudo instructions
+// into the real MOVi16 / MOVTi16 instructions.
+// See comment on MOVi16PIC for more details.
+void LowerARMMachineInstrToMCInstPCRel(const MachineInstr *MI,
+ MCInst &OutMI,
+ ARMAsmPrinter &AP,
+ unsigned ImmIndex,
+ unsigned PCIndex,
+ MCSymbol *PCLabel,
+ unsigned PCAdjustment);
+/* @LOCALMOD-END */
+
} // end namespace llvm;
#endif
diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td
index 23974ad905..00bf1b85ec 100644
--- a/lib/Target/ARM/ARM.td
+++ b/lib/Target/ARM/ARM.td
@@ -220,8 +220,12 @@ def : Processor<"arm1156t2f-s", ARMV6Itineraries, [HasV6T2Ops, FeatureVFP2,
// V7a Processors.
def : ProcessorModel<"cortex-a8", CortexA8Model,
- [ProcA8, HasV7Ops, FeatureNEON, FeatureDB,
- FeatureDSPThumb2, FeatureHasRAS]>;
+// @LOCALMOD-BEGIN
+// TODO(pdox): Resolve this mismatch.
+ [ProcA8, HasV7Ops, FeatureDB]>;
+// FeatureNEON, FeatureDSPThumb2, FeatureHasRAS]>;
+// @LOCALMOD-END
+
def : ProcessorModel<"cortex-a9", CortexA9Model,
[ProcA9, HasV7Ops, FeatureNEON, FeatureDB,
FeatureDSPThumb2, FeatureHasRAS]>;
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index e9e2803ad5..95caf529d6 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -51,6 +51,13 @@
#include <cctype>
using namespace llvm;
+// @LOCALMOD-START
+namespace llvm {
+ extern cl::opt<bool> FlagSfiBranch;
+ extern cl::opt<bool> FlagSfiData;
+}
+// @LOCALMOD-END
+
namespace {
// Per section and per symbol attributes are not supported.
@@ -222,6 +229,75 @@ getDebugValueLocation(const MachineInstr *MI) const {
return Location;
}
+// @LOCALMOD-START
+// Make sure all jump targets are aligned and also all constant pools
+void NaclAlignAllJumpTargetsAndConstantPools(MachineFunction &MF) {
+ // JUMP TABLE TARGETS
+ MachineJumpTableInfo *jt_info = MF.getJumpTableInfo();
+ if (jt_info) {
+ const std::vector<MachineJumpTableEntry> &JT = jt_info->getJumpTables();
+ for (unsigned i=0; i < JT.size(); ++i) {
+ std::vector<MachineBasicBlock*> MBBs = JT[i].MBBs;
+
+ for (unsigned j=0; j < MBBs.size(); ++j) {
+ if (MBBs[j]->begin()->getOpcode() == ARM::CONSTPOOL_ENTRY) {
+ continue;
+ }
+ MBBs[j]->setAlignment(4);
+ }
+ }
+ }
+
+ // FIRST ENTRY IN A ConstanPool
+ bool last_bb_was_constant_pool = false;
+ for (MachineFunction::iterator I = MF.begin(), E = MF.end();
+ I != E; ++I) {
+ if (I->isLandingPad()) {
+ I->setAlignment(4);
+ }
+
+ if (I->empty()) continue;
+
+ bool is_constant_pool = I->begin()->getOpcode() == ARM::CONSTPOOL_ENTRY;
+
+ if (last_bb_was_constant_pool != is_constant_pool) {
+ I->setAlignment(4);
+ }
+
+ last_bb_was_constant_pool = is_constant_pool;
+ }
+}
+
+bool ARMAsmPrinter::UseReadOnlyJumpTables() const {
+ if (Subtarget->isTargetNaCl())
+ return true;
+ return false;
+}
+
+unsigned ARMAsmPrinter::GetTargetBasicBlockAlign() const {
+ if (Subtarget->isTargetNaCl())
+ return 4;
+ return 0;
+}
+
+unsigned ARMAsmPrinter::GetTargetLabelAlign(const MachineInstr *MI) const {
+ if (Subtarget->isTargetNaCl()) {
+ switch (MI->getOpcode()) {
+ default: return 0;
+ // These labels may indicate an indirect entry point that is
+ // externally reachable and hence must be bundle aligned.
+ // Note: these labels appear to be always at basic block beginnings
+ // so it may be possible to simply set the MBB alignment.
+ // However, it is unclear whether this always holds.
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::GC_LABEL:
+ return 4;
+ }
+ }
+ return 0;
+}
+// @LOCALMOD-END
+
/// EmitDwarfRegOp - Emit dwarf register operation.
void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
const TargetRegisterInfo *RI = TM.getRegisterInfo();
@@ -298,6 +374,17 @@ void ARMAsmPrinter::EmitFunctionEntryLabel() {
OutStreamer.EmitThumbFunc(CurrentFnSym);
}
+ // @LOCALMOD-START
+ // make sure function entry is aligned. We use XmagicX as our basis
+ // for alignment decisions (c.f. assembler sfi macros)
+ int alignment = MF->getAlignment();
+ if (alignment < 4) alignment = 4;
+ EmitAlignment(alignment);
+ if (Subtarget->isTargetNaCl() && OutStreamer.hasRawTextSupport()) {
+ OutStreamer.EmitRawText(StringRef("\t.set XmagicX, .\n"));
+ }
+ // @LOCALMOD-END
+
OutStreamer.EmitLabel(CurrentFnSym);
}
@@ -324,6 +411,11 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
AFI = MF.getInfo<ARMFunctionInfo>();
MCP = MF.getConstantPool();
+ // @LOCALMOD-START
+ if (FlagSfiBranch) {
+ NaclAlignAllJumpTargetsAndConstantPools(MF);
+ }
+ // @LOCALMOD-END
return AsmPrinter::runOnMachineFunction(MF);
}
@@ -359,10 +451,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
case MachineOperand::MO_GlobalAddress: {
const GlobalValue *GV = MO.getGlobal();
if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
- (TF & ARMII::MO_LO16))
+ (TF == ARMII::MO_LO16)) // @LOCALMOD: TEMPORARY FIX
O << ":lower16:";
else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
- (TF & ARMII::MO_HI16))
+ (TF == ARMII::MO_HI16)) // @LOCALMOD: TEMPORARY FIX
O << ":upper16:";
O << *Mang->getSymbol(GV);
@@ -388,6 +480,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
//===--------------------------------------------------------------------===//
+
MCSymbol *ARMAsmPrinter::
GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
const MachineBasicBlock *MBB) const {
@@ -579,6 +672,8 @@ bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
return false;
}
+void EmitSFIHeaders(raw_ostream &O);
+
void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
if (Subtarget->isTargetDarwin()) {
Reloc::Model RelocM = TM.getRelocationModel();
@@ -623,8 +718,16 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
// Emit ARM Build Attributes
if (Subtarget->isTargetELF())
emitAttributes();
-}
+ // @LOCALMOD-BEGIN
+ if (Subtarget->isTargetNaCl() && OutStreamer.hasRawTextSupport()) {
+ std::string str;
+ raw_string_ostream OS(str);
+ EmitSFIHeaders(OS);
+ OutStreamer.EmitRawText(StringRef(OS.str()));
+ }
+ // @LOCALMOD-END
+}
void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetDarwin()) {
@@ -694,6 +797,7 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
}
}
+
//===----------------------------------------------------------------------===//
// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile()
// FIXME:
@@ -944,7 +1048,20 @@ EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
}
Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
+ } else { // @LOCALMOD-BEGIN
+ // Check mustAddCurrentAddress() when getPCAdjustment() == 0,
+ // and make it actually *Subtract* the current address.
+ // A more appropriate name is probably "relativeToCurrentAddress",
+ // since the assembler can't actually handle "X + .", only "X - .".
+ if (ACPV->mustAddCurrentAddress()) {
+ MCSymbol *DotSym = OutContext.CreateTempSymbol();
+ OutStreamer.EmitLabel(DotSym);
+ const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
+ Expr = MCBinaryExpr::CreateSub(Expr, DotExpr, OutContext);
+ }
}
+ // @LOCALMOD-END
+
OutStreamer.EmitValue(Expr, Size);
}
@@ -1609,6 +1726,28 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
InConstantPool = true;
}
+
+ // @LOCALMOD-START
+ // NOTE: we also should make sure that the first data item
+ // is not in a code bundle
+ // NOTE: there may be issues with alignment constraints
+ if (Subtarget->isTargetNaCl() && OutStreamer.hasRawTextSupport()) {
+ const unsigned size = MI->getOperand(2).getImm();
+ //assert(size == 4 || size == 8 && "Unsupported data item size");
+ if (size == 8) {
+ // we cannot generate a size 8 constant at offset 12 (mod 16)
+ OutStreamer.EmitRawText(StringRef("sfi_nop_if_at_bundle_end\n"));
+ }
+
+ if (FlagSfiData) {
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ OS << "sfi_illegal_if_at_bundle_begining @ ========== SFI (" <<
+ size << ")\n";
+ OutStreamer.EmitRawText(OS.str());
+ }
+ }
+ // @LOCALMOD-END
OutStreamer.EmitLabel(GetCPISymbol(LabelId));
const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
@@ -2037,6 +2176,50 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
return;
}
+
+ // @LOCALMOD-BEGIN
+ // These are pseudo ops for MOVW / MOVT with operands relative to a PC label.
+ // See the comments on MOVi16PIC in the .td file for more details.
+ case ARM::MOVi16PIC: {
+ MCInst TmpInst;
+ // First, build an instruction w/ the real opcode.
+ TmpInst.setOpcode(ARM::MOVi16);
+
+ unsigned ImmIndex = 1;
+ unsigned PIC_id_index = 2;
+ unsigned PCAdjustment = 8;
+ // NOTE: if getPICLabel was a method of "this", or otherwise in scope for
+ // LowerARMMachineInstrToMCInstPCRel, then we wouldn't need to create
+ // it here (as well as below).
+ MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
+ getFunctionNumber(),
+ MI->getOperand(PIC_id_index).getImm(),
+ OutContext);
+ LowerARMMachineInstrToMCInstPCRel(MI, TmpInst, *this, ImmIndex,
+ PIC_id_index, PCLabel, PCAdjustment);
+ OutStreamer.EmitInstruction(TmpInst);
+ return;
+ }
+ case ARM::MOVTi16PIC: {
+ MCInst TmpInst;
+ // First, build an instruction w/ the real opcode.
+ TmpInst.setOpcode(ARM::MOVTi16);
+
+ unsigned ImmIndex = 2;
+ unsigned PIC_id_index = 3;
+ unsigned PCAdjustment = 8;
+
+ MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
+ getFunctionNumber(),
+ MI->getOperand(PIC_id_index).getImm(),
+ OutContext);
+
+ LowerARMMachineInstrToMCInstPCRel(MI, TmpInst, *this, ImmIndex,
+ PIC_id_index, PCLabel, PCAdjustment);
+ OutStreamer.EmitInstruction(TmpInst);
+ return;
+ }
+ //@LOCALMOD-END
}
MCInst TmpInst;
diff --git a/lib/Target/ARM/ARMAsmPrinter.h b/lib/Target/ARM/ARMAsmPrinter.h
index 3555e8f50a..273f85026d 100644
--- a/lib/Target/ARM/ARMAsmPrinter.h
+++ b/lib/Target/ARM/ARMAsmPrinter.h
@@ -72,8 +72,18 @@ public:
virtual void EmitInstruction(const MachineInstr *MI);
bool runOnMachineFunction(MachineFunction &F);
- virtual void EmitConstantPool() {} // we emit constant pools customly!
virtual void EmitFunctionBodyEnd();
+
+ // @LOCALMOD-START
+ // usually this does nothing on ARM as constants pools
+ // are handled with custom code.
+ // For the sfi case we do not use the custom logic and fall back
+ // to the default implementation.
+ virtual void EmitConstantPool() {
+ if (FlagSfiDisableCP) AsmPrinter::EmitConstantPool();
+ }
+ // @LOCALMOD-END
+
virtual void EmitFunctionEntryLabel();
void EmitStartOfAsmFile(Module &M);
void EmitEndOfAsmFile(Module &M);
@@ -81,6 +91,17 @@ public:
// lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
+
+ // @LOCALMOD-START
+ /// UseReadOnlyJumpTables - true if JumpTableInfo must be in rodata.
+ virtual bool UseReadOnlyJumpTables() const;
+ /// GetTargetBasicBlockAlign - Get the target alignment for basic blocks.
+ virtual unsigned GetTargetBasicBlockAlign() const;
+ /// GetTargetLabelAlign - Get optional alignment for TargetOpcode
+ /// labels E.g., EH_LABEL.
+ /// TODO(sehr,robertm): remove this if the labeled block has address taken.
+ virtual unsigned GetTargetLabelAlign(const MachineInstr *MI) const;
+ // @LOCALMOD-END
private:
// Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 8c744d17f0..42b6bc3cdc 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1764,6 +1764,7 @@ void llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB,
// Build the new ADD / SUB.
unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
+
BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
.addReg(BaseReg, RegState::Kill).addImm(ThisVal)
.addImm((unsigned)Pred).addReg(PredReg).addReg(0)
@@ -2231,6 +2232,7 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
// be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc.
for (unsigned i = 0, e = OperandsToUpdate.size(); i < e; i++)
OperandsToUpdate[i].first->setImm(OperandsToUpdate[i].second);
+
return true;
}
}
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index f0c2d7e5a2..1cba45c3a5 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -17,6 +17,7 @@
#include "ARMFrameLowering.h"
#include "ARMMachineFunctionInfo.h"
#include "ARMSubtarget.h"
+#include "ARMTargetMachine.h" // @LOCALMOD
#include "MCTargetDesc/ARMAddressingModes.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
@@ -60,8 +61,10 @@ ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
BasePtr(ARM::R6) {
}
+extern cl::opt<bool> ReserveR9; // @LOCALMOD
const uint16_t*
ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+ if (ReserveR9) return CSR_NaCl_SaveList; // @LOCALMOD
bool ghcCall = false;
if (MF) {
@@ -80,6 +83,7 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
const uint32_t*
ARMBaseRegisterInfo::getCallPreservedMask(CallingConv::ID) const {
+ if (ReserveR9) return CSR_NaCl_RegMask; // @LOCALMOD
return (STI.isTargetIOS() && !STI.isAAPCS_ABI())
? CSR_iOS_RegMask : CSR_AAPCS_RegMask;
}
@@ -708,6 +712,13 @@ emitLoadConstPool(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred,
unsigned PredReg, unsigned MIFlags) const {
+ // @LOCALMOD-START
+ // In the sfi case we do not want to use the load const pseudo instr.
+ // Sadly, the ARM backend is not very consistent about using this
+ // pseudo instr. and hence checking this is not sufficient.
+ // But, it should help detect some regressions early.
+ assert(!FlagSfiDisableCP && "unexpected call to emitLoadConstPool");
+ // @LOCALMOD-END
MachineFunction &MF = *MBB.getParent();
MachineConstantPool *ConstantPool = MF.getConstantPool();
const Constant *C =
diff --git a/lib/Target/ARM/ARMCallingConv.td b/lib/Target/ARM/ARMCallingConv.td
index bda1517685..e0f3a871ba 100644
--- a/lib/Target/ARM/ARMCallingConv.td
+++ b/lib/Target/ARM/ARMCallingConv.td
@@ -105,6 +105,10 @@ def CC_ARM_APCS_GHC : CallingConv<[
def CC_ARM_AAPCS_Common : CallingConv<[
+ // @LOCALMOD-BEGIN (PR11018)
+ CCIfByVal<CCPassByVal<4, 4>>,
+ // @LOCALMOD-END
+
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
// i64/f64 is passed in even pairs of GPRs
@@ -202,3 +206,9 @@ def CSR_iOS : CalleeSavedRegs<(add LR, R7, R6, R5, R4, (sub CSR_AAPCS, R9))>;
// add is a workaround for not being able to compile empty list:
// def CSR_GHC : CalleeSavedRegs<()>;
def CSR_GHC : CalleeSavedRegs<(add)>;
+
+// @LOCALMOD-START
+// NaCl does not save R9, but otherwise uses the same order as AAPCS
+def CSR_NaCl : CalleeSavedRegs<(add LR, R11, R10, R8, R7, R6, R5, R4,
+ (sequence "D%u", 15, 8))>;
+// @LOCALMOD-END \ No newline at end of file
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp
index dd05f0cf40..2c4b9f7cb2 100644
--- a/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -374,6 +374,7 @@ FunctionPass *llvm::createARMConstantIslandPass() {
}
bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
+ if (FlagSfiDisableCP) return false; // @LOCALMOD
MF = &mf;
MCP = mf.getConstantPool();
diff --git a/lib/Target/ARM/ARMConstantPoolValue.h b/lib/Target/ARM/ARMConstantPoolValue.h
index 6b98d446b0..f523097d2c 100644
--- a/lib/Target/ARM/ARMConstantPoolValue.h
+++ b/lib/Target/ARM/ARMConstantPoolValue.h
@@ -81,6 +81,9 @@ public:
bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
+ // @LOCALMOD-START
+ bool isValue() const { return Kind == ARMCP::CPValue; }
+ // @LOCALMOD-END
virtual unsigned getRelocationInfo() const { return 2; }
diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index c130b2eede..56cfcface4 100644
--- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -24,6 +24,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetOptions.h" // @LOCALMOD for llvm::TLSUseCall
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h" // FIXME: for debug only. remove!
@@ -43,6 +44,7 @@ namespace {
const TargetRegisterInfo *TRI;
const ARMSubtarget *STI;
ARMFunctionInfo *AFI;
+ bool IsRelocPIC; // @LOCALMOD
virtual bool runOnMachineFunction(MachineFunction &Fn);
@@ -63,6 +65,16 @@ namespace {
unsigned Opc, bool IsExt);
void ExpandMOV32BitImm(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI);
+ // @LOCALMOD-BEGIN
+ void AddPICADD_MOVi16_PICID(MachineInstr &MI,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator &MBBI,
+ bool NotThumb,
+ unsigned PredReg, ARMCC::CondCodes Pred,
+ unsigned DstReg, bool DstIsDead,
+ MachineInstrBuilder &LO16,
+ MachineInstrBuilder &HI16);
+ // @LOCALMOD-END
};
char ARMExpandPseudo::ID = 0;
}
@@ -478,13 +490,46 @@ void ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator &MBBI) {
if (SrcIsKill && !SrcIsUndef) // Add an implicit kill for the super-reg.
MIB->addRegisterKilled(SrcReg, TRI, true);
TransferImpOps(MI, MIB, MIB);
-
// Transfer memoperands.
MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
-
MI.eraseFromParent();
}
+// @LOCALMOD-BEGIN
+// AddPICADD_MOVi16_PICID - Inserts a PICADD into the given basic block,
+// and adds the PC label ID (of the PICADD) as an operand of the LO16 / HI16
+// MOVs. The ID operand will follow the "Immediate" operand (assumes that
+// operand is already added).
+void ARMExpandPseudo::AddPICADD_MOVi16_PICID(MachineInstr &MI,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator &MBBI,
+ bool NotThumb,
+ unsigned PredReg, ARMCC::CondCodes Pred,
+ unsigned DstReg, bool DstIsDead,
+ MachineInstrBuilder &LO16,
+ MachineInstrBuilder &HI16) {
+ // Throw in a PICADD, and tack on the PC label ID to the MOVT/MOVWs
+ MachineFunction &MF = *MI.getParent()->getParent();
+ ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+
+ // Make a unique ID for this PC by pulling from pool of constPoolIDs
+ unsigned PC_ID = AFI->createPICLabelUId();
+ MachineInstrBuilder PicADD =
+ BuildMI(MBB, MBBI, MI.getDebugLoc(),
+ TII->get(NotThumb ? ARM::PICADD : ARM::tPICADD))
+ .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
+ .addReg(DstReg)
+ .addImm(PC_ID)
+ .addImm(Pred)
+ .addReg(PredReg);
+ (void)PicADD; // squelch unused warning.
+
+ // Add the PC label ID after what would have been an absolute address.
+ LO16 = LO16.addImm(PC_ID);
+ HI16 = HI16.addImm(PC_ID);
+}
+// @LOCALMOD-END
+
/// ExpandLaneOp - Translate VLD*LN and VST*LN instructions with Q, QQ or QQQQ
/// register operands to real instructions with D register operands.
void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator &MBBI) {
@@ -645,7 +690,9 @@ void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
unsigned LO16Opc = 0;
unsigned HI16Opc = 0;
- if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) {
+ // @LOCALMOD
+ bool isThumb2 = (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm);
+ if (isThumb2) {
LO16Opc = ARM::t2MOVi16;
HI16Opc = ARM::t2MOVTi16;
} else {
@@ -653,10 +700,28 @@ void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
HI16Opc = ARM::MOVTi16;
}
+ // @LOCALMOD-BEGIN
+ // If constant pools are "disabled" (actually, moved to rodata), then
+ // many addresses (e.g., the addresses of what used to be the "pools")
+ // may not be materialized in a pc-relative manner, because MOVT / MOVW
+ // are used to materialize the addresses.
+ // We need to know if it matters that references are pc-relative
+ // (e.g., to be PIC).
+ // See the comments on MOVi16PIC / MOVTi16PIC for more details.
+ const bool ShouldUseMOV16PIC = FlagSfiDisableCP && IsRelocPIC &&
+ (MO.isCPI() || MO.isJTI() || MO.isGlobal()); // TODO check this list.
+ if (ShouldUseMOV16PIC) {
+ if (isThumb2)
+ llvm_unreachable("FIXME: add PIC versions of t2MOVi16");
+ LO16Opc = ARM::MOVi16PIC;
+ HI16Opc = ARM::MOVTi16PIC;
+ }
+ // @LOCALMOD-END
+
LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg);
HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc))
.addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(DstReg);
+ .addReg(DstReg, RegState::Kill); // @LOCALMOD
if (MO.isImm()) {
unsigned Imm = MO.getImm();
@@ -664,13 +729,31 @@ void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
unsigned Hi16 = (Imm >> 16) & 0xffff;
LO16 = LO16.addImm(Lo16);
HI16 = HI16.addImm(Hi16);
- } else {
+ } else if (MO.isGlobal()) { // @LOCALMOD
const GlobalValue *GV = MO.getGlobal();
unsigned TF = MO.getTargetFlags();
LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
+ // @LOCALMOD-START - support for jumptable addresses and CPI
+ } else if (MO.isCPI()) {
+ int i = MO.getIndex();