| 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;
|
|
|