[mips][microMIPS] Implement ANDI16 instruction
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Wed, 5 Nov 2014 17:31:00 +0000 (17:31 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Wed, 5 Nov 2014 17:31:00 +0000 (17:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221367 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 277850c4deb07644970f23d4dbbf47fab7a7134f..f78eec5fdaa40d2172bd0941a61819b3817d24d4 100644 (file)
@@ -1198,6 +1198,16 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
         if (Imm < 0 || Imm > 255)
           return Error(IDLoc, "immediate operand value out of range");
         break;
+      case Mips::ANDI16_MM:
+        Opnd = Inst.getOperand(2);
+        if (!Opnd.isImm())
+          return Error(IDLoc, "expected immediate operand kind");
+        Imm = Opnd.getImm();
+        if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
+              Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
+              Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
+          return Error(IDLoc, "immediate operand value out of range");
+        break;
     }
   }
 
index 9636deb026cfa5937d4abfc89f4f07ef5bd3bbc8..6fa56e81a7308c5d90831f0f69415d2d444f64d6 100644 (file)
@@ -729,4 +729,32 @@ MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
   return MO.getImm() % 8;
 }
 
+unsigned
+MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
+                                    SmallVectorImpl<MCFixup> &Fixups,
+                                    const MCSubtargetInfo &STI) const {
+  assert(MI.getOperand(OpNo).isImm());
+  const MCOperand &MO = MI.getOperand(OpNo);
+  unsigned Value = MO.getImm();
+  switch (Value) {
+    case 128:   return 0x0;
+    case 1:     return 0x1;
+    case 2:     return 0x2;
+    case 3:     return 0x3;
+    case 4:     return 0x4;
+    case 7:     return 0x5;
+    case 8:     return 0x6;
+    case 15:    return 0x7;
+    case 16:    return 0x8;
+    case 31:    return 0x9;
+    case 32:    return 0xa;
+    case 63:    return 0xb;
+    case 64:    return 0xc;
+    case 255:   return 0xd;
+    case 32768: return 0xe;
+    case 65535: return 0xf;
+  }
+  llvm_unreachable("Unexpected value");
+}
+
 #include "MipsGenMCCodeEmitter.inc"
index 6a82a1df4249ba5f519a73ba7d697a2f3386adb2..65c4e6380eefc8f3a6ae7134c9ff5ff7323f771e 100644 (file)
@@ -168,6 +168,9 @@ public:
   unsigned getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
                                 SmallVectorImpl<MCFixup> &Fixups,
                                 const MCSubtargetInfo &STI) const;
+  unsigned getUImm4AndValue(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 dcddfbc8875c32d5040a103945dec9e16cb8684a..c0a4a1dfe0d83b7b5f84043050bc0d8155baa347 100644 (file)
@@ -55,6 +55,19 @@ class ARITH_FM_MM16<bit funct> {
   let Inst{0}     = funct;
 }
 
+class ANDI_FM_MM16<bits<6> funct> {
+  bits<3> rd;
+  bits<3> rs;
+  bits<4> imm;
+
+  bits<16> Inst;
+
+  let Inst{15-10} = funct;
+  let Inst{9-7}   = rd;
+  let Inst{6-4}   = rs;
+  let Inst{3-0}   = imm;
+}
+
 class LOGIC_FM_MM16<bits<4> funct> {
   bits<3> rt;
   bits<3> rs;
index ea8d65b1cb30d166411fbc83c8105a40b2c189fb..fe9d3478a03e928b74dfd9468d70ccca837bcf58 100644 (file)
@@ -27,6 +27,10 @@ def simm3_lsa2 : Operand<i32> {
   let EncoderMethod = "getSImm3Lsa2Value";
 }
 
+def uimm4_andi : Operand<i32> {
+  let EncoderMethod = "getUImm4AndValue";
+}
+
 def immZExt2Shift : ImmLeaf<i32, [{return Imm >= 1 && Imm <= 8;}]>;
 
 def immLi16 : ImmLeaf<i32, [{return Imm >= -1 && Imm <= 126;}]>;
@@ -116,6 +120,11 @@ class ArithRMM16<string opstr, RegisterOperand RO, bit isComm = 0,
   let isCommutable = isComm;
 }
 
+class AndImmMM16<string opstr, RegisterOperand RO,
+                 InstrItinClass Itin = NoItinerary> :
+  MicroMipsInst16<(outs RO:$rd), (ins RO:$rs, uimm4_andi:$imm),
+                  !strconcat(opstr, "\t$rd, $rs, $imm"), [], Itin, FrmI>;
+
 class LogicRMM16<string opstr, RegisterOperand RO,
                  InstrItinClass Itin = NoItinerary,
                  SDPatternOperator OpNode = null_frag> :
@@ -253,6 +262,7 @@ def ADDU16_MM : ArithRMM16<"addu16", GPRMM16Opnd, 1, II_ADDU, add>,
                 ARITH_FM_MM16<0>;
 def SUBU16_MM : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
                 ARITH_FM_MM16<1>;
+def ANDI16_MM : AndImmMM16<"andi16", GPRMM16Opnd, II_AND>, ANDI_FM_MM16<0x0b>;
 def AND16_MM : LogicRMM16<"and16", GPRMM16Opnd, II_AND, and>,
                LOGIC_FM_MM16<0x2>;
 def OR16_MM  : LogicRMM16<"or16", GPRMM16Opnd, II_OR, or>,
index 06938a9e6b9183491005219c3914e72aff539b9d..35855e1a995075901157ab69b0b278eab2bae4b1 100644 (file)
@@ -11,6 +11,7 @@
 #------------------------------------------------------------------------------
 # CHECK-EL: addu16  $6, $17, $4     # encoding: [0x42,0x07]
 # CHECK-EL: subu16  $5, $16, $3     # encoding: [0xb1,0x06]
+# CHECK-EL: andi16  $16, $2, 31     # encoding: [0x29,0x2c]
 # CHECK-EL: and16   $16, $2         # encoding: [0x82,0x44]
 # CHECK-EL: not16   $17, $3         # encoding: [0x0b,0x44]
 # CHECK-EL: or16    $16, $4         # encoding: [0xc4,0x44]
@@ -40,6 +41,7 @@
 #------------------------------------------------------------------------------
 # CHECK-EB: addu16  $6, $17, $4     # encoding: [0x07,0x42]
 # CHECK-EB: subu16  $5, $16, $3     # encoding: [0x06,0xb1]
+# CHECK-EB: andi16  $16, $2, 31     # encoding: [0x2c,0x29]
 # CHECK-EB: and16   $16, $2         # encoding: [0x44,0x82]
 # CHECK-EB: not16   $17, $3         # encoding: [0x44,0x0b]
 # CHECK-EB: or16    $16, $4         # encoding: [0x44,0xc4]
@@ -67,6 +69,7 @@
 
     addu16  $6, $17, $4
     subu16  $5, $16, $3
+    andi16  $16, $2, 31
     and16   $16, $2
     not16   $17, $3
     or16    $16, $4
index ad7b8aab10bda2a951fbc79058b2b9dac4e2b6c5..fb0e9ac84f4e5a521618e1b62fe7ff22fde5e778 100644 (file)
@@ -8,6 +8,8 @@
   addiusp 1032   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   addu16  $6, $14, $4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   subu16  $5, $16, $9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  andi16  $16, $10, 0x1f # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  andi16  $16, $2, 17 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
   and16   $16, $8   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   not16   $18, $9   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   or16    $16, $10  # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction