Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/coreclr/jit/codegenxarch.cpp')
-rw-r--r--src/coreclr/jit/codegenxarch.cpp79
1 files changed, 75 insertions, 4 deletions
diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp
index b16d2d221a7..6d632942647 100644
--- a/src/coreclr/jit/codegenxarch.cpp
+++ b/src/coreclr/jit/codegenxarch.cpp
@@ -5282,10 +5282,81 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
}
else
{
- GetEmitter()->emitInsStoreInd(data->OperIs(GT_BSWAP, GT_BSWAP16) && data->isContained()
- ? INS_movbe
- : ins_Store(data->TypeGet()),
- emitTypeSize(tree), tree);
+ instruction ins = INS_invalid;
+ emitAttr attr = emitTypeSize(tree);
+
+ if (data->isContained())
+ {
+ if (data->OperIs(GT_BSWAP, GT_BSWAP16))
+ {
+ ins = INS_movbe;
+ }
+#if defined(FEATURE_HW_INTRINSICS)
+ else if (data->OperIsHWIntrinsic())
+ {
+ GenTreeHWIntrinsic* hwintrinsic = data->AsHWIntrinsic();
+ NamedIntrinsic intrinsicId = hwintrinsic->GetHWIntrinsicId();
+ var_types baseType = hwintrinsic->GetSimdBaseType();
+
+ switch (intrinsicId)
+ {
+ case NI_SSE2_ConvertToInt32:
+ case NI_SSE2_ConvertToUInt32:
+ case NI_SSE2_X64_ConvertToInt64:
+ case NI_SSE2_X64_ConvertToUInt64:
+ case NI_AVX2_ConvertToInt32:
+ case NI_AVX2_ConvertToUInt32:
+ {
+ // These intrinsics are "ins reg/mem, xmm"
+ ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType);
+ attr = emitActualTypeSize(baseType);
+ break;
+ }
+
+ case NI_SSE2_Extract:
+ case NI_SSE41_Extract:
+ case NI_SSE41_X64_Extract:
+ case NI_AVX_ExtractVector128:
+ case NI_AVX2_ExtractVector128:
+ {
+ // These intrinsics are "ins reg/mem, xmm, imm8"
+ ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType);
+ attr = emitActualTypeSize(Compiler::getSIMDTypeForSize(hwintrinsic->GetSimdSize()));
+
+ if (intrinsicId == NI_SSE2_Extract)
+ {
+ // The encoding that supports containment is SSE4.1 only
+ ins = INS_pextrw_sse41;
+ }
+
+ // The hardware intrinsics take unsigned bytes between [0, 255].
+ // However, the emitter expects "fits in byte" to always be signed
+ // and therefore we need [128, 255] to be sign extended up to fill
+ // the entire constant value.
+
+ GenTreeIntCon* op2 = hwintrinsic->Op(2)->AsIntCon();
+ ssize_t ival = op2->IconValue();
+
+ assert((ival >= 0) && (ival <= 255));
+ op2->gtIconVal = static_cast<int8_t>(ival);
+ break;
+ }
+
+ default:
+ {
+ unreached();
+ }
+ }
+ }
+#endif // FEATURE_HW_INTRINSICS
+ }
+
+ if (ins == INS_invalid)
+ {
+ ins = ins_Store(data->TypeGet());
+ }
+
+ GetEmitter()->emitInsStoreInd(ins, attr, tree);
}
}
}