summaryrefslogtreecommitdiff
path: root/src/jit/emitarm.cpp
diff options
context:
space:
mode:
authorMikhail Skvortcov <m.skvortcov@partner.samsung.com>2017-04-12 09:18:08 +0300
committerMikhail Skvortcov <m.skvortcov@partner.samsung.com>2017-04-12 09:32:32 +0300
commit21b64422dc80a21eee8dfb8a64b9136ef7a0adcc (patch)
treea5b8e916fd3659eac8d0ee163efd698b4153badc /src/jit/emitarm.cpp
parent737ae7288bfd1537525b76b01edf21cba868fa9c (diff)
downloadcoreclr-21b64422dc80a21eee8dfb8a64b9136ef7a0adcc.tar.gz
coreclr-21b64422dc80a21eee8dfb8a64b9136ef7a0adcc.tar.bz2
coreclr-21b64422dc80a21eee8dfb8a64b9136ef7a0adcc.zip
RyuJIT/ARM32: encodable offsets for ld/st
Diffstat (limited to 'src/jit/emitarm.cpp')
-rw-r--r--src/jit/emitarm.cpp36
1 files changed, 33 insertions, 3 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