diff options
Diffstat (limited to 'lib/Target/ARM')
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(); |