Index: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -276,6 +276,18 @@ 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 @@ 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 @@ 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; Index: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -738,14 +738,13 @@ 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() { Index: llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td +++ llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td @@ -816,3 +816,22 @@ "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]; +} Index: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td @@ -2303,6 +2303,20 @@ 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 @@ 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 //===----------------------------------------------------------------------===//