Create hwintrinsic.cpp
authorSteve MacLean <sdmaclea.qdt@qualcommdatacenter.com>
Tue, 30 Jan 2018 01:59:59 +0000 (20:59 -0500)
committerSteve MacLean <sdmaclea.qdt@qualcommdatacenter.com>
Tue, 30 Jan 2018 19:42:55 +0000 (14:42 -0500)
src/jit/CMakeLists.txt
src/jit/compiler.h
src/jit/hwintrinsic.cpp [new file with mode: 0644]
src/jit/hwintrinsicArm64.cpp
src/jit/hwintrinsicxarch.cpp
src/jit/importer.cpp

index fa5bbc1..74380e6 100644 (file)
@@ -38,6 +38,7 @@ set( JIT_SOURCES
   gentree.cpp
   gschecks.cpp
   hashbv.cpp
+  hwintrinsic.cpp
   hostallocator.cpp
   importer.cpp
   inline.cpp
index aadd7fc..e612b94 100644 (file)
@@ -3044,20 +3044,20 @@ protected:
     NamedIntrinsic lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method);
 
 #ifdef FEATURE_HW_INTRINSICS
+    GenTree* impHWIntrinsic(NamedIntrinsic        intrinsic,
+                            CORINFO_METHOD_HANDLE method,
+                            CORINFO_SIG_INFO*     sig,
+                            bool                  mustExpand);
+    GenTree* impUnsupportedHWIntrinsic(unsigned              helper,
+                                       CORINFO_METHOD_HANDLE method,
+                                       CORINFO_SIG_INFO*     sig,
+                                       bool                  mustExpand);
 #ifdef _TARGET_XARCH_
     static InstructionSet lookupHWIntrinsicISA(const char* className);
     static NamedIntrinsic lookupHWIntrinsic(const char* methodName, InstructionSet isa);
     static InstructionSet isaOfHWIntrinsic(NamedIntrinsic intrinsic);
     static bool isIntrinsicAnIsSupportedPropertyGetter(NamedIntrinsic intrinsic);
     static bool isFullyImplmentedISAClass(InstructionSet isa);
