Emit all directives except for ".cprestore" during asm printing rather than emit

them as machine instructions. Directives ".set noat" and ".set at" are now
emitted only at the beginning and end of a function except in the case where
they are emitted to enclose .cpload with an immediate operand that doesn't fit
in 16-bit field or unaligned load/stores.

Also, make the following changes:
- Remove function isUnalignedLoadStore and use a switch-case statement to
  determine whether an instruction is an unaligned load or store.

- Define helper function CreateMCInst which generates an instance of an MCInst
  from an opcode and a list of operands.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153552 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2012-03-28 00:22:50 +00:00
parent d0b5c65b16
commit f93b863066
7 changed files with 186 additions and 149 deletions

View File

@ -16,8 +16,6 @@
#include "MipsAsmPrinter.h"
#include "Mips.h"
#include "MipsInstrInfo.h"
#include "MipsMachineFunction.h"
#include "MipsMCInstLower.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "llvm/ADT/SmallString.h"
@ -45,24 +43,23 @@
using namespace llvm;
static bool isUnalignedLoadStore(unsigned Opc) {
return Opc == Mips::ULW || Opc == Mips::ULH || Opc == Mips::ULHu ||
Opc == Mips::USW || Opc == Mips::USH ||
Opc == Mips::ULW_P8 || Opc == Mips::ULH_P8 || Opc == Mips::ULHu_P8 ||
Opc == Mips::USW_P8 || Opc == Mips::USH_P8 ||
Opc == Mips::ULD || Opc == Mips::ULW64 || Opc == Mips::ULH64 ||
Opc == Mips::ULHu64 || Opc == Mips::USD || Opc == Mips::USW64 ||
Opc == Mips::USH64 ||
Opc == Mips::ULD_P8 || Opc == Mips::ULW64_P8 ||
Opc == Mips::ULH64_P8 || Opc == Mips::ULHu64_P8 ||
Opc == Mips::USD_P8 || Opc == Mips::USW64_P8 ||
Opc == Mips::USH64_P8;
void MipsAsmPrinter::EmitInstrWithMacroNoAT(const MachineInstr *MI) {
MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
OutStreamer.EmitRawText(StringRef("\t.set\tmacro"));
if (MipsFI->getEmitNOAT())
OutStreamer.EmitRawText(StringRef("\t.set\tat"));
OutStreamer.EmitInstruction(TmpInst);
if (MipsFI->getEmitNOAT())
OutStreamer.EmitRawText(StringRef("\t.set\tnoat"));
OutStreamer.EmitRawText(StringRef("\t.set\tnomacro"));
}
static bool isDirective(unsigned Opc) {
return Opc == Mips::MACRO || Opc == Mips::NOMACRO ||
Opc == Mips::REORDER || Opc == Mips::NOREORDER ||
Opc == Mips::ATMACRO || Opc == Mips::NOAT;
bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
MipsFI = MF.getInfo<MipsFunctionInfo>();
AsmPrinter::runOnMachineFunction(MF);
return true;
}
void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
@ -74,49 +71,70 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
MipsMCInstLower MCInstLowering(Mang, *MF, *this);
unsigned Opc = MI->getOpcode();
MCInst TmpInst0;
SmallVector<MCInst, 4> MCInsts;
MCInstLowering.Lower(MI, TmpInst0);
if (!OutStreamer.hasRawTextSupport() && isDirective(Opc))
return;
// Enclose unaligned load or store with .macro & .nomacro directives.
if (isUnalignedLoadStore(Opc)) {
switch (Opc) {
case Mips::ULW:
case Mips::ULH:
case Mips::ULHu:
case Mips::USW:
case Mips::USH:
case Mips::ULW_P8:
case Mips::ULH_P8:
case Mips::ULHu_P8:
case Mips::USW_P8:
case Mips::USH_P8:
case Mips::ULD:
case Mips::ULW64:
case Mips::ULH64:
case Mips::ULHu64:
case Mips::USD:
case Mips::USW64:
case Mips::USH64:
case Mips::ULD_P8:
case Mips::ULW64_P8:
case Mips::ULH64_P8:
case Mips::ULHu64_P8:
case Mips::USD_P8:
case Mips::USW64_P8:
case Mips::USH64_P8: {
if (OutStreamer.hasRawTextSupport()) {
MCInst Directive;
Directive.setOpcode(Mips::MACRO);
OutStreamer.EmitInstruction(Directive);
OutStreamer.EmitInstruction(TmpInst0);
Directive.setOpcode(Mips::NOMACRO);
OutStreamer.EmitInstruction(Directive);
} else {
MCInstLowering.LowerUnalignedLoadStore(MI, MCInsts);
for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin(); I
!= MCInsts.end(); ++I)
OutStreamer.EmitInstruction(*I);
EmitInstrWithMacroNoAT(MI);
return;
}
MCInstLowering.LowerUnalignedLoadStore(MI, MCInsts);
for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin(); I
!= MCInsts.end(); ++I)
OutStreamer.EmitInstruction(*I);
return;
}
case Mips::CPRESTORE: {
const MachineOperand &MO = MI->getOperand(0);
assert(MO.isImm() && "CPRESTORE's operand must be an immediate.");
int64_t Offset = MO.getImm();
if (!OutStreamer.hasRawTextSupport()) {
// Lower CPLOAD and CPRESTORE
if (Opc == Mips::CPLOAD)
MCInstLowering.LowerCPLOAD(MI, MCInsts);
else if (Opc == Mips::CPRESTORE)
MCInstLowering.LowerCPRESTORE(MI, MCInsts);
if (OutStreamer.hasRawTextSupport()) {
if (!isInt<16>(Offset)) {
EmitInstrWithMacroNoAT(MI);
return;
}
} else {
MCInstLowering.LowerCPRESTORE(Offset, MCInsts);
if (!MCInsts.empty()) {
for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin();
I != MCInsts.end(); ++I)
OutStreamer.EmitInstruction(*I);
return;
}
}
if (Opc == Mips::SETGP01) {
break;
}
case Mips::SETGP01: {
MCInstLowering.LowerSETGP01(MI, MCInsts);
for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin();
@ -125,7 +143,11 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
default:
break;
}
MCInstLowering.Lower(MI, TmpInst0);
OutStreamer.EmitInstruction(TmpInst0);
}
@ -269,13 +291,35 @@ void MipsAsmPrinter::EmitFunctionEntryLabel() {
/// EmitFunctionBodyStart - Targets can override this to emit stuff before
/// the first basic block in the function.
void MipsAsmPrinter::EmitFunctionBodyStart() {
MCInstLowering.Initialize(Mang, &MF->getContext());
emitFrameDirective();
bool EmitCPLoad = (MF->getTarget().getRelocationModel() == Reloc::PIC_) &&
Subtarget->isABI_O32() && MipsFI->globalBaseRegSet() &&
MipsFI->globalBaseRegFixed();
if (OutStreamer.hasRawTextSupport()) {
SmallString<128> Str;
raw_svector_ostream OS(Str);
printSavedRegsBitmask(OS);
OutStreamer.EmitRawText(OS.str());
OutStreamer.EmitRawText(StringRef("\t.set\tnoreorder"));
// Emit .cpload directive if needed.
if (EmitCPLoad)
OutStreamer.EmitRawText(StringRef("\t.cpload\t$25"));
OutStreamer.EmitRawText(StringRef("\t.set\tnomacro"));
if (MipsFI->getEmitNOAT())
OutStreamer.EmitRawText(StringRef("\t.set\tnoat"));
} else if (EmitCPLoad) {
SmallVector<MCInst, 4> MCInsts;
MCInstLowering.LowerCPLOAD(MCInsts);
for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin();
I != MCInsts.end(); ++I)
OutStreamer.EmitInstruction(*I);
}
}
@ -286,6 +330,9 @@ void MipsAsmPrinter::EmitFunctionBodyEnd() {
// always be at the function end, and we can't emit and
// break with BB logic.
if (OutStreamer.hasRawTextSupport()) {
if (MipsFI->getEmitNOAT())
OutStreamer.EmitRawText(StringRef("\t.set\tat"));
OutStreamer.EmitRawText(StringRef("\t.set\tmacro"));
OutStreamer.EmitRawText(StringRef("\t.set\treorder"));
OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));

View File

@ -14,6 +14,8 @@
#ifndef MIPSASMPRINTER_H
#define MIPSASMPRINTER_H
#include "MipsMachineFunction.h"
#include "MipsMCInstLower.h"
#include "MipsSubtarget.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/Support/Compiler.h"
@ -28,12 +30,16 @@ class raw_ostream;
class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
void EmitInstrWithMacroNoAT(const MachineInstr *MI);
public:
const MipsSubtarget *Subtarget;
const MipsFunctionInfo *MipsFI;
MipsMCInstLower MCInstLowering;
explicit MipsAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
: AsmPrinter(TM, Streamer) {
: AsmPrinter(TM, Streamer), MCInstLowering(*this) {
Subtarget = &TM.getSubtarget<MipsSubtarget>();
}
@ -41,6 +47,8 @@ public:
return "Mips Assembly Printer";
}
virtual bool runOnMachineFunction(MachineFunction &MF);
void EmitInstruction(const MachineInstr *MI);
void printSavedRegsBitmask(raw_ostream &O);
void printHex32(unsigned int Value, raw_ostream &O);

View File

@ -108,9 +108,6 @@ static void expandLargeImm(unsigned Reg, int64_t Imm, bool IsN64,
AnalyzeImm.Analyze(Imm, IsN64 ? 64 : 32, false /* LastInstrIsADDiu */);
MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
// FIXME: change this when mips goes MC".
BuildMI(MBB, II, DL, TII.get(Mips::NOAT));
// The first instruction can be a LUi, which is different from other
// instructions (ADDiu, ORI and SLL) in that it does not have a register
// operand.
@ -127,7 +124,6 @@ static void expandLargeImm(unsigned Reg, int64_t Imm, bool IsN64,
.addImm(SignExtend64<16>(Inst->ImmOpnd));
BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(Reg).addReg(ATReg);
BuildMI(MBB, II, DL, TII.get(Mips::ATMACRO));
}
void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
@ -159,18 +155,22 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
// Update stack size
MFI->setStackSize(StackSize);
BuildMI(MBB, MBBI, dl, TII.get(Mips::NOREORDER));
BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO));
// Emit instructions that set the global base register if the target ABI is
// O32.
if (isPIC && MipsFI->globalBaseRegSet() && STI.isABI_O32()) {
if (MipsFI->globalBaseRegFixed())
BuildMI(MBB, llvm::prior(MBBI), dl, TII.get(Mips::CPLOAD))
.addReg(RegInfo->getPICCallReg());
else
if (isPIC && MipsFI->globalBaseRegSet() && STI.isABI_O32() &&
!MipsFI->globalBaseRegFixed()) {
// See MipsInstrInfo.td for explanation.
BuildMI(MBB, MBBI, dl, TII.get(Mips:: SETGP01), Mips::V0);
MachineBasicBlock *NewEntry = MF.CreateMachineBasicBlock();
MF.insert(&MBB, NewEntry);
NewEntry->addSuccessor(&MBB);
// Copy live in registers.
for (MachineBasicBlock::livein_iterator R = MBB.livein_begin();
R != MBB.livein_end(); ++R)
NewEntry->addLiveIn(*R);
BuildMI(*NewEntry, NewEntry->begin(), dl, TII.get(Mips:: SETGP01),
Mips::V0);
}
// No need to allocate space on the stack.
@ -183,8 +183,10 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
// Adjust stack.
if (isInt<16>(-StackSize)) // addi sp, sp, (-stacksize)
BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(-StackSize);
else // Expand immediate that doesn't fit in 16-bit.
else { // Expand immediate that doesn't fit in 16-bit.
MipsFI->setEmitNOAT();
expandLargeImm(SP, -StackSize, STI.isABI_N64(), TII, MBB, MBBI, dl);
}
// emit ".cfi_def_cfa_offset StackSize"
MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
@ -254,12 +256,8 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const {
// Restore GP from the saved stack location
if (MipsFI->needGPSaveRestore()) {
unsigned Offset = MFI->getObjectOffset(MipsFI->getGPFI());
BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE)).addImm(Offset);
if (Offset >= 0x8000) {
BuildMI(MBB, llvm::prior(MBBI), dl, TII.get(Mips::MACRO));
BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO));
}
BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE)).addImm(Offset)
.addReg(Mips::GP);
}
}

