forked from OSchip/llvm-project
[mips][ias] Moved most instruction emission helpers to MipsTargetStreamer. NFC.
Summary: * Moved all the emit*() helpers to MipsTargetStreamer. * Moved createNop() to MipsTargetStreamer as emitNop() and emitEmptyDelaySlot(). This instruction has been split to distinguish between the 'nop' instruction and the nop used in delay slots which is sometimes a different nop to the 'nop' instruction (e.g. for short delay slots on microMIPS). * Moved createAddu() to MipsTargetStreamer as emitAddu(). * Moved createAppropriateDSLL() to MipsTargetStreamer as emitDSLL(). Reviewers: sdardis Subscribers: dsanders, sdardis, llvm-commits Differential Revision: http://reviews.llvm.org/D19712 llvm-svn: 268041
This commit is contained in:
parent
9fc5908674
commit
a736b37a25
|
@ -240,12 +240,6 @@ class MipsAsmParser : public MCTargetAsmParser {
|
|||
bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI);
|
||||
|
||||
void createNop(bool hasShortDelaySlot, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI);
|
||||
|
||||
void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
|
||||
bool Is64Bit, MCStreamer &Out, const MCSubtargetInfo *STI);
|
||||
|
||||
void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
|
||||
MCStreamer &Out, const MCSubtargetInfo *STI);
|
||||
|
||||
|
@ -1488,82 +1482,10 @@ static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
|
||||
MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
MCInst tmpInst;
|
||||
tmpInst.setOpcode(Opcode);
|
||||
tmpInst.addOperand(MCOperand::createReg(Reg0));
|
||||
tmpInst.addOperand(Op1);
|
||||
tmpInst.setLoc(IDLoc);
|
||||
Out.EmitInstruction(tmpInst, *STI);
|
||||
}
|
||||
|
||||
void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
|
||||
MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Out, STI);
|
||||
}
|
||||
|
||||
void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
|
||||
MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Out, STI);
|
||||
}
|
||||
|
||||
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
|
||||
MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
MCInst tmpInst;
|
||||
tmpInst.setOpcode(Opcode);
|
||||
tmpInst.addOperand(MCOperand::createImm(Imm1));
|
||||
tmpInst.addOperand(MCOperand::createImm(Imm2));
|
||||
tmpInst.setLoc(IDLoc);
|
||||
Out.EmitInstruction(tmpInst, *STI);
|
||||
}
|
||||
|
||||
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
|
||||
MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
MCInst tmpInst;
|
||||
tmpInst.setOpcode(Opcode);
|
||||
tmpInst.addOperand(MCOperand::createReg(Reg0));
|
||||
tmpInst.setLoc(IDLoc);
|
||||
Out.EmitInstruction(tmpInst, *STI);
|
||||
}
|
||||
|
||||
void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
|
||||
SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
MCInst tmpInst;
|
||||
tmpInst.setOpcode(Opcode);
|
||||
tmpInst.addOperand(MCOperand::createReg(Reg0));
|
||||
tmpInst.addOperand(MCOperand::createReg(Reg1));
|
||||
tmpInst.addOperand(Op2);
|
||||
tmpInst.setLoc(IDLoc);
|
||||
Out.EmitInstruction(tmpInst, *STI);
|
||||
}
|
||||
|
||||
void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
|
||||
SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, Out, STI);
|
||||
}
|
||||
|
||||
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
|
||||
SMLoc IDLoc, MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, Out, STI);
|
||||
}
|
||||
|
||||
void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
|
||||
SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
if (ShiftAmount >= 32) {
|
||||
emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, Out, STI);
|
||||
return;
|
||||
}
|
||||
|
||||
emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Out, STI);
|
||||
}
|
||||
} // end anonymous namespace.
|
||||
|
||||
bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
||||
MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
|
||||
bool ExpandedJalSym = false;
|
||||
|
||||
|
@ -1722,10 +1644,10 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
|||
const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
|
||||
const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
|
||||
|
||||
emitRRX(Mips::LW, Mips::T9, Mips::GP,
|
||||
MCOperand::createExpr(Got16RelocExpr), IDLoc, Out, STI);
|
||||
emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
|
||||
MCOperand::createExpr(Lo16RelocExpr), IDLoc, Out, STI);
|
||||
TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
|
||||
MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
|
||||
TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
|
||||
MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
|
||||
} else if (isABI_N32() || isABI_N64()) {
|
||||
// If it's a local symbol and the N32/N64 ABIs are being used,
|
||||
// we expand to:
|
||||
|
@ -1734,8 +1656,9 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
|||
// jalr $25
|
||||
const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
|
||||
|
||||
emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
|
||||
MCOperand::createExpr(GotDispRelocExpr), IDLoc, Out, STI);
|
||||
TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
|
||||
Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
|
||||
STI);
|
||||
}
|
||||
} else {
|
||||
// If it's an external/weak symbol, we expand to:
|
||||
|
@ -1744,8 +1667,8 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
|||
// jalr $25
|
||||
const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
|
||||
|
||||
emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
|
||||
MCOperand::createExpr(Call16RelocExpr), IDLoc, Out, STI);
|
||||
TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
|
||||
MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
|
||||
}
|
||||
|
||||
MCInst JalrInst;
|
||||
|
@ -1816,8 +1739,8 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
|||
(BaseReg.getReg() == Mips::GP ||
|
||||
BaseReg.getReg() == Mips::GP_64)) {
|
||||
|
||||
emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
|
||||
IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
|
||||
IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1929,7 +1852,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
|||
bool FillDelaySlot =
|
||||
MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
|
||||
if (FillDelaySlot)
|
||||
getTargetStreamer().emitDirectiveSetNoReorder();
|
||||
TOut.emitDirectiveSetNoReorder();
|
||||
|
||||
MacroExpanderResultTy ExpandResult =
|
||||
tryExpandInstruction(Inst, IDLoc, Out, STI);
|
||||
|
@ -1946,8 +1869,8 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
|||
// If this instruction has a delay slot and .set reorder is active,
|
||||
// emit a NOP after it.
|
||||
if (FillDelaySlot) {
|
||||
createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Out, STI);
|
||||
getTargetStreamer().emitDirectiveSetReorder();
|
||||
TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
|
||||
TOut.emitDirectiveSetReorder();
|
||||
}
|
||||
|
||||
if ((Inst.getOpcode() == Mips::JalOneReg ||
|
||||
|
@ -1958,7 +1881,8 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
|||
// If .set reorder has been used, we've already emitted a NOP.
|
||||
// If .set noreorder has been used, we need to emit a NOP at this point.
|
||||
if (!AssemblerOptions.back()->isReorder())
|
||||
createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Out, STI);
|
||||
TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
|
||||
STI);
|
||||
|
||||
// Load the $gp from the stack.
|
||||
createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
|
||||
|
@ -2126,6 +2050,8 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
|
||||
MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
// Create a JALR instruction which is going to replace the pseudo-JAL.
|
||||
MCInst JalrInst;
|
||||
JalrInst.setLoc(IDLoc);
|
||||
|
@ -2160,9 +2086,9 @@ bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
|
|||
// If .set reorder is active and branch instruction has a delay slot,
|
||||
// emit a NOP after it.
|
||||
const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
|
||||
if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
|
||||
createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Out, STI);
|
||||
}
|
||||
if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
|
||||
TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
|
||||
STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2188,6 +2114,8 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||
unsigned SrcReg, bool Is32BitImm,
|
||||
bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
if (!Is32BitImm && !isGP64bit()) {
|
||||
Error(IDLoc, "instruction requires a 64-bit architecture");
|
||||
return true;
|
||||
|
@ -2231,11 +2159,11 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||
// traditional assembler behaviour. N32 would normally use addiu for both
|
||||
// integers and addresses.
|
||||
if (IsAddress && !Is32BitImm) {
|
||||
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2247,9 +2175,9 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||
return true;
|
||||
}
|
||||
|
||||
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
|
||||
if (UseSrcReg)
|
||||
emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2263,29 +2191,29 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||
// Traditional behaviour seems to special case this particular value. It's
|
||||
// not clear why other masks are handled differently.
|
||||
if (ImmValue == 0xffffffff) {
|
||||
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Out, STI);
|
||||
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Out, STI);
|
||||
TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
|
||||
TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
|
||||
if (UseSrcReg)
|
||||
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Expand to an ORi instead of a LUi to avoid sign-extending into the
|
||||
// upper 32 bits.
|
||||
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Out, STI);
|
||||
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
|
||||
TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
|
||||
if (Bits15To0)
|
||||
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
|
||||
if (UseSrcReg)
|
||||
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Out, STI);
|
||||
TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
|
||||
if (Bits15To0)
|
||||
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
|
||||
if (UseSrcReg)
|
||||
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2301,11 +2229,11 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||
unsigned LastSet = findLastSet((uint64_t)ImmValue);
|
||||
unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
|
||||
uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
|
||||
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Out, STI);
|
||||
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
|
||||
TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
|
||||
|
||||
if (UseSrcReg)
|
||||
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2328,9 +2256,8 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||
uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
|
||||
|
||||
if (ImmChunk != 0) {
|
||||
emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
|
||||
Out, STI);
|
||||
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Out, STI);
|
||||
TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
|
||||
TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
|
||||
ShiftCarriedForwards = 0;
|
||||
}
|
||||
|
||||
|
@ -2340,11 +2267,10 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||
|
||||
// Finish any remaining shifts left by trailing zeros.
|
||||
if (ShiftCarriedForwards)
|
||||
emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
|
||||
Out, STI);
|
||||
TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
|
||||
|
||||
if (UseSrcReg)
|
||||
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2402,6 +2328,7 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
|
|||
bool Is32BitSym, SMLoc IDLoc,
|
||||
MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
warnIfNoMacro(IDLoc);
|
||||
|
||||
const MCExpr *Symbol = cast<MCExpr>(SymExpr);
|
||||
|
@ -2436,17 +2363,17 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
|
|||
// dsll $at, $at, 16
|
||||
// daddiu $at, $at, %lo(sym)
|
||||
// daddu $rd, $at, $rd
|
||||
emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc, Out,
|
||||
STI);
|
||||
emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
|
||||
IDLoc, Out, STI);
|
||||
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Out, STI);
|
||||
emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
|
||||
Out, STI);
|
||||
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Out, STI);
|
||||
emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
|
||||
Out, STI);
|
||||
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
|
||||
STI);
|
||||
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
|
||||
MCOperand::createExpr(HigherExpr), IDLoc, STI);
|
||||
TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
|
||||
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
|
||||
IDLoc, STI);
|
||||
TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
|
||||
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
|
||||
IDLoc, STI);
|
||||
TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2459,17 +2386,17 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
|
|||
// dsll32 $rd, $rd, 0
|
||||
// daddu $rd, $rd, $at
|
||||
// (daddu $rd, $rd, $rs)
|
||||
emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc, Out,
|
||||
STI);
|
||||
emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, Out, STI);
|
||||
emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
|
||||
IDLoc, Out, STI);
|
||||
emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
|
||||
Out, STI);
|
||||
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Out, STI);
|
||||
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Out, STI);
|
||||
TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
|
||||
STI);
|
||||
TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
|
||||
TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
|
||||
MCOperand::createExpr(HigherExpr), IDLoc, STI);
|
||||
TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
|
||||
IDLoc, STI);
|
||||
TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
|
||||
TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
|
||||
if (UseSrcReg)
|
||||
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2494,12 +2421,12 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
|
|||
TmpReg = ATReg;
|
||||
}
|
||||
|
||||
emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Out, STI);
|
||||
emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
|
||||
Out, STI);
|
||||
TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
|
||||
TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
|
||||
IDLoc, STI);
|
||||
|
||||
if (UseSrcReg)
|
||||
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
|
||||
else
|
||||
assert(
|
||||
getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
|
||||
|
@ -2510,6 +2437,8 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
|
|||
bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
|
||||
MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
|
||||
"unexpected number of operands");
|
||||
|
||||
|
@ -2545,13 +2474,14 @@ bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
|
|||
// emit a NOP after it.
|
||||
const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
|
||||
if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
|
||||
createNop(true, IDLoc, Out, STI);
|
||||
TOut.emitEmptyDelaySlot(true, IDLoc, STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
const MCOperand &DstRegOp = Inst.getOperand(0);
|
||||
assert(DstRegOp.isReg() && "expected register operand kind");
|
||||
|
||||
|
@ -2577,8 +2507,8 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
|
||||
int64_t ImmValue = ImmOp.getImm();
|
||||
if (ImmValue == 0)
|
||||
emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc, Out,
|
||||
STI);
|
||||
TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
|
||||
STI);
|
||||
else {
|
||||
warnIfNoMacro(IDLoc);
|
||||
|
||||
|
@ -2590,7 +2520,7 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
IDLoc, Out, STI))
|
||||
return true;
|
||||
|
||||
emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Out, STI);
|
||||
TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2598,6 +2528,7 @@ bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI, bool isLoad,
|
||||
bool isImmOpnd) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
MCOperand HiOperand, LoOperand;
|
||||
unsigned TmpRegNum;
|
||||
// 1st operand is either the source or destination register.
|
||||
|
@ -2660,13 +2591,13 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
return;
|
||||
}
|
||||
|
||||
emitRX(Mips::LUi, TmpRegNum, HiOperand, IDLoc, Out, STI);
|
||||
TOut.emitRX(Mips::LUi, TmpRegNum, HiOperand, IDLoc, STI);
|
||||
// Add temp register to base.
|
||||
if (BaseRegNum != Mips::ZERO)
|
||||
emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Out, STI);
|
||||
TOut.emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, STI);
|
||||
// And finally, create original instruction with low part
|
||||
// of offset and new base.
|
||||
emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum, LoOperand, IDLoc, Out, STI);
|
||||
TOut.emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum, LoOperand, IDLoc, STI);
|
||||
}
|
||||
|
||||
bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
|
||||
|
@ -2701,6 +2632,7 @@ bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
|
|||
bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
|
||||
MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
bool EmittedNoMacroWarning = false;
|
||||
unsigned PseudoOpcode = Inst.getOpcode();
|
||||
unsigned SrcReg = Inst.getOperand(0).getReg();
|
||||
|
@ -2835,37 +2767,37 @@ bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
|
|||
// with GAS' behaviour. However, they may not generate the most efficient
|
||||
// code in some circumstances.
|
||||
if (PseudoOpcode == Mips::BLT) {
|
||||
emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
|
||||
Out, STI);
|
||||
TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
|
||||
IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
if (PseudoOpcode == Mips::BLE) {
|
||||
emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
|
||||
Out, STI);
|
||||
TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
|
||||
IDLoc, STI);
|
||||
Warning(IDLoc, "branch is always taken");
|
||||
return false;
|
||||
}
|
||||
if (PseudoOpcode == Mips::BGE) {
|
||||
emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
|
||||
Out, STI);
|
||||
TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
|
||||
IDLoc, STI);
|
||||
Warning(IDLoc, "branch is always taken");
|
||||
return false;
|
||||
}
|
||||
if (PseudoOpcode == Mips::BGT) {
|
||||
emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
|
||||
Out, STI);
|
||||
TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
|
||||
IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
if (PseudoOpcode == Mips::BGTU) {
|
||||
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
|
||||
MCOperand::createExpr(OffsetExpr), IDLoc, Out, STI);
|
||||
TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
|
||||
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
if (AcceptsEquality) {
|
||||
// If both registers are $0 and the pseudo-branch accepts equality, it
|
||||
// will always be taken, so we emit an unconditional branch.
|
||||
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
|
||||
MCOperand::createExpr(OffsetExpr), IDLoc, Out, STI);
|
||||
TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
|
||||
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
|
||||
Warning(IDLoc, "branch is always taken");
|
||||
return false;
|
||||
}
|
||||
|
@ -2889,8 +2821,8 @@ bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
|
|||
// the pseudo-branch will always be taken, so we emit an unconditional
|
||||
// branch.
|
||||
// This only applies to unsigned pseudo-branches.
|
||||
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
|
||||
MCOperand::createExpr(OffsetExpr), IDLoc, Out, STI);
|
||||
TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
|
||||
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
|
||||
Warning(IDLoc, "branch is always taken");
|
||||
return false;
|
||||
}
|
||||
|
@ -2907,17 +2839,17 @@ bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
|
|||
//
|
||||
// Because only BLEU and BGEU branch on equality, we can use the
|
||||
// AcceptsEquality variable to decide when to emit the BEQZ.
|
||||
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
|
||||
IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
|
||||
MCOperand::createExpr(OffsetExpr), IDLoc, Out, STI);
|
||||
TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
|
||||
IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
|
||||
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
// If we have a signed pseudo-branch and one of the registers is $0,
|
||||
// we can use an appropriate compare-to-zero branch. We select which one
|
||||
// to use in the switch statement above.
|
||||
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
|
||||
IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
|
||||
IDLoc, Out, STI);
|
||||
TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
|
||||
IsSrcRegZero ? TrgReg : SrcReg,
|
||||
MCOperand::createExpr(OffsetExpr), IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2945,20 +2877,22 @@ bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
|
|||
//
|
||||
// The same applies to the unsigned variants, except that SLTu is used
|
||||
// instead of SLT.
|
||||
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
|
||||
ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
|
||||
IDLoc, Out, STI);
|
||||
TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
|
||||
ReverseOrderSLT ? TrgReg : SrcReg,
|
||||
ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
|
||||
|
||||
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
|
||||
: (AcceptsEquality ? Mips::BEQ : Mips::BNE),
|
||||
ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
|
||||
Out, STI);
|
||||
TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
|
||||
: (AcceptsEquality ? Mips::BEQ : Mips::BNE),
|
||||
ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
|
||||
STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI, const bool IsMips64,
|
||||
const bool Signed) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
if (hasMips32r6()) {
|
||||
Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
|
||||
return false;
|
||||
|
@ -2992,15 +2926,15 @@ bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
if (IsMips64) {
|
||||
if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
|
||||
if (UseTraps) {
|
||||
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
emitII(Mips::BREAK, 0x7, 0, IDLoc, Out, STI);
|
||||
TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
emitRR(DivOp, RsReg, RtReg, IDLoc, Out, STI);
|
||||
TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3009,11 +2943,11 @@ bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
Warning(IDLoc, "division by zero");
|
||||
if (Signed) {
|
||||
if (UseTraps) {
|
||||
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
emitII(Mips::BREAK, 0x7, 0, IDLoc, Out, STI);
|
||||
TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3025,21 +2959,21 @@ bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
|
||||
if (UseTraps) {
|
||||
BranchTarget = IsMips64 ? 12 : 8;
|
||||
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
|
||||
} else {
|
||||
BranchTarget = IsMips64 ? 20 : 16;
|
||||
BranchTargetNoTraps = 8;
|
||||
// Branch to the li instruction.
|
||||
emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, STI);
|
||||
}
|
||||
|
||||
emitRR(DivOp, RsReg, RtReg, IDLoc, Out, STI);
|
||||
TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
|
||||
|
||||
if (!UseTraps)
|
||||
emitII(Mips::BREAK, 0x7, 0, IDLoc, Out, STI);
|
||||
TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
|
||||
|
||||
if (!Signed) {
|
||||
emitR(Mips::MFLO, RsReg, IDLoc, Out, STI);
|
||||
TOut.emitR(Mips::MFLO, RsReg, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3047,33 +2981,34 @@ bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
if (!ATReg)
|
||||
return true;
|
||||
|
||||
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
|
||||
if (IsMips64) {
|
||||
// Branch to the mflo instruction.
|
||||
emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Out, STI);
|
||||
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Out, STI);
|
||||
emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
|
||||
TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
|
||||
TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
|
||||
} else {
|
||||
// Branch to the mflo instruction.
|
||||
emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Out, STI);
|
||||
emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
|
||||
TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
|
||||
}
|
||||
|
||||
if (UseTraps)
|
||||
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
|
||||
else {
|
||||
// Branch to the mflo instruction.
|
||||
emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Out, STI);
|
||||
emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Out, STI);
|
||||
emitII(Mips::BREAK, 0x6, 0, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, STI);
|
||||
TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
|
||||
TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
|
||||
}
|
||||
emitR(Mips::MFLO, RsReg, IDLoc, Out, STI);
|
||||
TOut.emitR(Mips::MFLO, RsReg, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
|
||||
SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
assert(Inst.getNumOperands() == 3 && "Invalid operand count");
|
||||
assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
|
||||
|
@ -3087,30 +3022,32 @@ bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
|
|||
unsigned ATReg = getATReg(IDLoc);
|
||||
if (!ATReg)
|
||||
return true;
|
||||
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, Out, STI);
|
||||
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, Out, STI);
|
||||
createNop(false, IDLoc, Out, STI);
|
||||
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, Out, STI);
|
||||
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, Out, STI);
|
||||
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, Out, STI);
|
||||
createNop(false, IDLoc, Out, STI);
|
||||
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
|
||||
: Mips::CVT_W_S,
|
||||
FirstReg, SecondReg, IDLoc, Out, STI);
|
||||
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, Out, STI);
|
||||
createNop(false, IDLoc, Out, STI);
|
||||
TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
|
||||
TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
|
||||
TOut.emitNop(IDLoc, STI);
|
||||
TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
|
||||
TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
|
||||
TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
|
||||
TOut.emitNop(IDLoc, STI);
|
||||
TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
|
||||
: Mips::CVT_W_S,
|
||||
FirstReg, SecondReg, IDLoc, STI);
|
||||
TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
|
||||
TOut.emitNop(IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
|
||||
: Mips::TRUNC_W_S,
|
||||
FirstReg, SecondReg, IDLoc, Out, STI);
|
||||
TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
|
||||
: Mips::TRUNC_W_S,
|
||||
FirstReg, SecondReg, IDLoc, STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
|
||||
MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
if (hasMips32r6() || hasMips64r6()) {
|
||||
Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
|
||||
return false;
|
||||
|
@ -3155,7 +3092,7 @@ bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
|
|||
// NOTE: If there is no source register specified in the ULHU, the parser
|
||||
// will interpret it as $0.
|
||||
if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
|
||||
createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Out, STI);
|
||||
TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI);
|
||||
}
|
||||
|
||||
unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
|
||||
|
@ -3173,21 +3110,23 @@ bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
|
|||
|
||||
unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
|
||||
|
||||
emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
|
||||
FirstLbuOffset, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
|
||||
FirstLbuOffset, IDLoc, STI);
|
||||
|
||||
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc, Out,
|
||||
STI);
|
||||
TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
|
||||
STI);
|
||||
|
||||
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Out, STI);
|
||||
TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
|
||||
|
||||
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
if (hasMips32r6() || hasMips64r6()) {
|
||||
Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
|
||||
return false;
|
||||
|
@ -3229,7 +3168,7 @@ bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
// NOTE: If there is no source register specified in the ULW, the parser
|
||||
// will interpret it as $0.
|
||||
if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
|
||||
createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Out, STI);
|
||||
TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI);
|
||||
}
|
||||
|
||||
unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
|
||||
|
@ -3242,11 +3181,11 @@ bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
|
||||
}
|
||||
|
||||
emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc, Out,
|
||||
STI);
|
||||
TOut.emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
|
||||
STI);
|
||||
|
||||
emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
|
||||
Out, STI);
|
||||
TOut.emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset,
|
||||
IDLoc, STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -3254,6 +3193,7 @@ bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
|
||||
MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
assert (Inst.getNumOperands() == 3 && "Invalid operand count");
|
||||
assert (Inst.getOperand(0).isReg() &&
|
||||
|
@ -3309,9 +3249,9 @@ bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
|
|||
}
|
||||
|
||||
if (FinalDstReg == Mips::NoRegister)
|
||||
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
|
||||
else
|
||||
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, Out, STI);
|
||||
TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -3319,6 +3259,7 @@ bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
|
|||
|
||||
bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
unsigned ATReg = Mips::NoRegister;
|
||||
unsigned DReg = Inst.getOperand(0).getReg();
|
||||
unsigned SReg = Inst.getOperand(1).getReg();
|
||||
|
@ -3337,13 +3278,13 @@ bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
}
|
||||
|
||||
if (Inst.getOpcode() == Mips::ROL) {
|
||||
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Out, STI);
|
||||
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
|
||||
TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Inst.getOpcode() == Mips::ROR) {
|
||||
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3369,10 +3310,10 @@ bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
if (!ATReg)
|
||||
return true;
|
||||
|
||||
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Out, STI);
|
||||
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Out, STI);
|
||||
emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Out, STI);
|
||||
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
|
||||
TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
|
||||
TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
|
||||
TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -3383,7 +3324,7 @@ bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
|
||||
MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
unsigned ATReg = Mips::NoRegister;
|
||||
unsigned DReg = Inst.getOperand(0).getReg();
|
||||
unsigned SReg = Inst.getOperand(1).getReg();
|
||||
|
@ -3399,12 +3340,12 @@ bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
|
|||
uint64_t ShiftValue = ImmValue;
|
||||
if (ImmValue != 0)
|
||||
ShiftValue = MaxShift - ImmValue;
|
||||
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Inst.getOpcode() == Mips::RORImm) {
|
||||
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3414,7 +3355,7 @@ bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
|
|||
if (hasMips32()) {
|
||||
|
||||
if (ImmValue == 0) {
|
||||
emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3435,9 +3376,9 @@ bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
|
|||
if (!ATReg)
|
||||
return true;
|
||||
|
||||
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), Out, STI);
|
||||
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), Out, STI);
|
||||
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
|
||||
TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
|
||||
TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -3447,7 +3388,7 @@ bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
|
|||
|
||||
bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
unsigned ATReg = Mips::NoRegister;
|
||||
unsigned DReg = Inst.getOperand(0).getReg();
|
||||
unsigned SReg = Inst.getOperand(1).getReg();
|
||||
|
@ -3466,13 +3407,13 @@ bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
}
|
||||
|
||||
if (Inst.getOpcode() == Mips::DROL) {
|
||||
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), Out, STI);
|
||||
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
|
||||
TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Inst.getOpcode() == Mips::DROR) {
|
||||
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3498,10 +3439,10 @@ bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
if (!ATReg)
|
||||
return true;
|
||||
|
||||
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), Out, STI);
|
||||
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), Out, STI);
|
||||
emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), Out, STI);
|
||||
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
|
||||
TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
|
||||
TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
|
||||
TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -3512,7 +3453,7 @@ bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
|||
bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
|
||||
MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
unsigned ATReg = Mips::NoRegister;
|
||||
unsigned DReg = Inst.getOperand(0).getReg();
|
||||
unsigned SReg = Inst.getOperand(1).getReg();
|
||||
|
@ -3546,7 +3487,7 @@ bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
|
|||
if (Inst.getOpcode() == Mips::DROLImm)
|
||||
ShiftValue = (32 - ImmValue % 32) % 32;
|
||||
|
||||
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -3554,7 +3495,7 @@ bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
|
|||
if (hasMips64()) {
|
||||
|
||||
if (ImmValue == 0) {
|
||||
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3595,9 +3536,10 @@ bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
|
|||
if (!ATReg)
|
||||
return true;
|
||||
|
||||
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), Out, STI);
|
||||
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32, Inst.getLoc(), Out, STI);
|
||||
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), Out, STI);
|
||||
TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
|
||||
TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
|
||||
Inst.getLoc(), STI);
|
||||
TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -3607,38 +3549,25 @@ bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
|
|||
|
||||
bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
unsigned FirstRegOp = Inst.getOperand(0).getReg();
|
||||
unsigned SecondRegOp = Inst.getOperand(1).getReg();
|
||||
|
||||
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, Out, STI);
|
||||
TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
|
||||
if (FirstRegOp != SecondRegOp)
|
||||
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, Out, STI);
|
||||
TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
|
||||
else
|
||||
createNop(false, IDLoc, Out, STI);
|
||||
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, Out, STI);
|
||||
TOut.emitEmptyDelaySlot(false, IDLoc, STI);
|
||||
TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
|
||||
MCStreamer &Out, const MCSubtargetInfo *STI) {
|
||||
if (hasShortDelaySlot)
|
||||
emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Out, STI);
|
||||
else
|
||||
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Out, STI);
|
||||
}
|
||||
|
||||
void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
|
||||
unsigned TrgReg, bool Is64Bit, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
|
||||
Out, STI);
|
||||
}
|
||||
|
||||
void MipsAsmParser::createCpRestoreMemOp(bool IsLoad, int StackOffset,
|
||||
SMLoc IDLoc, MCStreamer &Out,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
// If the offset can not fit into 16 bits, we need to expand.
|
||||
if (!isInt<16>(StackOffset)) {
|
||||
MCInst MemInst;
|
||||
|
@ -3650,8 +3579,8 @@ void MipsAsmParser::createCpRestoreMemOp(bool IsLoad, int StackOffset,
|
|||
return;
|
||||
}
|
||||
|
||||
emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
|
||||
Out, STI);
|
||||
TOut.emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset,
|
||||
IDLoc, STI);
|
||||
}
|
||||
|
||||
unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
|
||||
|
|
|
@ -114,6 +114,99 @@ void MipsTargetStreamer::emitDirectiveSetNoOddSPReg() {
|
|||
forbidModuleDirective();
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MCInst TmpInst;
|
||||
TmpInst.setOpcode(Opcode);
|
||||
TmpInst.addOperand(MCOperand::createReg(Reg0));
|
||||
TmpInst.setLoc(IDLoc);
|
||||
getStreamer().EmitInstruction(TmpInst, *STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1,
|
||||
SMLoc IDLoc, const MCSubtargetInfo *STI) {
|
||||
MCInst TmpInst;
|
||||
TmpInst.setOpcode(Opcode);
|
||||
TmpInst.addOperand(MCOperand::createReg(Reg0));
|
||||
TmpInst.addOperand(Op1);
|
||||
TmpInst.setLoc(IDLoc);
|
||||
getStreamer().EmitInstruction(TmpInst, *STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm,
|
||||
SMLoc IDLoc, const MCSubtargetInfo *STI) {
|
||||
emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
|
||||
SMLoc IDLoc, const MCSubtargetInfo *STI) {
|
||||
emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2,
|
||||
SMLoc IDLoc, const MCSubtargetInfo *STI) {
|
||||
MCInst TmpInst;
|
||||
TmpInst.setOpcode(Opcode);
|
||||
TmpInst.addOperand(MCOperand::createImm(Imm1));
|
||||
TmpInst.addOperand(MCOperand::createImm(Imm2));
|
||||
TmpInst.setLoc(IDLoc);
|
||||
getStreamer().EmitInstruction(TmpInst, *STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1,
|
||||
MCOperand Op2, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MCInst TmpInst;
|
||||
TmpInst.setOpcode(Opcode);
|
||||
TmpInst.addOperand(MCOperand::createReg(Reg0));
|
||||
TmpInst.addOperand(MCOperand::createReg(Reg1));
|
||||
TmpInst.addOperand(Op2);
|
||||
TmpInst.setLoc(IDLoc);
|
||||
getStreamer().EmitInstruction(TmpInst, *STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
|
||||
unsigned Reg2, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1,
|
||||
int16_t Imm, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg,
|
||||
unsigned TrgReg, bool Is64Bit,
|
||||
const MCSubtargetInfo *STI) {
|
||||
emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
|
||||
STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitDSLL(unsigned DstReg, unsigned SrcReg,
|
||||
int16_t ShiftAmount, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
if (ShiftAmount >= 32) {
|
||||
emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, STI);
|
||||
return;
|
||||
}
|
||||
|
||||
emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
if (hasShortDelaySlot)
|
||||
emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, STI);
|
||||
else
|
||||
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
|
||||
}
|
||||
|
||||
void MipsTargetStreamer::emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI) {
|
||||
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
|
||||
}
|
||||
|
||||
MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
|
||||
formatted_raw_ostream &OS)
|
||||
: MipsTargetStreamer(S), OS(OS) {}
|
||||
|
|
|
@ -93,6 +93,30 @@ public:
|
|||
virtual void emitDirectiveSetOddSPReg();
|
||||
virtual void emitDirectiveSetNoOddSPReg();
|
||||
|
||||
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI);
|
||||
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI);
|
||||
void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI);
|
||||
void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI);
|
||||
void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI);
|
||||
void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
|
||||
SMLoc IDLoc, const MCSubtargetInfo *STI);
|
||||
void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
|
||||
SMLoc IDLoc, const MCSubtargetInfo *STI);
|
||||
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
|
||||
SMLoc IDLoc, const MCSubtargetInfo *STI);
|
||||
void emitAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg, bool Is64Bit,
|
||||
const MCSubtargetInfo *STI);
|
||||
void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
|
||||
SMLoc IDLoc, const MCSubtargetInfo *STI);
|
||||
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI);
|
||||
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI);
|
||||
|
||||
void forbidModuleDirective() { ModuleDirectiveAllowed = false; }
|
||||
void reallowModuleDirective() { ModuleDirectiveAllowed = true; }
|
||||
bool isModuleDirectiveAllowed() { return ModuleDirectiveAllowed; }
|
||||
|
|
Loading…
Reference in New Issue