Skip to content

Commit

Permalink
Refactor how the embedded rounding is handled so the logic is more re…
Browse files Browse the repository at this point in the history
…usable (#97569)

* Refactor how the embedded rounding is handled so the logic is more reusable

* Remove some unnecessary changes

* Apply formatting patch

* Ensure we always consume the rounding mode operand and produce the register
  • Loading branch information
tannergooding committed Jan 28, 2024
1 parent 4fc943c commit 7a60900
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 216 deletions.
23 changes: 14 additions & 9 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -974,31 +974,30 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#if defined(TARGET_XARCH)
void genHWIntrinsic_R_RM(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr, regNumber reg, GenTree* rmOp);
void genHWIntrinsic_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr, int8_t ival);
void genHWIntrinsic_R_R_RM(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr);
void genHWIntrinsic_R_R_RM(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr, int8_t ival);
void genHWIntrinsic_R_R_RM(
GenTreeHWIntrinsic* node, instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, GenTree* op2);
void genHWIntrinsic_R_R_RM(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr, insOpts instOptions);
void genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr, int8_t ival);
void genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr);
void genHWIntrinsic_R_R_R_RM(
instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTree* op3);
void genHWIntrinsic_R_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins, emitAttr attr, int8_t ival);

void genBaseIntrinsic(GenTreeHWIntrinsic* node);
void genX86BaseIntrinsic(GenTreeHWIntrinsic* node);
void genSSEIntrinsic(GenTreeHWIntrinsic* node);
void genSSE2Intrinsic(GenTreeHWIntrinsic* node);
void genSSEIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions);
void genSSE2Intrinsic(GenTreeHWIntrinsic* node, insOpts instOptions);
void genSSE41Intrinsic(GenTreeHWIntrinsic* node);
void genSSE42Intrinsic(GenTreeHWIntrinsic* node);
void genAvxFamilyIntrinsic(GenTreeHWIntrinsic* node);
void genAvxFamilyIntrinsic(GenTreeHWIntrinsic* node, insOpts instOptions);
void genAESIntrinsic(GenTreeHWIntrinsic* node);
void genBMI1OrBMI2Intrinsic(GenTreeHWIntrinsic* node);
void genBMI1OrBMI2Intrinsic(GenTreeHWIntrinsic* node, insOpts instOptions);
void genFMAIntrinsic(GenTreeHWIntrinsic* node);
void genPermuteVar2x(GenTreeHWIntrinsic* node);
void genLZCNTIntrinsic(GenTreeHWIntrinsic* node);
void genPCLMULQDQIntrinsic(GenTreeHWIntrinsic* node);
void genPOPCNTIntrinsic(GenTreeHWIntrinsic* node);
void genXCNTIntrinsic(GenTreeHWIntrinsic* node, instruction ins);
void genX86SerializeIntrinsic(GenTreeHWIntrinsic* node);

template <typename HWIntrinsicSwitchCaseBody>
void genHWIntrinsicJumpTableFallback(NamedIntrinsic intrinsic,
regNumber nonConstImmReg,
Expand Down Expand Up @@ -1562,7 +1561,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void inst_RV_TT(instruction ins, emitAttr size, regNumber op1Reg, GenTree* op2);
void inst_RV_RV_IV(instruction ins, emitAttr size, regNumber reg1, regNumber reg2, unsigned ival);
void inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenTree* rmOp, int ival);
void inst_RV_RV_TT(instruction ins, emitAttr size, regNumber targetReg, regNumber op1Reg, GenTree* op2, bool isRMW);
void inst_RV_RV_TT(instruction ins,
emitAttr size,
regNumber targetReg,
regNumber op1Reg,
GenTree* op2,
bool isRMW,
insOpts instOptions);
void inst_RV_RV_TT_IV(
instruction ins, emitAttr size, regNumber targetReg, regNumber op1Reg, GenTree* op2, int8_t ival, bool isRMW);
#endif
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,7 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
// all have RMW semantics if VEX support is not available

bool isRMW = !compiler->canUseVexEncoding();
inst_RV_RV_TT(ins, emitTypeSize(treeNode), targetReg, op1reg, op2, isRMW);
inst_RV_RV_TT(ins, emitTypeSize(treeNode), targetReg, op1reg, op2, isRMW, INS_OPTS_NONE);

genProduceReg(treeNode);
return;
Expand Down Expand Up @@ -7494,7 +7494,7 @@ void CodeGen::genFloatToFloatCast(GenTree* treeNode)
// is not available

