bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI, bool IsLoad);
+ bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI);
+
bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
Inst.getOpcode() == Mips::LDMacro)
? MER_Fail
: MER_Success;
+ case Mips::SDC1_M1:
+ return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
+ ? MER_Fail
+ : MER_Success;
case Mips::SEQMacro:
return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
case Mips::SEQIMacro:
return false;
}
+
+// Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
+// swc1 $<reg>, offset+4($reg2)'
+// or if little endian to 'swc1 $<reg>, offset($reg2);
+// swc1 $<reg+1>, offset+4($reg2)'
+// for Mips1.
+bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
+ MCStreamer &Out,
+ const MCSubtargetInfo *STI) {
+ if (!isABI_O32())
+ return true;
+
+ warnIfNoMacro(IDLoc);
+
+ MipsTargetStreamer &TOut = getTargetStreamer();
+ unsigned Opcode = Mips::SWC1;
+ unsigned FirstReg = Inst.getOperand(0).getReg();
+ unsigned SecondReg = nextReg(FirstReg);
+ unsigned BaseReg = Inst.getOperand(1).getReg();
+ if (!SecondReg)
+ return true;
+
+ warnIfRegIndexIsAT(FirstReg, IDLoc);
+
+ assert(Inst.getOperand(2).isImm() &&
+ "Offset for macro is not immediate!");
+
+ MCOperand &FirstOffset = Inst.getOperand(2);
+ signed NextOffset = FirstOffset.getImm() + 4;
+ MCOperand SecondOffset = MCOperand::createImm(NextOffset);
+
+ if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
+ return true;
+
+ if (!IsLittleEndian)
+ std::swap(FirstReg, SecondReg);
+
+ TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
+ TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
+
+ return false;
+}
+
bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI) {
"li.d\t$rd, $fpimm">,
FGR_64, HARDFLOAT;
+def SDC1_M1 : MipsAsmPseudoInst<(outs AFGR64Opnd:$fd),
+ (ins mem_simm16:$addr),
+ "s.d\t$fd, $addr">,
+ FGR_32, ISA_MIPS1, HARDFLOAT;
+
//===----------------------------------------------------------------------===//
// InstAliases.
//===----------------------------------------------------------------------===//
def : MipsInstAlias
<"s.d $fd, $addr", (SDC164 FGR64Opnd:$fd, mem_simm16:$addr), 0>,
FGR_64, ISA_MIPS2, HARDFLOAT;
+def : MipsInstAlias
+ <"s.d $fd, $addr", (SDC1_M1 AFGR64Opnd:$fd, mem_simm16:$addr), 0>,
+ FGR_32, ISA_MIPS1, HARDFLOAT;
def : MipsInstAlias
<"l.s $fd, $addr", (LWC1 FGR32Opnd:$fd, mem_simm16:$addr), 0>,
--- /dev/null
+# RUN: llvm-mc -filetype=obj -triple mips -mcpu=mips1 %s -o - \
+# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=MIPS1-EB
+# RUN: llvm-mc -filetype=obj -triple mipsel -mcpu=mips1 %s -o - \
+# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=MIPS1-EL
+
+# Check if s.d instruction alias is suported on Mips1.
+
+# MIPS1-EB: 0: e4 c1 00 00 swc1 $f1, 0($6)
+# MIPS1-EB: 4: e4 c0 00 04 swc1 $f0, 4($6)
+
+# MIPS1-EL: 0: 00 00 c0 e4 swc1 $f0, 0($6)
+# MIPS1-EL: 4: 04 00 c1 e4 swc1 $f1, 4($6)
+s.d $f0, 0($6)