Add MCInstBuilder, a utility class to simplify MCInst creation similar to MachineInstrBuilder.

Simplify some repetitive code with it. No functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168587 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2012-11-26 13:34:22 +00:00
parent 6702e53926
commit 391271f3bb
4 changed files with 441 additions and 484 deletions

View File

@ -0,0 +1,70 @@
//===-- llvm/MC/MCInstBuilder.h - Simplify creation of MCInsts --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the MCInstBuilder class for convenient creation of
// MCInsts.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCINSTBUILDER_H
#define LLVM_MC_MCINSTBUILDER_H
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
namespace llvm {
class MCInstBuilder {
MCInst Inst;
public:
/// \brief Create a new MCInstBuilder for an MCInst with a specific opcode.
MCInstBuilder(unsigned Opcode) {
Inst.setOpcode(Opcode);
}
/// \brief Add a new register operand.
MCInstBuilder &addReg(unsigned Reg) {
Inst.addOperand(MCOperand::CreateReg(Reg));
return *this;
}
/// \brief Add a new integer immediate operand.
MCInstBuilder &addImm(int64_t Val) {
Inst.addOperand(MCOperand::CreateImm(Val));
return *this;
}
/// \brief Add a new floating point immediate operand.
MCInstBuilder &addFPImm(double Val) {
Inst.addOperand(MCOperand::CreateFPImm(Val));
return *this;
}
/// \brief Add a new MCExpr operand.
MCInstBuilder &addExpr(const MCExpr *Val) {
Inst.addOperand(MCOperand::CreateExpr(Val));
return *this;
}
/// \brief Add a new MCInst operand.
MCInstBuilder &addInst(const MCInst *Val) {
Inst.addOperand(MCOperand::CreateInst(Val));
return *this;
}
/// \brief Emit the built instruction to an MCStreamer.
void emit(MCStreamer &OutStreamer) {
OutStreamer.EmitInstruction(Inst);
}
};
} // end namespace llvm
#endif

View File

