[llvm] r206949 - [ARM64] Enable feature predicates for NEON / FP / CRYPTO.

Kevin Qin Kevin.Qin at arm.com
Tue Apr 22 23:22:48 PDT 2014


Author: kevinqin
Date: Wed Apr 23 01:22:48 2014
New Revision: 206949

URL: http://llvm.org/viewvc/llvm-project?rev=206949&view=rev
Log:
[ARM64] Enable feature predicates for NEON / FP / CRYPTO.

AArch64 has feature predicates for NEON, FP and CRYPTO instructions.
This allows the compiler to generate code without using FP, NEON
or CRYPTO instructions.

Added:
    llvm/trunk/test/CodeGen/ARM64/complex-copy-noneon.ll
    llvm/trunk/test/CodeGen/ARM64/reg-copy-noneon.ll
    llvm/trunk/test/MC/ARM64/diagno-predicate.s
Modified:
    llvm/trunk/lib/Target/ARM64/ARM64CallingConvention.td
    llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp
    llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td
    llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp
    llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h
    llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
    llvm/trunk/lib/Target/ARM64/ARM64TargetTransformInfo.cpp
    llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
    llvm/trunk/test/CodeGen/ARM64/crypto.ll
    llvm/trunk/test/MC/ARM64/advsimd.s
    llvm/trunk/test/MC/ARM64/aliases.s
    llvm/trunk/test/MC/ARM64/arithmetic-encoding.s
    llvm/trunk/test/MC/ARM64/crypto.s
    llvm/trunk/test/MC/ARM64/fp-encoding.s
    llvm/trunk/test/MC/ARM64/nv-cond.s
    llvm/trunk/test/MC/ARM64/simd-ldst.s
    llvm/trunk/test/MC/ARM64/vector-lists.s
    llvm/trunk/test/MC/ARM64/verbose-vector-case.s
    llvm/trunk/test/MC/Disassembler/ARM64/advsimd.txt
    llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt
    llvm/trunk/test/MC/Disassembler/ARM64/crypto.txt
    llvm/trunk/test/MC/Disassembler/ARM64/non-apple-fmov.txt
    llvm/trunk/test/MC/Disassembler/ARM64/scalar-fp.txt