View File

@ -727,24 +727,13 @@ def ADJCALLSTACKUP : MipsPseudo<(outs), (ins uimm16:$amt1, uimm16:$amt2),
[(callseq_end timm:$amt1, timm:$amt2)]>;
}
// Some assembly macros need to avoid pseudoinstructions and assembler
// automatic reodering, we should reorder ourselves.
def MACRO : MipsPseudo<(outs), (ins), ".set\tmacro", []>;
def REORDER : MipsPseudo<(outs), (ins), ".set\treorder", []>;
def NOMACRO : MipsPseudo<(outs), (ins), ".set\tnomacro", []>;
def NOREORDER : MipsPseudo<(outs), (ins), ".set\tnoreorder", []>;
// These macros are inserted to prevent GAS from complaining
// when using the AT register.
def NOAT : MipsPseudo<(outs), (ins), ".set\tnoat", []>;
def ATMACRO : MipsPseudo<(outs), (ins), ".set\tat", []>;
// When handling PIC code the assembler needs .cpload and .cprestore
// directives. If the real instructions corresponding these directives
// are used, we have the same behavior, but get also a bunch of warnings
// from the assembler.
def CPLOAD : MipsPseudo<(outs), (ins CPURegs:$picreg), ".cpload\t$picreg", []>;
def CPRESTORE : MipsPseudo<(outs), (ins i32imm:$loc), ".cprestore\t$loc", []>;
let neverHasSideEffects = 1 in
def CPRESTORE : MipsPseudo<(outs), (ins i32imm:$loc, CPURegs:$gp),
".cprestore\t$loc", []>;
// For O32 ABI & PIC & non-fixed global base register, the following instruction
// seqeunce is emitted to set the global base register:
@ -762,7 +751,10 @@ def CPRESTORE : MipsPseudo<(outs), (ins i32imm:$loc), ".cprestore\t$loc", []>;
// before or between instructions 0 and 1, which is a limitation imposed by
// GNU linker.
let isTerminator = 1, isBarrier = 1 in
def SETGP01 : MipsPseudo<(outs CPURegs:$dst), (ins), "", []>;
let neverHasSideEffects = 1 in
def SETGP2 : MipsPseudo<(outs CPURegs:$globalreg), (ins CPURegs:$picreg), "",
[]>;

