[mips][microMIPS] Implement ADDIUS5 instruction
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Fri, 10 Oct 2014 13:45:34 +0000 (13:45 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Fri, 10 Oct 2014 13:45:34 +0000 (13:45 +0000)
Differential Revision: http://reviews.llvm.org/D5049

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

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/MicroMipsInstrFormats.td
lib/Target/Mips/MicroMipsInstrInfo.td
test/MC/Mips/micromips-16-bit-instructions.s
test/MC/Mips/micromips-invalid.s [new file with mode: 0644]

index 21d2876fdd0b78fef94fbe56204638b775987927..db9c679b7673ccc7b6fa30179ddb2e72fcd9f4aa 100644 (file)
@@ -1117,6 +1117,25 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
     } // for
   }   // if load/store
 
+  // TODO: Handle this with the AsmOperandClass.PredicateMethod.
+  if (inMicroMipsMode()) {
+    MCOperand Opnd;
+    int Imm;
+
+    switch (Inst.getOpcode()) {
+      default:
+        break;
+      case Mips::ADDIUS5_MM:
+        Opnd = Inst.getOperand(2);
+        if (!Opnd.isImm())
+          return Error(IDLoc, "expected immediate operand kind");
+        Imm = Opnd.getImm();
+        if (Imm < -8 || Imm > 7)
+          return Error(IDLoc, "immediate operand value out of range");
+        break;
+    }
+  }
+
   if (needsExpansion(Inst))
     return expandInstruction(Inst, IDLoc, Instructions);
   else
index 57f3dd540efaaf7a02536d32666b731bffa1fe63..9d403460cd85b16d06624ee8d7759b2650fec3fb 100644 (file)
@@ -41,6 +41,18 @@ class MicroMipsInst16<dag outs, dag ins, string asmstr, list<dag> pattern,
 // MicroMIPS 16-bit Instruction Formats
 //===----------------------------------------------------------------------===//
 
+class ADDIUS5_FM_MM16 {
+  bits<5> rd;
+  bits<4> imm;
+
+  bits<16> Inst;
+
+  let Inst{15-10} = 0x13;
+  let Inst{9-5}   = rd;
+  let Inst{4-1}   = imm;
+  let Inst{0}     = 0;
+}
+
 class MOVE_FM_MM16<bits<6> funct> {
   bits<5> rs;
   bits<5> rd;
index 86b4b0f279eb1bbfc7bab54863e5ad5a28256ed5..71abfcd82efcddaab45770b5ad93cdc62854510c 100644 (file)
@@ -1,5 +1,7 @@
 def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddrMM", [frameindex]>;
 
+def simm4 : Operand<i32>;
+
 def simm12 : Operand<i32> {
   let DecoderMethod = "DecodeSimm12";
 }
@@ -84,6 +86,13 @@ class LoadMM<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
   let mayLoad = 1;
 }
 
+class AddImmUS5<string opstr, RegisterOperand RO> :
+  MicroMipsInst16<(outs RO:$dst), (ins RO:$rd, simm4:$imm),
+                  !strconcat(opstr, "\t$rd, $imm"), [], NoItinerary, FrmR> {
+  let Constraints = "$rd = $dst";
+  let isCommutable = 1;
+}
+
 class MoveFromHILOMM<string opstr, RegisterOperand RO, Register UseReg> :
       MicroMipsInst16<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"),
   [], II_MFHI_MFLO, FrmR> {
@@ -156,6 +165,7 @@ let isCall = 1, hasDelaySlot = 1, Defs = [RA] in {
            !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>;
 }
 
+def ADDIUS5_MM : AddImmUS5<"addius5", GPR32Opnd>, ADDIUS5_FM_MM16;
 def MFHI16_MM : MoveFromHILOMM<"mfhi", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x10>;
 def MFLO16_MM : MoveFromHILOMM<"mflo", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x12>;
 def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>;
index 63ae5d0575c784f406f300074eb5e8a06b635887..c9d22936d3280106e5d4ad68b7d660ed7df9c567 100644 (file)
@@ -9,6 +9,7 @@
 #------------------------------------------------------------------------------
 # Little endian
 #------------------------------------------------------------------------------
+# CHECK-EL: addius5 $7, -2          # encoding: [0xfc,0x4c]
 # CHECK-EL: mfhi    $9              # encoding: [0x09,0x46]
 # CHECK-EL: mflo    $9              # encoding: [0x49,0x46]
 # CHECK-EL: move    $25, $1         # encoding: [0x21,0x0f]
@@ -21,6 +22,7 @@
 #------------------------------------------------------------------------------
 # Big endian
 #------------------------------------------------------------------------------
+# CHECK-EB: addius5 $7, -2          # encoding: [0x4c,0xfc]
 # CHECK-EB: mfhi    $9              # encoding: [0x46,0x09]
 # CHECK-EB: mflo    $9              # encoding: [0x46,0x49]
 # CHECK-EB: move    $25, $1         # encoding: [0x0f,0x21]
@@ -31,6 +33,7 @@
 # CHECK-EB: jalrs16 $9              # encoding: [0x45,0xe9]
 # CHECK-EB: move    $zero, $zero    # encoding: [0x0c,0x00]
 
+    addius5 $7, -2
     mfhi    $9
     mflo    $9
     move    $25, $1
diff --git a/test/MC/Mips/micromips-invalid.s b/test/MC/Mips/micromips-invalid.s
new file mode 100644 (file)
index 0000000..116628e
--- /dev/null
@@ -0,0 +1,4 @@
+# RUN: not llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips 2>%t1
+# RUN: FileCheck %s < %t1
+
+  addius5 $7, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range