Modified: llvm/trunk/lib/Target/ARM64/ARM64CallingConvention.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64CallingConvention.td?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64CallingConvention.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64CallingConvention.td Wed Apr 23 01:22:48 2014
@@ -21,7 +21,7 @@ class CCIfAlign<string Align, CCAction A
 
 def CC_ARM64_AAPCS : CallingConv<[
   CCIfType<[v2f32], CCBitConvertToType<v2i32>>,
-  CCIfType<[v2f64, v4f32, f128], CCBitConvertToType<v2i64>>,
+  CCIfType<[v2f64, v4f32], CCBitConvertToType<v2i64>>,
 
   // An SRet is passed in X8, not X0 like a normal pointer parameter.
   CCIfSRet<CCIfType<[i64], CCAssignToRegWithShadow<[X8], [W8]>>>,
@@ -51,7 +51,7 @@ def CC_ARM64_AAPCS : CallingConv<[
   CCIfType<[v1i64, v2i32, v4i16, v8i8, v1f64, v2f32],
            CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
                                    [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
-  CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32, v2f64],
+  CCIfType<[f128, v2i64, v4i32, v8i16, v16i8, v4f32, v2f64],
            CCAssignToReg<[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
 
   // If more than will fit in registers, pass them on the stack instead.
@@ -64,7 +64,7 @@ def CC_ARM64_AAPCS : CallingConv<[
 
 def RetCC_ARM64_AAPCS : CallingConv<[
   CCIfType<[v2f32], CCBitConvertToType<v2i32>>,
-  CCIfType<[v2f64, v4f32, f128], CCBitConvertToType<v2i64>>,
+  CCIfType<[v2f64, v4f32], CCBitConvertToType<v2i64>>,
 
   CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7],
                                           [X0, X1, X2, X3, X4, X5, X6, X7]>>,
@@ -77,7 +77,7 @@ def RetCC_ARM64_AAPCS : CallingConv<[
   CCIfType<[v1i64, v2i32, v4i16, v8i8, v1f64, v2f32],
       CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
                               [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
-  CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32, v2f64],
+  CCIfType<[f128, v2i64, v4i32, v8i16, v16i8, v4f32, v2f64],
       CCAssignToReg<[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>
 ]>;
 

Modified: llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp Wed Apr 23 01:22:48 2014
@@ -84,27 +84,32 @@ ARM64TargetLowering::ARM64TargetLowering
   // Set up the register classes.
   addRegisterClass(MVT::i32, &ARM64::GPR32allRegClass);
   addRegisterClass(MVT::i64, &ARM64::GPR64allRegClass);
-  addRegisterClass(MVT::f16, &ARM64::FPR16RegClass);
-  addRegisterClass(MVT::f32, &ARM64::FPR32RegClass);
-  addRegisterClass(MVT::f64, &ARM64::FPR64RegClass);
-  addRegisterClass(MVT::f128, &ARM64::FPR128RegClass);
-  addRegisterClass(MVT::v16i8, &ARM64::FPR8RegClass);
-  addRegisterClass(MVT::v8i16, &ARM64::FPR16RegClass);
-
-  // Someone set us up the NEON.
-  addDRTypeForNEON(MVT::v2f32);
-  addDRTypeForNEON(MVT::v8i8);
-  addDRTypeForNEON(MVT::v4i16);
-  addDRTypeForNEON(MVT::v2i32);
-  addDRTypeForNEON(MVT::v1i64);
-  addDRTypeForNEON(MVT::v1f64);
-
-  addQRTypeForNEON(MVT::v4f32);
-  addQRTypeForNEON(MVT::v2f64);
-  addQRTypeForNEON(MVT::v16i8);
-  addQRTypeForNEON(MVT::v8i16);
-  addQRTypeForNEON(MVT::v4i32);
-  addQRTypeForNEON(MVT::v2i64);
+
+  if (Subtarget->hasFPARMv8()) {
+    addRegisterClass(MVT::f16, &ARM64::FPR16RegClass);
+    addRegisterClass(MVT::f32, &ARM64::FPR32RegClass);
+    addRegisterClass(MVT::f64, &ARM64::FPR64RegClass);
+    addRegisterClass(MVT::f128, &ARM64::FPR128RegClass);
+  }
+
+  if (Subtarget->hasNEON()) {
+    addRegisterClass(MVT::v16i8, &ARM64::FPR8RegClass);
+    addRegisterClass(MVT::v8i16, &ARM64::FPR16RegClass);
+    // Someone set us up the NEON.
+    addDRTypeForNEON(MVT::v2f32);
+    addDRTypeForNEON(MVT::v8i8);
+    addDRTypeForNEON(MVT::v4i16);
+    addDRTypeForNEON(MVT::v2i32);
+    addDRTypeForNEON(MVT::v1i64);
+    addDRTypeForNEON(MVT::v1f64);
+
+    addQRTypeForNEON(MVT::v4f32);
+    addQRTypeForNEON(MVT::v2f64);
+    addQRTypeForNEON(MVT::v16i8);
+    addQRTypeForNEON(MVT::v8i16);
+    addQRTypeForNEON(MVT::v4i32);
+    addQRTypeForNEON(MVT::v2i64);
+  }
 
   // Compute derived properties from the register classes
   computeRegisterProperties();
@@ -140,42 +145,6 @@ ARM64TargetLowering::ARM64TargetLowering
   setOperationAction(ISD::FREM, MVT::f64, Expand);
   setOperationAction(ISD::FREM, MVT::f80, Expand);
 
-  // FIXME: v1f64 shouldn't be legal if we can avoid it, because it leads to
-  // silliness like this:
-  setOperationAction(ISD::FABS, MVT::v1f64, Expand);
-  setOperationAction(ISD::FADD, MVT::v1f64, Expand);
-  setOperationAction(ISD::FCEIL, MVT::v1f64, Expand);
-  setOperationAction(ISD::FCOPYSIGN, MVT::v1f64, Expand);
-  setOperationAction(ISD::FCOS, MVT::v1f64, Expand);
-  setOperationAction(ISD::FDIV, MVT::v1f64, Expand);
-  setOperationAction(ISD::FFLOOR, MVT::v1f64, Expand);
-  setOperationAction(ISD::FMA, MVT::v1f64, Expand);
-  setOperationAction(ISD::FMUL, MVT::v1f64, Expand);
-  setOperationAction(ISD::FNEARBYINT, MVT::v1f64, Expand);
-  setOperationAction(ISD::FNEG, MVT::v1f64, Expand);
-  setOperationAction(ISD::FPOW, MVT::v1f64, Expand);
-  setOperationAction(ISD::FREM, MVT::v1f64, Expand);
-  setOperationAction(ISD::FROUND, MVT::v1f64, Expand);
-  setOperationAction(ISD::FRINT, MVT::v1f64, Expand);
-  setOperationAction(ISD::FSIN, MVT::v1f64, Expand);
-  setOperationAction(ISD::FSINCOS, MVT::v1f64, Expand);
-  setOperationAction(ISD::FSQRT, MVT::v1f64, Expand);
-  setOperationAction(ISD::FSUB, MVT::v1f64, Expand);
-  setOperationAction(ISD::FTRUNC, MVT::v1f64, Expand);
-  setOperationAction(ISD::SETCC, MVT::v1f64, Expand);
-  setOperationAction(ISD::BR_CC, MVT::v1f64, Expand);
-  setOperationAction(ISD::SELECT, MVT::v1f64, Expand);
-  setOperationAction(ISD::SELECT_CC, MVT::v1f64, Expand);
-  setOperationAction(ISD::FP_EXTEND, MVT::v1f64, Expand);
-
-  setOperationAction(ISD::FP_TO_SINT, MVT::v1i64, Expand);
-  setOperationAction(ISD::FP_TO_UINT, MVT::v1i64, Expand);
-  setOperationAction(ISD::SINT_TO_FP, MVT::v1i64, Expand);
-  setOperationAction(ISD::UINT_TO_FP, MVT::v1i64, Expand);
-  setOperationAction(ISD::FP_ROUND, MVT::v1f64, Expand);
-
-  setOperationAction(ISD::MUL, MVT::v1i64, Expand);
-
   // Custom lowering hooks are needed for XOR
   // to fold it into CSINC/CSINV.
   setOperationAction(ISD::XOR, MVT::i32, Custom);
@@ -258,24 +227,10 @@ ARM64TargetLowering::ARM64TargetLowering
   setOperationAction(ISD::ROTL, MVT::i32, Expand);
   setOperationAction(ISD::ROTL, MVT::i64, Expand);
 
-  // ARM64 doesn't have a direct vector ->f32 conversion instructions for
-  // elements smaller than i32, so promote the input to i32 first.
-  setOperationAction(ISD::UINT_TO_FP, MVT::v4i8, Promote);
-  setOperationAction(ISD::SINT_TO_FP, MVT::v4i8, Promote);
-  setOperationAction(ISD::UINT_TO_FP, MVT::v4i16, Promote);
-  setOperationAction(ISD::SINT_TO_FP, MVT::v4i16, Promote);
-  // Similarly, there is no direct i32 -> f64 vector conversion instruction.
-  setOperationAction(ISD::SINT_TO_FP, MVT::v2i32, Custom);
-  setOperationAction(ISD::UINT_TO_FP, MVT::v2i32, Custom);
-  setOperationAction(ISD::SINT_TO_FP, MVT::v2i64, Custom);
-  setOperationAction(ISD::UINT_TO_FP, MVT::v2i64, Custom);
-
   // ARM64 doesn't have {U|S}MUL_LOHI.
   setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
   setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
 
-  // ARM64 doesn't have MUL.2d:
-  setOperationAction(ISD::MUL, MVT::v2i64, Expand);
 
   // Expand the undefined-at-zero variants to cttz/ctlz to their defined-at-zero
   // counterparts, which ARM64 supports directly.
@@ -320,8 +275,7 @@ ARM64TargetLowering::ARM64TargetLowering
   setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
 
   // ARM64 has implementations of a lot of rounding-like FP operations.
-  static MVT RoundingTypes[] = { MVT::f32,   MVT::f64,  MVT::v2f32,
-                                 MVT::v4f32, MVT::v2f64 };
+  static MVT RoundingTypes[] = { MVT::f32, MVT::f64};
   for (unsigned I = 0; I < array_lengthof(RoundingTypes); ++I) {
     MVT Ty = RoundingTypes[I];
     setOperationAction(ISD::FFLOOR, Ty, Legal);
@@ -358,7 +312,6 @@ ARM64TargetLowering::ARM64TargetLowering
   setTruncStoreAction(MVT::f128, MVT::f64, Expand);
   setTruncStoreAction(MVT::f128, MVT::f32, Expand);
   setTruncStoreAction(MVT::f128, MVT::f16, Expand);
-  setTruncStoreAction(MVT::v2i32, MVT::v2i16, Expand);
   // Indexed loads and stores are supported.
   for (unsigned im = (unsigned)ISD::PRE_INC;
        im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
@@ -376,26 +329,8 @@ ARM64TargetLowering::ARM64TargetLowering
     setIndexedStoreAction(im, MVT::f32, Legal);
   }
 
-  // Likewise, narrowing and extending vector loads/stores aren't handled
-  // directly.
-  for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
-       VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
-
-    setOperationAction(ISD::SIGN_EXTEND_INREG, (MVT::SimpleValueType)VT,
-                       Expand);
-
-    for (unsigned InnerVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
-         InnerVT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++InnerVT)
-      setTruncStoreAction((MVT::SimpleValueType)VT,
-                          (MVT::SimpleValueType)InnerVT, Expand);
-    setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT, Expand);
-    setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT, Expand);
-    setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT, Expand);
-  }
-
   // Trap.
   setOperationAction(ISD::TRAP, MVT::Other, Legal);
-  setOperationAction(ISD::ANY_EXTEND, MVT::v4i32, Legal);
 
   // We combine OR nodes for bitfield operations.
   setTargetDAGCombine(ISD::OR);
@@ -440,6 +375,89 @@ ARM64TargetLowering::ARM64TargetLowering
   RequireStrictAlign = StrictAlign;
 
   setHasExtractBitsInsn(true);
+
+  if (Subtarget->hasNEON()) {
+    // FIXME: v1f64 shouldn't be legal if we can avoid it, because it leads to
+    // silliness like this:
+    setOperationAction(ISD::FABS, MVT::v1f64, Expand);
+    setOperationAction(ISD::FADD, MVT::v1f64, Expand);
+    setOperationAction(ISD::FCEIL, MVT::v1f64, Expand);
+    setOperationAction(ISD::FCOPYSIGN, MVT::v1f64, Expand);
+    setOperationAction(ISD::FCOS, MVT::v1f64, Expand);
+    setOperationAction(ISD::FDIV, MVT::v1f64, Expand);
+    setOperationAction(ISD::FFLOOR, MVT::v1f64, Expand);
+    setOperationAction(ISD::FMA, MVT::v1f64, Expand);
+    setOperationAction(ISD::FMUL, MVT::v1f64, Expand);
+    setOperationAction(ISD::FNEARBYINT, MVT::v1f64, Expand);
+    setOperationAction(ISD::FNEG, MVT::v1f64, Expand);
+    setOperationAction(ISD::FPOW, MVT::v1f64, Expand);
+    setOperationAction(ISD::FREM, MVT::v1f64, Expand);
+    setOperationAction(ISD::FROUND, MVT::v1f64, Expand);
+    setOperationAction(ISD::FRINT, MVT::v1f64, Expand);
+    setOperationAction(ISD::FSIN, MVT::v1f64, Expand);
+    setOperationAction(ISD::FSINCOS, MVT::v1f64, Expand);
+    setOperationAction(ISD::FSQRT, MVT::v1f64, Expand);
+    setOperationAction(ISD::FSUB, MVT::v1f64, Expand);
+    setOperationAction(ISD::FTRUNC, MVT::v1f64, Expand);
+    setOperationAction(ISD::SETCC, MVT::v1f64, Expand);
+    setOperationAction(ISD::BR_CC, MVT::v1f64, Expand);
+    setOperationAction(ISD::SELECT, MVT::v1f64, Expand);
+    setOperationAction(ISD::SELECT_CC, MVT::v1f64, Expand);
+    setOperationAction(ISD::FP_EXTEND, MVT::v1f64, Expand);
+
+    setOperationAction(ISD::FP_TO_SINT, MVT::v1i64, Expand);
+    setOperationAction(ISD::FP_TO_UINT, MVT::v1i64, Expand);
+    setOperationAction(ISD::SINT_TO_FP, MVT::v1i64, Expand);
+    setOperationAction(ISD::UINT_TO_FP, MVT::v1i64, Expand);
+    setOperationAction(ISD::FP_ROUND, MVT::v1f64, Expand);
+
+    setOperationAction(ISD::MUL, MVT::v1i64, Expand);
+
+    // ARM64 doesn't have a direct vector ->f32 conversion instructions for
+    // elements smaller than i32, so promote the input to i32 first.
+    setOperationAction(ISD::UINT_TO_FP, MVT::v4i8, Promote);
+    setOperationAction(ISD::SINT_TO_FP, MVT::v4i8, Promote);
+    setOperationAction(ISD::UINT_TO_FP, MVT::v4i16, Promote);
+    setOperationAction(ISD::SINT_TO_FP, MVT::v4i16, Promote);
+    // Similarly, there is no direct i32 -> f64 vector conversion instruction.
+    setOperationAction(ISD::SINT_TO_FP, MVT::v2i32, Custom);
+    setOperationAction(ISD::UINT_TO_FP, MVT::v2i32, Custom);
+    setOperationAction(ISD::SINT_TO_FP, MVT::v2i64, Custom);
+    setOperationAction(ISD::UINT_TO_FP, MVT::v2i64, Custom);
+
+    // ARM64 doesn't have MUL.2d:
+    setOperationAction(ISD::MUL, MVT::v2i64, Expand);
+    setOperationAction(ISD::ANY_EXTEND, MVT::v4i32, Legal);
+    setTruncStoreAction(MVT::v2i32, MVT::v2i16, Expand);
+    // Likewise, narrowing and extending vector loads/stores aren't handled
+    // directly.
+    for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
+         VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
+
+      setOperationAction(ISD::SIGN_EXTEND_INREG, (MVT::SimpleValueType)VT,
+                         Expand);
+
+      for (unsigned InnerVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
+           InnerVT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++InnerVT)
+        setTruncStoreAction((MVT::SimpleValueType)VT,
+                            (MVT::SimpleValueType)InnerVT, Expand);
+      setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT, Expand);
+      setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT, Expand);
+      setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT, Expand);
+    }
+
+    // ARM64 has implementations of a lot of rounding-like FP operations.
+    static MVT RoundingVecTypes[] = {MVT::v2f32, MVT::v4f32, MVT::v2f64 };
+    for (unsigned I = 0; I < array_lengthof(RoundingVecTypes); ++I) {
+      MVT Ty = RoundingVecTypes[I];
+      setOperationAction(ISD::FFLOOR, Ty, Legal);
+      setOperationAction(ISD::FNEARBYINT, Ty, Legal);
+      setOperationAction(ISD::FCEIL, Ty, Legal);
+      setOperationAction(ISD::FRINT, Ty, Legal);
+      setOperationAction(ISD::FTRUNC, Ty, Legal);
+      setOperationAction(ISD::FROUND, Ty, Legal);
+    }
+  }
 }
 
 void ARM64TargetLowering::addTypeForNEON(EVT VT, EVT PromotedBitwiseVT) {
@@ -1662,8 +1680,9 @@ SDValue ARM64TargetLowering::LowerFormal
                RegVT == MVT::v1f64 || RegVT == MVT::v2i32 ||
                RegVT == MVT::v4i16 || RegVT == MVT::v8i8)
         RC = &ARM64::FPR64RegClass;
