]> granicus.if.org Git - llvm/commitdiff
[Mips] Add s.d instruction alias for Mips1
authorSimon Atanasyan <simon@atanasyan.com>
Wed, 12 Jun 2019 17:52:05 +0000 (17:52 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Wed, 12 Jun 2019 17:52:05 +0000 (17:52 +0000)
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

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/MipsInstrFPU.td
test/MC/Mips/mips1/sd.s [new file with mode: 0644]

index e45592274e3f1a23273ea2efb8af5e3cad2e51a7..439aeb30566f6a7da8dd14def73a3d04022cbfb8 100644 (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) {
 
index 549bce21d974d10c3f39fb9477f6de2bfc20fce5..e94e107e64c270a1545499e8bd3dde5c22611c52 100644 (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>,
diff --git a/test/MC/Mips/mips1/sd.s b/test/MC/Mips/mips1/sd.s
new file mode 100644 (file)
index 0000000..de2065b
--- /dev/null
@@ -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)