[llvm] r327709 - [ARM] Convert more invalid NEON immediate loads

Mikhail Maltsev via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 16 07:10:56 PDT 2018


Author: miyuki
Date: Fri Mar 16 07:10:56 2018
New Revision: 327709

URL: http://llvm.org/viewvc/llvm-project?rev=327709&view=rev
Log:
[ARM] Convert more invalid NEON immediate loads

Summary:
Currently the LLVM MC assembler is able to convert e.g.

  vmov.i32 d0, #0xabababab

(which is technically invalid) into a valid instruction

  vmov.i8 d0, #0xab

this patch adds support for vmov.i64 and for cases with the resulting
load types other than i8, e.g.:

  vmov.i32 d0, #0xab00ab00 ->
  vmov.i16 d0, #0xab00

Reviewers: olista01, rengolin

Reviewed By: rengolin

Subscribers: rengolin, javed.absar, kristof.beyls, rogfer01, llvm-commits

Differential Revision: https://reviews.llvm.org/D44467

Added:
    llvm/trunk/test/MC/ARM/vmov-vmvn-replicate.s
Removed:
    llvm/trunk/test/MC/ARM/vmov-vmvn-byte-replicate.s
Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=327709&r1=327708&r2=327709&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Fri Mar 16 07:10:56 2018
@@ -48,46 +48,28 @@ def nImmVMOVI32 : Operand<i32> {
   let ParserMatchClass = nImmVMOVI32AsmOperand;
 }
 
