[Arm64] Implement Simd.SetAllVector*
authorSteve MacLean <sdmaclea.qdt@qualcommdatacenter.com>
Wed, 31 Jan 2018 17:48:13 +0000 (12:48 -0500)
committerTanner Gooding <tagoo@outlook.com>
Thu, 1 Feb 2018 15:14:04 +0000 (07:14 -0800)
src/jit/codegenarm64.cpp
src/jit/codegenlinear.h
src/jit/hwintrinsicArm64.cpp

index ce61de7..991b599 100644 (file)
@@ -4994,6 +4994,9 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
         case HWIntrinsicInfo::SimdSelectOp:
             genHWIntrinsicSimdSelectOp(node);
             break;
+        case HWIntrinsicInfo::SimdSetAllOp:
+            genHWIntrinsicSimdSetAllOp(node);
+            break;
         case HWIntrinsicInfo::SimdUnaryOp:
             genHWIntrinsicSimdUnaryOp(node);
             break;
@@ -5324,6 +5327,56 @@ void CodeGen::genHWIntrinsicSimdSelectOp(GenTreeHWIntrinsic* node)
     genProduceReg(node);
 }
 
+//------------------------------------------------------------------------
+// genHWIntrinsicSimdSetAllOp:
+//
+// Produce code for a GT_HWIntrinsic node with form SimdSetAllOp.
+//
+// Consumes single scalar operand and produces a SIMD result
+//
+// Arguments:
+//    node - the GT_HWIntrinsic node
+//
+// Return Value:
+//    None.
+//
+void CodeGen::genHWIntrinsicSimdSetAllOp(GenTreeHWIntrinsic* node)
+{
+    GenTree*  op1       = node->gtGetOp1();
+    var_types baseType  = node->gtSIMDBaseType;
+    regNumber targetReg = node->gtRegNum;
+
+    assert(targetReg != REG_NA);
+    var_types targetType = node->TypeGet();
+
+    genConsumeOperands(node);
+
+    regNumber op1Reg = op1->gtRegNum;
+
+    assert(genIsValidFloatReg(targetReg));
+    assert(genIsValidIntReg(op1Reg) || genIsValidFloatReg(op1Reg));
+
+    instruction ins = getOpForHWIntrinsic(node, baseType);
+    assert(ins != INS_invalid);
+
+    bool     is16Byte = (node->gtSIMDSize > 8);
+    emitAttr attr     = is16Byte ? EA_16BYTE : EA_8BYTE;
+    insOpts  opt      = genGetSimdInsOpt(is16Byte, baseType);
+
+    // TODO-ARM64-CQ Support contained immediate cases
+
+    if (genIsValidIntReg(op1Reg))
+    {
+        getEmitter()->emitIns_R_R(ins, attr, targetReg, op1Reg, opt);
+    }
+    else
+    {
+        getEmitter()->emitIns_R_R_I(ins, attr, targetReg, op1Reg, 0, opt);
+    }
+
+    genProduceReg(node);
+}
+
 void CodeGen::genHWIntrinsicSimdUnaryOp(GenTreeHWIntrinsic* node)
 {
     GenTree*  op1       = node->gtGetOp1();
index 5376eb2..3b37684 100644 (file)
@@ -143,6 +143,7 @@ void genHWIntrinsicSimdBinaryOp(GenTreeHWIntrinsic* node);
 void genHWIntrinsicSimdExtractOp(GenTreeHWIntrinsic* node);
 void genHWIntrinsicSimdInsertOp(GenTreeHWIntrinsic* node);
 void genHWIntrinsicSimdSelectOp(GenTreeHWIntrinsic* node);
+void genHWIntrinsicSimdSetAllOp(GenTreeHWIntrinsic* node);
 void genHWIntrinsicSimdUnaryOp(GenTreeHWIntrinsic* node);
 template <typename HWIntrinsicSwitchCaseBody>
 void genHWIntrinsicSwitchTable(regNumber swReg, regNumber tmpReg, int swMax, HWIntrinsicSwitchCaseBody emitSwCase);
index 1acf242..2bd1c4f 100644 (file)
@@ -163,6 +163,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic        intrinsic,
     {
         case HWIntrinsicInfo::SimdBinaryOp:
         case HWIntrinsicInfo::SimdSelectOp:
+        case HWIntrinsicInfo::SimdSetAllOp:
         case HWIntrinsicInfo::SimdUnaryOp:
             simdClass = sig->retTypeClass;
             break;
@@ -211,10 +212,15 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic        intrinsic,
 
             return gtNewSimdHWIntrinsicNode(simdType, op1, op2, op3, intrinsic, simdBaseType, simdSizeBytes);
 
+        case HWIntrinsicInfo::SimdSetAllOp:
+            op1 = impPopStack().val;
+
+            return gtNewSimdHWIntrinsicNode(simdType, op1, intrinsic, simdBaseType, simdSizeBytes);
+
         case HWIntrinsicInfo::SimdUnaryOp:
             op1 = impSIMDPopStack(simdType);
 
-            return gtNewSimdHWIntrinsicNode(simdType, op1, nullptr, intrinsic, simdBaseType, simdSizeBytes);
+            return gtNewSimdHWIntrinsicNode(simdType, op1, intrinsic, simdBaseType, simdSizeBytes);
 
         case HWIntrinsicInfo::SimdExtractOp:
             if (!mustExpand && !impCheckImmediate(impStackTop(0).val, getSIMDVectorLength(simdSizeBytes, simdBaseType)))