[mips] Implement shorthand add / sub forms for MIPS.
authorDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 24 Mar 2014 14:05:39 +0000 (14:05 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 24 Mar 2014 14:05:39 +0000 (14:05 +0000)
Summary:
- If only two registers are passed to a three-register operation, then the
  first argument is both source and destination register.

- If a non-register is passed as the last argument, generate the immediate
  version of the instruction.

Also mark DADD commutative and add scheduling information (to the generic
scheduler), and implement DSUB.

Patch by David Chisnall
His work was sponsored by: DARPA, AFRL

CC: theraven
Differential Revision: http://llvm-reviews.chandlerc.com/D3148

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204605 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/Mips64InstrInfo.td
lib/Target/Mips/MipsSchedule.td
test/MC/Mips/mips-alu-instructions.s
test/MC/Mips/mips64-alu-instructions.s

index 8912243af09e07cf006f9017a645f190af3c2b77..8c0c181feca692646aeed23b839584aa075497e0 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstBuilder.h"
 #include "llvm/MC/MCParser/MCAsmLexer.h"
 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
 #include "llvm/MC/MCStreamer.h"
@@ -589,6 +590,7 @@ static const MCInstrDesc &getInstDesc(unsigned Opcode) {
 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
                                        SmallVectorImpl<MCInst> &Instructions) {
   const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
+
   Inst.setLoc(IDLoc);
 
   if (MCID.isBranch() || MCID.isCall()) {
@@ -690,6 +692,10 @@ bool MipsAsmParser::needsExpansion(MCInst &Inst) {
   case Mips::LoadImm32Reg:
   case Mips::LoadAddr32Imm:
   case Mips::LoadAddr32Reg:
+  case Mips::SUBi:
+  case Mips::SUBiu:
+  case Mips::DSUBi:
+  case Mips::DSUBiu:
     return true;
   default:
     return false;
@@ -705,6 +711,30 @@ void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
     return expandLoadAddressImm(Inst, IDLoc, Instructions);
   case Mips::LoadAddr32Reg:
     return expandLoadAddressReg(Inst, IDLoc, Instructions);
+  case Mips::SUBi:
+    Instructions.push_back(MCInstBuilder(Mips::ADDi)
+                               .addReg(Inst.getOperand(0).getReg())
+                               .addReg(Inst.getOperand(1).getReg())
+                               .addImm(-Inst.getOperand(2).getImm()));
+    return;
+  case Mips::SUBiu:
+    Instructions.push_back(MCInstBuilder(Mips::ADDiu)
+                               .addReg(Inst.getOperand(0).getReg())
+                               .addReg(Inst.getOperand(1).getReg())
+                               .addImm(-Inst.getOperand(2).getImm()));
+    return;
+  case Mips::DSUBi:
+    Instructions.push_back(MCInstBuilder(Mips::DADDi)
+                               .addReg(Inst.getOperand(0).getReg())
+                               .addReg(Inst.getOperand(1).getReg())
+                               .addImm(-Inst.getOperand(2).getImm()));
+    return;
+  case Mips::DSUBiu:
+    Instructions.push_back(MCInstBuilder(Mips::DADDiu)
+                               .addReg(Inst.getOperand(0).getReg())
+                               .addReg(Inst.getOperand(1).getReg())
+                               .addImm(-Inst.getOperand(2).getImm()));
+    return;
   }
 }
 
index 06a6c1ca521a41f13f22ea35936b2c628ae60440..74cafa8e415e6a06efabe59838a2f7fb1e40d23a 100644 (file)
@@ -73,11 +73,12 @@ def LUi64   : LoadUpper<"lui", GPR64Opnd, uimm16_64>, LUI_FM;
 }
 
 /// Arithmetic Instructions (3-Operand, R-Type)
-def DADD   : ArithLogicR<"dadd", GPR64Opnd>, ADD_FM<0, 0x2c>;
+def DADD   : ArithLogicR<"dadd", GPR64Opnd, 1, II_DADD>, ADD_FM<0, 0x2c>;
 def DADDu  : ArithLogicR<"daddu", GPR64Opnd, 1, II_DADDU, add>,
                               ADD_FM<0, 0x2d>;
 def DSUBu  : ArithLogicR<"dsubu", GPR64Opnd, 0, II_DSUBU, sub>,
                               ADD_FM<0, 0x2f>;
+def DSUB   : ArithLogicR<"dsub", GPR64Opnd, 0, II_DSUB, sub>, ADD_FM<0, 0x2e>;
 
 let isCodeGenOnly = 1 in {
 def SLT64  : SetCC_R<"slt", setlt, GPR64Opnd>, ADD_FM<0, 0x2a>;
@@ -356,6 +357,64 @@ def : InstAlias<"daddu $rs, $rt, $imm",
 def : InstAlias<"dadd $rs, $rt, $imm",
                 (DADDi GPR64Opnd:$rs, GPR64Opnd:$rt, simm16_64:$imm),
                 0>;
+def : InstAlias<"daddu $rs, $imm",
+                (DADDiu GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm),
+                0>;
+def : InstAlias<"dadd $rs, $imm",
+                (DADDi GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm),
+                0>;
+def : InstAlias<"dadd $rs, $rt",
+                (DADD GPR64Opnd:$rs, GPR64Opnd:$rs, GPR64Opnd:$rt),
+                0>;
+def : InstAlias<"daddu $rs, $rt",
+                (DADDu GPR64Opnd:$rs, GPR64Opnd:$rs, GPR64Opnd:$rt),
+                0>;
+def : InstAlias<"dsub $rs, $rt",
+                (DSUB GPR64Opnd:$rs, GPR64Opnd:$rs, GPR64Opnd:$rt),
+                0>;
+def : InstAlias<"dsubu $rs, $rt",
+                (DSUBu GPR64Opnd:$rs, GPR64Opnd:$rs, GPR64Opnd:$rt),
+                0>;
+def : InstAlias<"add $rs, $imm",
+                (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm),
+                0>;
+def : InstAlias<"addu $rs, $imm",
+                (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm),
+                0>;
+def : InstAlias<"add $rs, $rt",
+                (ADD GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt),
+                0>;
+def : InstAlias<"addu $rs, $rt",
+                (ADDu GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt),
+                0>;
+def : InstAlias<"sub $rs, $rt",
+                (SUB GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt),
+                0>;
+def : InstAlias<"subu $rs, $rt",
+                (SUBu GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt),
+                0>;
+let isPseudo=1, usesCustomInserter=1, isCodeGenOnly=1 in {
+def SUBi : MipsInst<(outs GPR32Opnd: $rt), (ins GPR32Opnd: $rs, simm16: $imm),
+                    "sub\t$rt, $rs, $imm", [], II_DSUB, Pseudo>;
+def SUBiu : MipsInst<(outs GPR32Opnd: $rt), (ins GPR32Opnd: $rs, simm16: $imm),
+                    "subu\t$rt, $rs, $imm", [], II_DSUB, Pseudo>;
+def DSUBi : MipsInst<(outs GPR64Opnd: $rt), (ins GPR64Opnd: $rs, simm16_64: $imm),
+                    "ssub\t$rt, $rs, $imm", [], II_DSUB, Pseudo>;
+def DSUBiu : MipsInst<(outs GPR64Opnd: $rt), (ins GPR64Opnd: $rs, simm16_64: $imm),
+                    "ssubu\t$rt, $rs, $imm", [], II_DSUB, Pseudo>;
+}
+def : InstAlias<"sub $rs, $imm",
+                (SUBi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm),
+                0>;
+def : InstAlias<"subu $rs, $imm",
+                (SUBiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm),
+                0>;
+def : InstAlias<"dsub $rs, $imm",
+                (DSUBi GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm),
+                0>;
+def : InstAlias<"dsubu $rs, $imm",
+                (DSUBiu GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm),
+                0>;
 
 /// Move between CPU and coprocessor registers
 let DecoderNamespace = "Mips64", Predicates = [HasMips64] in {
index e2fef8f94c692a3b7d49e428aa2e11a2fed4a351..ea981996bf15b489639db85166beb8d65aa661a1 100644 (file)
@@ -39,6 +39,7 @@ def II_C_CC_D           : InstrItinClass; // Any c.<cc>.d instruction
 def II_C_CC_S           : InstrItinClass; // Any c.<cc>.s instruction
 def II_DADDIU           : InstrItinClass;
 def II_DADDU            : InstrItinClass;
+def II_DADD             : InstrItinClass;
 def II_DDIV             : InstrItinClass;
 def II_DDIVU            : InstrItinClass;
 def II_DIV              : InstrItinClass;
@@ -63,6 +64,7 @@ def II_DSRL             : InstrItinClass;
 def II_DSRL32           : InstrItinClass;
 def II_DSRLV            : InstrItinClass;
 def II_DSUBU            : InstrItinClass;
+def II_DSUB             : InstrItinClass;
 def II_FLOOR            : InstrItinClass;
 def II_LB               : InstrItinClass;
 def II_LBU              : InstrItinClass;
@@ -185,6 +187,7 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
   InstrItinData<II_CLZ             , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DADDIU          , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DADDU           , [InstrStage<1,  [ALU]>]>,
+  InstrItinData<II_DADD            , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DSLL            , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DSRL            , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DSRA            , [InstrStage<1,  [ALU]>]>,
@@ -192,6 +195,7 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
   InstrItinData<II_DSRLV           , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DSRAV           , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DSUBU           , [InstrStage<1,  [ALU]>]>,
+  InstrItinData<II_DSUB            , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DROTR           , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DROTRV          , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_LUI             , [InstrStage<1,  [ALU]>]>,
index 68a8da07c2b1e097516a006c2d5a458894f740fc..1ee994f09afa497ec119650af0e8a432fb1bc7c3 100644 (file)
     negu   $6,$7
     move   $7,$8
     rdhwr   $5, $29
+
+#------------------------------------------------------------------------------
+# Shortcuts for arithmetic instructions
+#------------------------------------------------------------------------------
+
+# CHECK:       add     $9, $9, $3      # encoding: [0x20,0x48,0x23,0x01]
+# CHECK:       addu    $9, $9, $3      # encoding: [0x21,0x48,0x23,0x01]
+# CHECK:       addi    $9, $9, 10      # encoding: [0x0a,0x00,0x29,0x21]
+# CHECK:       addiu   $9, $9, 10      # encoding: [0x0a,0x00,0x29,0x25]
+# CHECK:       sub     $9, $9, $3      # encoding: [0x22,0x48,0x23,0x01]
+# CHECK:       subu    $9, $9, $3      # encoding: [0x23,0x48,0x23,0x01]
+# CHECK:       addi    $9, $9, -10     # encoding: [0xf6,0xff,0x29,0x21]
+# CHECK:       addiu   $9, $9, -10     # encoding: [0xf6,0xff,0x29,0x25]
+       add     $9, $3
+       addu    $9, $3
+       add     $9, 10
+       addu    $9, 10
+       sub     $9, $3
+       subu    $9, $3
+       sub     $9, 10
+       subu    $9, 10
index 8262a46ee4f3c2dac76ef9372ea87a8362c3ea93..12c49a4621504ca7a02c195e18d24f690aa78e75 100644 (file)
@@ -81,6 +81,7 @@
 # CHECK:  msubu  $6, $7          # encoding: [0x05,0x00,0xc7,0x70]
 # CHECK:  mult   $3, $5          # encoding: [0x18,0x00,0x65,0x00]
 # CHECK:  multu  $3, $5          # encoding: [0x19,0x00,0x65,0x00]
+# CHECK:  dsub    $9, $6, $7     # encoding: [0x2e,0x48,0xc7,0x00]
 # CHECK:  dsubu   $4, $3, $5     # encoding: [0x2f,0x20,0x65,0x00]
 # CHECK:  move    $7, $8         # encoding: [0x2d,0x38,0x00,0x01]
 # CHECK:  .set    push
     msubu  $6,$7
     mult   $3,$5
     multu  $3,$5
+    dsub    $9,$6,$7
     dsubu   $4,$3,$5
     move   $7,$8
     rdhwr   $5, $29
+
+#------------------------------------------------------------------------------
+# Shortcuts for arithmetic instructions
+#------------------------------------------------------------------------------
+
+# CHECK:       dadd    $9, $9, $3      # encoding: [0x2c,0x48,0x23,0x01]
+# CHECK:       daddu   $9, $9, $3      # encoding: [0x2d,0x48,0x23,0x01]
+# CHECK:       daddi   $9, $9, 10      # encoding: [0x0a,0x00,0x29,0x61]
+# CHECK:       daddiu  $9, $9, 10      # encoding: [0x0a,0x00,0x29,0x65]
+# CHECK:       dsub    $9, $9, $3      # encoding: [0x2e,0x48,0x23,0x01]
+# CHECK:       dsubu   $9, $9, $3      # encoding: [0x2f,0x48,0x23,0x01]
+# CHECK:       daddi   $9, $9, -10     # encoding: [0xf6,0xff,0x29,0x61]
+# CHECK:       daddiu  $9, $9, -10     # encoding: [0xf6,0xff,0x29,0x65]
+       dadd    $9, $3
+       daddu   $9, $3
+       dadd    $9, 10
+       daddu   $9, 10
+       dsub    $9, $3
+       dsubu   $9, $3
+       dsub    $9, 10
+       dsubu   $9, 10