-def nImmVMOVI16AsmOperandByteReplicate :
-  AsmOperandClass {
-  let Name = "NEONi16vmovByteReplicate";
-  let PredicateMethod = "isNEONi16ByteReplicate";
-  let RenderMethod = "addNEONvmovByteReplicateOperands";
-}
-def nImmVMOVI32AsmOperandByteReplicate :
-  AsmOperandClass {
-  let Name = "NEONi32vmovByteReplicate";
-  let PredicateMethod = "isNEONi32ByteReplicate";
-  let RenderMethod = "addNEONvmovByteReplicateOperands";
-}
-def nImmVMVNI16AsmOperandByteReplicate :
-  AsmOperandClass {
-  let Name = "NEONi16invByteReplicate";
-  let PredicateMethod = "isNEONi16ByteReplicate";
-  let RenderMethod = "addNEONinvByteReplicateOperands";
-}
-def nImmVMVNI32AsmOperandByteReplicate :
-  AsmOperandClass {
-  let Name = "NEONi32invByteReplicate";
-  let PredicateMethod = "isNEONi32ByteReplicate";
-  let RenderMethod = "addNEONinvByteReplicateOperands";
+class nImmVMOVIAsmOperandReplicate<ValueType From, ValueType To>
+  : AsmOperandClass {
+  let Name = "NEONi" # To.Size # "vmovi" # From.Size # "Replicate";
+  let PredicateMethod = "isNEONmovReplicate<" # From.Size # ", " # To.Size # ">";
+  let RenderMethod = "addNEONvmovi" # From.Size # "ReplicateOperands";
 }
 
-def nImmVMOVI16ByteReplicate : Operand<i32> {
-  let PrintMethod = "printNEONModImmOperand";
-  let ParserMatchClass = nImmVMOVI16AsmOperandByteReplicate;
-}
-def nImmVMOVI32ByteReplicate : Operand<i32> {
-  let PrintMethod = "printNEONModImmOperand";
-  let ParserMatchClass = nImmVMOVI32AsmOperandByteReplicate;
+class nImmVINVIAsmOperandReplicate<ValueType From, ValueType To>
+  : AsmOperandClass {
+  let Name = "NEONi" # To.Size # "invi" # From.Size # "Replicate";
+  let PredicateMethod = "isNEONinvReplicate<" # From.Size # ", " # To.Size # ">";
+  let RenderMethod = "addNEONinvi" # From.Size # "ReplicateOperands";
 }
-def nImmVMVNI16ByteReplicate : Operand<i32> {
+
+class nImmVMOVIReplicate<ValueType From, ValueType To> : Operand<i32> {
   let PrintMethod = "printNEONModImmOperand";
-  let ParserMatchClass = nImmVMVNI16AsmOperandByteReplicate;
+  let ParserMatchClass = nImmVMOVIAsmOperandReplicate<From, To>;
 }
-def nImmVMVNI32ByteReplicate : Operand<i32> {
+
+class nImmVINVIReplicate<ValueType From, ValueType To> : Operand<i32> {
   let PrintMethod = "printNEONModImmOperand";
-  let ParserMatchClass = nImmVMVNI32AsmOperandByteReplicate;
+  let ParserMatchClass = nImmVINVIAsmOperandReplicate<From, To>;
 }
 
 def nImmVMOVI32NegAsmOperand : AsmOperandClass { let Name = "NEONi32vmovNeg"; }
@@ -5933,34 +5915,57 @@ def VMOVv4f32 : N1ModImm<1, 0b000, 0b111
 } // isReMaterializable, isAsCheapAsAMove
 
 // Add support for bytes replication feature, so it could be GAS compatible.
-// E.g. instructions below:
-// "vmov.i32 d0, 0xffffffff"
-// "vmov.i32 d0, 0xabababab"
-// "vmov.i16 d0, 0xabab"
-// are incorrect, but we could deal with such cases.
-// For last two instructions, for example, it should emit:
-// "vmov.i8 d0, 0xab"
-def : NEONInstAlias<"vmov${p}.i16 $Vd, $Vm",
-                    (VMOVv8i8 DPR:$Vd, nImmVMOVI16ByteReplicate:$Vm, pred:$p)>;
-def : NEONInstAlias<"vmov${p}.i32 $Vd, $Vm",
-                    (VMOVv8i8 DPR:$Vd, nImmVMOVI32ByteReplicate:$Vm, pred:$p)>;
-def : NEONInstAlias<"vmov${p}.i16 $Vd, $Vm",
-                    (VMOVv16i8 QPR:$Vd, nImmVMOVI16ByteReplicate:$Vm, pred:$p)>;
-def : NEONInstAlias<"vmov${p}.i32 $Vd, $Vm",
-                    (VMOVv16i8 QPR:$Vd, nImmVMOVI32ByteReplicate:$Vm, pred:$p)>;
-
-// Also add same support for VMVN instructions. So instruction:
-// "vmvn.i32 d0, 0xabababab"
-// actually means:
-// "vmov.i8 d0, 0x54"
-def : NEONInstAlias<"vmvn${p}.i16 $Vd, $Vm",
-                    (VMOVv8i8 DPR:$Vd, nImmVMVNI16ByteReplicate:$Vm, pred:$p)>;
-def : NEONInstAlias<"vmvn${p}.i32 $Vd, $Vm",
-                    (VMOVv8i8 DPR:$Vd, nImmVMVNI32ByteReplicate:$Vm, pred:$p)>;
-def : NEONInstAlias<"vmvn${p}.i16 $Vd, $Vm",
-                    (VMOVv16i8 QPR:$Vd, nImmVMVNI16ByteReplicate:$Vm, pred:$p)>;
-def : NEONInstAlias<"vmvn${p}.i32 $Vd, $Vm",
-                    (VMOVv16i8 QPR:$Vd, nImmVMVNI32ByteReplicate:$Vm, pred:$p)>;
+multiclass NEONImmReplicateI8InstAlias<ValueType To> {
+  // E.g. instructions below:
+  // "vmov.i32 d0, #0xffffffff"
+  // "vmov.i32 d0, #0xabababab"
+  // "vmov.i16 d0, #0xabab"
+  // are incorrect, but we could deal with such cases.
+  // For last two instructions, for example, it should emit:
+  // "vmov.i8 d0, #0xab"
+  def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",
+                      (VMOVv8i8 DPR:$Vd, nImmVMOVIReplicate<i8, To>:$Vm, pred:$p)>;
+  def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",
+                      (VMOVv16i8 QPR:$Vd, nImmVMOVIReplicate<i8, To>:$Vm, pred:$p)>;
+  // Also add same support for VMVN instructions. So instruction:
+  // "vmvn.i32 d0, #0xabababab"
+  // actually means:
+  // "vmov.i8 d0, #0x54"
+  def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",
+                      (VMOVv8i8 DPR:$Vd, nImmVINVIReplicate<i8, To>:$Vm, pred:$p)>;
+  def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",
+                      (VMOVv16i8 QPR:$Vd, nImmVINVIReplicate<i8, To>:$Vm, pred:$p)>;
+}
+
+defm : NEONImmReplicateI8InstAlias<i16>;
+defm : NEONImmReplicateI8InstAlias<i32>;
+defm : NEONImmReplicateI8InstAlias<i64>;
+
+// Similar to above for types other than i8, e.g.:
+// "vmov.i32 d0, #0xab00ab00" -> "vmov.i16 d0, #0xab00"
+// "vmvn.i64 q0, #0xab000000ab000000" -> "vmvn.i32 q0, #0xab000000"
+// In this case we do not canonicalize VMVN to VMOV
+multiclass NEONImmReplicateInstAlias<ValueType From, NeonI V8, NeonI V16,
+                                     NeonI NV8, NeonI NV16, ValueType To> {
+  def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",
+                      (V8 DPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;
+  def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",
+                      (V16 QPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;
+  def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",
+                      (NV8 DPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;
+  def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",
+                      (NV16 QPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;
+}
+
+defm : NEONImmReplicateInstAlias<i16, VMOVv4i16, VMOVv8i16,
+                                      VMVNv4i16, VMVNv8i16, i32>;
+defm : NEONImmReplicateInstAlias<i16, VMOVv4i16, VMOVv8i16,
+                                      VMVNv4i16, VMVNv8i16, i64>;
+defm : NEONImmReplicateInstAlias<i32, VMOVv2i32, VMOVv4i32,
+                                      VMVNv2i32, VMVNv4i32, i64>;
+// TODO: add "VMOV <-> VMVN" conversion for cases like
+// "vmov.i32 d0, #0xffaaffaa" -> "vmvn.i16 d0, #0x55"
+// "vmvn.i32 d0, #0xaaffaaff" -> "vmov.i16 d0, #0xff00"
 
 // On some CPUs the two instructions "vmov.i32 dD, #0" and "vmov.i32 qD, #0"
 // require zero cycles to execute so they should be used wherever possible for

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=327709&r1=327708&r2=327709&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Fri Mar 16 07:10:56 2018
@@ -1857,7 +1857,22 @@ public:
     return ARM_AM::isNEONi32splat(~Value);
   }
 
-  bool isNEONByteReplicate(unsigned NumBytes) const {
+  static bool isValidNEONi32vmovImm(int64_t Value) {
+    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
+    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
+    return ((Value & 0xffffffffffffff00) == 0) ||
+           ((Value & 0xffffffffffff00ff) == 0) ||
+           ((Value & 0xffffffffff00ffff) == 0) ||
+           ((Value & 0xffffffff00ffffff) == 0) ||
+           ((Value & 0xffffffffffff00ff) == 0xff) ||
+           ((Value & 0xffffffffff00ffff) == 0xffff);
+  }
+
+  bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv,
+                       bool AllowMinusOne) const {
+    assert(Width == 8 || Width == 16 || Width == 32 && "Invalid element width");
+    assert(NumElems * Width <= 64 && "Invalid result width");
+
     if (!isImm())
       return false;
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
@@ -1867,28 +1882,47 @@ public:
     int64_t Value = CE->getValue();
     if (!Value)
       return false; // Don't bother with zero.
+    if (Inv)
+      Value = ~Value;
 
-    unsigned char B = Value & 0xff;
-    for (unsigned i = 1; i < NumBytes; ++i) {
-      Value >>= 8;
-      if ((Value & 0xff) != B)
+    uint64_t Mask = (1ull << Width) - 1;
+    uint64_t Elem = Value & Mask;
+    if (!AllowMinusOne && Elem == Mask)
+      return false;
+    if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
+      return false;
+    if (Width == 32 && !isValidNEONi32vmovImm(Elem))
+      return false;
+
+    for (unsigned i = 1; i < NumElems; ++i) {
+      Value >>= Width;
+      if ((Value & Mask) != Elem)
         return false;
     }
     return true;
   }
 
-  bool isNEONi16ByteReplicate() const { return isNEONByteReplicate(2); }
-  bool isNEONi32ByteReplicate() const { return isNEONByteReplicate(4); }
+  bool isNEONByteReplicate(unsigned NumBytes) const {
+    return isNEONReplicate(8, NumBytes, false, true);
+  }
 
-  static bool isValidNEONi32vmovImm(int64_t Value) {
-    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
-    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
-    return ((Value & 0xffffffffffffff00) == 0) ||
-           ((Value & 0xffffffffffff00ff) == 0) ||
-           ((Value & 0xffffffffff00ffff) == 0) ||
-           ((Value & 0xffffffff00ffffff) == 0) ||
-           ((Value & 0xffffffffffff00ff) == 0xff) ||
-           ((Value & 0xffffffffff00ffff) == 0xffff);
+  static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) {
+    assert(FromW == 8 || FromW == 16 || FromW == 32 && "Invalid source width");
+    assert(ToW == 16 || ToW == 32 || ToW == 64 && "Invalid destination width");
+    assert(FromW < ToW && "ToW is not less than FromW");
+  }
+
+  template<unsigned FromW, unsigned ToW>
+  bool isNEONmovReplicate() const {
+    checkNeonReplicateArgs(FromW, ToW);
+    bool AllowMinusOne = ToW != 64;
+    return isNEONReplicate(FromW, ToW / FromW, false, AllowMinusOne);
+  }
+
+  template<unsigned FromW, unsigned ToW>
+  bool isNEONinvReplicate() const {
+    checkNeonReplicateArgs(FromW, ToW);
+    return isNEONReplicate(FromW, ToW / FromW, true, true);
   }
 
   bool isNEONi32vmov() const {
@@ -2726,62 +2760,87 @@ public:
     Inst.addOperand(MCOperand::createImm(Value));
   }
 
-  void addNEONinvByteReplicateOperands(MCInst &Inst, unsigned N) const {
-    assert(N == 1 && "Invalid number of operands!");
+  void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const {
     // The immediate encodes the type of constant as well as the value.
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
-    unsigned Value = CE->getValue();
     assert((Inst.getOpcode() == ARM::VMOVv8i8 ||
             Inst.getOpcode() == ARM::VMOVv16i8) &&
-           "All vmvn instructions that wants to replicate non-zero byte "
-           "always must be replaced with VMOVv8i8 or VMOVv16i8.");
-    unsigned B = ((~Value) & 0xff);
+          "All instructions that wants to replicate non-zero byte "
+          "always must be replaced with VMOVv8i8 or VMOVv16i8.");
+    unsigned Value = CE->getValue();
+    if (Inv)
+      Value = ~Value;
+    unsigned B = Value & 0xff;
     B |= 0xe00; // cmode = 0b1110
     Inst.addOperand(MCOperand::createImm(B));
   }
 
-  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
+  void addNEONinvi8ReplicateOperands(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();
+    addNEONi8ReplicateOperands(Inst, true);
+  }
+
+  static unsigned encodeNeonVMOVImmediate(unsigned Value) {
     if (Value >= 256 && Value <= 0xffff)
       Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
     else if (Value > 0xffff && Value <= 0xffffff)
       Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
     else if (Value > 0xffffff)
       Value = (Value >> 24) | 0x600;
-    Inst.addOperand(MCOperand::createImm(Value));
+    return Value;
   }
 
-  void addNEONvmovByteReplicateOperands(MCInst &Inst, unsigned N) const {
+  void addNEONi32vmovOperands(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();
-    assert((Inst.getOpcode() == ARM::VMOVv8i8 ||
-            Inst.getOpcode() == ARM::VMOVv16i8) &&
-           "All instructions that wants to replicate non-zero byte "
-           "always must be replaced with VMOVv8i8 or VMOVv16i8.");
-    unsigned B = Value & 0xff;
-    B |= 0xe00; // cmode = 0b1110
-    Inst.addOperand(MCOperand::createImm(B));
+    unsigned Value = encodeNeonVMOVImmediate(CE->getValue());
+    Inst.addOperand(MCOperand::createImm(Value));
+  }
+
+  void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    addNEONi8ReplicateOperands(Inst, false);
+  }
+
+  void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    assert((Inst.getOpcode() == ARM::VMOVv4i16 ||
+            Inst.getOpcode() == ARM::VMOVv8i16 ||
+            Inst.getOpcode() == ARM::VMVNv4i16 ||
+            Inst.getOpcode() == ARM::VMVNv8i16) &&
+          "All instructions that want to replicate non-zero half-word "
+          "always must be replaced with V{MOV,MVN}v{4,8}i16.");
+    uint64_t Value = CE->getValue();
+    unsigned Elem = Value & 0xffff;
+    if (Elem >= 256)
+      Elem = (Elem >> 8) | 0x200;
+    Inst.addOperand(MCOperand::createImm(Elem));
   }
 
   void addNEONi32vmovNegOperands(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 <= 0xffff)
-      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
-    else if (Value > 0xffff && Value <= 0xffffff)
-      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
-    else if (Value > 0xffffff)
-      Value = (Value >> 24) | 0x600;
+    unsigned Value = encodeNeonVMOVImmediate(~CE->getValue());
     Inst.addOperand(MCOperand::createImm(Value));
   }
 
+  void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    assert((Inst.getOpcode() == ARM::VMOVv2i32 ||
+            Inst.getOpcode() == ARM::VMOVv4i32 ||
+            Inst.getOpcode() == ARM::VMVNv2i32 ||
+            Inst.getOpcode() == ARM::VMVNv4i32) &&
+          "All instructions that want to replicate non-zero word "
+          "always must be replaced with V{MOV,MVN}v{2,4}i32.");
+    uint64_t Value = CE->getValue();
+    unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
+    Inst.addOperand(MCOperand::createImm(Elem));
+  }
+
   void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     // The immediate encodes the type of constant as well as the value.

Removed: llvm/trunk/test/MC/ARM/vmov-vmvn-byte-replicate.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/vmov-vmvn-byte-replicate.s?rev=327708&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/vmov-vmvn-byte-replicate.s (original)
+++ llvm/trunk/test/MC/ARM/vmov-vmvn-byte-replicate.s (removed)
@@ -1,31 +0,0 @@
-@ PR18921, "vmov" part.
-@ RUN: llvm-mc -triple=armv7-linux-gnueabi -show-encoding < %s | FileCheck %s
-.text
-
-@ CHECK: vmov.i8 d2, #0xff @ encoding: [0x1f,0x2e,0x87,0xf3]
-@ CHECK: vmov.i8 q2, #0xff @ encoding: [0x5f,0x4e,0x87,0xf3]
-@ CHECK: vmov.i8 d2, #0xab @ encoding: [0x1b,0x2e,0x82,0xf3]
-@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]
-@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]
-@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]
-
-@ CHECK: vmov.i8 d2, #0x0  @ encoding: [0x10,0x2e,0x80,0xf2]
-@ CHECK: vmov.i8 q2, #0x0  @ encoding: [0x50,0x4e,0x80,0xf2]
-@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]
-@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]
-@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]
-@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]
-
-        vmov.i32        d2, #0xffffffff
-        vmov.i32        q2, #0xffffffff
-        vmov.i32        d2, #0xabababab
-        vmov.i32        q2, #0xabababab
-        vmov.i16        q2, #0xabab
-        vmov.i16        q2, #0xabab
-
-        vmvn.i32        d2, #0xffffffff
-        vmvn.i32        q2, #0xffffffff
-        vmvn.i32        d2, #0xabababab
-        vmvn.i32        q2, #0xabababab
-        vmvn.i16        d2, #0xabab
-        vmvn.i16        q2, #0xabab

