summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2017-04-12 09:00:34 -0700
committerGitHub <noreply@github.com>2017-04-12 09:00:34 -0700
commitf00dfaf7bf0c137ec904a9d3a480a55e3f9f79a1 (patch)
tree5d05d423f14903bb7e288314c04943268d2324ff /src
parente117bea8ce2e9f713351b184feac7dd780753a39 (diff)
parent21b64422dc80a21eee8dfb8a64b9136ef7a0adcc (diff)
downloadcoreclr-f00dfaf7bf0c137ec904a9d3a480a55e3f9f79a1.tar.gz
coreclr-f00dfaf7bf0c137ec904a9d3a480a55e3f9f79a1.tar.bz2
coreclr-f00dfaf7bf0c137ec904a9d3a480a55e3f9f79a1.zip
Merge pull request #10852 from mskvortsov/ryujit-arm32-ldst-offset
[RyuJIT/ARM32] Encodable offsets for ld/st
Diffstat (limited to 'src')
-rw-r--r--src/jit/emitarm.cpp36
-rw-r--r--src/jit/emitarm.h1
-rw-r--r--src/jit/lsraarmarch.cpp12
3 files changed, 36 insertions, 13 deletions
diff --git a/src/jit/emitarm.cpp b/src/jit/emitarm.cpp
index ebefa27fb8..53ee88b3a2 100644
--- a/src/jit/emitarm.cpp
+++ b/src/jit/emitarm.cpp
@@ -1422,6 +1422,20 @@ DONE:
/*****************************************************************************
*
+ * emitIns_valid_imm_for_ldst_offset() returns true when the immediate 'imm'
+ * can be encoded as the offset in a ldr/str instruction.
+ */
+/*static*/ bool emitter::emitIns_valid_imm_for_ldst_offset(int imm, emitAttr size)
+{
+ if ((imm & 0x0fff) == imm)
+ return true; // encodable using IF_T2_K1
+ if (unsigned_abs(imm) <= 0x0ff)
+ return true; // encodable using IF_T2_H0
+ return false;
+}
+
+/*****************************************************************************
+ *
* Add an instruction with no operands.
*/
@@ -7608,10 +7622,26 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
}
}
}
- else
+ else // no Index
{
- // TODO check offset is valid for encoding
- emitIns_R_R_I(ins, attr, dataReg, memBase->gtRegNum, offset);
+ if (emitIns_valid_imm_for_ldst_offset(offset, attr))
+ {
+ // Then load/store dataReg from/to [memBase + offset]
+ emitIns_R_R_I(ins, attr, dataReg, memBase->gtRegNum, offset);
+ }
+ else
+ {
+ // We require a tmpReg to hold the offset
+ regMaskTP tmpRegMask = indir->gtRsvdRegs;
+ regNumber tmpReg = genRegNumFromMask(tmpRegMask);
+ noway_assert(tmpReg != REG_NA);
+
+ // First load/store tmpReg with the large offset constant
+ codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset);
+
+ // Then load/store dataReg from/to [memBase + tmpReg]
+ emitIns_R_R_R(ins, attr, dataReg, memBase->gtRegNum, tmpReg);
+ }
}
}
else
diff --git a/src/jit/emitarm.h b/src/jit/emitarm.h
index 4ec189385c..d7c8d4d0ef 100644
--- a/src/jit/emitarm.h
+++ b/src/jit/emitarm.h
@@ -243,6 +243,7 @@ static bool emitIns_valid_imm_for_small_mov(regNumber reg, int imm, insFlags fla
static bool emitIns_valid_imm_for_add(int imm, insFlags flags);
static bool emitIns_valid_imm_for_cmp(int imm, insFlags flags);
static bool emitIns_valid_imm_for_add_sp(int imm);
+static bool emitIns_valid_imm_for_ldst_offset(int imm, emitAttr size);
void emitIns(instruction ins);
diff --git a/src/jit/lsraarmarch.cpp b/src/jit/lsraarmarch.cpp
index 11fc490954..7d999d880f 100644
--- a/src/jit/lsraarmarch.cpp
+++ b/src/jit/lsraarmarch.cpp
@@ -291,19 +291,13 @@ void Lowering::TreeNodeInfoInitIndir(GenTreePtr indirTree)
if (index != nullptr && !modifiedSources)
{
info->srcCount++;
-
-#ifdef _TARGET_ARM_
- info->internalIntCount++;
-#endif // _TARGET_ARM_
}
-#ifdef _TARGET_ARM64_
-
- // On ARM64 we may need a single internal register
+ // On ARM we may need a single internal register
// (when both conditions are true then we still only need a single internal register)
if ((index != nullptr) && (cns != 0))
{
- // ARM64 does not support both Index and offset so we need an internal register
+ // ARM does not support both Index and offset so we need an internal register
info->internalIntCount = 1;
}
else if (!emitter::emitIns_valid_imm_for_ldst_offset(cns, emitTypeSize(indirTree)))
@@ -311,8 +305,6 @@ void Lowering::TreeNodeInfoInitIndir(GenTreePtr indirTree)
// This offset can't be contained in the ldr/str instruction, so we need an internal register
info->internalIntCount = 1;
}
-
-#endif // _TARGET_ARM64_
}
//------------------------------------------------------------------------