@ -37,6 +37,7 @@
#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h" #include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
@ -1051,12 +1052,11 @@ void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
OutContext); OutContext);
// If this isn't a TBB or TBH, the entries are direct branch instructions. // If this isn't a TBB or TBH, the entries are direct branch instructions.
if (OffsetWidth == 4) { if (OffsetWidth == 4) {
MCInst BrInst; MCInstBuilder(ARM::t2B)
BrInst.setOpcode(ARM::t2B); .addExpr(MBBSymbolExpr)
BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); .addImm(ARMCC::AL)
BrInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addReg(0)
BrInst.addOperand(MCOperand::CreateReg(0)); .emit(OutStreamer);
OutStreamer.EmitInstruction(BrInst);
continue; continue;
} }
// Otherwise it's an offset from the dispatch instruction. Construct an // Otherwise it's an offset from the dispatch instruction. Construct an
@ -1100,18 +1100,6 @@ void ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
printOperand(MI, NOps-2, OS); printOperand(MI, NOps-2, OS);
} }
static void populateADROperands(MCInst &Inst, unsigned Dest,
const MCSymbol *Label,
unsigned pred, unsigned ccreg,
MCContext &Ctx) {
const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx);
Inst.addOperand(MCOperand::CreateReg(Dest));
Inst.addOperand(MCOperand::CreateExpr(SymbolExpr));
// Add predicate operands.
Inst.addOperand(MCOperand::CreateImm(pred));
Inst.addOperand(MCOperand::CreateReg(ccreg));
}
void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
assert(MI->getFlag(MachineInstr::FrameSetup) && assert(MI->getFlag(MachineInstr::FrameSetup) &&
"Only instruction which are involved into frame setup code are allowed"); "Only instruction which are involved into frame setup code are allowed");
@ -1288,129 +1276,112 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case ARM::tLEApcrel: case ARM::tLEApcrel:
case ARM::t2LEApcrel: { case ARM::t2LEApcrel: {
// FIXME: Need to also handle globals and externals // FIXME: Need to also handle globals and externals
MCInst TmpInst; MCSymbol *CPISymbol = GetCPISymbol(MI->getOperand(1).getIndex());
TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR MCInstBuilder(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR
: (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR
: ARM::ADR)); : ARM::ADR))
populateADROperands(TmpInst, MI->getOperand(0).getReg(), .addReg(MI->getOperand(0).getReg())
GetCPISymbol(MI->getOperand(1).getIndex()), .addExpr(MCSymbolRefExpr::Create(CPISymbol, OutContext))
MI->getOperand(2).getImm(), MI->getOperand(3).getReg(), // Add predicate operands.
OutContext); .addImm(MI->getOperand(2).getImm())
OutStreamer.EmitInstruction(TmpInst); .addReg(MI->getOperand(3).getReg())
.emit(OutStreamer);
return; return;
} }
case ARM::LEApcrelJT: case ARM::LEApcrelJT:
case ARM::tLEApcrelJT: case ARM::tLEApcrelJT:
case ARM::t2LEApcrelJT: { case ARM::t2LEApcrelJT: {
MCInst TmpInst; MCSymbol *JTIPICSymbol =
TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(),
: (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR MI->getOperand(2).getImm());
: ARM::ADR)); MCInstBuilder(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR
populateADROperands(TmpInst, MI->getOperand(0).getReg(), : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR
GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), : ARM::ADR))
MI->getOperand(2).getImm()), .addReg(MI->getOperand(0).getReg())
MI->getOperand(3).getImm(), MI->getOperand(4).getReg(), .addExpr(MCSymbolRefExpr::Create(JTIPICSymbol, OutContext))
OutContext); // Add predicate operands.
OutStreamer.EmitInstruction(TmpInst); .addImm(MI->getOperand(3).getImm())
.addReg(MI->getOperand(4).getReg())
.emit(OutStreamer);
return; return;
} }
// Darwin call instructions are just normal call instructions with different // Darwin call instructions are just normal call instructions with different
// clobber semantics (they clobber R9). // clobber semantics (they clobber R9).
case ARM::BX_CALL: { case ARM::BX_CALL: {
{ MCInstBuilder(ARM::MOVr)
MCInst TmpInst; .addReg(ARM::LR)
TmpInst.setOpcode(ARM::MOVr); .addReg(ARM::PC)
TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
// Add predicate operands. // Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
// Add 's' bit operand (always reg0 for this) // Add 's' bit operand (always reg0 for this)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::BX)
MCInst TmpInst; .addReg(MI->getOperand(0).getReg())
TmpInst.setOpcode(ARM::BX); .emit(OutStreamer);
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
OutStreamer.EmitInstruction(TmpInst);
}
return; return;
} }
case ARM::tBX_CALL: { case ARM::tBX_CALL: {
{ MCInstBuilder(ARM::tMOVr)
MCInst TmpInst; .addReg(ARM::LR)
TmpInst.setOpcode(ARM::tMOVr); .addReg(ARM::PC)
TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
// Add predicate operands. // Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::tBX)
MCInst TmpInst; .addReg(MI->getOperand(0).getReg())
TmpInst.setOpcode(ARM::tBX);
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
// Add predicate operands. // Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
return; return;
} }
case ARM::BMOVPCRX_CALL: { case ARM::BMOVPCRX_CALL: {
{ MCInstBuilder(ARM::MOVr)
MCInst TmpInst; .addReg(ARM::LR)
TmpInst.setOpcode(ARM::MOVr); .addReg(ARM::PC)
TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
// Add predicate operands. // Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
// Add 's' bit operand (always reg0 for this) // Add 's' bit operand (always reg0 for this)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::MOVr)
MCInst TmpInst; .addReg(ARM::PC)
TmpInst.setOpcode(ARM::MOVr); .addImm(MI->getOperand(0).getReg())
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
// Add predicate operands. // Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
// Add 's' bit operand (always reg0 for this) // Add 's' bit operand (always reg0 for this)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
return; return;
} }
case ARM::BMOVPCB_CALL: { case ARM::BMOVPCB_CALL: {
{ MCInstBuilder(ARM::MOVr)
MCInst TmpInst; .addReg(ARM::LR)
TmpInst.setOpcode(ARM::MOVr); .addReg(ARM::PC)
TmpInst.addOperand(MCOperand::CreateReg(ARM::LR));
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
// Add predicate operands. // Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
// Add 's' bit operand (always reg0 for this) // Add 's' bit operand (always reg0 for this)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ const GlobalValue *GV = MI->getOperand(0).getGlobal();
MCInst TmpInst; MCSymbol *GVSym = Mang->getSymbol(GV);
TmpInst.setOpcode(ARM::Bcc); const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
const GlobalValue *GV = MI->getOperand(0).getGlobal(); MCInstBuilder(ARM::Bcc)
MCSymbol *GVSym = Mang->getSymbol(GV); .addExpr(GVSymExpr)
const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
TmpInst.addOperand(MCOperand::CreateExpr(GVSymExpr));
// Add predicate operands. // Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
return; return;
} }
case ARM::MOVi16_ga_pcrel: case ARM::MOVi16_ga_pcrel:
@ -1498,15 +1469,14 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutContext)); OutContext));
// Form and emit the add. // Form and emit the add.
MCInst AddInst; MCInstBuilder(ARM::tADDhirr)
AddInst.setOpcode(ARM::tADDhirr); .addReg(MI->getOperand(0).getReg())
AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); .addReg(MI->getOperand(0).getReg())
AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); .addReg(ARM::PC)
AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); // Add predicate operands.
// Add predicate operands. .addImm(ARMCC::AL)
AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addReg(0)
AddInst.addOperand(MCOperand::CreateReg(0)); .emit(OutStreamer);
OutStreamer.EmitInstruction(AddInst);
return; return;
} }
case ARM::PICADD: { case ARM::PICADD: {
@ -1521,17 +1491,16 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutContext)); OutContext));
// Form and emit the add. // Form and emit the add.
MCInst AddInst; MCInstBuilder(ARM::ADDrr)
AddInst.setOpcode(ARM::ADDrr); .addReg(MI->getOperand(0).getReg())
AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); .addReg(ARM::PC)
AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); .addReg(MI->getOperand(1).getReg())
AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); // Add predicate operands.
// Add predicate operands. .addImm(MI->getOperand(3).getImm())
AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); .addReg(MI->getOperand(4).getReg())
AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); // Add 's' bit operand (always reg0 for this)
// Add 's' bit operand (always reg0 for this) .addReg(0)
AddInst.addOperand(MCOperand::CreateReg(0)); .emit(OutStreamer);
OutStreamer.EmitInstruction(AddInst);
return; return;
} }
case ARM::PICSTR: case ARM::PICSTR:
@ -1567,16 +1536,15 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
} }
MCInst LdStInst; MCInstBuilder(Opcode)
LdStInst.setOpcode(Opcode); .addReg(MI->getOperand(0).getReg())
LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); .addReg(ARM::PC)
LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); .addReg(MI->getOperand(1).getReg())
LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); .addImm(0)
LdStInst.addOperand(MCOperand::CreateImm(0)); // Add predicate operands.
// Add predicate operands. .addImm(MI->getOperand(3).getImm())
LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); .addReg(MI->getOperand(4).getReg())
LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); .emit(OutStreamer);
OutStreamer.EmitInstruction(LdStInst);
return; return;
} }
@ -1606,29 +1574,28 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
} }
case ARM::t2BR_JT: { case ARM::t2BR_JT: {
// Lower and emit the instruction itself, then the jump table following it. // Lower and emit the instruction itself, then the jump table following it.
MCInst TmpInst; MCInstBuilder(ARM::tMOVr)
TmpInst.setOpcode(ARM::tMOVr); .addReg(ARM::PC)
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); .addReg(MI->getOperand(0).getReg())
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); // Add predicate operands.
// Add predicate operands. .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addReg(0)
TmpInst.addOperand(MCOperand::CreateReg(0)); .emit(OutStreamer);
OutStreamer.EmitInstruction(TmpInst);
// Output the data for the jump table itself // Output the data for the jump table itself
EmitJump2Table(MI); EmitJump2Table(MI);
return; return;
} }
case ARM::t2TBB_JT: { case ARM::t2TBB_JT: {
// Lower and emit the instruction itself, then the jump table following it. // Lower and emit the instruction itself, then the jump table following it.
MCInst TmpInst; MCInstBuilder(ARM::t2TBB)
.addReg(ARM::PC)
.addReg(MI->getOperand(0).getReg())
// Add predicate operands.
.addImm(ARMCC::AL)
.addReg(0)
.emit(OutStreamer);
TmpInst.setOpcode(ARM::t2TBB);
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
// Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
TmpInst.addOperand(MCOperand::CreateReg(0));
OutStreamer.EmitInstruction(TmpInst);
// Output the data for the jump table itself // Output the data for the jump table itself
EmitJump2Table(MI); EmitJump2Table(MI);
// Make sure the next instruction is 2-byte aligned. // Make sure the next instruction is 2-byte aligned.
@ -1637,15 +1604,14 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
} }
case ARM::t2TBH_JT: { case ARM::t2TBH_JT: {
// Lower and emit the instruction itself, then the jump table following it. // Lower and emit the instruction itself, then the jump table following it.
MCInst TmpInst; MCInstBuilder(ARM::t2TBH)
.addReg(ARM::PC)
.addReg(MI->getOperand(0).getReg())
// Add predicate operands.
.addImm(ARMCC::AL)
.addReg(0)
.emit(OutStreamer);
TmpInst.setOpcode(ARM::t2TBH);
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
// Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
TmpInst.addOperand(MCOperand::CreateReg(0));
OutStreamer.EmitInstruction(TmpInst);
// Output the data for the jump table itself // Output the data for the jump table itself
EmitJump2Table(MI); EmitJump2Table(MI);
return; return;
@ -1705,17 +1671,16 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case ARM::BR_JTadd: { case ARM::BR_JTadd: {
// Lower and emit the instruction itself, then the jump table following it. // Lower and emit the instruction itself, then the jump table following it.
// add pc, target, idx // add pc, target, idx
MCInst TmpInst; MCInstBuilder(ARM::ADDrr)
TmpInst.setOpcode(ARM::ADDrr); .addReg(ARM::PC)
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); .addReg(MI->getOperand(0).getReg())
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); .addReg(MI->getOperand(1).getReg())
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); // Add predicate operands.
// Add predicate operands. .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addReg(0)
TmpInst.addOperand(MCOperand::CreateReg(0)); // Add 's' bit operand (always reg0 for this)
// Add 's' bit operand (always reg0 for this) .addReg(0)
TmpInst.addOperand(MCOperand::CreateReg(0)); .emit(OutStreamer);
OutStreamer.EmitInstruction(TmpInst);
// Output the data for the jump table itself // Output the data for the jump table itself
EmitJumpTable(MI); EmitJumpTable(MI);
@ -1759,75 +1724,63 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
unsigned SrcReg = MI->getOperand(0).getReg(); unsigned SrcReg = MI->getOperand(0).getReg();
unsigned ValReg = MI->getOperand(1).getReg(); unsigned ValReg = MI->getOperand(1).getReg();
MCSymbol *Label = GetARMSJLJEHLabel(); MCSymbol *Label = GetARMSJLJEHLabel();
{ OutStreamer.AddComment("eh_setjmp begin");
MCInst TmpInst; MCInstBuilder(ARM::tMOVr)
TmpInst.setOpcode(ARM::tMOVr); .addReg(ValReg)
TmpInst.addOperand(MCOperand::CreateReg(ValReg)); .addReg(ARM::PC)
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.AddComment("eh_setjmp begin"); .emit(OutStreamer);
OutStreamer.EmitInstruction(TmpInst);
} MCInstBuilder(ARM::tADDi3)
{ .addReg(ValReg)
MCInst TmpInst;
TmpInst.setOpcode(ARM::tADDi3);
TmpInst.addOperand(MCOperand::CreateReg(ValReg));
// 's' bit operand // 's' bit operand
TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); .addReg(ARM::CPSR)
TmpInst.addOperand(MCOperand::CreateReg(ValReg)); .addReg(ValReg)
TmpInst.addOperand(MCOperand::CreateImm(7)); .addImm(7)
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::tSTRi)
MCInst TmpInst; .addReg(ValReg)
TmpInst.setOpcode(ARM::tSTRi); .addReg(SrcReg)
TmpInst.addOperand(MCOperand::CreateReg(ValReg));
TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
// The offset immediate is #4. The operand value is scaled by 4 for the // The offset immediate is #4. The operand value is scaled by 4 for the
// tSTR instruction. // tSTR instruction.
TmpInst.addOperand(MCOperand::CreateImm(1)); .addImm(1)
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::tMOVi8)
MCInst TmpInst; .addReg(ARM::R0)
TmpInst.setOpcode(ARM::tMOVi8); .addReg(ARM::CPSR)
TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); .addImm(0)
TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
TmpInst.addOperand(MCOperand::CreateImm(0));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); MCInstBuilder(ARM::tB)
MCInst TmpInst; .addExpr(SymbolExpr)
TmpInst.setOpcode(ARM::tB); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); .addReg(0)
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .emit(OutStreamer);
TmpInst.addOperand(MCOperand::CreateReg(0));
OutStreamer.EmitInstruction(TmpInst); OutStreamer.AddComment("eh_setjmp end");
} MCInstBuilder(ARM::tMOVi8)
{ .addReg(ARM::R0)
MCInst TmpInst; .addReg(ARM::CPSR)
TmpInst.setOpcode(ARM::tMOVi8); .addImm(1)
TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
TmpInst.addOperand(MCOperand::CreateImm(1));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.AddComment("eh_setjmp end"); .emit(OutStreamer);
OutStreamer.EmitInstruction(TmpInst);
}
OutStreamer.EmitLabel(Label); OutStreamer.EmitLabel(Label);
return; return;
} }
@ -1843,69 +1796,58 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
unsigned SrcReg = MI->getOperand(0).getReg(); unsigned SrcReg = MI->getOperand(0).getReg();
unsigned ValReg = MI->getOperand(1).getReg(); unsigned ValReg = MI->getOperand(1).getReg();
{ OutStreamer.AddComment("eh_setjmp begin");
MCInst TmpInst; MCInstBuilder(ARM::ADDri)
TmpInst.setOpcode(ARM::ADDri); .addReg(ValReg)
TmpInst.addOperand(MCOperand::CreateReg(ValReg)); .addReg(ARM::PC)
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); .addImm(8)
TmpInst.addOperand(MCOperand::CreateImm(8));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
// 's' bit operand (always reg0 for this). // 's' bit operand (always reg0 for this).
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.AddComment("eh_setjmp begin"); .emit(OutStreamer);
OutStreamer.EmitInstruction(TmpInst);
} MCInstBuilder(ARM::STRi12)
{ .addReg(ValReg)
MCInst TmpInst; .addReg(SrcReg)
TmpInst.setOpcode(ARM::STRi12); .addImm(4)
TmpInst.addOperand(MCOperand::CreateReg(ValReg));
TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
TmpInst.addOperand(MCOperand::CreateImm(4));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::MOVi)
MCInst TmpInst; .addReg(ARM::R0)
TmpInst.setOpcode(ARM::MOVi); .addImm(0)
TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
TmpInst.addOperand(MCOperand::CreateImm(0));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
// 's' bit operand (always reg0 for this). // 's' bit operand (always reg0 for this).
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::ADDri)
MCInst TmpInst; .addReg(ARM::PC)
TmpInst.setOpcode(ARM::ADDri); .addReg(ARM::PC)
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); .addImm(0)
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
TmpInst.addOperand(MCOperand::CreateImm(0));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
// 's' bit operand (always reg0 for this). // 's' bit operand (always reg0 for this).
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ OutStreamer.AddComment("eh_setjmp end");
MCInst TmpInst; MCInstBuilder(ARM::MOVi)
TmpInst.setOpcode(ARM::MOVi); .addReg(ARM::R0)
TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); .addImm(1)
TmpInst.addOperand(MCOperand::CreateImm(1));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
// 's' bit operand (always reg0 for this). // 's' bit operand (always reg0 for this).
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.AddComment("eh_setjmp end"); .emit(OutStreamer);
OutStreamer.EmitInstruction(TmpInst);
}
return; return;
} }
case ARM::Int_eh_sjlj_longjmp: { case ARM::Int_eh_sjlj_longjmp: {
@ -1915,48 +1857,39 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// bx $scratch // bx $scratch
unsigned SrcReg = MI->getOperand(0).getReg(); unsigned SrcReg = MI->getOperand(0).getReg();
unsigned ScratchReg = MI->getOperand(1).getReg(); unsigned ScratchReg = MI->getOperand(1).getReg();
{ MCInstBuilder(ARM::LDRi12)
MCInst TmpInst; .addReg(ARM::SP)
TmpInst.setOpcode(ARM::LDRi12); .addReg(SrcReg)
TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); .addImm(8)
TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
TmpInst.addOperand(MCOperand::CreateImm(8));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::LDRi12)
MCInst TmpInst; .addReg(ScratchReg)
TmpInst.setOpcode(ARM::LDRi12); .addReg(SrcReg)
TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); .addImm(4)
TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
TmpInst.addOperand(MCOperand::CreateImm(4));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::LDRi12)
MCInst TmpInst; .addReg(ARM::R7)
TmpInst.setOpcode(ARM::LDRi12); .addReg(SrcReg)
TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); .addImm(0)
TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
TmpInst.addOperand(MCOperand::CreateImm(0));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::BX)
MCInst TmpInst; .addReg(ScratchReg)
TmpInst.setOpcode(ARM::BX);
TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
return; return;
} }
case ARM::tInt_eh_sjlj_longjmp: { case ARM::tInt_eh_sjlj_longjmp: {
@ -1967,60 +1900,49 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// bx $scratch // bx $scratch
unsigned SrcReg = MI->getOperand(0).getReg(); unsigned SrcReg = MI->getOperand(0).getReg();
unsigned ScratchReg = MI->getOperand(1).getReg(); unsigned ScratchReg = MI->getOperand(1).getReg();
{ MCInstBuilder(ARM::tLDRi)
MCInst TmpInst; .addReg(ScratchReg)
TmpInst.setOpcode(ARM::tLDRi); .addReg(SrcReg)
TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
// The offset immediate is #8. The operand value is scaled by 4 for the // The offset immediate is #8. The operand value is scaled by 4 for the
// tLDR instruction. // tLDR instruction.
TmpInst.addOperand(MCOperand::CreateImm(2)); .addImm(2)
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::tMOVr)
MCInst TmpInst; .addReg(ARM::SP)
TmpInst.setOpcode(ARM::tMOVr); .addReg(ScratchReg)
TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::tLDRi)
MCInst TmpInst; .addReg(ScratchReg)
TmpInst.setOpcode(ARM::tLDRi); .addReg(SrcReg)
TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); .addImm(1)
TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
TmpInst.addOperand(MCOperand::CreateImm(1));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::tLDRi)
MCInst TmpInst; .addReg(ARM::R7)
TmpInst.setOpcode(ARM::tLDRi); .addReg(SrcReg)
TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); .addImm(0)
TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
TmpInst.addOperand(MCOperand::CreateImm(0));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
{ MCInstBuilder(ARM::tBX)
MCInst TmpInst; .addReg(ScratchReg)
TmpInst.setOpcode(ARM::tBX);
TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
// Predicate. // Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); .addImm(ARMCC::AL)
TmpInst.addOperand(MCOperand::CreateReg(0)); .addReg(0)
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
}
return; return;
} }
} }