View File

@ -26,9 +26,13 @@
using namespace llvm;
MipsMCInstLower::MipsMCInstLower(Mangler *mang, const MachineFunction &mf,
MipsAsmPrinter &asmprinter)
: Ctx(mf.getContext()), Mang(mang), AsmPrinter(asmprinter) {}
MipsMCInstLower::MipsMCInstLower(MipsAsmPrinter &asmprinter)
: AsmPrinter(asmprinter) {}
void MipsMCInstLower::Initialize(Mangler *M, MCContext* C) {
Mang = M;
Ctx = C;
}
MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MachineOperandType MOTy,
@ -90,7 +94,7 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
llvm_unreachable("<unknown operand type>");
}
const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, Ctx);
const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx);
if (!Offset)
return MCOperand::CreateExpr(MCSym);
@ -98,76 +102,68 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
// Assume offset is never negative.
assert(Offset > 0);
const MCConstantExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx);
const MCBinaryExpr *AddExpr = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, Ctx);
const MCConstantExpr *OffsetExpr = MCConstantExpr::Create(Offset, *Ctx);
const MCBinaryExpr *AddExpr = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx);
return MCOperand::CreateExpr(AddExpr);
}
static void CreateMCInst(MCInst& Inst, unsigned Opc, const MCOperand& Opnd0,
const MCOperand& Opnd1,
const MCOperand& Opnd2 = MCOperand()) {
Inst.setOpcode(Opc);
Inst.addOperand(Opnd0);
Inst.addOperand(Opnd1);
if (Opnd2.isValid())
Inst.addOperand(Opnd2);
}
// Lower ".cpload $reg" to
// "lui $gp, %hi(_gp_disp)"
// "addiu $gp, $gp, %lo(_gp_disp)"
// "addu $gp. $gp, $reg"
void MipsMCInstLower::LowerCPLOAD(const MachineInstr *MI,
SmallVector<MCInst, 4>& MCInsts) {
MCInst Lui, Addiu, Addu;
// "addu $gp, $gp, $t9"
void MipsMCInstLower::LowerCPLOAD(SmallVector<MCInst, 4>& MCInsts) {
MCOperand GPReg = MCOperand::CreateReg(Mips::GP);
MCOperand T9Reg = MCOperand::CreateReg(Mips::T9);
StringRef SymName("_gp_disp");
const MCSymbol *Symbol = Ctx.GetOrCreateSymbol(SymName);
const MCSymbol *Sym = Ctx->GetOrCreateSymbol(SymName);
const MCSymbolRefExpr *MCSym;
// lui $gp, %hi(_gp_disp)
Lui.setOpcode(Mips::LUi);
Lui.addOperand(MCOperand::CreateReg(Mips::GP));
MCSym = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_Mips_ABS_HI, Ctx);
Lui.addOperand(MCOperand::CreateExpr(MCSym));
MCInsts.push_back(Lui);
MCSym = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_Mips_ABS_HI, *Ctx);
MCOperand SymHi = MCOperand::CreateExpr(MCSym);
MCSym = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_Mips_ABS_LO, *Ctx);
MCOperand SymLo = MCOperand::CreateExpr(MCSym);
// addiu $gp, $gp, %lo(_gp_disp)
Addiu.setOpcode(Mips::ADDiu);
Addiu.addOperand(MCOperand::CreateReg(Mips::GP));
Addiu.addOperand(MCOperand::CreateReg(Mips::GP));
MCSym = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_Mips_ABS_LO, Ctx);
Addiu.addOperand(MCOperand::CreateExpr(MCSym));
MCInsts.push_back(Addiu);
MCInsts.resize(3);
// addu $gp. $gp, $reg
Addu.setOpcode(Mips::ADDu);
Addu.addOperand(MCOperand::CreateReg(Mips::GP));
Addu.addOperand(MCOperand::CreateReg(Mips::GP));
const MachineOperand &MO = MI->getOperand(0);
assert(MO.isReg() && "CPLOAD's operand must be a register.");
Addu.addOperand(MCOperand::CreateReg(MO.getReg()));
MCInsts.push_back(Addu);
CreateMCInst(MCInsts[0], Mips::LUi, GPReg, SymHi);
CreateMCInst(MCInsts[1], Mips::ADDiu, GPReg, GPReg, SymLo);
CreateMCInst(MCInsts[2], Mips::ADDu, GPReg, GPReg, T9Reg);
}
// Lower ".cprestore offset" to "sw $gp, offset($sp)".
void MipsMCInstLower::LowerCPRESTORE(const MachineInstr *MI,
void MipsMCInstLower::LowerCPRESTORE(int64_t Offset,
SmallVector<MCInst, 4>& MCInsts) {
const MachineOperand &MO = MI->getOperand(0);
assert(MO.isImm() && "CPRESTORE's operand must be an immediate.");
unsigned Offset = MO.getImm(), Reg = Mips::SP;
MCInst Sw;
assert(isInt<32>(Offset) && (Offset >= 0) &&
"Imm operand of .cprestore must be a non-negative 32-bit value.");
if (Offset >= 0x8000) {
unsigned Hi = (Offset >> 16) + ((Offset & 0x8000) != 0);
MCOperand SPReg = MCOperand::CreateReg(Mips::SP), BaseReg = SPReg;
MCOperand GPReg = MCOperand::CreateReg(Mips::GP);
if (!isInt<16>(Offset)) {
unsigned Hi = ((Offset + 0x8000) >> 16) & 0xffff;
Offset &= 0xffff;
Reg = Mips::AT;
MCOperand ATReg = MCOperand::CreateReg(Mips::AT);
BaseReg = ATReg;
// lui at,hi
// addu at,at,sp
MCInsts.resize(2);
MCInsts[0].setOpcode(Mips::LUi);
MCInsts[0].addOperand(MCOperand::CreateReg(Mips::AT));
MCInsts[0].addOperand(MCOperand::CreateImm(Hi));
MCInsts[1].setOpcode(Mips::ADDu);
MCInsts[1].addOperand(MCOperand::CreateReg(Mips::AT));
MCInsts[1].addOperand(MCOperand::CreateReg(Mips::AT));
MCInsts[1].addOperand(MCOperand::CreateReg(Mips::SP));
CreateMCInst(MCInsts[0], Mips::LUi, ATReg, MCOperand::CreateImm(Hi));
CreateMCInst(MCInsts[1], Mips::ADDu, ATReg, ATReg, SPReg);
}
Sw.setOpcode(Mips::SW);
Sw.addOperand(MCOperand::CreateReg(Mips::GP));
Sw.addOperand(MCOperand::CreateReg(Reg));
Sw.addOperand(MCOperand::CreateImm(Offset));
MCInst Sw;
CreateMCInst(Sw, Mips::SW, GPReg, BaseReg, MCOperand::CreateImm(Offset));
MCInsts.push_back(Sw);
}
@ -332,18 +328,16 @@ void MipsMCInstLower::LowerSETGP01(const MachineInstr *MI,
assert(MO.isReg());
MCOperand RegOpnd = MCOperand::CreateReg(MO.getReg());
StringRef SymName("_gp_disp");
const MCSymbol *Sym = Ctx.GetOrCreateSymbol(SymName);
const MCSymbol *Sym = Ctx->GetOrCreateSymbol(SymName);
const MCSymbolRefExpr *MCSym;
MCSym = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_Mips_ABS_HI, *Ctx);
MCOperand SymHi = MCOperand::CreateExpr(MCSym);
MCSym = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_Mips_ABS_LO, *Ctx);
MCOperand SymLo = MCOperand::CreateExpr(MCSym);
MCInsts.resize(2);
MCSym = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_Mips_ABS_HI, Ctx);
MCInsts[0].setOpcode(Mips::LUi);
MCInsts[0].addOperand(RegOpnd);
MCInsts[0].addOperand(MCOperand::CreateExpr(MCSym));
MCSym = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_Mips_ABS_LO, Ctx);
MCInsts[1].setOpcode(Mips::ADDiu);
MCInsts[1].addOperand(RegOpnd);
MCInsts[1].addOperand(RegOpnd);
MCInsts[1].addOperand(MCOperand::CreateExpr(MCSym));
CreateMCInst(MCInsts[0], Mips::LUi, RegOpnd, SymHi);
CreateMCInst(MCInsts[1], Mips::ADDiu, RegOpnd, RegOpnd, SymLo);
}