-      else if (RegVT == MVT::v2i64 || RegVT == MVT::v4i32 ||
-               RegVT == MVT::v8i16 || RegVT == MVT::v16i8)
+      else if (RegVT == MVT::f128 ||RegVT == MVT::v2i64 ||
+               RegVT == MVT::v4i32||RegVT == MVT::v8i16 ||
+               RegVT == MVT::v16i8)
         RC = &ARM64::FPR128RegClass;
       else
         llvm_unreachable("RegVT not supported by FORMAL_ARGUMENTS Lowering");
@@ -1747,13 +1766,6 @@ void ARM64TargetLowering::saveVarArgRegi
   unsigned FirstVariadicGPR =
       CCInfo.getFirstUnallocated(GPRArgRegs, NumGPRArgRegs);
 
-  static const MCPhysReg FPRArgRegs[] = { ARM64::Q0, ARM64::Q1, ARM64::Q2,
-                                          ARM64::Q3, ARM64::Q4, ARM64::Q5,
-                                          ARM64::Q6, ARM64::Q7 };
-  static const unsigned NumFPRArgRegs = array_lengthof(FPRArgRegs);
-  unsigned FirstVariadicFPR =
-      CCInfo.getFirstUnallocated(FPRArgRegs, NumFPRArgRegs);
-
   unsigned GPRSaveSize = 8 * (NumGPRArgRegs - FirstVariadicGPR);
   int GPRIdx = 0;
   if (GPRSaveSize != 0) {
@@ -1772,31 +1784,39 @@ void ARM64TargetLowering::saveVarArgRegi
                         DAG.getConstant(8, getPointerTy()));
     }
   }
