diff options
author | helloguo <xiangyang.guo@intel.com> | 2017-04-03 10:28:09 -0700 |
---|---|---|
committer | helloguo <xiangyang.guo@intel.com> | 2017-05-10 15:56:43 -0700 |
commit | 965d5eea7f9b2aac3e6bd5a2f0061b926b7c5f8c (patch) | |
tree | b6e36f358042bff21c5673814507eea0604fa244 /src/jit/simd.cpp | |
parent | 377073385e4545d36e1a96429dd78548f87c597c (diff) | |
download | coreclr-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.cpp | 59 |
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); |