[mips] Absolute value macro expansion
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Fri, 29 Jan 2016 16:18:34 +0000 (16:18 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Fri, 29 Jan 2016 16:18:34 +0000 (16:18 +0000)
Author: obucina
Reviewers: dsanders
Differential Revision: http://reviews.llvm.org/D16323

llvm-svn: 259202

llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/lib/Target/Mips/MipsInstrInfo.td
llvm/test/MC/Mips/macro-abs.s [new file with mode: 0644]

index a13d1d7..192b344 100644 (file)
@@ -233,6 +233,9 @@ class MipsAsmParser : public MCTargetAsmParser {
   bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
                           SmallVectorImpl<MCInst> &Instructions);
 
+  bool expandAbs(MCInst &Inst, SMLoc IDLoc,
+                 SmallVectorImpl<MCInst> &Instructions);
+
   void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
                  SmallVectorImpl<MCInst> &Instructions);
 
@@ -2087,6 +2090,9 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
   case Mips::DRORImm:
     return expandDRotationImm(Inst, IDLoc, Instructions) ? MER_Fail
                                                          : MER_Success;
+  case Mips::ABSMacro:
+    return expandAbs(Inst, IDLoc, Instructions) ? MER_Fail
+                                                : MER_Success;
   }
 }
 
@@ -3531,6 +3537,22 @@ bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
   return true;
 }
 
+bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc,
+                              SmallVectorImpl<MCInst> &Instructions) {
+
+  unsigned FirstRegOp = Inst.getOperand(0).getReg();
+  unsigned SecondRegOp = Inst.getOperand(1).getReg();
+
+  emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, Instructions);
+  if (FirstRegOp != SecondRegOp)
+    emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, Instructions);
+  else
+    createNop(false, IDLoc, Instructions);
+  emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, Instructions);
+
+  return false;
+}
+
 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
                               SmallVectorImpl<MCInst> &Instructions) {
   if (hasShortDelaySlot)
index ffda491..c5a314f 100644 (file)
@@ -1808,6 +1808,9 @@ def : MipsInstAlias<"dror $rd, $rs",
 def : MipsInstAlias<"dror $rd, $imm",
                     (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
 
+def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
+                                 "abs\t$rd, $rs">;
+
 //===----------------------------------------------------------------------===//
 // Instruction aliases
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/Mips/macro-abs.s b/llvm/test/MC/Mips/macro-abs.s
new file mode 100644 (file)
index 0000000..2fa7b48
--- /dev/null
@@ -0,0 +1,12 @@
+# RUN: llvm-mc -triple mips-unknown-linux -show-encoding %s | FileCheck %s
+
+.text
+# CHECK:    .text
+  abs $4, $4
+# CHECK:    bgez    $4, 8       # encoding: [0x04,0x81,0x00,0x02]
+# CHECK:    nop                 # encoding: [0x00,0x00,0x00,0x00]
+# CHECK:    neg     $4, $4      # encoding: [0x00,0x04,0x20,0x22]
+  abs $4, $5
+# CHECK:    bgez    $5, 8       # encoding: [0x04,0xa1,0x00,0x02]
+# CHECK:    move    $4, $5      # encoding: [0x00,0xa0,0x20,0x21]
+# CHECK:    neg     $4, $5      # encoding: [0x00,0x05,0x20,0x22]