summaryrefslogtreecommitdiff
path: root/src/jit/codegenarmarch.cpp
diff options
context:
space:
mode:
authorHyeongseok Oh <hseok82.oh@samsung.com>2017-07-11 10:49:55 +0900
committerHyeongseok Oh <hseok82.oh@samsung.com>2017-07-11 10:49:55 +0900
commitf2907af68caaec855a16118876492c42ed88d745 (patch)
tree59cd711817faa072286f668da6cae33e06a90bea /src/jit/codegenarmarch.cpp
parentd8b212f3190bedac609bf822638561e515694a93 (diff)
downloadcoreclr-f2907af68caaec855a16118876492c42ed88d745.tar.gz
coreclr-f2907af68caaec855a16118876492c42ed88d745.tar.bz2
coreclr-f2907af68caaec855a16118876492c42ed88d745.zip
[RyuJIT/ARM32] Internal register candadate for split struct argument
Change candidate mask for internal register candidate to not include target registers. On codegen phase, if addrReg is allocated to be destroyed by targetReg, we use internal register as addrReg.
Diffstat (limited to 'src/jit/codegenarmarch.cpp')
-rw-r--r--src/jit/codegenarmarch.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp
index e5146445a4..3339e56e0f 100644
--- a/src/jit/codegenarmarch.cpp
+++ b/src/jit/codegenarmarch.cpp
@@ -1019,6 +1019,11 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
// Generate code to load the address that we need into a register
genConsumeAddress(addrNode);
addrReg = addrNode->gtRegNum;
+
+ // If addrReg equal to baseReg, we use the last target register as alternative baseReg.
+ // Because the candidate mask for the internal baseReg does not include any of the target register,
+ // we can ensure that baseReg, addrReg, and the last target register are not all same.
+ assert(baseReg != addrReg);
}
// If we have an HFA we can't have any GC pointers,
@@ -1062,7 +1067,8 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
nextIndex += 1;
}
- // Set registers
+ // We set up the registers in order, so that we assign the last target register `baseReg` is no longer in use,
+ // in case we had to reuse the last target register for it.
structOffset = 0;
for (unsigned idx = 0; idx < treeNode->gtNumRegs; idx++)
{
@@ -1077,7 +1083,12 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
else
{
// check for case of destroying the addrRegister while we still need it
- assert(targetReg != addrReg);
+ if (targetReg == addrReg && idx != treeNode->gtNumRegs - 1)
+ {
+ assert(targetReg != baseReg);
+ emit->emitIns_R_R(INS_mov, emitTypeSize(type), baseReg, addrReg);
+ addrReg = baseReg;
+ }
// Load from our address expression source
emit->emitIns_R_R_I(INS_ldr, emitTypeSize(type), targetReg, addrReg, structOffset);