diff options
author | Carol Eidt <carol.eidt@microsoft.com> | 2018-09-18 15:40:32 -0700 |
---|---|---|
committer | Carol Eidt <carol.eidt@microsoft.com> | 2018-09-18 15:40:32 -0700 |
commit | 8194ab91d6d535b15fe46877bbe2cc650595f334 (patch) | |
tree | 2560df0338ca9d3efc1dcf5bb2fb3a3b892764e6 /src/jit/gentree.h | |
parent | 44fd2693a85a35d2f4e532bb5a12f145224ee5bf (diff) | |
download | coreclr-8194ab91d6d535b15fe46877bbe2cc650595f334.tar.gz coreclr-8194ab91d6d535b15fe46877bbe2cc650595f334.tar.bz2 coreclr-8194ab91d6d535b15fe46877bbe2cc650595f334.zip |
Fix MultiReg methods on GenTree
The Copy/Reload case was not being handled for 64-bit targets with multireg ops.
Also, the methods `IsMultiRegNode`, `GetMultiRegCount`, `GetRegByIndex` and `GetRegTypeByIndex` should be in sync.
Fix #20031
Diffstat (limited to 'src/jit/gentree.h')
-rw-r--r-- | src/jit/gentree.h | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/src/jit/gentree.h b/src/jit/gentree.h index 12bb9aaed8..dbb5a75913 100644 --- a/src/jit/gentree.h +++ b/src/jit/gentree.h @@ -6023,20 +6023,39 @@ inline bool GenTree::IsMultiRegCall() const // // Return Value: // Returns true if this GenTree is a multi-reg node. +// +// Notes: +// All targets that support multi-reg ops of any kind also support multi-reg return +// values for calls. Should that change with a future target, this method will need +// to change accordingly. +// inline bool GenTree::IsMultiRegNode() const { +#if FEATURE_MULTIREG_RET if (IsMultiRegCall()) { return true; } +#if FEATURE_ARG_SPLIT + if (OperIsPutArgSplit()) + { + return true; + } +#endif + #if !defined(_TARGET_64BIT_) - if (OperIsMultiRegOp() || OperIsPutArgSplit() || (gtOper == GT_COPY)) + if (OperIsMultiRegOp()) { return true; } #endif + if (OperIs(GT_COPY, GT_RELOAD)) + { + return true; + } +#endif // FEATURE_MULTIREG_RET return false; } //----------------------------------------------------------------------------------- @@ -6047,8 +6066,15 @@ inline bool GenTree::IsMultiRegNode() const // // Return Value: // Returns the number of registers defined by this node. +// +// Notes: +// All targets that support multi-reg ops of any kind also support multi-reg return +// values for calls. Should that change with a future target, this method will need +// to change accordingly. +// inline unsigned GenTree::GetMultiRegCount() { +#if FEATURE_MULTIREG_RET if (IsMultiRegCall()) { return AsCall()->GetReturnTypeDesc()->GetReturnRegCount(); @@ -6060,16 +6086,19 @@ inline unsigned GenTree::GetMultiRegCount() return AsPutArgSplit()->gtNumRegs; } #endif + #if !defined(_TARGET_64BIT_) if (OperIsMultiRegOp()) { return AsMultiRegOp()->GetRegCount(); } +#endif + if (OperIs(GT_COPY, GT_RELOAD)) { return AsCopyOrReload()->GetRegCount(); } -#endif +#endif // FEATURE_MULTIREG_RET assert(!"GetMultiRegCount called with non-multireg node"); return 1; } @@ -6084,12 +6113,20 @@ inline unsigned GenTree::GetMultiRegCount() // Return Value: // The register, if any, assigned to this index for this node. // +// Notes: +// All targets that support multi-reg ops of any kind also support multi-reg return +// values for calls. Should that change with a future target, this method will need +// to change accordingly. +// inline regNumber GenTree::GetRegByIndex(int regIndex) { if (regIndex == 0) { return gtRegNum; } + +#if FEATURE_MULTIREG_RET + if (IsMultiRegCall()) { return AsCall()->GetRegNumByIdx(regIndex); @@ -6106,11 +6143,14 @@ inline regNumber GenTree::GetRegByIndex(int regIndex) { return AsMultiRegOp()->GetRegNumByIdx(regIndex); } +#endif + if (OperIs(GT_COPY, GT_RELOAD)) { return AsCopyOrReload()->GetRegNumByIdx(regIndex); } -#endif +#endif // FEATURE_MULTIREG_RET + assert(!"Invalid regIndex for GetRegFromMultiRegNode"); return REG_NA; } @@ -6129,8 +6169,13 @@ inline regNumber GenTree::GetRegByIndex(int regIndex) // This must be a multireg node that is *not* a copy or reload (which must retrieve the // type from its source), and 'regIndex' must be a valid index for this node. // +// All targets that support multi-reg ops of any kind also support multi-reg return +// values for calls. Should that change with a future target, this method will need +// to change accordingly. +// inline var_types GenTree::GetRegTypeByIndex(int regIndex) { +#if FEATURE_MULTIREG_RET if (IsMultiRegCall()) { return AsCall()->AsCall()->GetReturnTypeDesc()->GetReturnRegType(regIndex); @@ -6148,6 +6193,8 @@ inline var_types GenTree::GetRegTypeByIndex(int regIndex) return AsMultiRegOp()->GetRegType(regIndex); } #endif + +#endif // FEATURE_MULTIREG_RET assert(!"Invalid node type for GetRegTypeByIndex"); return TYP_UNDEF; } |