diff options
author | Carol Eidt <carol.eidt@microsoft.com> | 2018-08-27 14:04:19 -0700 |
---|---|---|
committer | Carol Eidt <carol.eidt@microsoft.com> | 2018-08-28 13:32:22 -0700 |
commit | 9e55f6cf2c20945077974311be03951ce9eb346b (patch) | |
tree | bb83ec57fdbc911337829b56c10c113c2e2312ef /src/jit/gentree.h | |
parent | 4a97250c8878cc507dd41a5d25ec73792c1d8ce6 (diff) | |
download | coreclr-9e55f6cf2c20945077974311be03951ce9eb346b.tar.gz coreclr-9e55f6cf2c20945077974311be03951ce9eb346b.tar.bz2 coreclr-9e55f6cf2c20945077974311be03951ce9eb346b.zip |
Handle multiReg COPY
On x86, `MUL_LONG` wasn't considered a multi-reg node, as it should be, so that when it gets spilled or copied, the additional register will be correctly handled.
Also, the ARM and X86 versions of genStoreLongLclVar should be identical and shared (neither version were handling the copy of a `MUL_LONG`).
Finally, fix the LSRA dumping of multi-reg nodes.
Fix #19397
Diffstat (limited to 'src/jit/gentree.h')
-rw-r--r-- | src/jit/gentree.h | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/jit/gentree.h b/src/jit/gentree.h index 724bae66cb..5841e9ed2c 100644 --- a/src/jit/gentree.h +++ b/src/jit/gentree.h @@ -1213,13 +1213,18 @@ public: bool OperIsMultiRegOp() const { +#if !defined(_TARGET_64BIT_) + if (OperIs(GT_MUL_LONG)) + { + return true; + } #if defined(_TARGET_ARM_) - if ((gtOper == GT_MUL_LONG) || (gtOper == GT_PUTARG_REG) || (gtOper == GT_BITCAST)) + if (OperIs(GT_PUTARG_REG, GT_BITCAST)) { return true; } -#endif - +#endif // _TARGET_ARM_ +#endif // _TARGET_64BIT_ return false; } @@ -3839,7 +3844,7 @@ struct GenTreeCmpXchg : public GenTree #endif }; -#if defined(_TARGET_ARM_) +#if !defined(_TARGET_64BIT_) struct GenTreeMultiRegOp : public GenTreeOp { regNumber gtOtherReg; @@ -3994,7 +3999,7 @@ struct GenTreeMultiRegOp : public GenTreeOp } #endif }; -#endif // defined(_TARGET_ARM_) +#endif // !defined(_TARGET_64BIT_) struct GenTreeFptrVal : public GenTree { @@ -5425,6 +5430,11 @@ struct GenTreePutArgSplit : public GenTreePutArgStk #endif // FEATURE_ARG_SPLIT // Represents GT_COPY or GT_RELOAD node +// +// As it turns out, these are only needed on targets that happen to have multi-reg returns. +// However, they are actually needed on any target that has any multi-reg ops. It is just +// coincidence that those are the same (and there isn't a FEATURE_MULTIREG_OPS). +// struct GenTreeCopyOrReload : public GenTreeUnOp { #if FEATURE_MULTIREG_RET @@ -6031,7 +6041,7 @@ inline bool GenTree::IsMultiRegNode() const return true; } -#if defined(_TARGET_ARM_) +#if !defined(_TARGET_64BIT_) if (OperIsMultiRegOp() || OperIsPutArgSplit() || (gtOper == GT_COPY)) { return true; @@ -6061,7 +6071,7 @@ inline unsigned GenTree::GetMultiRegCount() return AsPutArgSplit()->gtNumRegs; } #endif -#if defined(_TARGET_ARM_) +#if !defined(_TARGET_64BIT_) if (OperIsMultiRegOp()) { return AsMultiRegOp()->GetRegCount(); @@ -6102,7 +6112,7 @@ inline regNumber GenTree::GetRegByIndex(int regIndex) return AsPutArgSplit()->GetRegNumByIdx(regIndex); } #endif -#if defined(_TARGET_ARM_) +#if !defined(_TARGET_64BIT_) if (OperIsMultiRegOp()) { return AsMultiRegOp()->GetRegNumByIdx(regIndex); @@ -6143,7 +6153,7 @@ inline var_types GenTree::GetRegTypeByIndex(int regIndex) return AsPutArgSplit()->GetRegType(regIndex); } #endif -#if defined(_TARGET_ARM_) +#if !defined(_TARGET_64BIT_) if (OperIsMultiRegOp()) { return AsMultiRegOp()->GetRegType(regIndex); |