ARM assembly parsing and encoding for VMOV/VMVN/VORR/VBIC.i16.
authorJim Grosbach <grosbach@apple.com>
Mon, 17 Oct 2011 23:09:09 +0000 (23:09 +0000)
committerJim Grosbach <grosbach@apple.com>
Mon, 17 Oct 2011 23:09:09 +0000 (23:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142303 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrNEON.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/neont2-mov-encoding.s
utils/TableGen/EDEmitter.cpp

index d5f5772cf040a517c1e3241464a9c35ce596abb9..7ceedd68c2a01d6087e19f6fa7dffd21702a2459 100644 (file)
@@ -24,6 +24,11 @@ def nImmSplatI8 : Operand<i32> {
   let PrintMethod = "printNEONModImmOperand";
   let ParserMatchClass = nImmSplatI8AsmOperand;
 }
+def nImmSplatI16AsmOperand : AsmOperandClass { let Name = "NEONi16splat"; }
+def nImmSplatI16 : Operand<i32> {
+  let PrintMethod = "printNEONModImmOperand";
+  let ParserMatchClass = nImmSplatI16AsmOperand;
+}
 
 def VectorIndex8Operand  : AsmOperandClass { let Name = "VectorIndex8"; }
 def VectorIndex16Operand : AsmOperandClass { let Name = "VectorIndex16"; }
@@ -3743,7 +3748,7 @@ def  VORRq    : N3VQX<0, 0, 0b10, 0b0001, 1, IIC_VBINiQ, "vorr",
                       v4i32, v4i32, or, 1>;
 
 def VORRiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 0, 1,
-                          (outs DPR:$Vd), (ins nModImm:$SIMM, DPR:$src),
+                          (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src),
                           IIC_VMOVImm,
                           "vorr", "i16", "$Vd, $SIMM", "$src = $Vd",
                           [(set DPR:$Vd,
@@ -3761,7 +3766,7 @@ def VORRiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 0, 1,
 }
 
 def VORRiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 0, 1,
-                          (outs QPR:$Vd), (ins nModImm:$SIMM, QPR:$src),
+                          (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src),
                           IIC_VMOVImm,
                           "vorr", "i16", "$Vd, $SIMM", "$src = $Vd",
                           [(set QPR:$Vd,
@@ -3792,7 +3797,7 @@ def  VBICq    : N3VX<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd),
                                                  (vnotq QPR:$Vm))))]>;
 
 def VBICiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 1, 1,
