[Mips] Add s.d instruction alias for Mips1

Add support for s.d instruction for Mips1 which expands into two swc1
instructions.

Patch by Mirko Brkusanin.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363184 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Simon Atanasyan 2019-06-12 17:52:05 +00:00
parent a5dd191d8d
commit 81930059a1
3 changed files with 71 additions and 0 deletions

View File

@ -302,6 +302,9 @@ class MipsAsmParser : public MCTargetAsmParser {
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);
@ -2538,6 +2541,10 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
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:
@ -4844,6 +4851,49 @@ bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
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) {

View File

@ -787,6 +787,11 @@ def LoadImmDoubleFGR : MipsAsmPseudoInst<(outs StrictlyFGR64Opnd:$rd),
"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.
//===----------------------------------------------------------------------===//
@ -799,6 +804,9 @@ def : MipsInstAlias
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>,

13
test/MC/Mips/mips1/sd.s Normal file
View File

@ -0,0 +1,13 @@
# 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)