[llvm] r227225 - [mips] Add range checks and transformation to octeon instructions in AsmParser.

Kai Nacke kai.nacke at redstar.de
Tue Jan 27 11:11:28 PST 2015


Author: redstar
Date: Tue Jan 27 13:11:28 2015
New Revision: 227225

URL: http://llvm.org/viewvc/llvm-project?rev=227225&view=rev
Log:
[mips] Add range checks and transformation to octeon instructions in AsmParser.

This patch adds range checks to the immediate operands of octeon
instructions in the AsmParser. Like gas, it applies the following
transformations if the immediate is to large:

bbit0 $8, 42, foo => bbit032 $8, 10, foo
bbit1 $8, 46, foo => bbit132 $8, 14, foo
cins $8, $31, 32, 31 => cins32 $8, $31, 0, 31
exts $7, $4, 54, 9 => exts32 $7, $4, 22, 9

Reviewed By: dsanders

Differential Revision: http://reviews.llvm.org/D7080

Modified:
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/trunk/test/MC/Mips/octeon-instructions.s

Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=227225&r1=227224&r2=227225&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Tue Jan 27 13:11:28 2015
@@ -382,6 +382,9 @@ public:
   bool hasMips64r6() const {
     return (STI.getFeatureBits() & Mips::FeatureMips64r6);
   }
+  bool hasCnMips() const {
+    return (STI.getFeatureBits() & Mips::FeatureCnMips);
+  }
   bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
   bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
   bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
@@ -1168,6 +1171,13 @@ bool MipsAsmParser::processInstruction(M
     switch (Opcode) {
     default:
       break;
+    case Mips::BBIT0:
+    case Mips::BBIT032:
+    case Mips::BBIT1:
+    case Mips::BBIT132:
+      assert(hasCnMips() && "instruction only valid for octeon cpus");
+      // Fall through
+
     case Mips::BEQ:
     case Mips::BNE:
     case Mips::BEQ_MM:
@@ -1230,6 +1240,74 @@ bool MipsAsmParser::processInstruction(M
                                                       "nop instruction");
   }
 
+  if (hasCnMips()) {
+    const unsigned Opcode = Inst.getOpcode();
+    MCOperand Opnd;
+    int Imm;
+
+    switch (Opcode) {
+      default:
+        break;
+
+      case Mips::BBIT0:
+      case Mips::BBIT032:
+      case Mips::BBIT1:
+      case Mips::BBIT132:
+        assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
+        // The offset is handled above
+        Opnd = Inst.getOperand(1);
+        if (!Opnd.isImm())
+          return Error(IDLoc, "expected immediate operand kind");
+        Imm = Opnd.getImm();
+        if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
+                              Opcode == Mips::BBIT1 ? 63 : 31))
+          return Error(IDLoc, "immediate operand value out of range");
+        if (Imm > 31) {
+          Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
+                                               : Mips::BBIT132);
+          Inst.getOperand(1).setImm(Imm - 32);
+        }
+        break;
+
+      case Mips::CINS:
+      case Mips::CINS32:
+      case Mips::EXTS:
+      case Mips::EXTS32:
+        assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
+        // Check length
+        Opnd = Inst.getOperand(3);
+        if (!Opnd.isImm())
+          return Error(IDLoc, "expected immediate operand kind");
+        Imm = Opnd.getImm();
+        if (Imm < 0 || Imm > 31)
+          return Error(IDLoc, "immediate operand value out of range");
+        // Check position
+        Opnd = Inst.getOperand(2);
+        if (!Opnd.isImm())
+          return Error(IDLoc, "expected immediate operand kind");
+        Imm = Opnd.getImm();
+        if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
+                              Opcode == Mips::EXTS ? 63 : 31))
+          return Error(IDLoc, "immediate operand value out of range");
+        if (Imm > 31) {
+          Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
+          Inst.getOperand(2).setImm(Imm - 32);
+        }
+        break;
+
+      case Mips::SEQi:
+      case Mips::SNEi:
+        assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
+        Opnd = Inst.getOperand(2);
+        if (!Opnd.isImm())
+          return Error(IDLoc, "expected immediate operand kind");
+        Imm = Opnd.getImm();
+        if (!isInt<10>(Imm))
+          return Error(IDLoc, "immediate operand value out of range");
+        break;
+    }
+  }
+
   if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
     // If this instruction has a delay slot and .set reorder is active,
     // emit a NOP after it.