-                          (outs DPR:$Vd), (ins nModImm:$SIMM, DPR:$src),
+                          (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src),
                           IIC_VMOVImm,
                           "vbic", "i16", "$Vd, $SIMM", "$src = $Vd",
                           [(set DPR:$Vd,
@@ -3810,7 +3815,7 @@ def VBICiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 1, 1,
 }
 
 def VBICiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 1, 1,
-                          (outs QPR:$Vd), (ins nModImm:$SIMM, QPR:$src),
+                          (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src),
                           IIC_VMOVImm,
                           "vbic", "i16", "$Vd, $SIMM", "$src = $Vd",
                           [(set QPR:$Vd,
@@ -3844,14 +3849,14 @@ def  VORNq    : N3VX<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$Vd),
 let isReMaterializable = 1 in {
 
 def VMVNv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 1, 1, (outs DPR:$Vd),
-                         (ins nModImm:$SIMM), IIC_VMOVImm,
+                         (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
                          "vmvn", "i16", "$Vd, $SIMM", "",
                          [(set DPR:$Vd, (v4i16 (NEONvmvnImm timm:$SIMM)))]> {
   let Inst{9} = SIMM{9};
 }
 
 def VMVNv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 1, 1, (outs QPR:$Vd),
-                         (ins nModImm:$SIMM), IIC_VMOVImm,
+                         (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
                          "vmvn", "i16", "$Vd, $SIMM", "",
                          [(set QPR:$Vd, (v8i16 (NEONvmvnImm timm:$SIMM)))]> {
   let Inst{9} = SIMM{9};
@@ -4329,14 +4334,14 @@ def VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$Vd),
                          [(set QPR:$Vd, (v16i8 (NEONvmovImm timm:$SIMM)))]>;
 
 def VMOVv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 0, 1, (outs DPR:$Vd),
-                         (ins nModImm:$SIMM), IIC_VMOVImm,
+                         (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
                          "vmov", "i16", "$Vd, $SIMM", "",
                          [(set DPR:$Vd, (v4i16 (NEONvmovImm timm:$SIMM)))]> {
   let Inst{9} = SIMM{9};
 }
 
 def VMOVv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 0, 1, (outs QPR:$Vd),
-                         (ins nModImm:$SIMM), IIC_VMOVImm,
+                         (ins nImmSplatI16:$SIMM), IIC_VMOVImm,
                          "vmov", "i16", "$Vd, $SIMM", "",
                          [(set QPR:$Vd, (v8i16 (NEONvmovImm timm:$SIMM)))]> {
  let Inst{9} = SIMM{9};
index c887179fc33e1da266d397c20802c03576a2e920..11b6574c2866bd2fe26165784b363c540fd02c66 100644 (file)
@@ -924,6 +924,17 @@ public:
     return Value >= 0 && Value < 256;
   }
 
+  bool isNEONi16splat() const {
+    if (Kind != k_Immediate)
+      return false;
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    // Must be a constant.
+    if (!CE) return false;
+    int64_t Value = CE->getValue();
+    // i16 value in the range [0,255] or [0x0100, 0xff00]
+    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
+  }
+
   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
     // Add as immediates when possible.  Null MCExpr = 0.
     if (Expr == 0)
@@ -1454,6 +1465,18 @@ public:
     Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
   }
 
+  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    // The immediate encodes the type of constant as well as the value.
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    unsigned Value = CE->getValue();
+    if (Value >= 256)
+      Value = (Value >> 8) | 0xa00;
+    else
+      Value |= 0x800;
+    Inst.addOperand(MCOperand::CreateImm(Value));
+  }
+
   virtual void print(raw_ostream &OS) const;
 
   static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
index 89fe82cf7110cfa35c70ee45199ed9937232ab7c..9b5e8016d8dba67a341fdf3072786013490b2709 100644 (file)
@@ -3,8 +3,8 @@
 .code 16
 
        vmov.i8 d16, #0x8
-@      vmov.i16        d16, #0x10
-@      vmov.i16        d16, #0x1000
+       vmov.i16        d16, #0x10
+       vmov.i16        d16, #0x1000
 @      vmov.i32        d16, #0x20
 @      vmov.i32        d16, #0x2000
 @      vmov.i32        d16, #0x200000
@@ -14,8 +14,8 @@
 @      vmov.i64        d16, #0xFF0000FF0000FFFF
 
 @ CHECK: vmov.i8       d16, #0x8       @ encoding: [0xc0,0xef,0x18,0x0e]
-@ FIXME: vmov.i16      d16, #0x10      @ encoding: [0xc1,0xef,0x10,0x08]
-@ FIXME: vmov.i16      d16, #0x1000    @ encoding: [0xc1,0xef,0x10,0x0a]
+@ CHECK: vmov.i16      d16, #0x10      @ encoding: [0xc1,0xef,0x10,0x08]
+@ CHECK: vmov.i16      d16, #0x1000    @ encoding: [0xc1,0xef,0x10,0x0a]
 @ FIXME: vmov.i32      d16, #0x20      @ encoding: [0xc2,0xef,0x10,0x00]
 @ FIXME: vmov.i32      d16, #0x2000    @ encoding: [0xc2,0xef,0x10,0x02]
 @ FIXME: vmov.i32      d16, #0x200000  @ encoding: [0xc2,0xef,0x10,0x04]
@@ -26,8 +26,8 @@
 
 
        vmov.i8 q8, #0x8
-@      vmov.i16        q8, #0x10
-@      vmov.i16        q8, #0x1000
+       vmov.i16        q8, #0x10
+       vmov.i16        q8, #0x1000
 @      vmov.i32        q8, #0x20
 @      vmov.i32        q8, #0x2000
 @      vmov.i32        q8, #0x200000
@@ -37,8 +37,8 @@
 @      vmov.i64        q8, #0xFF0000FF0000FFFF
 
 @ CHECK: vmov.i8       q8, #0x8        @ encoding: [0xc0,0xef,0x58,0x0e]
-@ FIXME: vmov.i16      q8, #0x10       @ encoding: [0xc1,0xef,0x50,0x08]
-@ FIXME: vmov.i16      q8, #0x1000     @ encoding: [0xc1,0xef,0x50,0x0a]
+@ CHECK: vmov.i16      q8, #0x10       @ encoding: [0xc1,0xef,0x50,0x08]
+@ CHECK: vmov.i16      q8, #0x1000     @ encoding: [0xc1,0xef,0x50,0x0a]
 @ FIXME: vmov.i32      q8, #0x20       @ encoding: [0xc2,0xef,0x50,0x00]
 @ FIXME: vmov.i32      q8, #0x2000     @ encoding: [0xc2,0xef,0x50,0x02]
 @ FIXME: vmov.i32      q8, #0x200000   @ encoding: [0xc2,0xef,0x50,0x04]
@@ -48,8 +48,8 @@
 @ FIXME: vmov.i64 q8, #0xFF0000FF0000FFFF @ encoding: [0xc1,0xff,0x73,0x0e]
 
 
-@      vmvn.i16        d16, #0x10
-@      vmvn.i16        d16, #0x1000
+       vmvn.i16        d16, #0x10
+       vmvn.i16        d16, #0x1000
 @      vmvn.i32        d16, #0x20
 @      vmvn.i32        d16, #0x2000
 @      vmvn.i32        d16, #0x200000
@@ -57,8 +57,8 @@
 @      vmvn.i32        d16, #0x20FF
 @      vmvn.i32        d16, #0x20FFFF
 
-@ FIXME: vmvn.i16      d16, #0x10      @ encoding: [0xc1,0xef,0x30,0x08]
-@ FIXME: vmvn.i16      d16, #0x1000    @ encoding: [0xc1,0xef,0x30,0x0a]
+@ CHECK: vmvn.i16      d16, #0x10      @ encoding: [0xc1,0xef,0x30,0x08]
+@ CHECK: vmvn.i16      d16, #0x1000    @ encoding: [0xc1,0xef,0x30,0x0a]
 @ FIXME: vmvn.i32      d16, #0x20      @ encoding: [0xc2,0xef,0x30,0x00]
 @ FIXME: vmvn.i32      d16, #0x2000    @ encoding: [0xc2,0xef,0x30,0x02]
 @ FIXME: vmvn.i32      d16, #0x200000  @ encoding: [0xc2,0xef,0x30,0x04]
index 9e9384f6c625adc039e05e2154789a703153bdc3..90346b77be112f8b06ccaa972a835c0072c17ca4 100644 (file)
@@ -598,6 +598,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   IMM("imm1_32");
   IMM("nModImm");
   IMM("nImmSplatI8");
+  IMM("nImmSplatI16");
   IMM("imm0_7");
   IMM("imm0_15");
   IMM("imm0_255");