-    GenTree* impUnsupportedHWIntrinsic(unsigned              helper,
-                                       CORINFO_METHOD_HANDLE method,
-                                       CORINFO_SIG_INFO*     sig,
-                                       bool                  mustExpand);
-    GenTree* impX86HWIntrinsic(NamedIntrinsic        intrinsic,
-                               CORINFO_METHOD_HANDLE method,
-                               CORINFO_SIG_INFO*     sig,
-                               bool                  mustExpand);
     GenTree* impSSEIntrinsic(NamedIntrinsic        intrinsic,
                              CORINFO_METHOD_HANDLE method,
                              CORINFO_SIG_INFO*     sig,
@@ -3131,14 +3131,6 @@ protected:
 #ifdef _TARGET_ARM64_
     InstructionSet lookupHWIntrinsicISA(const char* className);
     NamedIntrinsic lookupHWIntrinsic(const char* className, const char* methodName);
-    GenTree* impHWIntrinsic(NamedIntrinsic        intrinsic,
-                            CORINFO_METHOD_HANDLE method,
-                            CORINFO_SIG_INFO*     sig,
-                            bool                  mustExpand);
-    GenTree* impUnsupportedHWIntrinsic(unsigned              helper,
-                                       CORINFO_METHOD_HANDLE method,
-                                       CORINFO_SIG_INFO*     sig,
-                                       bool                  mustExpand);
     const HWIntrinsicInfo& getHWIntrinsicInfo(NamedIntrinsic);
 #endif // _TARGET_ARM64_
 #endif // FEATURE_HW_INTRINSICS
diff --git a/src/jit/hwintrinsic.cpp b/src/jit/hwintrinsic.cpp
new file mode 100644 (file)
index 0000000..e3b36d9
--- /dev/null
@@ -0,0 +1,141 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "jitpch.h"
+
+#ifdef FEATURE_HW_INTRINSICS
+
+//------------------------------------------------------------------------
+// impUnsupportedHWIntrinsic: returns a node for an unsupported HWIntrinsic
+//
+// Arguments:
+//    helper     - JIT helper ID for the exception to be thrown
+//    method     - method handle of the intrinsic function.
+//    sig        - signature of the intrinsic call
+//    mustExpand - true if the intrinsic must return a GenTree*; otherwise, false
+//
+// Return Value:
+//    a gtNewMustThrowException if mustExpand is true; otherwise, nullptr
+//
+GenTree* Compiler::impUnsupportedHWIntrinsic(unsigned              helper,
+                                             CORINFO_METHOD_HANDLE method,
+                                             CORINFO_SIG_INFO*     sig,
+                                             bool                  mustExpand)
+{
+    // We've hit some error case and may need to return a node for the given error.
+    //
+    // When `mustExpand=false`, we are attempting to inline the intrinsic directly into another method. In this
+    // scenario, we need to return `nullptr` so that a GT_CALL to the intrinsic is emitted instead. This is to
+    // ensure that everything continues to behave correctly when optimizations are enabled (e.g. things like the
+    // inliner may expect the node we return to have a certain signature, and the `MustThrowException` node won't
+    // match that).
+    //
+    // When `mustExpand=true`, we are in a GT_CALL to the intrinsic and are attempting to JIT it. This will generally
+    // be in response to an indirect call (e.g. done via reflection) or in response to an earlier attempt returning
+    // `nullptr` (under `mustExpand=false`). In that scenario, we are safe to return the `MustThrowException` node.
+
+    if (mustExpand)
+    {
+        for (unsigned i = 0; i < sig->numArgs; i++)
+        {
+            impPopStack();
+        }
+
+        return gtNewMustThrowException(helper, JITtype2varType(sig->retType), sig->retTypeClass);
+    }
+    else
+    {
+        return nullptr;
+    }
+}
+
+CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, var_types simdBaseType)
+{
+    if (simdType == TYP_SIMD16)
+    {
+        switch (simdBaseType)
+        {
+            case TYP_FLOAT:
+                return Vector128FloatHandle;
+            case TYP_DOUBLE:
+                return Vector128DoubleHandle;
+            case TYP_INT:
+                return Vector128IntHandle;
+            case TYP_USHORT:
+                return Vector128UShortHandle;
+            case TYP_UBYTE:
+                return Vector128UByteHandle;
+            case TYP_SHORT:
+                return Vector128ShortHandle;
+            case TYP_BYTE:
+                return Vector128ByteHandle;
+            case TYP_LONG:
+                return Vector128LongHandle;
+            case TYP_UINT:
+                return Vector128UIntHandle;
+            case TYP_ULONG:
+                return Vector128ULongHandle;
+            default:
+                assert(!"Didn't find a class handle for simdType");
+        }
+    }
+#ifdef _TARGET_XARCH_
+    else if (simdType == TYP_SIMD32)
+    {
+        switch (simdBaseType)
+        {
+            case TYP_FLOAT:
+                return Vector256FloatHandle;
+            case TYP_DOUBLE:
+                return Vector256DoubleHandle;
+            case TYP_INT:
+                return Vector256IntHandle;
+            case TYP_USHORT:
+                return Vector256UShortHandle;
+            case TYP_UBYTE:
+                return Vector256UByteHandle;
+            case TYP_SHORT:
+                return Vector256ShortHandle;
+            case TYP_BYTE:
+                return Vector256ByteHandle;
+            case TYP_LONG:
+                return Vector256LongHandle;
+            case TYP_UINT:
+                return Vector256UIntHandle;
+            case TYP_ULONG:
+                return Vector256ULongHandle;
+            default:
+                assert(!"Didn't find a class handle for simdType");
+        }
+    }
+#endif // _TARGET_XARCH_
+#ifdef _TARGET_ARM64_
+    else if (simdType == TYP_SIMD8)
+    {
+        switch (simdBaseType)
+        {
+            case TYP_FLOAT:
+                return Vector64FloatHandle;
+            case TYP_UINT:
+                return Vector64UIntHandle;
+            case TYP_USHORT:
+                return Vector64UShortHandle;
+            case TYP_UBYTE:
+                return Vector64UByteHandle;
+            case TYP_SHORT:
+                return Vector64ShortHandle;
+            case TYP_BYTE:
+                return Vector64ByteHandle;
+            case TYP_INT:
+                return Vector64IntHandle;
+            default:
+                assert(!"Didn't find a class handle for simdType");
+        }
+    }
+#endif // _TARGET_ARM64_
+
+    return NO_CLASS_HANDLE;
+}
+
+#endif // FEATURE_HW_INTRINSICS
index 3a49ff9..5aa5aba 100644 (file)
@@ -126,50 +126,6 @@ NamedIntrinsic Compiler::lookupHWIntrinsic(const char* className, const char* me
 }
 
 //------------------------------------------------------------------------
-// impUnsupportedHWIntrinsic: returns a node for an unsupported HWIntrinsic
-//
-// Arguments:
-//    helper     - JIT helper ID for the exception to be thrown
-//    method     - method handle of the intrinsic function.
-//    sig        - signature of the intrinsic call
-//    mustExpand - true if the intrinsic must return a GenTree*; otherwise, false
-//
-// Return Value:
-//    a gtNewMustThrowException if mustExpand is true; otherwise, nullptr
-//
-GenTree* Compiler::impUnsupportedHWIntrinsic(unsigned              helper,
-                                             CORINFO_METHOD_HANDLE method,
-                                             CORINFO_SIG_INFO*     sig,
-                                             bool                  mustExpand)
-{
-    // We've hit some error case and may need to return a node for the given error.
-    //
-    // When `mustExpand=false`, we are attempting to inline the intrinsic directly into another method. In this
-    // scenario, we need to return `nullptr` so that a GT_CALL to the intrinsic is emitted instead. This is to
-    // ensure that everything continues to behave correctly when optimizations are enabled (e.g. things like the
-    // inliner may expect the node we return to have a certain signature, and the `MustThrowException` node won't
-    // match that).
-    //
-    // When `mustExpand=true`, we are in a GT_CALL to the intrinsic and are attempting to JIT it. This will generally
-    // be in response to an indirect call (e.g. done via reflection) or in response to an earlier attempt returning
-    // `nullptr` (under `mustExpand=false`). In that scenario, we are safe to return the `MustThrowException` node.
-
-    if (mustExpand)
-    {
-        for (unsigned i = 0; i < sig->numArgs; i++)
-        {
-            impPopStack();
-        }
-
-        return gtNewMustThrowException(helper, JITtype2varType(sig->retType), sig->retTypeClass);
-    }
-    else
-    {
-        return nullptr;
-    }
-}
-
-//------------------------------------------------------------------------
 // impHWIntrinsic: dispatch hardware intrinsics to their own implementation
 // function
 //
@@ -243,60 +199,4 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic        intrinsic,
     return retNode;
 }
 
-CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, var_types simdBaseType)
-{
-    if (simdType == TYP_SIMD16)
-    {
-        switch (simdBaseType)
-        {
-            case TYP_FLOAT:
-                return Vector128FloatHandle;
-            case TYP_DOUBLE:
-                return Vector128DoubleHandle;
-            case TYP_INT:
-                return Vector128IntHandle;
-            case TYP_USHORT:
-                return Vector128UShortHandle;
-            case TYP_UBYTE:
-                return Vector128UByteHandle;
-            case TYP_SHORT:
-                return Vector128ShortHandle;
-            case TYP_BYTE:
-                return Vector128ByteHandle;
-            case TYP_LONG:
-                return Vector128LongHandle;
-            case TYP_UINT:
-                return Vector128UIntHandle;
-            case TYP_ULONG:
-                return Vector128ULongHandle;
-            default:
-                assert(!"Didn't find a class handle for simdType");
-        }
-    }
-    else if (simdType == TYP_SIMD8)
-    {
-        switch (simdBaseType)
-        {
-            case TYP_FLOAT:
-                return Vector64FloatHandle;
-            case TYP_UINT:
-                return Vector64UIntHandle;
-            case TYP_USHORT:
-                return Vector64UShortHandle;
-            case TYP_UBYTE:
-                return Vector64UByteHandle;
-            case TYP_SHORT:
-                return Vector64ShortHandle;
-            case TYP_BYTE:
-                return Vector64ByteHandle;
-            case TYP_INT:
-                return Vector64IntHandle;
-            default:
-                assert(!"Didn't find a class handle for simdType");
-        }
-    }
-
-    return NO_CLASS_HANDLE;
-}
-
 #endif // FEATURE_HW_INTRINSICS
index 09e3c72..795fb98 100644 (file)
@@ -384,50 +384,6 @@ static bool isTypeSupportedForIntrinsic(var_types type)
 }
 
 //------------------------------------------------------------------------
-// impUnsupportedHWIntrinsic: returns a node for an unsupported HWIntrinsic
-//
-// Arguments:
-//    helper     - JIT helper ID for the exception to be thrown
-//    method     - method handle of the intrinsic function.
-//    sig        - signature of the intrinsic call
-//    mustExpand - true if the intrinsic must return a GenTree*; otherwise, false
-//
-// Return Value:
-//    a gtNewMustThrowException if mustExpand is true; otherwise, nullptr
-//
-GenTree* Compiler::impUnsupportedHWIntrinsic(unsigned              helper,
-                                             CORINFO_METHOD_HANDLE method,
-                                             CORINFO_SIG_INFO*     sig,
-                                             bool                  mustExpand)
-{
-    // We've hit some error case and may need to return a node for the given error.
-    //
-    // When `mustExpand=false`, we are attempting to inline the intrinsic directly into another method. In this
-    // scenario, we need to return `nullptr` so that a GT_CALL to the intrinsic is emitted instead. This is to
-    // ensure that everything continues to behave correctly when optimizations are enabled (e.g. things like the
-    // inliner may expect the node we return to have a certain signature, and the `MustThrowException` node won't
-    // match that).
-    //
-    // When `mustExpand=true`, we are in a GT_CALL to the intrinsic and are attempting to JIT it. This will generally
-    // be in response to an indirect call (e.g. done via reflection) or in response to an earlier attempt returning
-    // `nullptr` (under `mustExpand=false`). In that scenario, we are safe to return the `MustThrowException` node.
-
-    if (mustExpand)
-    {
-        for (unsigned i = 0; i < sig->numArgs; i++)
-        {
-            impPopStack();
-        }
-
-        return gtNewMustThrowException(helper, JITtype2varType(sig->retType), sig->retTypeClass);
-    }
-    else
-    {
-        return nullptr;
-    }
-}
-
-//------------------------------------------------------------------------
 // impIsTableDrivenHWIntrinsic:
 //
 // Arguments:
@@ -443,7 +399,7 @@ static bool impIsTableDrivenHWIntrinsic(HWIntrinsicCategory category, HWIntrinsi
 }
 
 //------------------------------------------------------------------------
-// impX86HWIntrinsic: dispatch hardware intrinsics to their own implementation
+// impHWIntrinsic: dispatch hardware intrinsics to their own implementation
 //
 // Arguments:
 //    intrinsic -- id of the intrinsic function.
