diff options
author | Mikhail Skvortcov <m.skvortcov@partner.samsung.com> | 2017-04-12 09:18:08 +0300 |
---|---|---|
committer | Mikhail Skvortcov <m.skvortcov@partner.samsung.com> | 2017-04-12 09:32:32 +0300 |
commit | 21b64422dc80a21eee8dfb8a64b9136ef7a0adcc (patch) | |
tree | a5b8e916fd3659eac8d0ee163efd698b4153badc /src/jit/emitarm.cpp | |
parent | 737ae7288bfd1537525b76b01edf21cba868fa9c (diff) | |
download | coreclr-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.cpp | 36 |
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 |