diff options
Diffstat (limited to 'lib/Target/ARM/ARMAsmPrinter.cpp')
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 189 |
1 files changed, 186 insertions, 3 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 5bff9fb756..967c0a8462 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 { @@ -563,6 +656,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(); @@ -607,8 +702,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()) { @@ -678,6 +781,7 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { } } + //===----------------------------------------------------------------------===// // Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() // FIXME: @@ -928,7 +1032,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); } @@ -1587,6 +1704,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]; @@ -2015,6 +2154,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; |