[mips][microMIPS] Implement ADDIUSP instruction
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Fri, 10 Oct 2014 14:37:30 +0000 (14:37 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Fri, 10 Oct 2014 14:37:30 +0000 (14:37 +0000)
Differential Revision: http://reviews.llvm.org/D5084

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

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
lib/Target/Mips/MicroMipsInstrFormats.td
lib/Target/Mips/MicroMipsInstrInfo.td
test/MC/Mips/micromips-16-bit-instructions.s
test/MC/Mips/micromips-invalid.s

index db9c679b7673ccc7b6fa30179ddb2e72fcd9f4aa..5d704e655a83970a4dd3faf50cc5400fe9a58e39 100644 (file)
@@ -1133,6 +1133,15 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
         if (Imm < -8 || Imm > 7)
           return Error(IDLoc, "immediate operand value out of range");
         break;
+      case Mips::ADDIUSP_MM:
+        Opnd = Inst.getOperand(0);
+        if (!Opnd.isImm())
+          return Error(IDLoc, "expected immediate operand kind");
+        Imm = Opnd.getImm();
+        if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
+            Imm % 4 != 0)
+          return Error(IDLoc, "immediate operand value out of range");
+        break;
     }
   }
 
index acab141cde8d8b6f4fe888194802a8c97d7cc202..84e5292cd590065e70442e7cf6e826d2ba916b25 100644 (file)
@@ -363,6 +363,20 @@ getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
   return 0;
 }
 
+unsigned MipsMCCodeEmitter::
+getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
+                     SmallVectorImpl<MCFixup> &Fixups,
+                     const MCSubtargetInfo &STI) const {
+
+  const MCOperand &MO = MI.getOperand(OpNo);
+  if (MO.isImm()) {
+    unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff;
+    return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
+  }
+
+  return 0;
+}
+
 unsigned MipsMCCodeEmitter::
 getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups,
                const MCSubtargetInfo &STI) const {
index 7717fe4453215bb94bec8760ba4f4396ecf53351..2c4895581a93cbf885ce1e5ee2bd1782ff4152f7 100644 (file)
@@ -80,6 +80,12 @@ public:
                                 SmallVectorImpl<MCFixup> &Fixups,
                                 const MCSubtargetInfo &STI) const;
 
+  // getSImm9AddiuspValue - Return binary encoding of the microMIPS addiusp
+  // instruction immediate operand.
+  unsigned getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
+                                SmallVectorImpl<MCFixup> &Fixups,
+                                const MCSubtargetInfo &STI) const;
+
   // getBranchTargetOpValue - Return binary encoding of the branch
   // target operand. If the machine operand requires relocation,
   // record the relocation and return zero.
index 9d403460cd85b16d06624ee8d7759b2650fec3fb..91be3e0f1c176f6b7318cb2fafc8062c0a64f5d2 100644 (file)
@@ -53,6 +53,16 @@ class ADDIUS5_FM_MM16 {
   let Inst{0}     = 0;
 }
 
+class ADDIUSP_FM_MM16 {
+  bits<9> imm;
+
+  bits<16> Inst;
+
+  let Inst{15-10} = 0x13;
+  let Inst{9-1}   = imm;
+  let Inst{0}     = 1;
+}
+
 class MOVE_FM_MM16<bits<6> funct> {
   bits<5> rs;
   bits<5> rd;
index df90290de5f8c9c5d5a6ea77d1acd376021d22e8..bc35d65cacbfba992127cfc89f686fd8ea00f1ce 100644 (file)
@@ -10,6 +10,10 @@ def uimm5_lsl2 : Operand<OtherVT> {
   let EncoderMethod = "getUImm5Lsl2Encoding";
 }
 
+def simm9_addiusp : Operand<i32> {
+  let EncoderMethod = "getSImm9AddiuspValue";
+}
+
 def mem_mm_12 : Operand<i32> {
   let PrintMethod = "printMemOperand";
   let MIOperandInfo = (ops GPR32, simm12);
@@ -93,6 +97,10 @@ class AddImmUS5<string opstr, RegisterOperand RO> :
   let isCommutable = 1;
 }
 
+class AddImmUSP<string opstr> :
+  MicroMipsInst16<(outs), (ins simm9_addiusp:$imm),
+                  !strconcat(opstr, "\t$imm"), [], NoItinerary, FrmI>;
+
 class MoveFromHILOMM<string opstr, RegisterOperand RO, Register UseReg> :
       MicroMipsInst16<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"),
   [], II_MFHI_MFLO, FrmR> {
@@ -175,6 +183,7 @@ let isCall = 1, hasDelaySlot = 1, Defs = [RA] in {
 }
 
 def ADDIUS5_MM : AddImmUS5<"addius5", GPR32Opnd>, ADDIUS5_FM_MM16;
+def ADDIUSP_MM : AddImmUSP<"addiusp">, ADDIUSP_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 25582df2dd93df4823b9e02a3df0b7544a839643..964008c707384e3d1091173097d1ca112619205f 100644 (file)
@@ -10,6 +10,7 @@
 # Little endian
 #------------------------------------------------------------------------------
 # CHECK-EL: addius5 $7, -2          # encoding: [0xfc,0x4c]
+# CHECK-EL: addiusp -16             # encoding: [0xf9,0x4f]
 # CHECK-EL: mfhi    $9              # encoding: [0x09,0x46]
 # CHECK-EL: mflo    $9              # encoding: [0x49,0x46]
 # CHECK-EL: move    $25, $1         # encoding: [0x21,0x0f]
@@ -25,6 +26,7 @@
 # Big endian
 #------------------------------------------------------------------------------
 # CHECK-EB: addius5 $7, -2          # encoding: [0x4c,0xfc]
+# CHECK-EB: addiusp -16             # encoding: [0x4f,0xf9]
 # CHECK-EB: mfhi    $9              # encoding: [0x46,0x09]
 # CHECK-EB: mflo    $9              # encoding: [0x46,0x49]
 # CHECK-EB: move    $25, $1         # encoding: [0x0f,0x21]
@@ -38,6 +40,7 @@
 # CHECK-EB: nop                     # encoding: [0x00,0x00,0x00,0x00]
 
     addius5 $7, -2
+    addiusp -16
     mfhi    $9
     mflo    $9
     move    $25, $1
index 116628e8715f40d045078d74c2c35c0ee98b9af2..0064dd47ee77191ea1153d3a89fbc87496c8b439 100644 (file)
@@ -2,3 +2,4 @@
 # RUN: FileCheck %s < %t1
 
   addius5 $7, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
+  addiusp 1032   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range