Index: lib/Target/ARM/ARMAsmPrinter.cpp |
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp |
index 695fd4d16c562ddfc7895e24294f01e13bfe9a4f..f779824c580b8dfb8e1d83b2a96c6646dfb986bf 100644 |
--- a/lib/Target/ARM/ARMAsmPrinter.cpp |
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp |
@@ -39,6 +39,7 @@ |
#include "llvm/MC/MCELFStreamer.h" |
#include "llvm/MC/MCInst.h" |
#include "llvm/MC/MCInstBuilder.h" |
+#include "llvm/MC/MCNaCl.h" // @LOCALMOD |
#include "llvm/MC/MCObjectStreamer.h" |
#include "llvm/MC/MCSectionMachO.h" |
#include "llvm/MC/MCStreamer.h" |
@@ -57,6 +58,77 @@ using namespace llvm; |
#define DEBUG_TYPE "asm-printer" |
+ |
+// @LOCALMOD-START |
+// Make sure all jump targets are aligned and also all constant pools |
+static 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 ConstantPool |
+ 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 |
+ |
+ |
void ARMAsmPrinter::EmitFunctionBodyEnd() { |
// Make sure to terminate any constant pools that were at the end |
// of the function. |
@@ -72,6 +144,18 @@ 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) |
+ if (Subtarget->isTargetNaCl()) { |
+ EmitAlignment(std::max(MF->getAlignment(), 4u)); |
+ |
+ if (OutStreamer.hasRawTextSupport()) { |
+ OutStreamer.EmitRawText(StringRef("\t.set XmagicX, .\n")); |
+ } |
+ } |
+ // @LOCALMOD-END |
+ |
OutStreamer.EmitLabel(CurrentFnSym); |
} |
@@ -100,6 +184,12 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { |
AFI = MF.getInfo<ARMFunctionInfo>(); |
MCP = MF.getConstantPool(); |
+ // @LOCALMOD-START |
+ if (Subtarget->isTargetNaCl()) { |
+ NaClAlignAllJumpTargetsAndConstantPools(MF); |
+ } |
+ // @LOCALMOD-END |
+ |
SetupMachineFunction(MF); |
if (Subtarget->isTargetCOFF()) { |
@@ -161,10 +251,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 (pr8252) |
O << ":lower16:"; |
else if ((Modifier && strcmp(Modifier, "hi16") == 0) || |
- (TF & ARMII::MO_HI16)) |
+ (TF == ARMII::MO_HI16)) // @LOCALMOD: TEMPORARY FIX (pr8252) |
O << ":upper16:"; |
O << *GetARMGVSymbol(GV, TF); |
@@ -399,6 +489,8 @@ bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, |
return false; |
} |
+void EmitSFIHeaders(raw_ostream &O); // @LOCALMOD |
+ |
static bool isThumb(const MCSubtargetInfo& STI) { |
return (STI.getFeatureBits() & ARM::ModeThumb) != 0; |
} |
@@ -480,6 +572,19 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { |
if (Subtarget->isTargetELF()) |
emitAttributes(); |
+ // @LOCALMOD-BEGIN |
+ if (Subtarget->isTargetNaCl()) { |
+ if (OutStreamer.hasRawTextSupport()) { |
+ std::string str; |
+ raw_string_ostream OS(str); |
+ EmitSFIHeaders(OS); |
+ OutStreamer.EmitRawText(StringRef(OS.str())); |
+ } |
+ initializeNaClMCStreamer(OutStreamer, OutContext, |
+ Subtarget->getTargetTriple()); |
+ } |
+ // @LOCALMOD-END |
+ |
if (!M.getModuleInlineAsm().empty() && Subtarget->isThumb()) |
OutStreamer.EmitAssemblerFlag(MCAF_Code16); |
} |
@@ -915,7 +1020,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); |
} |
@@ -1841,6 +1959,50 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { |
.addReg(0)); |
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); |
+ EmitToStreamer(OutStreamer, 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); |
+ EmitToStreamer(OutStreamer, TmpInst); |
+ return; |
+ } |
+ //@LOCALMOD-END |
} |
MCInst TmpInst; |