View File

@ -26,15 +26,15 @@ namespace llvm {
// MCInst.
class LLVM_LIBRARY_VISIBILITY MipsMCInstLower {
typedef MachineOperand::MachineOperandType MachineOperandType;
MCContext &Ctx;
MCContext *Ctx;
Mangler *Mang;
MipsAsmPrinter &AsmPrinter;
public:
MipsMCInstLower(Mangler *mang, const MachineFunction &MF,
MipsAsmPrinter &asmprinter);
MipsMCInstLower(MipsAsmPrinter &asmprinter);
void Initialize(Mangler *mang, MCContext* C);
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
void LowerCPLOAD(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts);
void LowerCPRESTORE(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts);
void LowerCPLOAD(SmallVector<MCInst, 4>& MCInsts);
void LowerCPRESTORE(int64_t Offset, SmallVector<MCInst, 4>& MCInsts);
void LowerUnalignedLoadStore(const MachineInstr *MI,
SmallVector<MCInst, 4>& MCInsts);
void LowerSETGP01(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts);

View File

@ -227,8 +227,7 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
AnalyzeImm.Analyze(Offset, Size, true /* LastInstrIsADDiu */);
MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
// FIXME: change this when mips goes MC".
BuildMI(MBB, II, DL, TII.get(Mips::NOAT));
MipsFI->setEmitNOAT();
// The first instruction can be a LUi, which is different from other
// instructions (ADDiu, ORI and SLL) in that it does not have a register
@ -249,7 +248,6 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
FrameReg = ATReg;
Offset = SignExtend64<16>(Inst->ImmOpnd);
BuildMI(MBB, ++II, MI.getDebugLoc(), TII.get(Mips::ATMACRO));
}
MI.getOperand(i).ChangeToRegister(FrameReg, false);