+  FuncInfo->setVarArgsGPRIndex(GPRIdx);
+  FuncInfo->setVarArgsGPRSize(GPRSaveSize);
 
-  unsigned FPRSaveSize = 16 * (NumFPRArgRegs - FirstVariadicFPR);
-  int FPRIdx = 0;
-  if (FPRSaveSize != 0) {
-    FPRIdx = MFI->CreateStackObject(FPRSaveSize, 16, false);
-
-    SDValue FIN = DAG.getFrameIndex(FPRIdx, getPointerTy());
-
-    for (unsigned i = FirstVariadicFPR; i < NumFPRArgRegs; ++i) {
-      unsigned VReg = MF.addLiveIn(FPRArgRegs[i], &ARM64::FPR128RegClass);
-      SDValue Val = DAG.getCopyFromReg(Chain, DL, VReg, MVT::v2i64);
-      SDValue Store =
-          DAG.getStore(Val.getValue(1), DL, Val, FIN,
-                       MachinePointerInfo::getStack(i * 16), false, false, 0);
-      MemOps.push_back(Store);
-      FIN = DAG.getNode(ISD::ADD, DL, getPointerTy(), FIN,
-                        DAG.getConstant(16, getPointerTy()));
+  if (Subtarget->hasFPARMv8()) {
+    static const MCPhysReg FPRArgRegs[] = { ARM64::Q0, ARM64::Q1, ARM64::Q2,
+                                            ARM64::Q3, ARM64::Q4, ARM64::Q5,
+                                            ARM64::Q6, ARM64::Q7 };
+    static const unsigned NumFPRArgRegs = array_lengthof(FPRArgRegs);
+    unsigned FirstVariadicFPR =
+        CCInfo.getFirstUnallocated(FPRArgRegs, NumFPRArgRegs);
+
+    unsigned FPRSaveSize = 16 * (NumFPRArgRegs - FirstVariadicFPR);
+    int FPRIdx = 0;
+    if (FPRSaveSize != 0) {
+      FPRIdx = MFI->CreateStackObject(FPRSaveSize, 16, false);
+
+      SDValue FIN = DAG.getFrameIndex(FPRIdx, getPointerTy());
+
+      for (unsigned i = FirstVariadicFPR; i < NumFPRArgRegs; ++i) {
+        unsigned VReg = MF.addLiveIn(FPRArgRegs[i], &ARM64::FPR128RegClass);
+        SDValue Val = DAG.getCopyFromReg(Chain, DL, VReg, MVT::v2i64);
+        SDValue Store =
+            DAG.getStore(Val.getValue(1), DL, Val, FIN,
+                         MachinePointerInfo::getStack(i * 16), false, false, 0);
+        MemOps.push_back(Store);
+        FIN = DAG.getNode(ISD::ADD, DL, getPointerTy(), FIN,
+                          DAG.getConstant(16, getPointerTy()));
+      }
     }
+    FuncInfo->setVarArgsFPRIndex(FPRIdx);
+    FuncInfo->setVarArgsFPRSize(FPRSaveSize);
   }
 
-  FuncInfo->setVarArgsGPRIndex(GPRIdx);
-  FuncInfo->setVarArgsGPRSize(GPRSaveSize);
-  FuncInfo->setVarArgsFPRIndex(FPRIdx);
-  FuncInfo->setVarArgsFPRSize(FPRSaveSize);
-
   if (!MemOps.empty()) {
     Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, &MemOps[0],
                         MemOps.size());

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrFormats.td Wed Apr 23 01:22:48 2014
@@ -3077,6 +3077,8 @@ class ExceptionGeneration<bits<3> op1, b
   let Inst{1-0}   = ll;
 }
 
+let Predicates = [HasFPARMv8] in {
+
 //---
 // Floating point to integer conversion
 //---
@@ -3708,6 +3710,7 @@ multiclass FPMoveImmediate<string asm> {
     let Inst{22} = 1;
   }
 }
+} // end of 'let Predicates = [HasFPARMv8]'
 
 //----------------------------------------------------------------------------
 // AdvSIMD
@@ -3746,6 +3749,20 @@ def VectorIndexD : Operand<i64>, ImmLeaf
   let MIOperandInfo = (ops i64imm);
 }
 