bool isRMW = !compiler->canUseVexEncoding();
inst_RV_RV_TT(ins, emitTypeSize(dstType), targetReg, targetReg, op1, isRMW);
inst_RV_RV_TT(ins, emitTypeSize(dstType), targetReg, targetReg, op1, isRMW, INS_OPTS_NONE);
}

genProduceReg(treeNode);
Expand Down Expand Up @@ -7606,7 +7606,7 @@ void CodeGen::genIntToFloatCast(GenTree* treeNode)
// is not available

bool isRMW = !compiler->canUseVexEncoding();
inst_RV_RV_TT(ins, emitTypeSize(srcType), targetReg, targetReg, op1, isRMW);
inst_RV_RV_TT(ins, emitTypeSize(srcType), targetReg, targetReg, op1, isRMW, INS_OPTS_NONE);

// Handle the case of srcType = TYP_ULONG. SSE2 conversion instruction
// will interpret ULONG value as LONG. Hence we need to adjust the
Expand Down Expand Up @@ -8127,7 +8127,7 @@ void CodeGen::genIntrinsic(GenTreeIntrinsic* treeNode)
regNumber targetReg = treeNode->GetRegNum();
bool isRMW = !compiler->canUseVexEncoding();

inst_RV_RV_TT(ins, emitTypeSize(treeNode), targetReg, targetReg, srcNode, isRMW);
inst_RV_RV_TT(ins, emitTypeSize(treeNode), targetReg, targetReg, srcNode, isRMW, INS_OPTS_NONE);
break;
}

Expand Down
44 changes: 0 additions & 44 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,13 +556,6 @@ enum GenTreeFlags : unsigned int
GTF_MDARRLEN_NONFAULTING = 0x20000000, // GT_MDARR_LENGTH -- An MD array length operation that cannot fault. Same as GT_IND_NONFAULTING.

GTF_MDARRLOWERBOUND_NONFAULTING = 0x20000000, // GT_MDARR_LOWER_BOUND -- An MD array lower bound operation that cannot fault. Same as GT_IND_NONFAULTING.

GTF_HW_ER_MASK = 0x30000000, // Bits used by handle types below
GTF_HW_ER_TO_EVEN = 0x00000000, // GT_HWINTRINSIC -- embedded rounding mode: FloatRoundingMode = ToEven (Default) "{rn-sae}"
GTF_HW_ER_TO_NEGATIVEINFINITY = 0x10000000, // GT_HWINTRINSIC -- embedded rounding mode: FloatRoundingMode = ToNegativeInfinity "{rd-sae}"
GTF_HW_ER_TO_POSITIVEINFINITY = 0x20000000, // GT_HWINTRINSIC -- embedded rounding mode: FloatRoundingMode = ToPositiveInfinity "{ru-sae}"
GTF_HW_ER_TO_ZERO = 0x30000000, // GT_HWINTRINSIC -- embedded rounding mode: FloatRoundingMode = ToZero "{rz-sae}"

};

inline constexpr GenTreeFlags operator ~(GenTreeFlags a)
Expand Down Expand Up @@ -2232,43 +2225,6 @@ struct GenTree
return (gtOper == GT_CNS_INT) ? (gtFlags & GTF_ICON_HDL_MASK) : GTF_EMPTY;
}

#ifdef FEATURE_HW_INTRINSICS

void ClearEmbRoundingMode()
{
assert(gtOper == GT_HWINTRINSIC);
gtFlags &= ~GTF_HW_ER_MASK;
}
// Set GenTreeFlags on HardwareIntrinsic node to specify the FloatRoundingMode.
// mode can be one of the values from System.Runtime.Intrinsics.X86.FloatRoundingMode.
void SetEmbRoundingMode(uint8_t mode)
{
assert(gtOper == GT_HWINTRINSIC);
ClearEmbRoundingMode();
switch (mode)
{
case 0x09:
gtFlags |= GTF_HW_ER_TO_NEGATIVEINFINITY;
break;
case 0x0A:
gtFlags |= GTF_HW_ER_TO_POSITIVEINFINITY;
break;
case 0x0B:
gtFlags |= GTF_HW_ER_TO_ZERO;
break;
default:
break;
}
}

uint8_t GetEmbRoundingMode()
{
assert(gtOper == GT_HWINTRINSIC);
return (uint8_t)((gtFlags & GTF_HW_ER_MASK) >> 28);
}

#endif // FEATURE_HW_INTRINSICS

// Mark this node as no longer being a handle; clear its GTF_ICON_*_HDL bits.
void ClearIconHandleMask()
{
Expand Down
Loading

0 comments on commit 7a60900

Please sign in to comment.