Modified: llvm/trunk/test/MC/Mips/octeon-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/octeon-instructions.s?rev=227225&r1=227224&r2=227225&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/octeon-instructions.s (original)
+++ llvm/trunk/test/MC/Mips/octeon-instructions.s Tue Jan 27 13:11:28 2015
@@ -5,12 +5,16 @@
 # CHECK: baddu $2, $2, $3             # encoding: [0x70,0x43,0x10,0x28]
 # CHECK: bbit0 $19, 22, foo           # encoding: [0xca,0x76,A,A]
 # CHECK: bbit032 $fp, 11, foo         # encoding: [0xdb,0xcb,A,A]
+# CHECK: bbit032 $8, 10, foo          # encoding: [0xd9,0x0a,A,A]
 # CHECK: bbit1 $3, 31, foo            # encoding: [0xe8,0x7f,A,A]
 # CHECK: bbit132 $24, 10, foo         # encoding: [0xfb,0x0a,A,A]
+# CHECK: bbit132 $14, 14, foo         # encoding: [0xf9,0xce,A,A]
 # CHECK: cins  $25, $10, 22, 2        # encoding: [0x71,0x59,0x15,0xb2]
 # CHECK: cins  $9, $9, 17, 29         # encoding: [0x71,0x29,0xec,0x72]
 # CHECK: cins32 $15, $2, 18, 8        # encoding: [0x70,0x4f,0x44,0xb3]
 # CHECK: cins32 $22, $22, 9, 22       # encoding: [0x72,0xd6,0xb2,0x73]
+# CHECK: cins32 $24, $ra, 0, 31       # encoding: [0x73,0xf8,0xf8,0x33]
+# CHECK: cins32 $15, $15, 5, 5        # encoding: [0x71,0xef,0x29,0x73]
 # CHECK: dmul  $9, $6, $7             # encoding: [0x70,0xc7,0x48,0x03]
 # CHECK: dmul  $19, $24, $25          # encoding: [0x73,0x19,0x98,0x03]
 # CHECK: dmul  $9, $9, $6             # encoding: [0x71,0x26,0x48,0x03]
@@ -22,6 +26,8 @@
 # CHECK: exts  $15, $15, 17, 6        # encoding: [0x71,0xef,0x34,0x7a]
 # CHECK: exts32 $4, $13, 10, 8        # encoding: [0x71,0xa4,0x42,0xbb]
 # CHECK: exts32 $15, $15, 11, 20      # encoding: [0x71,0xef,0xa2,0xfb]
+# CHECK: exts32 $7, $4, 22, 9         # encoding: [0x70,0x87,0x4d,0xbb]
+# CHECK: exts32 $25, $25, 5, 25       # encoding: [0x73,0x39,0xc9,0x7b]
 # CHECK: mtm0  $15                    # encoding: [0x71,0xe0,0x00,0x08]
 # CHECK: mtm1  $16                    # encoding: [0x72,0x00,0x00,0x0c]
 # CHECK: mtm2  $17                    # encoding: [0x72,0x20,0x00,0x0d]
@@ -56,12 +62,16 @@ foo:
   baddu $2, $3
   bbit0 $19, 22, foo
   bbit032 $30, 11, foo
+  bbit0 $8, 42, foo
   bbit1 $3, 31, foo
   bbit132 $24, 10, foo
+  bbit1 $14, 46, foo
   cins  $25, $10, 22, 2
   cins  $9, 17, 29
   cins32 $15, $2, 18, 8
   cins32 $22, 9, 22
+  cins  $24, $31, 32, 31
+  cins  $15, 37, 5
   dmul  $9, $6, $7
   dmul  $19, $24, $25
   dmul  $9, $6
@@ -73,6 +83,8 @@ foo:
   exts  $15, 17, 6
   exts32 $4, $13, 10, 8
   exts32 $15, 11, 20
+  exts  $7, $4, 54, 9
+  exts  $25, 37, 25
   mtm0  $15
   mtm1  $16
   mtm2  $17





More information about the llvm-commits mailing list