+def MemorySIMDNoIndexOperand : AsmOperandClass {
+  let Name = "MemorySIMDNoIndex";
+  let ParserMethod = "tryParseNoIndexMemory";
+}
+def am_simdnoindex : Operand<i64>,
+                     ComplexPattern<i64, 1, "SelectAddrModeNoIndex", []> {
+  let PrintMethod = "printAMNoIndex";
+  let ParserMatchClass = MemorySIMDNoIndexOperand;
+  let MIOperandInfo = (ops GPR64sp:$base);
+  let DecoderMethod = "DecodeGPR64spRegisterClass";
+}
+
+let Predicates = [HasNEON] in {
+
 //----------------------------------------------------------------------------
 // AdvSIMD three register vector instructions
 //----------------------------------------------------------------------------
@@ -4634,12 +4651,14 @@ multiclass SIMDDifferentThreeVectorBD<bi
   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
                                             V128, V128, V128,
                                             asm#"2", ".8h", ".16b", ".16b", []>;
-  def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
-                                            V128, V64, V64,
-                                            asm, ".1q", ".1d", ".1d", []>;
-  def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
-                                            V128, V128, V128,
-                                            asm#"2", ".1q", ".2d", ".2d", []>;
+  let Predicates = [HasCrypto] in {
+    def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
+                                              V128, V64, V64,
+                                              asm, ".1q", ".1d", ".1d", []>;
+    def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
+                                              V128, V128, V128,
+                                              asm#"2", ".1q", ".2d", ".2d", []>;
+  }
 
   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
@@ -7366,17 +7385,6 @@ multiclass SIMDVectorLShiftLongBHSD<bit
 // ", #0" constant and handle post-indexing explicitly, so we use
 // a more specialized parse method for them. Otherwise, it's the same as
 // the general am_noindex handling.
-def MemorySIMDNoIndexOperand : AsmOperandClass {
-  let Name = "MemorySIMDNoIndex";
-  let ParserMethod = "tryParseNoIndexMemory";
-}
-def am_simdnoindex : Operand<i64>,
-                     ComplexPattern<i64, 1, "SelectAddrModeNoIndex", []> {
-  let PrintMethod = "printAMNoIndex";
-  let ParserMatchClass = MemorySIMDNoIndexOperand;
-  let MIOperandInfo = (ops GPR64sp:$base);
-  let DecoderMethod = "DecodeGPR64spRegisterClass";
-}
 
 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
                    string asm, dag oops, dag iops, list<dag> pattern>
@@ -8191,11 +8199,13 @@ multiclass SIMDLdSt4SingleAliases<string
   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
 }
+} // end of 'let Predicates = [HasNEON]'
 
 //----------------------------------------------------------------------------
 // Crypto extensions
 //----------------------------------------------------------------------------
 
+let Predicates = [HasCrypto] in {
 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
               list<dag> pat>
@@ -8285,6 +8295,7 @@ class SHATiedInstVV<bits<4> opc, string
 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
+} // end of 'let Predicates = [HasCrypto]'
 
 // Allow the size specifier tokens to be upper case, not just lower.
 def : TokenAlias<".8B", ".8b">;

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.cpp Wed Apr 23 01:22:48 2014
@@ -1102,6 +1102,8 @@ void ARM64InstrInfo::copyPhysRegTuple(Ma
                                       unsigned SrcReg, bool KillSrc,
                                       unsigned Opcode,
                                       llvm::ArrayRef<unsigned> Indices) const {
+  assert(getSubTarget().hasNEON() &&
+         "Unexpected register copy without NEON");
   const TargetRegisterInfo *TRI = &getRegisterInfo();
   uint16_t DestEncoding = TRI->getEncodingValue(DestReg);
   uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
@@ -1261,52 +1263,91 @@ void ARM64InstrInfo::copyPhysReg(Machine
 
   if (ARM64::FPR128RegClass.contains(DestReg) &&
       ARM64::FPR128RegClass.contains(SrcReg)) {
-    BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
-        SrcReg, getKillRegState(KillSrc));
+    if(getSubTarget().hasNEON()) {
+      BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
+          SrcReg, getKillRegState(KillSrc));
+    } else {
+      BuildMI(MBB, I, DL, get(ARM64::STRQpre))
+        .addReg(SrcReg, getKillRegState(KillSrc))
+        .addReg(ARM64::SP)
+        .addImm(-16);
+      BuildMI(MBB, I, DL, get(ARM64::LDRQpre))
+        .addReg(DestReg, RegState::Define)
+        .addReg(ARM64::SP)
+        .addImm(16);
+    }
     return;
   }
 
   if (ARM64::FPR64RegClass.contains(DestReg) &&
       ARM64::FPR64RegClass.contains(SrcReg)) {
-    DestReg =
-        RI.getMatchingSuperReg(DestReg, ARM64::dsub, &ARM64::FPR128RegClass);
-    SrcReg =
-        RI.getMatchingSuperReg(SrcReg, ARM64::dsub, &ARM64::FPR128RegClass);
-    BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
-        SrcReg, getKillRegState(KillSrc));
+    if(getSubTarget().hasNEON()) {
+      DestReg =
+          RI.getMatchingSuperReg(DestReg, ARM64::dsub, &ARM64::FPR128RegClass);
+      SrcReg =
+          RI.getMatchingSuperReg(SrcReg, ARM64::dsub, &ARM64::FPR128RegClass);
+      BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
+          SrcReg, getKillRegState(KillSrc));
+    } else {
+      BuildMI(MBB, I, DL, get(ARM64::FMOVDr), DestReg)
+          .addReg(SrcReg, getKillRegState(KillSrc));
+    }
     return;
   }
 
   if (ARM64::FPR32RegClass.contains(DestReg) &&
       ARM64::FPR32RegClass.contains(SrcReg)) {
-    DestReg =
-        RI.getMatchingSuperReg(DestReg, ARM64::ssub, &ARM64::FPR128RegClass);
-    SrcReg =
-        RI.getMatchingSuperReg(SrcReg, ARM64::ssub, &ARM64::FPR128RegClass);
-    BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
-        SrcReg, getKillRegState(KillSrc));
+    if(getSubTarget().hasNEON()) {
+      DestReg =
+          RI.getMatchingSuperReg(DestReg, ARM64::ssub, &ARM64::FPR128RegClass);
+      SrcReg =
+          RI.getMatchingSuperReg(SrcReg, ARM64::ssub, &ARM64::FPR128RegClass);
+      BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
+          SrcReg, getKillRegState(KillSrc));
+    } else {
+      BuildMI(MBB, I, DL, get(ARM64::FMOVSr), DestReg)
+          .addReg(SrcReg, getKillRegState(KillSrc));
+    }
     return;
   }
 
   if (ARM64::FPR16RegClass.contains(DestReg) &&
       ARM64::FPR16RegClass.contains(SrcReg)) {
-    DestReg =
-        RI.getMatchingSuperReg(DestReg, ARM64::hsub, &ARM64::FPR128RegClass);
-    SrcReg =
-        RI.getMatchingSuperReg(SrcReg, ARM64::hsub, &ARM64::FPR128RegClass);
-    BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
-        SrcReg, getKillRegState(KillSrc));
+    if(getSubTarget().hasNEON()) {
+      DestReg =
+          RI.getMatchingSuperReg(DestReg, ARM64::hsub, &ARM64::FPR128RegClass);
+      SrcReg =
+          RI.getMatchingSuperReg(SrcReg, ARM64::hsub, &ARM64::FPR128RegClass);
+      BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
+          SrcReg, getKillRegState(KillSrc));
+    } else {
+      DestReg =
+          RI.getMatchingSuperReg(DestReg, ARM64::hsub, &ARM64::FPR32RegClass);
+      SrcReg =
+          RI.getMatchingSuperReg(SrcReg, ARM64::hsub, &ARM64::FPR32RegClass);
+      BuildMI(MBB, I, DL, get(ARM64::FMOVSr), DestReg)
+          .addReg(SrcReg, getKillRegState(KillSrc));
+    }
     return;
   }
 
   if (ARM64::FPR8RegClass.contains(DestReg) &&
       ARM64::FPR8RegClass.contains(SrcReg)) {
-    DestReg =
-        RI.getMatchingSuperReg(DestReg, ARM64::bsub, &ARM64::FPR128RegClass);
-    SrcReg =
-        RI.getMatchingSuperReg(SrcReg, ARM64::bsub, &ARM64::FPR128RegClass);
-    BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
-        SrcReg, getKillRegState(KillSrc));
+    if(getSubTarget().hasNEON()) {
+      DestReg =
+          RI.getMatchingSuperReg(DestReg, ARM64::bsub, &ARM64::FPR128RegClass);
+      SrcReg =
+          RI.getMatchingSuperReg(SrcReg, ARM64::bsub, &ARM64::FPR128RegClass);
+      BuildMI(MBB, I, DL, get(ARM64::ORRv16i8), DestReg).addReg(SrcReg).addReg(
+          SrcReg, getKillRegState(KillSrc));
+    } else {
+      DestReg =
+          RI.getMatchingSuperReg(DestReg, ARM64::bsub, &ARM64::FPR32RegClass);
+      SrcReg =
+          RI.getMatchingSuperReg(SrcReg, ARM64::bsub, &ARM64::FPR32RegClass);
+      BuildMI(MBB, I, DL, get(ARM64::FMOVSr), DestReg)
+          .addReg(SrcReg, getKillRegState(KillSrc));
+    }
     return;
   }
 
