summaryrefslogtreecommitdiff
path: root/src/jit/simd.cpp
diff options
context:
space:
mode:
authorhelloguo <xiangyang.guo@intel.com>2017-04-03 10:28:09 -0700
committerhelloguo <xiangyang.guo@intel.com>2017-05-10 15:56:43 -0700
commit965d5eea7f9b2aac3e6bd5a2f0061b926b7c5f8c (patch)
treeb6e36f358042bff21c5673814507eea0604fa244 /src/jit/simd.cpp
parent377073385e4545d36e1a96429dd78548f87c597c (diff)
downloadcoreclr-965d5eea7f9b2aac3e6bd5a2f0061b926b7c5f8c.tar.gz
coreclr-965d5eea7f9b2aac3e6bd5a2f0061b926b7c5f8c.tar.bz2
coreclr-965d5eea7f9b2aac3e6bd5a2f0061b926b7c5f8c.zip
add jit intrinsic support for vector conversion/narrow/widen on AMD64 and x86, except double->long/ulong conversion on x86
Diffstat (limited to 'src/jit/simd.cpp')
-rw-r--r--src/jit/simd.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/jit/simd.cpp b/src/jit/simd.cpp
index 4ba7832cca..bbb9a57cc4 100644
--- a/src/jit/simd.cpp
+++ b/src/jit/simd.cpp
@@ -2609,6 +2609,10 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
// Unary operators that take and return a Vector.
case SIMDIntrinsicCast:
+ case SIMDIntrinsicConvertToSingle:
+ case SIMDIntrinsicConvertToDouble:
+ case SIMDIntrinsicConvertToInt32:
+ case SIMDIntrinsicConvertToUInt32:
{
op1 = impSIMDPopStack(simdType, instMethod);
@@ -2617,6 +2621,61 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
}
break;
+ case SIMDIntrinsicConvertToInt64:
+ case SIMDIntrinsicConvertToUInt64:
+ {
+#ifdef _TARGET_AMD64_
+ op1 = impSIMDPopStack(simdType, instMethod);
+
+ simdTree = gtNewSIMDNode(simdType, op1, nullptr, simdIntrinsicID, baseType, size);
+ retVal = simdTree;
+#else
+ JITDUMP("SIMD Conversion to Int64/UInt64 is not supported on this platform\n");
+ return nullptr;
+#endif
+ }
+ break;
+
+ case SIMDIntrinsicNarrow:
+ {
+ assert(!instMethod);
+ op2 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(simdType);
+ // op1 and op2 are two input Vector<T>.
+ simdTree = gtNewSIMDNode(simdType, op1, op2, simdIntrinsicID, baseType, size);
+ retVal = simdTree;
+ }
+ break;
+
+ case SIMDIntrinsicWiden:
+ {
+ GenTree* dstAddrHi = impSIMDPopStack(TYP_BYREF);
+ GenTree* dstAddrLo = impSIMDPopStack(TYP_BYREF);
+ op1 = impSIMDPopStack(simdType);
+ GenTree* dupOp1 = fgInsertCommaFormTemp(&op1, gtGetStructHandleForSIMD(simdType, baseType));
+
+ // Widen the lower half and assign it to dstAddrLo.
+ simdTree = gtNewSIMDNode(simdType, op1, nullptr, SIMDIntrinsicWidenLo, baseType, size);
+ GenTree* loDest =
+ new (this, GT_BLK) GenTreeBlk(GT_BLK, simdType, dstAddrLo, getSIMDTypeSizeInBytes(clsHnd));
+ GenTree* loAsg = gtNewBlkOpNode(loDest, simdTree, getSIMDTypeSizeInBytes(clsHnd),
+ false, // not volatile
+ true); // copyBlock
+ loAsg->gtFlags |= ((simdTree->gtFlags | dstAddrLo->gtFlags) & GTF_ALL_EFFECT);
+
+ // Widen the upper half and assign it to dstAddrHi.
+ simdTree = gtNewSIMDNode(simdType, dupOp1, nullptr, SIMDIntrinsicWidenHi, baseType, size);
+ GenTree* hiDest =
+ new (this, GT_BLK) GenTreeBlk(GT_BLK, simdType, dstAddrHi, getSIMDTypeSizeInBytes(clsHnd));
+ GenTree* hiAsg = gtNewBlkOpNode(hiDest, simdTree, getSIMDTypeSizeInBytes(clsHnd),
+ false, // not volatile
+ true); // copyBlock
+ hiAsg->gtFlags |= ((simdTree->gtFlags | dstAddrHi->gtFlags) & GTF_ALL_EFFECT);
+
+ retVal = gtNewOperNode(GT_COMMA, simdType, loAsg, hiAsg);
+ }
+ break;
+
case SIMDIntrinsicHWAccel:
{
GenTreeIntCon* intConstTree = new (this, GT_CNS_INT) GenTreeIntCon(TYP_INT, 1);