From: Mikhail Skvortcov Date: Wed, 12 Apr 2017 06:18:08 +0000 (+0300) Subject: RyuJIT/ARM32: encodable offsets for ld/st X-Git-Tag: submit/tizen/20210909.063632~11030^2~7294^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1b6be2dfdd67ab301e089649920a1049d0cd7b11;p=platform%2Fupstream%2Fdotnet%2Fruntime.git RyuJIT/ARM32: encodable offsets for ld/st Commit migrated from https://github.com/dotnet/coreclr/commit/21b64422dc80a21eee8dfb8a64b9136ef7a0adcc --- diff --git a/src/coreclr/src/jit/emitarm.cpp b/src/coreclr/src/jit/emitarm.cpp index ebefa27..53ee88b 100644 --- a/src/coreclr/src/jit/emitarm.cpp +++ b/src/coreclr/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/coreclr/src/jit/emitarm.h b/src/coreclr/src/jit/emitarm.h index 4ec1893..d7c8d4d 100644 --- a/src/coreclr/src/jit/emitarm.h +++ b/src/coreclr/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/coreclr/src/jit/lsraarmarch.cpp b/src/coreclr/src/jit/lsraarmarch.cpp index 11fc490..7d999d8 100644 --- a/src/coreclr/src/jit/lsraarmarch.cpp +++ b/src/coreclr/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_ } //------------------------------------------------------------------------