[mips][microMIPS] Implement CodeGen support for SLL16 and SRL16 instructions
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Thu, 23 Oct 2014 10:42:01 +0000 (10:42 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Thu, 23 Oct 2014 10:42:01 +0000 (10:42 +0000)
Differential Revision: http://reviews.llvm.org/D5774

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220474 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 0a2fce1..6e8639c 100644 (file)
@@ -1161,6 +1161,15 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
             Imm % 4 != 0)
           return Error(IDLoc, "immediate operand value out of range");
         break;
+      case Mips::SLL16_MM:
+      case Mips::SRL16_MM:
+        Opnd = Inst.getOperand(2);
+        if (!Opnd.isImm())
+          return Error(IDLoc, "expected immediate operand kind");
+        Imm = Opnd.getImm();
+        if (Imm < 1 || Imm > 8)
+          return Error(IDLoc, "immediate operand value out of range");
+        break;
     }
   }
 
index 84e5292..020c3f6 100644 (file)
@@ -692,4 +692,13 @@ MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
   return 0;
 }
 
+unsigned
+MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
+                                        SmallVectorImpl<MCFixup> &Fixups,
+                                        const MCSubtargetInfo &STI) const {
+  assert(MI.getOperand(OpNo).isImm());
+  const MCOperand &MO = MI.getOperand(OpNo);
+  return MO.getImm() % 8;
+}
+
 #include "MipsGenMCCodeEmitter.inc"
index 2c48955..32ed5cc 100644 (file)
@@ -157,6 +157,10 @@ public:
                                  SmallVectorImpl<MCFixup> &Fixups,
                                  const MCSubtargetInfo &STI) const;
 
+  unsigned getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
+                                SmallVectorImpl<MCFixup> &Fixups,
+                                const MCSubtargetInfo &STI) const;
+
   unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
                           const MCSubtargetInfo &STI) const;
 
index 4f2444c..90ee077 100644 (file)
@@ -67,6 +67,20 @@ class LOGIC_FM_MM16<bits<4> funct> {
   let Inst{2-0}   = rs;
 }
 
+class SHIFT_FM_MM16<bits<1> funct> {
+  bits<3> rd;
+  bits<3> rt;
+  bits<3> shamt;
+
+  bits<16> Inst;
+
+  let Inst{15-10} = 0x09;
+  let Inst{9-7}   = rd;
+  let Inst{6-4}   = rt;
+  let Inst{3-1}   = shamt;
+  let Inst{0}     = funct;
+}
+
 class ADDIUS5_FM_MM16 {
   bits<5> rd;
   bits<4> imm;
index ab649be..656d369 100644 (file)
@@ -14,6 +14,12 @@ def simm9_addiusp : Operand<i32> {
   let EncoderMethod = "getSImm9AddiuspValue";
 }
 
+def uimm3_shift : Operand<i32> {
+  let EncoderMethod = "getUImm3Mod8Encoding";
+}
+
+def immZExt2Shift : ImmLeaf<i32, [{return Imm >= 1 && Imm <= 8;}]>;
+
 def mem_mm_12 : Operand<i32> {
   let PrintMethod = "printMemOperand";
   let MIOperandInfo = (ops GPR32, simm12);
@@ -114,6 +120,14 @@ class NotMM16<string opstr, RegisterOperand RO> :
          !strconcat(opstr, "\t$rt, $rs"),
          [(set RO:$rt, (not RO:$rs))], NoItinerary, FrmR>;
 
+class ShiftIMM16<string opstr, Operand ImmOpnd,
+                 RegisterOperand RO, SDPatternOperator OpNode = null_frag,
+                 SDPatternOperator PF = null_frag,
+                 InstrItinClass Itin = NoItinerary> :
+  MicroMipsInst16<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
+                  !strconcat(opstr, "\t$rd, $rt, $shamt"),
+                  [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], Itin, FrmR>;
+
 class AddImmUS5<string opstr, RegisterOperand RO> :
   MicroMipsInst16<(outs RO:$dst), (ins RO:$rd, simm4:$imm),
                   !strconcat(opstr, "\t$rd, $imm"), [], NoItinerary, FrmR> {
@@ -217,6 +231,10 @@ def OR16_MM  : LogicRMM16<"or16", GPRMM16Opnd, II_OR, or>,
 def XOR16_MM : LogicRMM16<"xor16", GPRMM16Opnd, II_XOR, xor>,
                LOGIC_FM_MM16<0x1>;
 def NOT16_MM : NotMM16<"not16", GPRMM16Opnd>, LOGIC_FM_MM16<0x0>;
+def SLL16_MM : ShiftIMM16<"sll16", uimm3_shift, GPRMM16Opnd, shl,
+                          immZExt2Shift, II_SLL>, SHIFT_FM_MM16<0>;
+def SRL16_MM : ShiftIMM16<"srl16", uimm3_shift, GPRMM16Opnd, srl,
+                          immZExt2Shift, II_SRL>, SHIFT_FM_MM16<1>;
 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>;
index 4a4b9eb..64296e8 100644 (file)
@@ -15,6 +15,8 @@
 # CHECK-EL: not16   $17, $3         # encoding: [0x0b,0x44]
 # CHECK-EL: or16    $16, $4         # encoding: [0xc4,0x44]
 # CHECK-EL: xor16   $17, $5         # encoding: [0x4d,0x44]
+# CHECK-EL: sll16   $3, $16, 5      # encoding: [0x8a,0x25]
+# CHECK-EL: srl16   $4, $17, 6      # encoding: [0x1d,0x26]
 # CHECK-EL: addius5 $7, -2          # encoding: [0xfc,0x4c]
 # CHECK-EL: addiusp -16             # encoding: [0xf9,0x4f]
 # CHECK-EL: mfhi    $9              # encoding: [0x09,0x46]
@@ -37,6 +39,8 @@
 # CHECK-EB: not16   $17, $3         # encoding: [0x44,0x0b]
 # CHECK-EB: or16    $16, $4         # encoding: [0x44,0xc4]
 # CHECK-EB: xor16   $17, $5         # encoding: [0x44,0x4d]
+# CHECK-EB: sll16   $3, $16, 5      # encoding: [0x25,0x8a]
+# CHECK-EB: srl16   $4, $17, 6      # encoding: [0x26,0x1d]
 # CHECK-EB: addius5 $7, -2          # encoding: [0x4c,0xfc]
 # CHECK-EB: addiusp -16             # encoding: [0x4f,0xf9]
 # CHECK-EB: mfhi    $9              # encoding: [0x46,0x09]
@@ -57,6 +61,8 @@
     not16   $17, $3
     or16    $16, $4
     xor16   $17, $5
+    sll16   $3, $16, 5
+    srl16   $4, $17, 6
     addius5 $7, -2
     addiusp -16
     mfhi    $9
index 9cea8ef..d9a5beb 100644 (file)
@@ -9,3 +9,7 @@
   not16   $18, $9   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   or16    $16, $10  # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   xor16   $15, $5   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  sll16   $1, $16, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  srl16   $4, $9, 6  # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  sll16   $3, $16, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
+  srl16   $4, $5, 15 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range