summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHyung-Kyu Choi <hk0110.choi@samsung.com>2017-10-25 17:49:38 +0900
committerHyung-Kyu Choi <hk0110.choi@samsung.com>2017-10-25 19:17:46 +0900
commit40e95f2bce9f50dcd26150994149c0fd476622f7 (patch)
treeba2cc700f4d3eb8242375a591f3d39e9021a1451 /src
parent138f0b70a3dbdc695aa805356a65fb8a741b11b2 (diff)
downloadcoreclr-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.cpp29
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
}