Added: llvm/trunk/test/MC/ARM/vmov-vmvn-replicate.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/vmov-vmvn-replicate.s?rev=327709&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/vmov-vmvn-replicate.s (added)
+++ llvm/trunk/test/MC/ARM/vmov-vmvn-replicate.s Fri Mar 16 07:10:56 2018
@@ -0,0 +1,102 @@
+@ PR18921, "vmov" part.
+@ RUN: llvm-mc -triple=armv7-linux-gnueabi -show-encoding < %s | FileCheck %s
+.text
+        vmov.i64        d2, #0xffffffffffffffff
+        vmov.i64        q2, #0xffffffffffffffff
+        vmov.i32        d2, #0xffffffff
+        vmov.i32        q2, #0xffffffff
+        vmov.i64        d2, #0xabababababababab
+        vmov.i64        q2, #0xabababababababab
+        vmov.i32        d2, #0xabababab
+        vmov.i32        q2, #0xabababab
+        vmov.i16        q2, #0xabab
+        vmov.i16        q2, #0xabab
+
+@ CHECK: vmov.i64 d2, #0xffffffffffffffff @ encoding: [0x3f,0x2e,0x87,0xf3]
+@ CHECK: vmov.i64 q2, #0xffffffffffffffff @ encoding: [0x7f,0x4e,0x87,0xf3]
+@ CHECK: vmov.i8 d2, #0xff @ encoding: [0x1f,0x2e,0x87,0xf3]
+@ CHECK: vmov.i8 q2, #0xff @ encoding: [0x5f,0x4e,0x87,0xf3]
+@ CHECK: vmov.i8 d2, #0xab @ encoding: [0x1b,0x2e,0x82,0xf3]
+@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]
+@ CHECK: vmov.i8 d2, #0xab @ encoding: [0x1b,0x2e,0x82,0xf3]
+@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]
+@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]
+@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]
+
+        vmov.i64        d2, #0x00a500a500a500a5
+        vmov.i64        q2, #0x00a500a500a500a5
+        vmov.i32        d2, #0x00a500a5
+        vmov.i32        q2, #0x00a500a5
+        vmov.i64        d2, #0xa500a500a500a500
+        vmov.i64        q2, #0xa500a500a500a500
+        vmov.i32        d2, #0xa500a500
+        vmov.i32        q2, #0xa500a500
+
+@ CHECK: vmov.i16 d2, #0xa5 @ encoding: [0x15,0x28,0x82,0xf3]
+@ CHECK: vmov.i16 q2, #0xa5 @ encoding: [0x55,0x48,0x82,0xf3]
+@ CHECK: vmov.i16 d2, #0xa5 @ encoding: [0x15,0x28,0x82,0xf3]
+@ CHECK: vmov.i16 q2, #0xa5 @ encoding: [0x55,0x48,0x82,0xf3]
+@ CHECK: vmov.i16 d2, #0xa500 @ encoding: [0x15,0x2a,0x82,0xf3]
+@ CHECK: vmov.i16 q2, #0xa500 @ encoding: [0x55,0x4a,0x82,0xf3]
+@ CHECK: vmov.i16 d2, #0xa500 @ encoding: [0x15,0x2a,0x82,0xf3]
+@ CHECK: vmov.i16 q2, #0xa500 @ encoding: [0x55,0x4a,0x82,0xf3]
+
+        vmov.i64        d2, #0x000000a5000000a5
+        vmov.i64        q2, #0x000000a5000000a5
+        vmov.i64        d2, #0x00a5ffff00a5ffff
+        vmov.i64        q2, #0x00a5ffff00a5ffff
+
+@ CHECK: vmov.i32 d2, #0xa5 @ encoding: [0x15,0x20,0x82,0xf3]
+@ CHECK: vmov.i32 q2, #0xa5 @ encoding: [0x55,0x40,0x82,0xf3]
+@ CHECK: vmov.i32 d2, #0xa5ffff @ encoding: [0x15,0x2d,0x82,0xf3]
+@ CHECK: vmov.i32 q2, #0xa5ffff @ encoding: [0x55,0x4d,0x82,0xf3]
+
+        vmvn.i64        d2, #0xffffffffffffffff
+        vmvn.i64        q2, #0xffffffffffffffff
+        vmvn.i32        d2, #0xffffffff
+        vmvn.i32        q2, #0xffffffff
+        vmvn.i64        d2, #0xabababababababab
+        vmvn.i64        q2, #0xabababababababab
+        vmvn.i32        d2, #0xabababab
+        vmvn.i32        q2, #0xabababab
+        vmvn.i16        d2, #0xabab
+        vmvn.i16        q2, #0xabab
+
+@ CHECK: vmov.i8 d2, #0x0  @ encoding: [0x10,0x2e,0x80,0xf2]
+@ CHECK: vmov.i8 q2, #0x0  @ encoding: [0x50,0x4e,0x80,0xf2]
+@ CHECK: vmov.i8 d2, #0x0  @ encoding: [0x10,0x2e,0x80,0xf2]
+@ CHECK: vmov.i8 q2, #0x0  @ encoding: [0x50,0x4e,0x80,0xf2]
+@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]
+@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]
+@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]
+@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]
+@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]
+@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]
+
+        vmvn.i64        d2, #0x00a500a500a500a5
+        vmvn.i64        q2, #0x00a500a500a500a5
+        vmvn.i32        d2, #0x00a500a5
+        vmvn.i32        q2, #0x00a500a5
+        vmvn.i64        d2, #0xa500a500a500a500
+        vmvn.i64        q2, #0xa500a500a500a500
+        vmvn.i32        d2, #0xa500a500
+        vmvn.i32        q2, #0xa500a500
+
+@ CHECK: vmvn.i16 d2, #0xa5 @ encoding: [0x35,0x28,0x82,0xf3]
+@ CHECK: vmvn.i16 q2, #0xa5 @ encoding: [0x75,0x48,0x82,0xf3]
+@ CHECK: vmvn.i16 d2, #0xa5 @ encoding: [0x35,0x28,0x82,0xf3]
+@ CHECK: vmvn.i16 q2, #0xa5 @ encoding: [0x75,0x48,0x82,0xf3]
+@ CHECK: vmvn.i16 d2, #0xa500 @ encoding: [0x35,0x2a,0x82,0xf3]
+@ CHECK: vmvn.i16 q2, #0xa500 @ encoding: [0x75,0x4a,0x82,0xf3]
+@ CHECK: vmvn.i16 d2, #0xa500 @ encoding: [0x35,0x2a,0x82,0xf3]
+@ CHECK: vmvn.i16 q2, #0xa500 @ encoding: [0x75,0x4a,0x82,0xf3]
+
+        vmvn.i64        d2, #0x000000a5000000a5
+        vmvn.i64        q2, #0x000000a5000000a5
+        vmvn.i64        d2, #0x00a5ffff00a5ffff
+        vmvn.i64        q2, #0x00a5ffff00a5ffff
+
+@ CHECK: vmvn.i32 d2, #0xa5 @ encoding: [0x35,0x20,0x82,0xf3]
+@ CHECK: vmvn.i32 q2, #0xa5 @ encoding: [0x75,0x40,0x82,0xf3]
+@ CHECK: vmvn.i32 d2, #0xa5ffff @ encoding: [0x35,0x2d,0x82,0xf3]
+@ CHECK: vmvn.i32 q2, #0xa5ffff @ encoding: [0x75,0x4d,0x82,0xf3]




More information about the llvm-commits mailing list