[mips] MUL macro variations

[mips] MUL macro variations

Adds support for MUL macro variations.

Patch by: Srdjan Obucina

Reviewers: zoran.jovanovic, vkalintiris, dsanders, sdardis, obucina, seanbruno

Differential Revision: https://reviews.llvm.org/D16807

llvm-svn: 294471
This commit is contained in:
Simon Dardis 2017-02-08 16:25:05 +00:00
parent 6dd2eae76a
commit 3c82a64636
4 changed files with 179 additions and 3 deletions

View File

@ -276,6 +276,18 @@ class MipsAsmParser : public MCTargetAsmParser {
bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI, bool IsLoad);
@ -2332,6 +2344,17 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::ABSMacro:
return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::MULImmMacro:
case Mips::DMULImmMacro:
return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::MULOMacro:
case Mips::DMULOMacro:
return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::MULOUMacro:
case Mips::DMULOUMacro:
return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::DMULMacro:
return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::LDMacro:
case Mips::SDMacro:
return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
@ -4060,6 +4083,119 @@ bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return false;
}
bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI) {
MipsTargetStreamer &TOut = getTargetStreamer();
unsigned ATReg = Mips::NoRegister;
unsigned DstReg = Inst.getOperand(0).getReg();
unsigned SrcReg = Inst.getOperand(1).getReg();
int32_t ImmValue = Inst.getOperand(2).getImm();
ATReg = getATReg(IDLoc);
if (!ATReg)
return true;
loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out, STI);
TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
SrcReg, ATReg, IDLoc, STI);
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
return false;
}
bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI) {
MipsTargetStreamer &TOut = getTargetStreamer();
unsigned ATReg = Mips::NoRegister;
unsigned DstReg = Inst.getOperand(0).getReg();
unsigned SrcReg = Inst.getOperand(1).getReg();
unsigned TmpReg = Inst.getOperand(2).getReg();
ATReg = getATReg(Inst.getLoc());
if (!ATReg)
return true;
TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
SrcReg, TmpReg, IDLoc, STI);
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
DstReg, DstReg, 0x1F, IDLoc, STI);
TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
if (useTraps()) {
TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
} else {
MCContext & Context = TOut.getStreamer().getContext();
MCSymbol * BrTarget = Context.createTempSymbol();
MCOperand LabelOp =
MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
if (AssemblerOptions.back()->isReorder())
TOut.emitNop(IDLoc, STI);
TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
TOut.getStreamer().EmitLabel(BrTarget);
}
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
return false;
}
bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI) {
MipsTargetStreamer &TOut = getTargetStreamer();
unsigned ATReg = Mips::NoRegister;
unsigned DstReg = Inst.getOperand(0).getReg();
unsigned SrcReg = Inst.getOperand(1).getReg();
unsigned TmpReg = Inst.getOperand(2).getReg();
ATReg = getATReg(IDLoc);
if (!ATReg)
return true;
TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
SrcReg, TmpReg, IDLoc, STI);
TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
if (useTraps()) {
TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
} else {
MCContext & Context = TOut.getStreamer().getContext();
MCSymbol * BrTarget = Context.createTempSymbol();
MCOperand LabelOp =
MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
if (AssemblerOptions.back()->isReorder())
TOut.emitNop(IDLoc, STI);
TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
TOut.getStreamer().EmitLabel(BrTarget);
}
return false;
}
bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI) {
MipsTargetStreamer &TOut = getTargetStreamer();
unsigned DstReg = Inst.getOperand(0).getReg();
unsigned SrcReg = Inst.getOperand(1).getReg();
unsigned TmpReg = Inst.getOperand(2).getReg();
TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
return false;
}
static unsigned nextReg(unsigned Reg) {
switch (Reg) {
case Mips::ZERO: return Mips::AT;

View File

@ -738,14 +738,13 @@ MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
void MipsTargetELFStreamer::emitLabel(MCSymbol *S) {
auto *Symbol = cast<MCSymbolELF>(S);
if (!isMicroMipsEnabled())
return;
getStreamer().getAssembler().registerSymbol(*Symbol);
uint8_t Type = Symbol->getType();
if (Type != ELF::STT_FUNC)
return;
Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
if (isMicroMipsEnabled())
Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
}
void MipsTargetELFStreamer::finish() {

View File

@ -816,3 +816,22 @@ def LoadAddrReg64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rt), (ins mem:$addr),
"dla\t$rt, $addr">;
def LoadAddrImm64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rt), (ins imm64:$imm64),
"dla\t$rt, $imm64">;
def DMULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt,
simm32_relaxed:$imm),
"dmul\t$rs, $rt, $imm">,
ISA_MIPS3_NOT_32R6_64R6;
def DMULOMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt,
GPR64Opnd:$rd),
"dmulo\t$rs, $rt, $rd">,
ISA_MIPS3_NOT_32R6_64R6;
def DMULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt,
GPR64Opnd:$rd),
"dmulou\t$rs, $rt, $rd">,
ISA_MIPS3_NOT_32R6_64R6;
def DMULMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt,
GPR64Opnd:$rd),
"dmul\t$rs, $rt, $rd"> {
let InsnPredicates = [HasMips3, NotMips64r6, NotCnMips];
}

View File

@ -2303,6 +2303,20 @@ def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
def : MipsInstAlias<"seq $rd, $imm",
(SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
NOT_ASE_CNMIPS;
def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
simm32_relaxed:$imm),
"mul\t$rd, $rs, $imm">,
ISA_MIPS1_NOT_32R6_64R6;
def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
GPR32Opnd:$rt),
"mulo\t$rd, $rs, $rt">,
ISA_MIPS1_NOT_32R6_64R6;
def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
GPR32Opnd:$rt),
"mulou\t$rd, $rs, $rt">,
ISA_MIPS1_NOT_32R6_64R6;
//===----------------------------------------------------------------------===//
// Instruction aliases
//===----------------------------------------------------------------------===//
@ -2467,6 +2481,14 @@ let AdditionalPredicates = [NotInMicroMips] in {
def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
def : MipsInstAlias<"sync",
(SYNC 0), 1>, ISA_MIPS2;
def : MipsInstAlias<"mulo $rs, $rt",
(MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
ISA_MIPS1_NOT_32R6_64R6;
def : MipsInstAlias<"mulou $rs, $rt",
(MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
ISA_MIPS1_NOT_32R6_64R6;
//===----------------------------------------------------------------------===//
// Assembler Pseudo Instructions
//===----------------------------------------------------------------------===//