diff --git a/src/coreclr/jit/codegenarm64test.cpp b/src/coreclr/jit/codegenarm64test.cpp index 0406bc4a6e19a2..e136de5a075953 100644 --- a/src/coreclr/jit/codegenarm64test.cpp +++ b/src/coreclr/jit/codegenarm64test.cpp @@ -6096,6 +6096,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_PATTERN_I(INS_sve_uqincw, EA_SCALABLE, REG_V11, SVE_PATTERN_ALL, 16, INS_OPTS_SCALABLE_S); // UQINCW .S{, {, MUL #}} +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_BQ_2A theEmitter->emitIns_R_R_I(INS_sve_ext, EA_SCALABLE, REG_V0, REG_V1, 0, INS_OPTS_SCALABLE_B, INS_SCALABLE_OPTS_WITH_VECTOR_PAIR); // EXT .B, {.B, .B }, # @@ -6105,6 +6106,7 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_SCALABLE_OPTS_WITH_VECTOR_PAIR); // EXT .B, {.B, .B }, # theEmitter->emitIns_R_R_I(INS_sve_ext, EA_SCALABLE, REG_V6, REG_FP_LAST, 255, INS_OPTS_SCALABLE_B, INS_SCALABLE_OPTS_WITH_VECTOR_PAIR); // EXT .B, {.B, .B }, # +#endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_BQ_2B theEmitter->emitIns_R_R_I(INS_sve_ext, EA_SCALABLE, REG_V0, REG_V1, 0, @@ -8391,23 +8393,23 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_D); // ST1B {.D }, , [, .D] // IF_SVE_GP_3A - theEmitter->emitIns_R_R_R_I(INS_sve_fcadd, EA_SCALABLE, REG_V0, REG_P1, REG_V2, 90, + theEmitter->emitIns_R_R_R_I(INS_sve_fcadd, EA_SCALABLE, REG_V0, REG_P1, REG_V2, 0, INS_OPTS_SCALABLE_H); // FCADD ., /M, ., ., - theEmitter->emitIns_R_R_R_I(INS_sve_fcadd, EA_SCALABLE, REG_V0, REG_P1, REG_V2, 270, + theEmitter->emitIns_R_R_R_I(INS_sve_fcadd, EA_SCALABLE, REG_V0, REG_P1, REG_V2, 1, INS_OPTS_SCALABLE_H); // FCADD ., /M, ., ., - theEmitter->emitIns_R_R_R_I(INS_sve_fcadd, EA_SCALABLE, REG_V0, REG_P1, REG_V2, 270, + theEmitter->emitIns_R_R_R_I(INS_sve_fcadd, EA_SCALABLE, REG_V0, REG_P1, REG_V2, 1, INS_OPTS_SCALABLE_S); // FCADD ., /M, ., ., - theEmitter->emitIns_R_R_R_I(INS_sve_fcadd, EA_SCALABLE, REG_V0, REG_P1, REG_V2, 270, + theEmitter->emitIns_R_R_R_I(INS_sve_fcadd, EA_SCALABLE, REG_V0, REG_P1, REG_V2, 1, INS_OPTS_SCALABLE_D); // FCADD ., /M, ., ., // IF_SVE_GT_4A theEmitter->emitIns_R_R_R_R_I(INS_sve_fcmla, EA_SCALABLE, REG_V2, REG_P1, REG_V3, REG_V4, 0, INS_OPTS_SCALABLE_H); // FCMLA ., /M, ., ., - theEmitter->emitIns_R_R_R_R_I(INS_sve_fcmla, EA_SCALABLE, REG_V0, REG_P2, REG_V1, REG_V5, 90, + theEmitter->emitIns_R_R_R_R_I(INS_sve_fcmla, EA_SCALABLE, REG_V0, REG_P2, REG_V1, REG_V5, 1, INS_OPTS_SCALABLE_S); // FCMLA ., /M, ., ., - theEmitter->emitIns_R_R_R_R_I(INS_sve_fcmla, EA_SCALABLE, REG_V2, REG_P3, REG_V0, REG_V6, 180, + theEmitter->emitIns_R_R_R_R_I(INS_sve_fcmla, EA_SCALABLE, REG_V2, REG_P3, REG_V0, REG_V6, 2, INS_OPTS_SCALABLE_D); // FCMLA ., /M, ., ., - theEmitter->emitIns_R_R_R_R_I(INS_sve_fcmla, EA_SCALABLE, REG_V2, REG_P3, REG_V0, REG_V6, 270, + theEmitter->emitIns_R_R_R_R_I(INS_sve_fcmla, EA_SCALABLE, REG_V2, REG_P3, REG_V0, REG_V6, 3, INS_OPTS_SCALABLE_D); // FCMLA ., /M, ., ., // IF_SVE_GI_4A diff --git a/src/coreclr/jit/emitarm64sve.cpp b/src/coreclr/jit/emitarm64sve.cpp index 589cc1b29bae6a..6fb6723eb63811 100644 --- a/src/coreclr/jit/emitarm64sve.cpp +++ b/src/coreclr/jit/emitarm64sve.cpp @@ -4410,7 +4410,6 @@ void emitter::emitInsSve_R_R_R(instruction ins, /***************************************************************************** * * Add a SVE instruction referencing three registers and a constant. - * Do not call this directly. Use 'emitIns_R_R_R_I' instead. */ void emitter::emitInsSve_R_R_R_I(instruction ins, @@ -5577,7 +5576,7 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, assert(isLowPredicateRegister(reg2)); assert(isVectorRegister(reg3)); assert(isScalableVectorSize(size)); - imm = emitEncodeRotationImm90_or_270(imm); + assert(emitIsValidEncodedRotationImm90_or_270(imm)); fmt = IF_SVE_GP_3A; break; @@ -5860,7 +5859,6 @@ void emitter::emitInsSve_R_R_R_I_I(instruction ins, /***************************************************************************** * * Add a SVE instruction referencing four registers. - * Do not call this directly. Use 'emitIns_R_R_R_R' instead. */ void emitter::emitInsSve_R_R_R_R(instruction ins, @@ -6991,7 +6989,7 @@ void emitter::emitInsSve_R_R_R_R_I(instruction ins, assert(isVectorRegister(reg3)); assert(isVectorRegister(reg4)); assert(isScalableVectorSize(size)); - imm = emitEncodeRotationImm0_to_270(imm); + assert(emitIsValidEncodedRotationImm0_to_270(imm)); fmt = IF_SVE_GT_4A; break; @@ -9798,7 +9796,7 @@ void emitter::emitIns_PRFOP_R_R_I(instruction ins, /*static*/ bool emitter::emitIsValidEncodedRotationImm90_or_270(ssize_t imm) { - return (imm == 0) || (imm == 1); + return isValidUimm<1>(imm); } /************************************************************************ @@ -9867,7 +9865,7 @@ void emitter::emitIns_PRFOP_R_R_I(instruction ins, /*static*/ bool emitter::emitIsValidEncodedRotationImm0_to_270(ssize_t imm) { - return (imm >= 0) && (imm <= 3); + return isValidUimm<2>(imm); } /***************************************************************************** diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 91b053a49163e2..d573135350f5bd 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -504,6 +504,16 @@ void HWIntrinsicInfo::lookupImmBounds( immUpperBound = (int)SVE_PRFOP_CONST15; break; + case NI_Sve_AddRotateComplex: + immLowerBound = 0; + immUpperBound = 1; + break; + + case NI_Sve_MultiplyAddRotateComplex: + immLowerBound = 0; + immUpperBound = 3; + break; + case NI_Sve_TrigonometricMultiplyAddCoefficient: immLowerBound = 0; immUpperBound = 7; diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index db33fb25771786..17f929fef2bb7a 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -480,10 +480,16 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) regNumber embMaskOp1Reg = REG_NA; regNumber embMaskOp2Reg = REG_NA; regNumber embMaskOp3Reg = REG_NA; + regNumber embMaskOp4Reg = REG_NA; regNumber falseReg = op3Reg; switch (intrinEmbMask.numOperands) { + case 4: + assert(intrinEmbMask.op4 != nullptr); + embMaskOp4Reg = intrinEmbMask.op4->GetRegNum(); + FALLTHROUGH; + case 3: assert(intrinEmbMask.op3 != nullptr); embMaskOp3Reg = intrinEmbMask.op3->GetRegNum(); @@ -503,6 +509,70 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) unreached(); } + // Shared code for setting up embedded mask arg for intrinsics with 3+ operands + auto emitEmbeddedMaskSetup = [&] { + if (intrin.op3->IsVectorZero()) + { + // If `falseReg` is zero, then move the first operand of `intrinEmbMask` in the + // destination using /Z. + + assert(targetReg != embMaskOp2Reg); + assert(intrin.op3->isContained() || !intrin.op1->IsMaskAllBitsSet()); + GetEmitter()->emitInsSve_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, opt); + } + else + { + // Below are the considerations we need to handle: + // + // targetReg == falseReg && targetReg == embMaskOp1Reg + // fmla Zd, P/m, Zn, Zm + // + // targetReg == falseReg && targetReg != embMaskOp1Reg + // movprfx target, P/m, embMaskOp1Reg + // fmla target, P/m, embMaskOp2Reg, embMaskOp3Reg + // + // targetReg != falseReg && targetReg == embMaskOp1Reg + // sel target, P/m, embMaskOp1Reg, falseReg + // fmla target, P/m, embMaskOp2Reg, embMaskOp3Reg + // + // targetReg != falseReg && targetReg != embMaskOp1Reg + // sel target, P/m, embMaskOp1Reg, falseReg + // fmla target, P/m, embMaskOp2Reg, embMaskOp3Reg + // + // Note that, we just check if the targetReg/falseReg or targetReg/embMaskOp1Reg + // coincides or not. + + if (targetReg != falseReg) + { + if (falseReg == embMaskOp1Reg) + { + // If falseReg value and embMaskOp1Reg value are same, then just mov the value + // to the target. + + GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, embMaskOp1Reg, + /* canSkip */ true); + } + else + { + // If falseReg value is not present in targetReg yet, move the inactive lanes + // into the targetReg using `sel`. Since this is RMW, the active lanes should + // have the value from embMaskOp1Reg + + GetEmitter()->emitInsSve_R_R_R_R(INS_sve_sel, emitSize, targetReg, maskReg, embMaskOp1Reg, + falseReg, opt); + } + } + else if (targetReg != embMaskOp1Reg) + { + // If target already contains the values of `falseReg`, just merge the lanes from + // `embMaskOp1Reg`, again because this is RMW semantics. + + GetEmitter()->emitInsSve_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, + opt, INS_SCALABLE_OPTS_PREDICATE_MERGE); + } + } + }; + switch (intrinEmbMask.numOperands) { case 1: @@ -703,174 +773,151 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) break; } + case 3: { assert(instrIsRMW); - assert(HWIntrinsicInfo::IsFmaIntrinsic(intrinEmbMask.id)); - assert(falseReg != embMaskOp3Reg); - // For FMA, the operation we are trying to perform is: - // result = op1 + (op2 * op3) - // - // There are two instructions that can be used depending on which operand's register, - // optionally, will store the final result. - // - // 1. If the result is stored in the operand that was used as an "addend" in the operation, - // then we use `FMLA` format: - // reg1 = reg1 + (reg2 * reg3) - // - // 2. If the result is stored in the operand that was used as a "multiplicand" in the operation, - // then we use `FMAD` format: - // reg1 = (reg1 * reg2) + reg3 - // - // Check if the result's register is same as that of one of the operand's register and accordingly - // pick the appropriate format. Suppose `targetReg` holds the result, then we have following cases: - // - // Case# 1: Result is stored in the operand that held the "addend" - // targetReg == reg1 - // - // We generate the FMLA instruction format and no further changes are needed. - // - // Case# 2: Result is stored in the operand `op2` that held the "multiplicand" - // targetReg == reg2 - // - // So we basically have an operation: - // reg2 = reg1 + (reg2 * reg3) - // - // Since, the result will be stored in the "multiplicand", we pick format `FMAD`. - // Then, we rearrange the operands to ensure that the operation is done correctly. - // reg2 = reg1 + (reg2 * reg3) // to start with - // reg2 = reg3 + (reg2 * reg1) // swap reg1 <--> reg3 - // reg1 = reg3 + (reg1 * reg2) // swap reg1 <--> reg2 - // reg1 = (reg1 * reg2) + reg3 // rearrange to get FMAD format - // - // Case# 3: Result is stored in the operand `op3` that held the "multiplier" - // targetReg == reg3 - // - // So we basically have an operation: - // reg3 = reg1 + (reg2 * reg3) - // Since, the result will be stored in the "multiplier", we again pick format `FMAD`. - // Then, we rearrange the operands to ensure that the operation is done correctly. - // reg3 = reg1 + (reg2 * reg3) // to start with - // reg1 = reg3 + (reg2 * reg1) // swap reg1 <--> reg3 - // reg1 = (reg1 * reg2) + reg3 // rearrange to get FMAD format - - bool useAddend = true; - if (targetReg == embMaskOp2Reg) - { - // Case# 2 - useAddend = false; - std::swap(embMaskOp1Reg, embMaskOp3Reg); - std::swap(embMaskOp1Reg, embMaskOp2Reg); - } - else if (targetReg == embMaskOp3Reg) - { - // Case# 3 - useAddend = false; - std::swap(embMaskOp1Reg, embMaskOp3Reg); - } - else + if (HWIntrinsicInfo::IsFmaIntrinsic(intrinEmbMask.id)) { - // Case# 1 - } + assert(falseReg != embMaskOp3Reg); + // For FMA, the operation we are trying to perform is: + // result = op1 + (op2 * op3) + // + // There are two instructions that can be used depending on which operand's register, + // optionally, will store the final result. + // + // 1. If the result is stored in the operand that was used as an "addend" in the operation, + // then we use `FMLA` format: + // reg1 = reg1 + (reg2 * reg3) + // + // 2. If the result is stored in the operand that was used as a "multiplicand" in the operation, + // then we use `FMAD` format: + // reg1 = (reg1 * reg2) + reg3 + // + // Check if the result's register is same as that of one of the operand's register and + // accordingly pick the appropriate format. Suppose `targetReg` holds the result, then we have + // following cases: + // + // Case# 1: Result is stored in the operand that held the "addend" + // targetReg == reg1 + // + // We generate the FMLA instruction format and no further changes are needed. + // + // Case# 2: Result is stored in the operand `op2` that held the "multiplicand" + // targetReg == reg2 + // + // So we basically have an operation: + // reg2 = reg1 + (reg2 * reg3) + // + // Since, the result will be stored in the "multiplicand", we pick format `FMAD`. + // Then, we rearrange the operands to ensure that the operation is done correctly. + // reg2 = reg1 + (reg2 * reg3) // to start with + // reg2 = reg3 + (reg2 * reg1) // swap reg1 <--> reg3 + // reg1 = reg3 + (reg1 * reg2) // swap reg1 <--> reg2 + // reg1 = (reg1 * reg2) + reg3 // rearrange to get FMAD format + // + // Case# 3: Result is stored in the operand `op3` that held the "multiplier" + // targetReg == reg3 + // + // So we basically have an operation: + // reg3 = reg1 + (reg2 * reg3) + // Since, the result will be stored in the "multiplier", we again pick format `FMAD`. + // Then, we rearrange the operands to ensure that the operation is done correctly. + // reg3 = reg1 + (reg2 * reg3) // to start with + // reg1 = reg3 + (reg2 * reg1) // swap reg1 <--> reg3 + // reg1 = (reg1 * reg2) + reg3 // rearrange to get FMAD format + + bool useAddend = true; + if (targetReg == embMaskOp2Reg) + { + // Case# 2 + useAddend = false; + std::swap(embMaskOp1Reg, embMaskOp3Reg); + std::swap(embMaskOp1Reg, embMaskOp2Reg); + } + else if (targetReg == embMaskOp3Reg) + { + // Case# 3 + useAddend = false; + std::swap(embMaskOp1Reg, embMaskOp3Reg); + } + else + { + // Case# 1 + } - switch (intrinEmbMask.id) - { - case NI_Sve_FusedMultiplyAdd: - insEmbMask = useAddend ? INS_sve_fmla : INS_sve_fmad; - break; + switch (intrinEmbMask.id) + { + case NI_Sve_FusedMultiplyAdd: + insEmbMask = useAddend ? INS_sve_fmla : INS_sve_fmad; + break; - case NI_Sve_FusedMultiplyAddNegated: - insEmbMask = useAddend ? INS_sve_fnmla : INS_sve_fnmad; - break; + case NI_Sve_FusedMultiplyAddNegated: + insEmbMask = useAddend ? INS_sve_fnmla : INS_sve_fnmad; + break; - case NI_Sve_FusedMultiplySubtract: - insEmbMask = useAddend ? INS_sve_fmls : INS_sve_fmsb; - break; + case NI_Sve_FusedMultiplySubtract: + insEmbMask = useAddend ? INS_sve_fmls : INS_sve_fmsb; + break; - case NI_Sve_FusedMultiplySubtractNegated: - insEmbMask = useAddend ? INS_sve_fnmls : INS_sve_fnmsb; - break; + case NI_Sve_FusedMultiplySubtractNegated: + insEmbMask = useAddend ? INS_sve_fnmls : INS_sve_fnmsb; + break; - case NI_Sve_MultiplyAdd: - insEmbMask = useAddend ? INS_sve_mla : INS_sve_mad; - break; + case NI_Sve_MultiplyAdd: + insEmbMask = useAddend ? INS_sve_mla : INS_sve_mad; + break; - case NI_Sve_MultiplySubtract: - insEmbMask = useAddend ? INS_sve_mls : INS_sve_msb; - break; + case NI_Sve_MultiplySubtract: + insEmbMask = useAddend ? INS_sve_mls : INS_sve_msb; + break; - default: - unreached(); + default: + unreached(); + } } - if (intrin.op3->IsVectorZero()) - { - // If `falseReg` is zero, then move the first operand of `intrinEmbMask` in the - // destination using /Z. + emitEmbeddedMaskSetup(); - assert(targetReg != embMaskOp2Reg); - assert(intrin.op3->isContained() || !intrin.op1->IsMaskAllBitsSet()); - GetEmitter()->emitIns_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, opt); + // Finally, perform the desired operation. + if (HWIntrinsicInfo::HasImmediateOperand(intrinEmbMask.id)) + { + HWIntrinsicImmOpHelper helper(this, intrinEmbMask.op3, op2->AsHWIntrinsic()); + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + GetEmitter()->emitInsSve_R_R_R_I(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, + helper.ImmValue(), opt); + } } else { - // Below are the considerations we need to handle: - // - // targetReg == falseReg && targetReg == embMaskOp1Reg - // fmla Zd, P/m, Zn, Zm - // - // targetReg == falseReg && targetReg != embMaskOp1Reg - // movprfx target, P/m, embMaskOp1Reg - // fmla target, P/m, embMaskOp2Reg, embMaskOp3Reg - // - // targetReg != falseReg && targetReg == embMaskOp1Reg - // sel target, P/m, embMaskOp1Reg, falseReg - // fmla target, P/m, embMaskOp2Reg, embMaskOp3Reg - // - // targetReg != falseReg && targetReg != embMaskOp1Reg - // sel target, P/m, embMaskOp1Reg, falseReg - // fmla target, P/m, embMaskOp2Reg, embMaskOp3Reg - // - // Note that, we just check if the targetReg/falseReg or targetReg/embMaskOp1Reg - // coincides or not. + assert(HWIntrinsicInfo::IsFmaIntrinsic(intrinEmbMask.id)); + GetEmitter()->emitInsSve_R_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, + embMaskOp3Reg, opt); + } - if (targetReg != falseReg) - { - if (falseReg == embMaskOp1Reg) - { - // If falseReg value and embMaskOp1Reg value are same, then just mov the value - // to the target. + break; + } - GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, embMaskOp1Reg, - /* canSkip */ true); - } - else - { - // If falseReg value is not present in targetReg yet, move the inactive lanes - // into the targetReg using `sel`. Since this is RMW, the active lanes should - // have the value from embMaskOp1Reg + case 4: + { + assert(instrIsRMW); + assert(intrinEmbMask.op4->isContained() == (embMaskOp4Reg == REG_NA)); + assert(HWIntrinsicInfo::HasImmediateOperand(intrinEmbMask.id)); - GetEmitter()->emitIns_R_R_R_R(INS_sve_sel, emitSize, targetReg, maskReg, embMaskOp1Reg, - falseReg, opt); - } - } - else if (targetReg != embMaskOp1Reg) - { - // If target already contains the values of `falseReg`, just merge the lanes from - // `embMaskOp1Reg`, again because this is RMW semantics. + emitEmbeddedMaskSetup(); - GetEmitter()->emitIns_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, - opt, INS_SCALABLE_OPTS_PREDICATE_MERGE); - } + HWIntrinsicImmOpHelper helper(this, intrinEmbMask.op4, op2->AsHWIntrinsic()); + for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) + { + GetEmitter()->emitInsSve_R_R_R_R_I(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, + embMaskOp3Reg, helper.ImmValue(), opt); } - // Finally, perform the desired operation. - GetEmitter()->emitIns_R_R_R_R(insEmbMask, emitSize, targetReg, maskReg, embMaskOp2Reg, - embMaskOp3Reg, opt); - break; } + default: unreached(); } diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index e3a1d979b7fd38..c7df23557516e7 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -24,6 +24,7 @@ HARDWARE_INTRINSIC(Sve, AbsoluteCompareLessThanOrEqual, HARDWARE_INTRINSIC(Sve, AbsoluteDifference, -1, -1, false, {INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_fabd, INS_sve_fabd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Add, -1, -1, false, {INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_fadd, INS_sve_fadd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, AddAcross, -1, 1, true, {INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_faddv, INS_sve_faddv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, AddRotateComplex, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcadd, INS_sve_fcadd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) HARDWARE_INTRINSIC(Sve, AddSaturate, -1, 2, true, {INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, AddSequentialAcross, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fadda, INS_sve_fadda}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve, And, -1, -1, false, {INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) @@ -186,6 +187,7 @@ HARDWARE_INTRINSIC(Sve, MinNumber, HARDWARE_INTRINSIC(Sve, MinNumberAcross, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnmv, INS_sve_fminnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Multiply, -1, 2, true, {INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_fmul, INS_sve_fmul}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, MultiplyAdd, -1, -1, false, {INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_FmaIntrinsic|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve, MultiplyAddRotateComplex, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcmla, INS_sve_fcmla}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) HARDWARE_INTRINSIC(Sve, MultiplyBySelectedScalar, -1, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmul, INS_sve_fmul}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) HARDWARE_INTRINSIC(Sve, MultiplyExtended, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmulx, INS_sve_fmulx}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, MultiplySubtract, -1, -1, false, {INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_FmaIntrinsic|HW_Flag_SpecialCodeGen) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 3ecc41f20d99f7..2ae67d5899b97d 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -3434,6 +3434,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_PrefetchInt32: case NI_Sve_PrefetchInt64: case NI_Sve_ExtractVector: + case NI_Sve_AddRotateComplex: case NI_Sve_TrigonometricMultiplyAddCoefficient: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op3)); @@ -3638,6 +3639,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_Sve_FusedMultiplyAddBySelectedScalar: case NI_Sve_FusedMultiplySubtractBySelectedScalar: + case NI_Sve_MultiplyAddRotateComplex: assert(hasImmediateOperand); assert(varTypeIsIntegral(intrin.op4)); if (intrin.op4->IsCnsIntOrI()) diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 9cd5dd0f3ec035..5fbcc0b468f009 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -1920,18 +1920,44 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou } else { - assert((numArgs == 1) || (numArgs == 2) || (numArgs == 3)); + const bool embHasImmediateOperand = HWIntrinsicInfo::HasImmediateOperand(intrinEmb.id); + assert((numArgs == 1) || (numArgs == 2) || (numArgs == 3) || (embHasImmediateOperand && (numArgs == 4))); - // Special handling for ShiftRightArithmeticForDivide: + // Special handling for embedded intrinsics with immediates: // We might need an additional register to hold branch targets into the switch table // that encodes the immediate - if (intrinEmb.id == NI_Sve_ShiftRightArithmeticForDivide) + switch (intrinEmb.id) { - assert(embOp2Node->GetOperandCount() == 2); - if (!embOp2Node->Op(2)->isContainedIntOrIImmed()) - { - buildInternalIntRegisterDefForNode(embOp2Node); - } + case NI_Sve_ShiftRightArithmeticForDivide: + assert(embHasImmediateOperand); + assert(numArgs == 2); + if (!embOp2Node->Op(2)->isContainedIntOrIImmed()) + { + buildInternalIntRegisterDefForNode(embOp2Node); + } + break; + + case NI_Sve_AddRotateComplex: + assert(embHasImmediateOperand); + assert(numArgs == 3); + if (!embOp2Node->Op(3)->isContainedIntOrIImmed()) + { + buildInternalIntRegisterDefForNode(embOp2Node); + } + break; + + case NI_Sve_MultiplyAddRotateComplex: + assert(embHasImmediateOperand); + assert(numArgs == 4); + if (!embOp2Node->Op(4)->isContainedIntOrIImmed()) + { + buildInternalIntRegisterDefForNode(embOp2Node); + } + break; + + default: + assert(!embHasImmediateOperand); + break; } tgtPrefUse = BuildUse(embOp2Node->Op(1)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index 736b3fd1484fd1..81863a057638d5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -347,6 +347,26 @@ internal Arm64() { } /// public static unsafe Vector AddAcross(Vector value) { throw new PlatformNotSupportedException(); } + /// Complex add with rotate + + /// + /// svfloat64_t svcadd[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D, #imm_rotation + /// svfloat64_t svcadd[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D, #imm_rotation + /// svfloat64_t svcadd[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// + public static unsafe Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svcadd[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S, #imm_rotation + /// svfloat32_t svcadd[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S, #imm_rotation + /// svfloat32_t svcadd[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// + public static unsafe Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw new PlatformNotSupportedException(); } + /// AddSaturate : Saturating add /// @@ -5717,6 +5737,26 @@ internal Arm64() { } /// public static unsafe Vector MultiplyAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + /// Complex multiply-add with rotate + + /// + /// svfloat64_t svcmla[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.D, Pg/M, Zop2.D, Zop3.D, #imm_rotation + /// svfloat64_t svcmla[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.D, Pg/M, Zop2.D, Zop3.D, #imm_rotation + /// svfloat64_t svcmla[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// + public static unsafe Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svcmla[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.S, Pg/M, Zop2.S, Zop3.S, #imm_rotation + /// svfloat32_t svcmla[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.S, Pg/M, Zop2.S, Zop3.S, #imm_rotation + /// svfloat32_t svcmla[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// + public static unsafe Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw new PlatformNotSupportedException(); } + /// MultiplyBySelectedScalar : Multiply /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index 930ae6afd2bdf0..73d4c556249fb6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -377,6 +377,26 @@ internal Arm64() { } /// public static unsafe Vector AddAcross(Vector value) => AddAcross(value); + /// Complex add with rotate + + /// + /// svfloat64_t svcadd[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D, #imm_rotation + /// svfloat64_t svcadd[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D, #imm_rotation + /// svfloat64_t svcadd[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2, uint64_t imm_rotation) + /// + public static unsafe Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + + /// + /// svfloat32_t svcadd[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S, #imm_rotation + /// svfloat32_t svcadd[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// FCADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S, #imm_rotation + /// svfloat32_t svcadd[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2, uint64_t imm_rotation) + /// + public static unsafe Vector AddRotateComplex(Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) => AddRotateComplex(left, right, rotation); + /// AddSaturate : Saturating add /// @@ -5773,6 +5793,26 @@ internal Arm64() { } /// public static unsafe Vector MultiplyAdd(Vector addend, Vector left, Vector right) => MultiplyAdd(addend, left, right); + /// Complex multiply-add with rotate + + /// + /// svfloat64_t svcmla[_f64]_m(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.D, Pg/M, Zop2.D, Zop3.D, #imm_rotation + /// svfloat64_t svcmla[_f64]_x(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.D, Pg/M, Zop2.D, Zop3.D, #imm_rotation + /// svfloat64_t svcmla[_f64]_z(svbool_t pg, svfloat64_t op1, svfloat64_t op2, svfloat64_t op3, uint64_t imm_rotation) + /// + public static unsafe Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + + /// + /// svfloat32_t svcmla[_f32]_m(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.S, Pg/M, Zop2.S, Zop3.S, #imm_rotation + /// svfloat32_t svcmla[_f32]_x(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// FCMLA Ztied1.S, Pg/M, Zop2.S, Zop3.S, #imm_rotation + /// svfloat32_t svcmla[_f32]_z(svbool_t pg, svfloat32_t op1, svfloat32_t op2, svfloat32_t op3, uint64_t imm_rotation) + /// + public static unsafe Vector MultiplyAddRotateComplex(Vector addend, Vector left, Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) => MultiplyAddRotateComplex(addend, left, right, rotation); + /// MultiplyBySelectedScalar : Multiply /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 13a0b2ee9695f6..419dee05737bd6 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4364,6 +4364,9 @@ internal Arm64() { } public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector AddAcross(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddRotateComplex(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(1))] byte rotation) { throw null; } + public static System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -5178,6 +5181,9 @@ internal Arm64() { } public static System.Numerics.Vector MultiplyAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector MultiplyAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyAddRotateComplex(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected(Min = 0, Max = (byte)(3))] byte rotation) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index d02ccf461648b9..2abaf62dcd680f 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -280,11 +280,13 @@ ("_SveBinaryOpDifferentTypesTestTemplate.template", "SveVecBinOpDifferentTypesTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveBinaryMaskOpTestTemplate.template", "SveMaskVecBinOpConvertTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveImmBinaryOpTestTemplate.template", "SveVecImmBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmBinaryOpTestTemplate.template", "SveVecImmBinOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveImmUnaryOpTestTemplate.template", "SveVecImmUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveTernOpTestTemplate.template", "SveVecTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveTernOpTestTemplate.template", "SveVecTernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveTernOpFirstArgTestTemplate.template", "SveVecTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveImmTernOpTestTemplate.template", "SveVecImmTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), + ("_SveImmTernOpTestTemplate.template", "SveVecImmTernOpVecTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleVecOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleVecOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveTernOpMaskedOpTestTemplate.template", "SveVecTernOpMaskedTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveImmTernOpFirstArgTestTemplate.template", "SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveScalarTernOpTestTemplate.template", "SveScalarTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), @@ -3113,6 +3115,11 @@ ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateReduceOpResult"] = "Helpers.AddAcrossWidening(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), ("SveVecReduceUnOpTest.template", new Dictionary { ["TestName"] = "Sve_AddAcross_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddAcross", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateReduceOpResult"] = "Helpers.AddAcross(firstOp) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_float_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_double_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecImmBinOpVecTest.template", new Dictionary { ["TestName"] = "Sve_AddRotateComplex_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.AddRotateComplex(firstOp, secondOp, Imm))", ["GetVectorResult"] = "Helpers.AddRotateComplex(first, second, Imm)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_AddSaturate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.AddSaturate(left[i], right[i])"}), @@ -3364,8 +3371,8 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplyAdd_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplyAdd_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "0", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddNegated_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplyAddNegated_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplyAddNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplyAddNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), @@ -3373,8 +3380,8 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplySubtract_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_FusedMultiplySubtract_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "0", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractNegated_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2BaseType"] = "Single", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.SingleToInt32Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve_FusedMultiplySubtractNegated_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "FusedMultiplySubtractNegated", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2BaseType"] = "Double", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])) != BitConverter.DoubleToInt64Bits(result[i])", ["GetIterResult"] = "Helpers.FusedMultiplySubtractNegated(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), @@ -3850,8 +3857,17 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyAdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[i])", ["ConvertFunc"] = ""}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_float_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetSingle()",["NextValueOp2"] = "TestLibrary.Generator.GetSingle()",["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + ("SveVecImmTernOpVecTest.template", new Dictionary {["TestName"] = "Sve_MultiplyAddRotateComplex_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyAddRotateComplex", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetDouble()",["NextValueOp2"] = "TestLibrary.Generator.GetDouble()",["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.MultiplyAddRotateComplex(firstOp, secondOp, thirdOp, Imm))", ["GetVectorResult"] = "Helpers.MultiplyAddRotateComplex(first, second, third, Imm)"}), + + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ValidateIterResult"] = "BitConverter.SingleToInt32Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.SingleToInt32Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_MultiplyBySelectedScalar_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Multiply(firstOp[i], secondOp[Imm])) != BitConverter.DoubleToInt64Bits(result[i])",["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_MultiplyExtended_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "MultiplyExtended", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.MultiplyExtended(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.MultiplyExtended(left[i], right[i])"}), @@ -4139,14 +4155,14 @@ ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Sqrt_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Sqrt", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Sqrt(firstOp[i])", ["GetIterResult"] = "Helpers.Sqrt(leftOp[i])"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "0", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_4", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_6", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_5", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), - ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_7", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_0", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "0", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_2", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "2", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_4", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "4", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_float_6", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueMask"] = "Helpers.getMaskSingle()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_1", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_3", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_5", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "5", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), + ("SveVecImmBinOpTest.template", new Dictionary {["TestName"] = "Sve_TrigonometricMultiplyAddCoefficient_double_7", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "TrigonometricMultiplyAddCoefficient", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueMask"] = "Helpers.getMaskDouble()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) && (Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) != result[i])", ["GetIterResult"] = "((firstOp[i] <= (Math.PI / 4)) && (firstOp[i] > (-Math.PI / 4))) ? Helpers.TrigonometricMultiplyAddCoefficient(firstOp[i], secondOp[i], Imm) : result[i]"}), ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.SingleToInt32Bits"}), ("SveVecTernOpMaskedTest.template", new Dictionary { ["TestName"] = "Sve_Splice_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Splice", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "result[i] != Helpers.Splice(first, second, maskArray, i)", ["GetIterResult"] = "Helpers.Splice(left, right, mask, i)", ["ConvertFunc"] = "BitConverter.DoubleToInt64Bits"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index d143df3432e87f..54ddade391f939 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -5234,6 +5234,28 @@ private static (ulong val, bool ovf) ShiftOvf(ulong value, int shift) public static float MinNumberPairwise(float[] op1, float[] op2, int i) => Pairwise(MinNumber, op1, op2, i); + public static float[] MultiplyAddRotateComplex(float[] op1, float[] op2, float[] op3, byte imm) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + (float ans1, float ans2) = imm switch + { + 0 => (FusedMultiplyAdd(op1[real], op2[real], op3[real]), FusedMultiplyAdd(op1[img], op2[real], op3[img])), + 1 => (FusedMultiplySubtract(op1[real], op2[img], op3[img]), FusedMultiplyAdd(op1[img], op2[img], op3[i])), + 2 => (FusedMultiplySubtract(op1[real], op2[real], op3[real]), FusedMultiplySubtract(op1[img], op2[real], op3[img])), + 3 => (FusedMultiplyAdd(op1[real], op2[img], op3[img]), FusedMultiplySubtract(op1[img], op2[img], op3[real])), + _ => (0.0f, 0.0f) + }; + + op1[real] = ans1; + op1[img] = ans2; + } + + return op1; + } + public static float MultiplyExtended(float op1, float op2) { bool inf1 = float.IsInfinity(op1); @@ -5411,6 +5433,28 @@ public static float FPExponentialAccelerator(uint op1) public static double MinNumberPairwise(double[] op1, double[] op2, int i) => Pairwise(MinNumber, op1, op2, i); + public static double[] MultiplyAddRotateComplex(double[] op1, double[] op2, double[] op3, byte imm) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + (double ans1, double ans2) = imm switch + { + 0 => (FusedMultiplyAdd(op1[real], op2[real], op3[real]), FusedMultiplyAdd(op1[img], op2[real], op3[img])), + 1 => (FusedMultiplySubtract(op1[real], op2[img], op3[img]), FusedMultiplyAdd(op1[img], op2[img], op3[i])), + 2 => (FusedMultiplySubtract(op1[real], op2[real], op3[real]), FusedMultiplySubtract(op1[img], op2[real], op3[img])), + 3 => (FusedMultiplyAdd(op1[real], op2[img], op3[img]), FusedMultiplySubtract(op1[img], op2[img], op3[real])), + _ => (0.0, 0.0) + }; + + op1[real] = ans1; + op1[img] = ans2; + } + + return op1; + } + public static double MultiplyExtended(double op1, double op2) { bool inf1 = double.IsInfinity(op1); @@ -6084,6 +6128,28 @@ private static ulong Pairwise(Func pairOp, ulong[] op1, ulo public static float AddPairwise(float[] op1, float[] op2, int i) => Pairwise(Add, op1, op2, i); + public static float[] AddRotateComplex(float[] op1, float[] op2, byte rot) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + + if (rot == 0) + { + op1[real] -= op2[img]; + op1[img] += op2[real]; + } + else + { + op1[real] += op2[img]; + op1[img] -= op2[real]; + } + } + + return op1; + } + public static float Max(float op1, float op2) => Math.Max(op1, op2); public static float MaxPairwise(float[] op1, int i) => Pairwise(Max, op1, i); @@ -6134,6 +6200,28 @@ private static float Pairwise(Func pairOp, float[] op1, flo public static double AddPairwise(double[] op1, double[] op2, int i) => Pairwise(Add, op1, op2, i); + public static double[] AddRotateComplex(double[] op1, double[] op2, byte rot) + { + for (int i = 0; i < op1.Length; i += 2) + { + int real = i; + int img = i + 1; + + if (rot == 0) + { + op1[real] -= op2[img]; + op1[img] += op2[real]; + } + else + { + op1[real] += op2[img]; + op1[img] -= op2[real]; + } + } + + return op1; + } + public static double Max(double op1, double op2) => Math.Max(op1, op2); public static double MaxPairwise(double[] op1, int i) => Pairwise(Max, op1, i); diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template index 3132da3fa1fdbf..e3c3957aa01fd6 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template @@ -9,6 +9,7 @@ ******************************************************************************/ using System; +using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -145,7 +146,7 @@ namespace JIT.HardwareIntrinsics.Arm for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); return testStruct; @@ -173,7 +174,7 @@ namespace JIT.HardwareIntrinsics.Arm private {Op1VectorType}<{Op1BaseType}> _mask; private {Op1VectorType}<{Op1BaseType}> _fld1; private {Op1VectorType}<{Op1BaseType}> _fld2; - private {Op1VectorType}<{Op1BaseType}> _falseFld; + private {Op1VectorType}<{Op1BaseType}> _falseFld; private DataTable _dataTable; @@ -181,16 +182,16 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueOp1} % 2); } + for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueMask} % 2); } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp1}; } + for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } _dataTable = new DataTable(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize); } diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template index c1bcca1eb32c65..9ce3a334f7d7ad 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template @@ -9,6 +9,7 @@ ******************************************************************************/ using System; +using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -65,6 +66,9 @@ namespace JIT.HardwareIntrinsics.Arm // Validates executing the test inside conditional, with op3 as zero test.ConditionalSelect_ZeroOp(); + + // Validates basic functionality fails with an invalid imm, using Unsafe.ReadUnaligned + test.RunBasicScenario_UnsafeRead_InvalidImm(); } else { @@ -194,7 +198,7 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueOp1} % 2); } + for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueMask} % 2); } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); @@ -229,6 +233,32 @@ namespace JIT.HardwareIntrinsics.Arm ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr); } + public void RunBasicScenario_UnsafeRead_InvalidImm() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead_InvalidImm)); + + bool succeeded = false; + try + { + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr), + {InvalidImm} + ); + Console.WriteLine(result); + } + catch (ArgumentOutOfRangeException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + public void RunBasicScenario_Load() { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));