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);
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,
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;
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
//===----------------------------------------------------------------------===//
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
//===----------------------------------------------------------------------===//