@@ -1389,26 +1430,43 @@ void ARM64InstrInfo::storeRegToStackSlot
   case 16:
     if (ARM64::FPR128RegClass.hasSubClassEq(RC))
       Opc = ARM64::STRQui;
-    else if (ARM64::DDRegClass.hasSubClassEq(RC))
+    else if (ARM64::DDRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register store without NEON");
       Opc = ARM64::ST1Twov1d, Offset = false;
+    }
     break;
   case 24:
-    if (ARM64::DDDRegClass.hasSubClassEq(RC))
+    if (ARM64::DDDRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register store without NEON");
       Opc = ARM64::ST1Threev1d, Offset = false;
+    }
     break;
   case 32:
-    if (ARM64::DDDDRegClass.hasSubClassEq(RC))
+    if (ARM64::DDDDRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register store without NEON");
       Opc = ARM64::ST1Fourv1d, Offset = false;
-    else if (ARM64::QQRegClass.hasSubClassEq(RC))
+    } else if (ARM64::QQRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register store without NEON");
       Opc = ARM64::ST1Twov2d, Offset = false;
+    }
     break;
   case 48:
-    if (ARM64::QQQRegClass.hasSubClassEq(RC))
+    if (ARM64::QQQRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register store without NEON");
       Opc = ARM64::ST1Threev2d, Offset = false;
+    }
     break;
   case 64:
-    if (ARM64::QQQQRegClass.hasSubClassEq(RC))
+    if (ARM64::QQQQRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register store without NEON");
       Opc = ARM64::ST1Fourv2d, Offset = false;
+    }
     break;
   }
   assert(Opc && "Unknown register class");
@@ -1471,26 +1529,43 @@ void ARM64InstrInfo::loadRegFromStackSlo
   case 16:
     if (ARM64::FPR128RegClass.hasSubClassEq(RC))
       Opc = ARM64::LDRQui;
-    else if (ARM64::DDRegClass.hasSubClassEq(RC))
+    else if (ARM64::DDRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register load without NEON");
       Opc = ARM64::LD1Twov1d, Offset = false;
+    }
     break;
   case 24:
-    if (ARM64::DDDRegClass.hasSubClassEq(RC))
+    if (ARM64::DDDRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register load without NEON");
       Opc = ARM64::LD1Threev1d, Offset = false;
+    }
     break;
   case 32:
-    if (ARM64::DDDDRegClass.hasSubClassEq(RC))
+    if (ARM64::DDDDRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register load without NEON");
       Opc = ARM64::LD1Fourv1d, Offset = false;
-    else if (ARM64::QQRegClass.hasSubClassEq(RC))
+    } else if (ARM64::QQRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register load without NEON");
       Opc = ARM64::LD1Twov2d, Offset = false;
+    }
     break;
   case 48:
-    if (ARM64::QQQRegClass.hasSubClassEq(RC))
+    if (ARM64::QQQRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register load without NEON");
       Opc = ARM64::LD1Threev2d, Offset = false;
+    }
     break;
   case 64:
-    if (ARM64::QQQQRegClass.hasSubClassEq(RC))
+    if (ARM64::QQQQRegClass.hasSubClassEq(RC)) {
+      assert(getSubTarget().hasNEON() &&
+             "Unexpected register load without NEON");
       Opc = ARM64::LD1Fourv2d, Offset = false;
+    }
     break;
   }
   assert(Opc && "Unknown register class");

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.h Wed Apr 23 01:22:48 2014
@@ -44,6 +44,8 @@ public:
   /// always be able to get register info as well (through this method).
   const ARM64RegisterInfo &getRegisterInfo() const { return RI; }
 
+  const ARM64Subtarget &getSubTarget() const { return Subtarget; }
+
   unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
 
   bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg,

Modified: llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64InstrInfo.td Wed Apr 23 01:22:48 2014
@@ -12,6 +12,16 @@
 //===----------------------------------------------------------------------===//
 
 //===----------------------------------------------------------------------===//
+// ARM Instruction Predicate Definitions.
+//
+def HasFPARMv8       : Predicate<"Subtarget->hasFPARMv8()">,
+                               AssemblerPredicate<"FeatureFPARMv8", "fp-armv8">;
+def HasNEON          : Predicate<"Subtarget->hasNEON()">,
+                                 AssemblerPredicate<"FeatureNEON", "neon">;
+def HasCrypto          : Predicate<"Subtarget->hasCrypto()">,
+                                 AssemblerPredicate<"FeatureCrypto", "crypto">;
+
+//===----------------------------------------------------------------------===//
 // ARM64-specific DAG Nodes.
 //
 

Modified: llvm/trunk/lib/Target/ARM64/ARM64TargetTransformInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64TargetTransformInfo.cpp?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64TargetTransformInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64TargetTransformInfo.cpp Wed Apr 23 01:22:48 2014
@@ -87,16 +87,20 @@ public:
   /// @{
 
   unsigned getNumberOfRegisters(bool Vector) const override {
-    if (Vector)
-      return 32;
-
+    if (Vector) {
+      if (ST->hasNEON())
+        return 32;
+      return 0;
+    }
     return 31;
   }
 
   unsigned getRegisterBitWidth(bool Vector) const override {
-    if (Vector)
-      return 128;
-
+    if (Vector) {
+      if (ST->hasNEON())
+        return 128;
+      return 0;
+    }
     return 64;
   }
 

