diff options
author | Hyung-Kyu Choi <hk0110.choi@samsung.com> | 2017-10-25 17:49:38 +0900 |
---|---|---|
committer | Hyung-Kyu Choi <hk0110.choi@samsung.com> | 2017-10-25 19:17:46 +0900 |
commit | 40e95f2bce9f50dcd26150994149c0fd476622f7 (patch) | |
tree | ba2cc700f4d3eb8242375a591f3d39e9021a1451 /src | |
parent | 138f0b70a3dbdc695aa805356a65fb8a741b11b2 (diff) | |
download | coreclr-40e95f2bce9f50dcd26150994149c0fd476622f7.tar.gz coreclr-40e95f2bce9f50dcd26150994149c0fd476622f7.tar.bz2 coreclr-40e95f2bce9f50dcd26150994149c0fd476622f7.zip |
[RyuJIT/ARM32] Fix to find a free temp double register correctly
When finding a free temporary double register to resolve conflicting edges,
we have to consider both two float registers consisting a double register.
Signed-off-by: Hyung-Kyu Choi <hk0110.choi@samsung.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/jit/lsra.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp index 41184f8db8..56bd2dbd6f 100644 --- a/src/jit/lsra.cpp +++ b/src/jit/lsra.cpp @@ -10029,7 +10029,21 @@ regNumber LinearScan::getTempRegForResolution(BasicBlock* fromBlock, BasicBlock* VarToRegMap fromVarToRegMap = getOutVarToRegMap(fromBlock->bbNum); VarToRegMap toVarToRegMap = getInVarToRegMap(toBlock->bbNum); +#ifdef _TARGET_ARM_ + regMaskTP freeRegs; + if (type == TYP_DOUBLE) + { + // We have to consider all float registers for TYP_DOUBLE + freeRegs = allRegs(TYP_FLOAT); + } + else + { + freeRegs = allRegs(type); + } +#else // !_TARGET_ARM_ regMaskTP freeRegs = allRegs(type); +#endif // !_TARGET_ARM_ + #ifdef DEBUG if (getStressLimitRegs() == LSRA_LIMIT_SMALL_SET) { @@ -10048,13 +10062,22 @@ regNumber LinearScan::getTempRegForResolution(BasicBlock* fromBlock, BasicBlock* assert(fromReg != REG_NA && toReg != REG_NA); if (fromReg != REG_STK) { - freeRegs &= ~genRegMask(fromReg); + freeRegs &= ~genRegMask(fromReg, getIntervalForLocalVar(varIndex)->registerType); } if (toReg != REG_STK) { - freeRegs &= ~genRegMask(toReg); + freeRegs &= ~genRegMask(toReg, getIntervalForLocalVar(varIndex)->registerType); } } + +#ifdef _TARGET_ARM_ + if (type == TYP_DOUBLE) + { + // Exclude any doubles for which the odd half isn't in freeRegs. + freeRegs = freeRegs & ((freeRegs << 1) & RBM_ALLDOUBLE); + } +#endif + if (freeRegs == RBM_NONE) { return REG_NA; @@ -10674,7 +10697,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT); } #else - tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT); + tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT); #endif } |