[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 0a2fce111d141eee6386eb4389e5618fd5e0895b..6e8639c0914f775d5b17a2916c18866a932b733f 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 84e5292cd590065e70442e7cf6e826d2ba916b25..020c3f6d8c698c8ca7da556a2e776b053e9c1356 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 2c4895581a93cbf885ce1e5ee2bd1782ff4152f7..32ed5cc9d18b3b9969a990e67d60310c4ea5b7f9 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 4f2444cd13987d3695191f1816c5e431f2f680ee..90ee077347e143f3ddcfe19547c823ddeee81bb9 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 ab649beea835618b149dfdc1a3900311dcb69bd0..656d369fe4d512260bd96d84b4daa334d6a03687 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 4a4b9eb82d8eb2ae369913c6e6ab1f765e64af33..64296e8a17f3936a6a4786b3bd6b7aed8e90e7f0 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 9cea8ef8b57802a6d1f868c3014c377133c70fc5..d9a5beb93ce372136ac668f9bb4349ec6b7d1a18 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