Modified: llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp Wed Apr 23 01:22:48 2014
@@ -107,6 +107,9 @@ public:
                  const MCInstrInfo &MII)
       : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
     MCAsmParserExtension::Initialize(_Parser);
+
+    // Initialize the set of available features.
+    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
   }
 
   virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
@@ -3815,6 +3818,8 @@ bool ARM64AsmParser::showMatchError(SMLo
   }
 }
 
+static const char *getSubtargetFeatureName(unsigned Val);
+
 bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                              OperandVector &Operands,
                                              MCStreamer &Out,
@@ -4247,7 +4252,21 @@ bool ARM64AsmParser::MatchAndEmitInstruc
     Out.EmitInstruction(Inst, STI);
     return false;
   }
-  case Match_MissingFeature:
+  case Match_MissingFeature: {
+    assert(ErrorInfo && "Unknown missing feature!");
+    // Special case the error message for the very common case where only
+    // a single subtarget feature is missing (neon, e.g.).
+    std::string Msg = "instruction requires:";
+    unsigned Mask = 1;
+    for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
+      if (ErrorInfo & Mask) {
+        Msg += " ";
+        Msg += getSubtargetFeatureName(ErrorInfo & Mask);
+      }
+      Mask <<= 1;
+    }
+    return Error(IDLoc, Msg);
+  }
   case Match_MnemonicFail:
     return showMatchError(IDLoc, MatchResult);
   case Match_InvalidOperand: {
@@ -4494,6 +4513,7 @@ extern "C" void LLVMInitializeARM64AsmPa
 }
 
 #define GET_REGISTER_MATCHER
+#define GET_SUBTARGET_FEATURE_NAME
 #define GET_MATCHER_IMPLEMENTATION
 #include "ARM64GenAsmMatcher.inc"
 

Added: llvm/trunk/test/CodeGen/ARM64/complex-copy-noneon.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/complex-copy-noneon.ll?rev=206949&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM64/complex-copy-noneon.ll (added)
+++ llvm/trunk/test/CodeGen/ARM64/complex-copy-noneon.ll Wed Apr 23 01:22:48 2014
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple=arm64-none-linux-gnu -mattr=-neon < %s
+
+; The DAG combiner decided to use a vector load/store for this struct copy
+; previously. This probably shouldn't happen without NEON, but the most
+; important thing is that it compiles.
+
+define void @store_combine() nounwind {
+  %src = alloca { double, double }, align 8
+  %dst = alloca { double, double }, align 8
+
+  %src.realp = getelementptr inbounds { double, double }* %src, i32 0, i32 0
+  %src.real = load double* %src.realp
+  %src.imagp = getelementptr inbounds { double, double }* %src, i32 0, i32 1
+  %src.imag = load double* %src.imagp
+
+  %dst.realp = getelementptr inbounds { double, double }* %dst, i32 0, i32 0
+  %dst.imagp = getelementptr inbounds { double, double }* %dst, i32 0, i32 1
+  store double %src.real, double* %dst.realp
+  store double %src.imag, double* %dst.imagp
+  ret void
+}

Modified: llvm/trunk/test/CodeGen/ARM64/crypto.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/crypto.ll?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM64/crypto.ll (original)
+++ llvm/trunk/test/CodeGen/ARM64/crypto.ll Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-; RUN: llc -march=arm64 -arm64-neon-syntax=apple -o - %s | FileCheck %s
+; RUN: llc -march=arm64 -mattr=crypto -arm64-neon-syntax=apple -o - %s | FileCheck %s
 
 declare <16 x i8> @llvm.arm64.crypto.aese(<16 x i8> %data, <16 x i8> %key)
 declare <16 x i8> @llvm.arm64.crypto.aesd(<16 x i8> %data, <16 x i8> %key)

