From: Simon Dardis Date: Wed, 8 Feb 2017 16:25:05 +0000 (+0000) Subject: [mips] MUL macro variations X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cf360fec123f9159e8a42574ae4ff12b6074e1fe;p=llvm [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294471 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 254175c05e1..c4e38a2771a 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -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; diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 59bd04a7fde..2d4083b27ed 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -738,14 +738,13 @@ MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, void MipsTargetELFStreamer::emitLabel(MCSymbol *S) { auto *Symbol = cast(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() { diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index 03882dadbe1..6cff5a0b096 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -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]; +} diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 98d798e859d..b6cc9589cac 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -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 //===----------------------------------------------------------------------===//