@@ -453,10 +409,10 @@ static bool impIsTableDrivenHWIntrinsic(HWIntrinsicCategory category, HWIntrinsi
 // Return Value:
 //    the expanded intrinsic.
 //
-GenTree* Compiler::impX86HWIntrinsic(NamedIntrinsic        intrinsic,
-                                     CORINFO_METHOD_HANDLE method,
-                                     CORINFO_SIG_INFO*     sig,
-                                     bool                  mustExpand)
+GenTree* Compiler::impHWIntrinsic(NamedIntrinsic        intrinsic,
+                                  CORINFO_METHOD_HANDLE method,
+                                  CORINFO_SIG_INFO*     sig,
+                                  bool                  mustExpand)
 {
     InstructionSet      isa      = isaOfHWIntrinsic(intrinsic);
     HWIntrinsicCategory category = categoryOfHWIntrinsic(intrinsic);
@@ -641,68 +597,6 @@ GenTree* Compiler::impX86HWIntrinsic(NamedIntrinsic        intrinsic,
     }
 }
 
-CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, var_types simdBaseType)
-{
-    if (simdType == TYP_SIMD16)
-    {
-        switch (simdBaseType)
-        {
-            case TYP_FLOAT:
-                return Vector128FloatHandle;
-            case TYP_DOUBLE:
-                return Vector128DoubleHandle;
-            case TYP_INT:
-                return Vector128IntHandle;
-            case TYP_USHORT:
-                return Vector128UShortHandle;
-            case TYP_UBYTE:
-                return Vector128UByteHandle;
-            case TYP_SHORT:
-                return Vector128ShortHandle;
-            case TYP_BYTE:
-                return Vector128ByteHandle;
-            case TYP_LONG:
-                return Vector128LongHandle;
-            case TYP_UINT:
-                return Vector128UIntHandle;
-            case TYP_ULONG:
-                return Vector128ULongHandle;
-            default:
-                assert(!"Didn't find a class handle for simdType");
-        }
-    }
-    else if (simdType == TYP_SIMD32)
-    {
-        switch (simdBaseType)
-        {
-            case TYP_FLOAT:
-                return Vector256FloatHandle;
-            case TYP_DOUBLE:
-                return Vector256DoubleHandle;
-            case TYP_INT:
-                return Vector256IntHandle;
-            case TYP_USHORT:
-                return Vector256UShortHandle;
-            case TYP_UBYTE:
-                return Vector256UByteHandle;
-            case TYP_SHORT:
-                return Vector256ShortHandle;
-            case TYP_BYTE:
-                return Vector256ByteHandle;
-            case TYP_LONG:
-                return Vector256LongHandle;
-            case TYP_UINT:
-                return Vector256UIntHandle;
-            case TYP_ULONG:
-                return Vector256ULongHandle;
-            default:
-                assert(!"Didn't find a class handle for simdType");
-        }
-    }
-
-    return NO_CLASS_HANDLE;
-}
-
 GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic        intrinsic,
                                    CORINFO_METHOD_HANDLE method,
                                    CORINFO_SIG_INFO*     sig,
index e242d3f..0c7b560 100644 (file)
@@ -3395,18 +3395,10 @@ GenTree* Compiler::impIntrinsic(GenTree*                newobjThis,
             ni = lookupNamedIntrinsic(method);
 
 #ifdef FEATURE_HW_INTRINSICS
-#ifdef _TARGET_XARCH_
-            if (ni > NI_HW_INTRINSIC_START && ni < NI_HW_INTRINSIC_END)
-            {
-                return impX86HWIntrinsic(ni, method, sig, mustExpand);
-            }
-#endif // _TARGET_XARCH_
-#ifdef _TARGET_ARM64_
             if (ni > NI_HW_INTRINSIC_START && ni < NI_HW_INTRINSIC_END)
             {
                 return impHWIntrinsic(ni, method, sig, mustExpand);
             }
-#endif // _TARGET_XARCH_
 #endif // FEATURE_HW_INTRINSICS
         }
     }