Added: llvm/trunk/test/CodeGen/ARM64/reg-copy-noneon.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/reg-copy-noneon.ll?rev=206949&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM64/reg-copy-noneon.ll (added)
+++ llvm/trunk/test/CodeGen/ARM64/reg-copy-noneon.ll Wed Apr 23 01:22:48 2014
@@ -0,0 +1,20 @@
+; RUN: llc -mtriple=arm64-none-linux-gnu -mattr=-neon < %s | FileCheck %s
+
+define float @copy_FPR32(float %a, float %b) {
+;CHECK-LABEL: copy_FPR32:
+;CHECK: fmov s0, s1
+  ret float %b;
+}
+  
+define double @copy_FPR64(double %a, double %b) {
+;CHECK-LABEL: copy_FPR64:
+;CHECK: fmov d0, d1
+  ret double %b;
+}
+  
+define fp128 @copy_FPR128(fp128 %a, fp128 %b) {
+;CHECK-LABEL: copy_FPR128:
+;CHECK: str	q1, [sp, #-16]!
+;CHECK-NEXT: ldr	q0, [sp, #16]!
+  ret fp128 %b;
+}

Modified: llvm/trunk/test/MC/ARM64/advsimd.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/advsimd.s?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/advsimd.s (original)
+++ llvm/trunk/test/MC/ARM64/advsimd.s Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-; RUN: llvm-mc -triple arm64-apple-darwin -output-asm-variant=1 -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -triple arm64-apple-darwin -mattr=crypto -output-asm-variant=1 -show-encoding < %s | FileCheck %s
 
 foo:
 

Modified: llvm/trunk/test/MC/ARM64/aliases.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/aliases.s?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/aliases.s (original)
+++ llvm/trunk/test/MC/ARM64/aliases.s Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-; RUN: llvm-mc -triple arm64-apple-darwin -output-asm-variant=1 -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -triple arm64-apple-darwin -mattr=neon -output-asm-variant=1 -show-encoding < %s | FileCheck %s
 
 foo:
 ;-----------------------------------------------------------------------------

Modified: llvm/trunk/test/MC/ARM64/arithmetic-encoding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/arithmetic-encoding.s?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/arithmetic-encoding.s (original)
+++ llvm/trunk/test/MC/ARM64/arithmetic-encoding.s Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-; RUN: llvm-mc -triple arm64-apple-darwin -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -triple arm64-apple-darwin -mattr=neon -show-encoding < %s | FileCheck %s
 
 foo:
 ;==---------------------------------------------------------------------------==

Modified: llvm/trunk/test/MC/ARM64/crypto.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/crypto.s?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/crypto.s (original)
+++ llvm/trunk/test/MC/ARM64/crypto.s Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-; RUN: llvm-mc -triple arm64-apple-darwin -show-encoding -output-asm-variant=1 < %s | FileCheck %s
+; RUN: llvm-mc -triple arm64-apple-darwin -mattr=crypto -show-encoding -output-asm-variant=1 < %s | FileCheck %s
 
 foo:
   aese.16b v0, v1

Added: llvm/trunk/test/MC/ARM64/diagno-predicate.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/diagno-predicate.s?rev=206949&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM64/diagno-predicate.s (added)
+++ llvm/trunk/test/MC/ARM64/diagno-predicate.s Wed Apr 23 01:22:48 2014
@@ -0,0 +1,19 @@
+// RUN: not llvm-mc  -triple arm64-linux-gnu -mattr=-fp-armv8 < %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-ERROR < %t %s
+
+
+        fcvt d0, s0
+// CHECK-ERROR: error: instruction requires: fp-armv8
+// CHECK-ERROR-NEXT:        fcvt d0, s0
+// CHECK-ERROR-NEXT:        ^
+
+        fmla v9.2s, v9.2s, v0.2s
+// CHECK-ERROR: error: instruction requires: neon
+// CHECK-ERROR-NEXT:        fmla v9.2s, v9.2s, v0.2s
+// CHECK-ERROR-NEXT:        ^
+
+        pmull v0.1q, v1.1d, v2.1d
+// CHECK-ERROR: error: instruction requires: crypto
+// CHECK-ERROR-NEXT:        pmull v0.1q, v1.1d, v2.1d
+// CHECK-ERROR-NEXT:        ^
+

Modified: llvm/trunk/test/MC/ARM64/fp-encoding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/fp-encoding.s?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/fp-encoding.s (original)
+++ llvm/trunk/test/MC/ARM64/fp-encoding.s Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-; RUN: llvm-mc -triple arm64-apple-darwin -show-encoding -output-asm-variant=1 < %s | FileCheck %s
+; RUN: llvm-mc -triple arm64-apple-darwin -mattr=neon -show-encoding -output-asm-variant=1 < %s | FileCheck %s
 
 foo:
 ;-----------------------------------------------------------------------------

Modified: llvm/trunk/test/MC/ARM64/nv-cond.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/nv-cond.s?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/nv-cond.s (original)
+++ llvm/trunk/test/MC/ARM64/nv-cond.s Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-// RUN: llvm-mc < %s -triple arm64 -show-encoding | FileCheck %s
+// RUN: llvm-mc < %s -triple arm64 -mattr=neon -show-encoding | FileCheck %s
 
 fcsel d28,d31,d31,nv
 csel x0,x0,x0,nv

Modified: llvm/trunk/test/MC/ARM64/simd-ldst.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/simd-ldst.s?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/simd-ldst.s (original)
+++ llvm/trunk/test/MC/ARM64/simd-ldst.s Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-; RUN: llvm-mc -triple arm64-apple-darwin -output-asm-variant=1 -show-encoding < %s | FileCheck %s
+; RUN: llvm-mc -triple arm64-apple-darwin -mattr=neon -output-asm-variant=1 -show-encoding < %s | FileCheck %s
 
 _ld1st1_multiple:
   ld1.8b {v0}, [x1]

Modified: llvm/trunk/test/MC/ARM64/vector-lists.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/vector-lists.s?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/vector-lists.s (original)
+++ llvm/trunk/test/MC/ARM64/vector-lists.s Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-// RUN: not llvm-mc -triple arm64 -show-encoding < %s 2>%t | FileCheck %s
+// RUN: not llvm-mc -triple arm64 -mattr=neon -show-encoding < %s 2>%t | FileCheck %s
 // RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
 
     ST4     {v0.8B-v3.8B}, [x0]

Modified: llvm/trunk/test/MC/ARM64/verbose-vector-case.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM64/verbose-vector-case.s?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM64/verbose-vector-case.s (original)
+++ llvm/trunk/test/MC/ARM64/verbose-vector-case.s Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-// RUN: llvm-mc -triple arm64 -show-encoding < %s | FileCheck %s
+// RUN: llvm-mc -triple arm64 -mattr=crypto -show-encoding < %s | FileCheck %s
 
 pmull v8.8h, v8.8b, v8.8b
 pmull2 v8.8h, v8.16b, v8.16b

Modified: llvm/trunk/test/MC/Disassembler/ARM64/advsimd.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM64/advsimd.txt?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM64/advsimd.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM64/advsimd.txt Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -triple arm64-apple-darwin -output-asm-variant=1 --disassemble < %s | FileCheck %s
+# RUN: llvm-mc -triple arm64-apple-darwin -mattr=crypto -output-asm-variant=1 --disassemble < %s | FileCheck %s
 
 0x00 0xb8 0x20 0x0e
 0x00 0xb8 0x20 0x4e

Modified: llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM64/canonical-form.txt Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -triple arm64-apple-darwin --disassemble < %s | FileCheck %s
+# RUN: llvm-mc -triple arm64-apple-darwin -mattr=neon --disassemble < %s | FileCheck %s
 
 0x00 0x08 0x00 0xc8
 

Modified: llvm/trunk/test/MC/Disassembler/ARM64/crypto.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM64/crypto.txt?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM64/crypto.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM64/crypto.txt Wed Apr 23 01:22:48 2014
@@ -1,5 +1,5 @@
-# RUN: llvm-mc -triple arm64-apple-darwin --disassemble < %s | FileCheck %s
-# RUN: llvm-mc -triple arm64-apple-darwin -output-asm-variant=1 --disassemble < %s | FileCheck %s --check-prefix=CHECK-APPLE
+# RUN: llvm-mc -triple arm64-apple-darwin -mattr=crypto --disassemble < %s | FileCheck %s
+# RUN: llvm-mc -triple arm64-apple-darwin -mattr=crypto -output-asm-variant=1 --disassemble < %s | FileCheck %s --check-prefix=CHECK-APPLE
 
   0x20 0x48 0x28 0x4e
   0x20 0x58 0x28 0x4e

Modified: llvm/trunk/test/MC/Disassembler/ARM64/non-apple-fmov.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM64/non-apple-fmov.txt?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM64/non-apple-fmov.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM64/non-apple-fmov.txt Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -triple arm64 -disassemble < %s | FileCheck %s
+# RUN: llvm-mc -triple arm64 -mattr=neon -disassemble < %s | FileCheck %s
 
 0x00 0x00 0xae 0x9e
 0x00 0x00 0xaf 0x9e

Modified: llvm/trunk/test/MC/Disassembler/ARM64/scalar-fp.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM64/scalar-fp.txt?rev=206949&r1=206948&r2=206949&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM64/scalar-fp.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARM64/scalar-fp.txt Wed Apr 23 01:22:48 2014
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -triple arm64-apple-darwin --disassemble -output-asm-variant=1 < %s | FileCheck %s
+# RUN: llvm-mc -triple arm64-apple-darwin -mattr=neon --disassemble -output-asm-variant=1 < %s | FileCheck %s
 
 #-----------------------------------------------------------------------------
 # Floating-point arithmetic





More information about the llvm-commits mailing list