View File

@ -37,6 +37,7 @@
#include "llvm/MC/MCContext.h" #include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbol.h"
@ -55,7 +56,6 @@
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallString.h"
#include "llvm/ADT/MapVector.h" #include "llvm/ADT/MapVector.h"
#include "llvm/ADT/VariadicFunction.h"
using namespace llvm; using namespace llvm;
namespace { namespace {
@ -350,14 +350,11 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCSymbol *PICBase = MF->getPICBaseSymbol(); MCSymbol *PICBase = MF->getPICBaseSymbol();
// Emit the 'bl'. // Emit the 'bl'.
TmpInst.setOpcode(PPC::BL_Darwin); // Darwin vs SVR4 doesn't matter here. MCInstBuilder(PPC::BL_Darwin) // Darwin vs SVR4 doesn't matter here.
// FIXME: We would like an efficient form for this, so we don't have to do
// a lot of extra uniquing.
// FIXME: We would like an efficient form for this, so we don't have to do .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))
// a lot of extra uniquing. .emit(OutStreamer);
TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::
Create(PICBase, OutContext)));
OutStreamer.EmitInstruction(TmpInst);
// Emit the label. // Emit the label.
OutStreamer.EmitLabel(PICBase); OutStreamer.EmitLabel(PICBase);
@ -406,9 +403,9 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Into: %R3 = MFCR ;; cr7 // Into: %R3 = MFCR ;; cr7
OutStreamer.AddComment(PPCInstPrinter:: OutStreamer.AddComment(PPCInstPrinter::
getRegisterName(MI->getOperand(1).getReg())); getRegisterName(MI->getOperand(1).getReg()));
TmpInst.setOpcode(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR); MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR)
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); .addReg(MI->getOperand(0).getReg())
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
return; return;
case PPC::SYNC: case PPC::SYNC:
// In Book E sync is called msync, handle this special case here... // In Book E sync is called msync, handle this special case here...
@ -559,21 +556,6 @@ static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
} }
namespace {
// Helper function to emit a custom MCInst.
void emitMCInstImpl(MCStreamer &OutStreamer, unsigned Opcode,
ArrayRef<const MCOperand *> Ops) {
MCInst TmpInst;
TmpInst.setOpcode(Opcode);
for (unsigned I = 0, E = Ops.size(); I != E; ++I)
TmpInst.addOperand(*Ops[I]);
OutStreamer.EmitInstruction(TmpInst);
}
const VariadicFunction2<void, MCStreamer &, unsigned, MCOperand,
emitMCInstImpl> emitMCInst = {};
}
void PPCDarwinAsmPrinter:: void PPCDarwinAsmPrinter::
EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
@ -604,36 +586,36 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
// mflr r0 // mflr r0
emitMCInst(OutStreamer, PPC::MFLR, MCOperand::CreateReg(PPC::R0)); MCInstBuilder(PPC::MFLR).addReg(PPC::R0).emit(OutStreamer);
// FIXME: MCize this. // FIXME: MCize this.
OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName())); OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName()));
OutStreamer.EmitLabel(AnonSymbol); OutStreamer.EmitLabel(AnonSymbol);
// mflr r11 // mflr r11
emitMCInst(OutStreamer, PPC::MFLR, MCOperand::CreateReg(PPC::R11)); MCInstBuilder(PPC::MFLR).addReg(PPC::R11).emit(OutStreamer);
// addis r11, r11, ha16(LazyPtr - AnonSymbol) // addis r11, r11, ha16(LazyPtr - AnonSymbol)
MCOperand Sub = MCOperand::CreateExpr( const MCExpr *Sub =
MCBinaryExpr::CreateSub( MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext),
MCSymbolRefExpr::Create(LazyPtr, OutContext), MCSymbolRefExpr::Create(AnonSymbol, OutContext),
MCSymbolRefExpr::Create(AnonSymbol, OutContext), OutContext);
OutContext)); MCInstBuilder(PPC::ADDIS)
emitMCInst(OutStreamer, PPC::ADDIS, MCOperand::CreateReg(PPC::R11), .addReg(PPC::R11)
MCOperand::CreateReg(PPC::R11), Sub); .addReg(PPC::R11)
.addExpr(Sub)
.emit(OutStreamer);
// mtlr r0 // mtlr r0
emitMCInst(OutStreamer, PPC::MTLR, MCOperand::CreateReg(PPC::R0)); MCInstBuilder(PPC::MTLR).addReg(PPC::R0).emit(OutStreamer);
if (isPPC64) { // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
// ldu r12, lo16(LazyPtr - AnonSymbol)(r11) // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
emitMCInst(OutStreamer, PPC::LDU, MCOperand::CreateReg(PPC::R12), MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
Sub, Sub, MCOperand::CreateReg(PPC::R11)); .addReg(PPC::R12)
} else { .addExpr(Sub).addExpr(Sub)
// lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) .addReg(PPC::R11)
emitMCInst(OutStreamer, PPC::LWZU, MCOperand::CreateReg(PPC::R12), .emit(OutStreamer);
Sub, Sub, MCOperand::CreateReg(PPC::R11));
}
// mtctr r12 // mtctr r12
emitMCInst(OutStreamer, PPC::MTCTR, MCOperand::CreateReg(PPC::R12)); MCInstBuilder(PPC::MTCTR).addReg(PPC::R12).emit(OutStreamer);
// bctr // bctr
emitMCInst(OutStreamer, PPC::BCTR); MCInstBuilder(PPC::BCTR).emit(OutStreamer);
OutStreamer.SwitchSection(LSPSection); OutStreamer.SwitchSection(LSPSection);
OutStreamer.EmitLabel(LazyPtr); OutStreamer.EmitLabel(LazyPtr);
@ -668,30 +650,30 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
OutStreamer.EmitLabel(Stub); OutStreamer.EmitLabel(Stub);
OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
// lis r11, ha16(LazyPtr) // lis r11, ha16(LazyPtr)
MCOperand LazyPtrHa16 = const MCExpr *LazyPtrHa16 =
MCOperand::CreateExpr( MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16,
MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16, OutContext);
OutContext)); MCInstBuilder(PPC::LIS)
emitMCInst(OutStreamer, PPC::LIS, MCOperand::CreateReg(PPC::R11), .addReg(PPC::R11)
LazyPtrHa16); .addExpr(LazyPtrHa16)
.emit(OutStreamer);
const MCExpr *LazyPtrLo16 =
MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
OutContext);
// ldu r12, lo16(LazyPtr)(r11)
// lwzu r12, lo16(LazyPtr)(r11)
MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
.addReg(PPC::R12)
.addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
.addReg(PPC::R11)
.emit(OutStreamer);
MCOperand LazyPtrLo16 =
MCOperand::CreateExpr(
MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
OutContext));
if (isPPC64) {
// ldu r12, lo16(LazyPtr)(r11)
emitMCInst(OutStreamer, PPC::LDU, MCOperand::CreateReg(PPC::R12),
LazyPtrLo16, LazyPtrLo16, MCOperand::CreateReg(PPC::R11));
} else {
// lwzu r12, lo16(LazyPtr)(r11)
emitMCInst(OutStreamer, PPC::LWZU, MCOperand::CreateReg(PPC::R12),
LazyPtrLo16, LazyPtrLo16, MCOperand::CreateReg(PPC::R11));
}
// mtctr r12 // mtctr r12
emitMCInst(OutStreamer, PPC::MTCTR, MCOperand::CreateReg(PPC::R12)); MCInstBuilder(PPC::MTCTR).addReg(PPC::R12).emit(OutStreamer);
// bctr // bctr
emitMCInst(OutStreamer, PPC::BCTR); MCInstBuilder(PPC::BCTR).emit(OutStreamer);
OutStreamer.SwitchSection(LSPSection); OutStreamer.SwitchSection(LSPSection);
OutStreamer.EmitLabel(LazyPtr); OutStreamer.EmitLabel(LazyPtr);
OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);

