summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorTanner Gooding <tagoo@outlook.com>2018-06-02 11:19:57 -0700
committerTanner Gooding <tagoo@outlook.com>2018-06-02 14:23:38 -0700
commit05b05fa9e4ee44fcf5b8246fbbafc9b16b519abb (patch)
treefb45df3b344f4b2ed338c96435eff3912886ead3 /src/jit
parent8dc10aaa421ab5d0890ebc55b3aeded18507c160 (diff)
downloadcoreclr-05b05fa9e4ee44fcf5b8246fbbafc9b16b519abb.tar.gz
coreclr-05b05fa9e4ee44fcf5b8246fbbafc9b16b519abb.tar.bz2
coreclr-05b05fa9e4ee44fcf5b8246fbbafc9b16b519abb.zip
Updating the x86 HWIntrinsics to query flags via explicit methods.
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/compiler.h2
-rw-r--r--src/jit/gentree.cpp10
-rw-r--r--src/jit/hwintrinsiccodegenxarch.cpp26
-rw-r--r--src/jit/hwintrinsicxarch.cpp57
-rw-r--r--src/jit/hwintrinsicxarch.h122
-rw-r--r--src/jit/lowerxarch.cpp9
-rw-r--r--src/jit/lsraxarch.cpp11
7 files changed, 178 insertions, 59 deletions
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index a7a6e71d73..e8c45945fe 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -3015,7 +3015,7 @@ protected:
GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass);
GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, var_types baseType);
GenTree* addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* lastOp, bool mustExpand);
- bool hwIntrinsicSignatureTypeSupported(var_types retType, CORINFO_SIG_INFO* sig, HWIntrinsicFlag flags);
+ bool hwIntrinsicSignatureTypeSupported(var_types retType, CORINFO_SIG_INFO* sig, NamedIntrinsic intrinsic);
#endif // _TARGET_XARCH_
#ifdef _TARGET_ARM64_
InstructionSet lookupHWIntrinsicISA(const char* className);
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index b40c026367..47d76e1a76 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -17384,8 +17384,7 @@ bool GenTree::isCommutativeHWIntrinsic() const
assert(gtOper == GT_HWIntrinsic);
#ifdef _TARGET_XARCH_
- HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(AsHWIntrinsic()->gtHWIntrinsicId);
- return ((flags & HW_Flag_Commutative) != 0);
+ return HWIntrinsicInfo::IsCommutative(AsHWIntrinsic()->gtHWIntrinsicId);
#else
return false;
#endif // _TARGET_XARCH_
@@ -17428,8 +17427,7 @@ bool GenTree::isRMWHWIntrinsic(Compiler* comp)
#ifdef _TARGET_XARCH_
if (!comp->canUseVexEncoding())
{
- HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(AsHWIntrinsic()->gtHWIntrinsicId);
- return ((flags & HW_Flag_NoRMWSemantics) == 0);
+ return HWIntrinsicInfo::HasRMWSemantics(AsHWIntrinsic()->gtHWIntrinsicId);
}
switch (AsHWIntrinsic()->gtHWIntrinsicId)
@@ -17447,10 +17445,14 @@ bool GenTree::isRMWHWIntrinsic(Compiler* comp)
case NI_FMA_MultiplySubtractNegated:
case NI_FMA_MultiplySubtractNegatedScalar:
case NI_FMA_MultiplySubtractScalar:
+ {
return true;
+ }
default:
+ {
return false;
+ }
}
#else
return false;
diff --git a/src/jit/hwintrinsiccodegenxarch.cpp b/src/jit/hwintrinsiccodegenxarch.cpp
index f210889620..c7decfa2f0 100644
--- a/src/jit/hwintrinsiccodegenxarch.cpp
+++ b/src/jit/hwintrinsiccodegenxarch.cpp
@@ -33,13 +33,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Return Value:
// returns true if this category can be table-driven in CodeGen
//
-static bool genIsTableDrivenHWIntrinsic(HWIntrinsicCategory category, HWIntrinsicFlag flags)
+static bool genIsTableDrivenHWIntrinsic(NamedIntrinsic intrinsicId, HWIntrinsicCategory category)
{
// TODO - make more categories to the table-driven framework
// HW_Category_Helper and HW_Flag_MultiIns/HW_Flag_SpecialCodeGen usually need manual codegen
const bool tableDrivenCategory =
- category != HW_Category_Special && category != HW_Category_Scalar && category != HW_Category_Helper;
- const bool tableDrivenFlag = (flags & (HW_Flag_MultiIns | HW_Flag_SpecialCodeGen)) == 0;
+ (category != HW_Category_Special) && (category != HW_Category_Scalar) && (category != HW_Category_Helper);
+ const bool tableDrivenFlag = !(HWIntrinsicInfo::GeneratesMultipleIns(intrinsicId) | HWIntrinsicInfo::HasSpecialCodegen(intrinsicId));
return tableDrivenCategory && tableDrivenFlag;
}
@@ -54,13 +54,12 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
NamedIntrinsic intrinsicId = node->gtHWIntrinsicId;
InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId);
HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId);
- HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(intrinsicId);
int ival = HWIntrinsicInfo::lookupIval(intrinsicId);
int numArgs = HWIntrinsicInfo::lookupNumArgs(node);
- assert((flags & HW_Flag_NoCodeGen) == 0);
+ assert(HWIntrinsicInfo::RequiresCodegen(intrinsicId));
- if (genIsTableDrivenHWIntrinsic(category, flags))
+ if (genIsTableDrivenHWIntrinsic(intrinsicId, category))
{
GenTree* op1 = node->gtGetOp1();
GenTree* op2 = node->gtGetOp2();
@@ -88,7 +87,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
{
emit->emitIns_R_AR(ins, simdSize, targetReg, op1Reg, 0);
}
- else if (category == HW_Category_SIMDScalar && (flags & HW_Flag_CopyUpperBits) != 0)
+ else if ((category == HW_Category_SIMDScalar) && HWIntrinsicInfo::CopiesUpperBits(intrinsicId))
{
emit->emitIns_SIMD_R_R_R(ins, simdSize, targetReg, op1Reg, op1Reg);
}
@@ -324,7 +323,7 @@ void CodeGen::genHWIntrinsic_R_R_RM(GenTreeHWIntrinsic* node, instruction ins)
if (op2->isContained() || op2->isUsedFromSpillTemp())
{
- assert((HWIntrinsicInfo::lookupFlags(node->gtHWIntrinsicId) & HW_Flag_NoContainment) == 0);
+ assert(HWIntrinsicInfo::SupportsContainment(node->gtHWIntrinsicId));
#if DEBUG
bool supportsRegOptional = false;
@@ -471,7 +470,7 @@ void CodeGen::genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins)
if (op2->isContained() || op2->isUsedFromSpillTemp())
{
- assert((HWIntrinsicInfo::lookupFlags(node->gtHWIntrinsicId) & HW_Flag_NoContainment) == 0);
+ assert(HWIntrinsicInfo::SupportsContainment(node->gtHWIntrinsicId));
#if DEBUG
bool supportsRegOptional = false;
@@ -1702,7 +1701,6 @@ void CodeGen::genFMAIntrinsic(GenTreeHWIntrinsic* node)
{
NamedIntrinsic intrinsicId = node->gtHWIntrinsicId;
var_types baseType = node->gtSIMDBaseType;
- HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(intrinsicId);
emitAttr attr = EA_ATTR(node->gtSIMDSize);
instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType);
GenTree* op1 = node->gtGetOp1();
@@ -1730,10 +1728,10 @@ void CodeGen::genFMAIntrinsic(GenTreeHWIntrinsic* node)
regNumber op2Reg;
bool isCommutative = false;
- bool copyUpperBits = (flags & HW_Flag_CopyUpperBits) != 0;
+ const bool copiesUpperBits = HWIntrinsicInfo::CopiesUpperBits(intrinsicId);
// Intrinsics with CopyUpperBits semantics cannot have op1 be contained
- assert(!copyUpperBits || !op1->isContained());
+ assert(!copiesUpperBits || !op1->isContained());
if (op3->isContained() || op3->isUsedFromSpillTemp())
{
@@ -1742,7 +1740,7 @@ void CodeGen::genFMAIntrinsic(GenTreeHWIntrinsic* node)
op1Reg = op1->gtRegNum;
op2Reg = op2->gtRegNum;
- isCommutative = !copyUpperBits;
+ isCommutative = !copiesUpperBits;
}
else if (op2->isContained() || op2->isUsedFromSpillTemp())
{
@@ -1769,7 +1767,7 @@ void CodeGen::genFMAIntrinsic(GenTreeHWIntrinsic* node)
op1Reg = op1->gtRegNum;
op2Reg = op2->gtRegNum;
- isCommutative = !copyUpperBits;
+ isCommutative = !copiesUpperBits;
}
if (isCommutative && (op1Reg != targetReg) && (op2Reg == targetReg))
diff --git a/src/jit/hwintrinsicxarch.cpp b/src/jit/hwintrinsicxarch.cpp
index 46119919c0..b5d7fd42f2 100644
--- a/src/jit/hwintrinsicxarch.cpp
+++ b/src/jit/hwintrinsicxarch.cpp
@@ -172,7 +172,7 @@ InstructionSet HWIntrinsicInfo::lookupIsa(const char* className)
// get the SIMD size from the GenTreeHWIntrinsic node.
unsigned HWIntrinsicInfo::lookupSimdSize(Compiler* comp, NamedIntrinsic id, CORINFO_SIG_INFO* sig)
{
- if ((lookupFlags(id) & HW_Flag_UnfixedSIMDSize) == 0)
+ if (HWIntrinsicInfo::HasFixedSimdSize(id))
{
return lookupSimdSize(id);
}
@@ -185,7 +185,7 @@ unsigned HWIntrinsicInfo::lookupSimdSize(Compiler* comp, NamedIntrinsic id, CORI
}
else
{
- assert((lookupFlags(id) & HW_Flag_BaseTypeFromFirstArg) != 0);
+ assert(HWIntrinsicInfo::BaseTypeFromFirstArg(id));
typeHnd = comp->info.compCompHnd->getArgClass(sig, sig->args);
}
@@ -321,7 +321,7 @@ bool HWIntrinsicInfo::isImmOp(NamedIntrinsic id, const GenTree* op)
return false;
}
- if ((HWIntrinsicInfo::lookupFlags(id) & HW_Flag_MaybeIMM) == 0)
+ if (!HWIntrinsicInfo::MaybeImm(id))
{
return true;
}
@@ -352,13 +352,13 @@ int HWIntrinsicInfo::lookupImmUpperBound(NamedIntrinsic id)
case NI_AVX_Compare:
case NI_AVX_CompareScalar:
{
- assert((HWIntrinsicInfo::lookupFlags(id) & HW_Flag_FullRangeIMM) == 0);
+ assert(!HWIntrinsicInfo::HasFullRangeImm(id));
return 31; // enum FloatComparisonMode has 32 values
}
default:
{
- assert((HWIntrinsicInfo::lookupFlags(id) & HW_Flag_FullRangeIMM) != 0);
+ assert(HWIntrinsicInfo::HasFullRangeImm(id));
return 255;
}
}
@@ -486,7 +486,7 @@ GenTree* Compiler::getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE
//
GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, var_types baseType)
{
- assert((HWIntrinsicInfo::lookupFlags(intrinsic) & HW_Flag_NoJmpTableIMM) != 0);
+ assert(HWIntrinsicInfo::NoJmpTableImm(intrinsic));
switch (intrinsic)
{
case NI_SSE2_ShiftLeftLogical:
@@ -526,7 +526,7 @@ GenTree* Compiler::addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* last
assert(lastOp != nullptr);
// Full-range imm-intrinsics do not need the range-check
// because the imm-parameter of the intrinsic method is a byte.
- if (mustExpand && ((HWIntrinsicInfo::lookupFlags(intrinsic) & HW_Flag_FullRangeIMM) == 0) &&
+ if (mustExpand && !HWIntrinsicInfo::HasFullRangeImm(intrinsic) &&
HWIntrinsicInfo::isImmOp(intrinsic, lastOp))
{
assert(!lastOp->IsCnsIntOrI());
@@ -576,23 +576,22 @@ bool Compiler::compSupportsHWIntrinsic(InstructionSet isa)
// Arguments:
// retType - return type
// sig - intrinsic signature
-// flags - flags of the intrinsics
//
// Return Value:
// Returns true iff the given type signature is supported
// Notes:
// - This is only used on 32-bit systems to determine whether the signature uses no 64-bit registers.
// - The `retType` is passed to avoid another call to the type system, as it has already been retrieved.
-bool Compiler::hwIntrinsicSignatureTypeSupported(var_types retType, CORINFO_SIG_INFO* sig, HWIntrinsicFlag flags)
+bool Compiler::hwIntrinsicSignatureTypeSupported(var_types retType, CORINFO_SIG_INFO* sig, NamedIntrinsic intrinsic)
{
#ifdef _TARGET_X86_
CORINFO_CLASS_HANDLE argClass;
- if ((flags & HW_Flag_64BitOnly) != 0)
+ if (HWIntrinsicInfo::Is64BitOnly(intrinsic))
{
return false;
}
- else if ((flags & HW_Flag_SecondArgMaybe64Bit) != 0)
+ else if (HWIntrinsicInfo::SecondArgMaybe64Bit(intrinsic))
{
assert(sig->numArgs >= 2);
CorInfoType corType =
@@ -615,11 +614,11 @@ bool Compiler::hwIntrinsicSignatureTypeSupported(var_types retType, CORINFO_SIG_
// Return Value:
// returns true if this category can be table-driven in the importer
//
-static bool impIsTableDrivenHWIntrinsic(HWIntrinsicCategory category, HWIntrinsicFlag flags)
+static bool impIsTableDrivenHWIntrinsic(NamedIntrinsic intrinsicId, HWIntrinsicCategory category)
{
// HW_Flag_NoCodeGen implies this intrinsic should be manually morphed in the importer.
- return category != HW_Category_Special && category != HW_Category_Scalar &&
- ((flags & (HW_Flag_NoCodeGen | HW_Flag_SpecialImport)) == 0);
+ return (category != HW_Category_Special) && (category != HW_Category_Scalar) &&
+ HWIntrinsicInfo::RequiresCodegen(intrinsicId) | !HWIntrinsicInfo::HasSpecialImport(intrinsicId);
}
//------------------------------------------------------------------------
@@ -640,7 +639,6 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
{
InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsic);
HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsic);
- HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(intrinsic);
int numArgs = sig->numArgs;
var_types retType = JITtype2varType(sig->retType);
var_types baseType = TYP_UNKNOWN;
@@ -659,7 +657,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
// - intrinsics do not require 64-bit registers (r64) on 32-bit platforms (signatureTypeSupproted returns
// true)
bool issupported =
- compSupports(isa) && compSupportsHWIntrinsic(isa) && hwIntrinsicSignatureTypeSupported(retType, sig, flags);
+ compSupports(isa) && compSupportsHWIntrinsic(isa) && hwIntrinsicSignatureTypeSupported(retType, sig, intrinsic);
if (category == HW_Category_IsSupportedProperty)
{
@@ -676,7 +674,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
GenTree* lastOp = impStackTop().val;
// The imm-HWintrinsics that do not accept all imm8 values may throw
// ArgumentOutOfRangeException when the imm argument is not in the valid range
- if ((flags & HW_Flag_FullRangeIMM) == 0)
+ if (!HWIntrinsicInfo::HasFullRangeImm(intrinsic))
{
if (!mustExpand && lastOp->IsCnsIntOrI() &&
lastOp->AsIntCon()->IconValue() > HWIntrinsicInfo::lookupImmUpperBound(intrinsic))
@@ -687,7 +685,12 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
if (!lastOp->IsCnsIntOrI())
{
- if ((flags & HW_Flag_NoJmpTableIMM) == 0 && !mustExpand)
+ if (HWIntrinsicInfo::NoJmpTableImm(intrinsic))
+ {
+ return impNonConstFallback(intrinsic, retType, baseType);
+ }
+
+ if (!mustExpand)
{
// When the imm-argument is not a constant and we are not being forced to expand, we need to
// return nullptr so a GT_CALL to the intrinsic method is emitted instead. The
@@ -695,25 +698,21 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
// we emit some less efficient fallback code.
return nullptr;
}
- else if ((flags & HW_Flag_NoJmpTableIMM) != 0)
- {
- return impNonConstFallback(intrinsic, retType, baseType);
- }
}
}
- bool isTableDriven = impIsTableDrivenHWIntrinsic(category, flags);
+ bool isTableDriven = impIsTableDrivenHWIntrinsic(intrinsic, category);
if (isTableDriven && ((category == HW_Category_MemoryStore) ||
- ((flags & (HW_Flag_BaseTypeFromFirstArg | HW_Flag_BaseTypeFromSecondArg)) != 0)))
+ HWIntrinsicInfo::BaseTypeFromFirstArg(intrinsic) || HWIntrinsicInfo::BaseTypeFromSecondArg(intrinsic)))
{
- if ((flags & HW_Flag_BaseTypeFromFirstArg) != 0)
+ if (HWIntrinsicInfo::BaseTypeFromFirstArg(intrinsic))
{
baseType = getBaseTypeOfSIMDType(info.compCompHnd->getArgClass(sig, sig->args));
}
else
{
- assert((category == HW_Category_MemoryStore) || ((flags & HW_Flag_BaseTypeFromSecondArg) != 0));
+ assert((category == HW_Category_MemoryStore) || HWIntrinsicInfo::BaseTypeFromSecondArg(intrinsic));
CORINFO_ARG_LIST_HANDLE secondArg = info.compCompHnd->getArgNext(sig->args);
CORINFO_CLASS_HANDLE secondArgClass = info.compCompHnd->getArgClass(sig, secondArg);
baseType = getBaseTypeOfSIMDType(secondArgClass);
@@ -728,14 +727,14 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
assert(baseType != TYP_UNKNOWN);
}
- if (((flags & (HW_Flag_OneTypeGeneric | HW_Flag_TwoTypeGeneric)) != 0) && ((flags & HW_Flag_SpecialImport) == 0))
+ if ((HWIntrinsicInfo::IsOneTypeGeneric(intrinsic) || HWIntrinsicInfo::IsTwoTypeGeneric(intrinsic)) && !HWIntrinsicInfo::HasSpecialImport(intrinsic))
{
if (!varTypeIsArithmetic(baseType))
{
return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED, method, sig, mustExpand);
}
- if ((flags & HW_Flag_TwoTypeGeneric) != 0)
+ if (HWIntrinsicInfo::IsTwoTypeGeneric(intrinsic))
{
// StaticCast<T, U> has two type parameters.
assert(numArgs == 1);
@@ -747,7 +746,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
}
}
- if ((flags & HW_Flag_NoFloatingPointUsed) == 0)
+ if (HWIntrinsicInfo::IsFloatingPointUsed(intrinsic))
{
// Set `compFloatingPointUsed` to cover the scenario where an intrinsic is being on SIMD fields, but
// where no SIMD local vars are in use. This is the same logic as is used for FEATURE_SIMD.
diff --git a/src/jit/hwintrinsicxarch.h b/src/jit/hwintrinsicxarch.h
index 4af604e3cc..dc1df77f0e 100644
--- a/src/jit/hwintrinsicxarch.h
+++ b/src/jit/hwintrinsicxarch.h
@@ -200,6 +200,128 @@ struct HWIntrinsicInfo
{
return lookup(id).flags;
}
+
+ // Flags lookup
+
+ static const bool IsCommutative(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_Commutative) != 0;
+ }
+
+ static const bool HasFullRangeImm(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_FullRangeIMM) != 0;
+ }
+
+ static const bool IsOneTypeGeneric(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_OneTypeGeneric) != 0;
+ }
+
+ static const bool IsTwoTypeGeneric(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_TwoTypeGeneric) != 0;
+ }
+
+ static const bool RequiresCodegen(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_NoCodeGen) == 0;
+ }
+
+ static const bool HasFixedSimdSize(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_UnfixedSIMDSize) == 0;
+ }
+
+ static const bool HasComplexOverloads(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_ComplexOverloads) != 0;
+ }
+
+ static const bool GeneratesMultipleIns(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_MultiIns) != 0;
+ }
+
+ static const bool SupportsContainment(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_NoContainment) == 0;
+ }
+
+ static const bool CopiesUpperBits(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_CopyUpperBits) != 0;
+ }
+
+ static const bool BaseTypeFromFirstArg(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_BaseTypeFromFirstArg) != 0;
+ }
+
+ static const bool IsFloatingPointUsed(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_NoFloatingPointUsed) == 0;
+ }
+
+ static const bool MaybeImm(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_MaybeIMM) != 0;
+ }
+
+ static const bool NoJmpTableImm(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_NoJmpTableIMM) != 0;
+ }
+
+ static const bool Is64BitOnly(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_64BitOnly) != 0;
+ }
+
+ static const bool SecondArgMaybe64Bit(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_SecondArgMaybe64Bit) != 0;
+ }
+
+ static const bool BaseTypeFromSecondArg(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_BaseTypeFromSecondArg) != 0;
+ }
+
+ static const bool HasSpecialCodegen(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_SpecialCodeGen) != 0;
+ }
+
+ static const bool HasRMWSemantics(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_NoRMWSemantics) == 0;
+ }
+
+ static const bool HasSpecialImport(NamedIntrinsic id)
+ {
+ HWIntrinsicFlag flags = lookupFlags(id);
+ return (flags & HW_Flag_SpecialImport) != 0;
+ }
};
#endif // FEATURE_HW_INTRINSICS
diff --git a/src/jit/lowerxarch.cpp b/src/jit/lowerxarch.cpp
index 49bea0d0fa..27fa52a6bd 100644
--- a/src/jit/lowerxarch.cpp
+++ b/src/jit/lowerxarch.cpp
@@ -2312,7 +2312,7 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode, Ge
HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(containingIntrinsicID);
// We shouldn't have called in here if containingNode doesn't support containment
- assert((HWIntrinsicInfo::lookupFlags(containingIntrinsicID) & HW_Flag_NoContainment) == 0);
+ assert(HWIntrinsicInfo::SupportsContainment(containingIntrinsicID));
// containingNode supports nodes that read from an aligned memory address
//
@@ -2504,7 +2504,6 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
{
NamedIntrinsic intrinsicID = node->gtHWIntrinsicId;
HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicID);
- HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(intrinsicID);
int numArgs = HWIntrinsicInfo::lookupNumArgs(node);
var_types baseType = node->gtSIMDBaseType;
@@ -2512,7 +2511,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
GenTree* op2 = node->gtGetOp2();
GenTree* op3 = nullptr;
- if ((flags & HW_Flag_NoContainment) != 0)
+ if (!HWIntrinsicInfo::SupportsContainment(intrinsicID))
{
// Exit early if containment isn't supported
return;
@@ -2520,7 +2519,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
// TODO-XArch-CQ: Non-VEX encoded instructions can have both ops contained
- bool isCommutative = ((flags & HW_Flag_Commutative) != 0);
+ const bool isCommutative = HWIntrinsicInfo::IsCommutative(intrinsicID);
if (numArgs == 1)
{
@@ -2613,7 +2612,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
{
// Intrinsics with CopyUpperBits semantics cannot have op1 be contained
- if ((flags & HW_Flag_CopyUpperBits) == 0)
+ if (!HWIntrinsicInfo::CopiesUpperBits(intrinsicID))
{
// 231 form: op3 = (op2 * op3) + [op1]
MakeSrcContained(node, op1);
diff --git a/src/jit/lsraxarch.cpp b/src/jit/lsraxarch.cpp
index 2a4d1b2a37..490c8fa1ad 100644
--- a/src/jit/lsraxarch.cpp
+++ b/src/jit/lsraxarch.cpp
@@ -2294,7 +2294,6 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
var_types baseType = intrinsicTree->gtSIMDBaseType;
InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsicId);
HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId);
- HWIntrinsicFlag flags = HWIntrinsicInfo::lookupFlags(intrinsicId);
int numArgs = HWIntrinsicInfo::lookupNumArgs(intrinsicTree);
if ((isa == InstructionSet_AVX) || (isa == InstructionSet_AVX2))
@@ -2353,7 +2352,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
bool buildUses = true;
- if ((category == HW_Category_IMM) && ((flags & HW_Flag_NoJmpTableIMM) == 0))
+ if ((category == HW_Category_IMM) && !HWIntrinsicInfo::NoJmpTableImm(intrinsicId))
{
if (HWIntrinsicInfo::isImmOp(intrinsicId, lastOp) && !lastOp->isContainedIntOrIImmed())
{
@@ -2522,16 +2521,16 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
assert(numArgs == 3);
assert(isRMW);
- bool copyUpperBits = (flags & HW_Flag_CopyUpperBits) != 0;
+ const bool copiesUpperBits = HWIntrinsicInfo::CopiesUpperBits(intrinsicId);;
// Intrinsics with CopyUpperBits semantics cannot have op1 be contained
- assert(!copyUpperBits || !op1->isContained());
+ assert(!copiesUpperBits || !op1->isContained());
if (op3->isContained())
{
// 213 form: op1 = (op2 * op1) + [op3]
- if (copyUpperBits)
+ if (copiesUpperBits)
{
tgtPrefUse = BuildUse(op1);
@@ -2573,7 +2572,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
{
// 213 form: op1 = (op2 * op1) + op3
- if (copyUpperBits)
+ if (copiesUpperBits)
{
tgtPrefUse = BuildUse(op1);