View File

@ -21,6 +21,7 @@
#include "llvm/MC/MCContext.h" #include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h" #include "llvm/Target/Mangler.h"
@ -549,18 +550,14 @@ ReSimplify:
OutMI.setOpcode(X86::RET); OutMI.setOpcode(X86::RET);
break; break;
case X86::MORESTACK_RET_RESTORE_R10: { case X86::MORESTACK_RET_RESTORE_R10:
MCInst retInst;
OutMI.setOpcode(X86::MOV64rr); OutMI.setOpcode(X86::MOV64rr);
OutMI.addOperand(MCOperand::CreateReg(X86::R10)); OutMI.addOperand(MCOperand::CreateReg(X86::R10));
OutMI.addOperand(MCOperand::CreateReg(X86::RAX)); OutMI.addOperand(MCOperand::CreateReg(X86::RAX));
retInst.setOpcode(X86::RET); MCInstBuilder(X86::RET).emit(AsmPrinter.OutStreamer);
AsmPrinter.OutStreamer.EmitInstruction(retInst);
break; break;
} }
}
} }
static void LowerTlsAddr(MCStreamer &OutStreamer, static void LowerTlsAddr(MCStreamer &OutStreamer,
@ -574,11 +571,8 @@ static void LowerTlsAddr(MCStreamer &OutStreamer,
MCContext &context = OutStreamer.getContext(); MCContext &context = OutStreamer.getContext();
if (needsPadding) { if (needsPadding)
MCInst prefix; MCInstBuilder(X86::DATA16_PREFIX).emit(OutStreamer);
prefix.setOpcode(X86::DATA16_PREFIX);
OutStreamer.EmitInstruction(prefix);
}
MCSymbolRefExpr::VariantKind SRVK; MCSymbolRefExpr::VariantKind SRVK;
switch (MI.getOpcode()) { switch (MI.getOpcode()) {
@ -628,20 +622,11 @@ static void LowerTlsAddr(MCStreamer &OutStreamer,
OutStreamer.EmitInstruction(LEA); OutStreamer.EmitInstruction(LEA);
if (needsPadding) { if (needsPadding) {
MCInst prefix; MCInstBuilder(X86::DATA16_PREFIX).emit(OutStreamer);
prefix.setOpcode(X86::DATA16_PREFIX); MCInstBuilder(X86::DATA16_PREFIX).emit(OutStreamer);
OutStreamer.EmitInstruction(prefix); MCInstBuilder(X86::REX64_PREFIX).emit(OutStreamer);
prefix.setOpcode(X86::DATA16_PREFIX);
OutStreamer.EmitInstruction(prefix);
prefix.setOpcode(X86::REX64_PREFIX);
OutStreamer.EmitInstruction(prefix);
} }
MCInst call;
if (is64Bits)
call.setOpcode(X86::CALL64pcrel32);
else
call.setOpcode(X86::CALLpcrel32);
StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr"; StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr";
MCSymbol *tlsGetAddr = context.GetOrCreateSymbol(name); MCSymbol *tlsGetAddr = context.GetOrCreateSymbol(name);
const MCSymbolRefExpr *tlsRef = const MCSymbolRefExpr *tlsRef =
@ -649,8 +634,9 @@ static void LowerTlsAddr(MCStreamer &OutStreamer,
MCSymbolRefExpr::VK_PLT, MCSymbolRefExpr::VK_PLT,
context); context);
call.addOperand(MCOperand::CreateExpr(tlsRef)); MCInstBuilder(is64Bits ? X86::CALL64pcrel32 : X86::CALLpcrel32)
OutStreamer.EmitInstruction(call); .addExpr(tlsRef)
.emit(OutStreamer);
} }
void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
@ -694,7 +680,6 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
return LowerTlsAddr(OutStreamer, MCInstLowering, *MI); return LowerTlsAddr(OutStreamer, MCInstLowering, *MI);
case X86::MOVPC32r: { case X86::MOVPC32r: {
MCInst TmpInst;
// This is a pseudo op for a two instruction sequence with a label, which // This is a pseudo op for a two instruction sequence with a label, which
// looks like: // looks like:
// call "L1$pb" // call "L1$pb"
@ -703,20 +688,19 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Emit the call. // Emit the call.
MCSymbol *PICBase = MF->getPICBaseSymbol(); MCSymbol *PICBase = MF->getPICBaseSymbol();
TmpInst.setOpcode(X86::CALLpcrel32);
// FIXME: We would like an efficient form for this, so we don't have to do a // FIXME: We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing. // lot of extra uniquing.
TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase, MCInstBuilder(X86::CALLpcrel32)
OutContext))); .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
// Emit the label. // Emit the label.
OutStreamer.EmitLabel(PICBase); OutStreamer.EmitLabel(PICBase);
// popl $reg // popl $reg
TmpInst.setOpcode(X86::POP32r); MCInstBuilder(X86::POP32r)
TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg()); .addReg(MI->getOperand(0).getReg())
OutStreamer.EmitInstruction(TmpInst); .emit(OutStreamer);
return; return;
} }
@ -746,12 +730,11 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext), DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext),
DotExpr, OutContext); DotExpr, OutContext);
MCInst TmpInst; MCInstBuilder(X86::ADD32ri)
TmpInst.setOpcode(X86::ADD32ri); .addReg(MI->getOperand(0).getReg())
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); .addReg(MI->getOperand(1).getReg())
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); .addExpr(DotExpr)
TmpInst.addOperand(MCOperand::CreateExpr(DotExpr)); .emit(OutStreamer);
OutStreamer.EmitInstruction(TmpInst);
return; return;
} }
} }