From 8feb986bf4b232e2450849081ca2f1fb110d23c1 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Mon, 22 May 2017 11:34:15 -0700 Subject: [PATCH] Handle INS_adr in emitIns_R_L on both arm32 and arm64 Commit migrated from https://github.com/dotnet/coreclr/commit/48794652d5077bce1f759df58b1550941717fb56 --- src/coreclr/src/jit/codegenarmarch.cpp | 4 -- src/coreclr/src/jit/codegenlegacy.cpp | 12 +----- src/coreclr/src/jit/emitarm.cpp | 75 ++++++++++++++++++---------------- 3 files changed, 41 insertions(+), 50 deletions(-) diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 5ef1219..40fb746 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -341,11 +341,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode) case GT_LABEL: genPendingCallLabel = genCreateTempLabel(); treeNode->gtLabel.gtLabBB = genPendingCallLabel; -#if defined(_TARGET_ARM_) - emit->emitIns_J_R(INS_adr, EA_PTRSIZE, genPendingCallLabel, targetReg); -#elif defined(_TARGET_ARM64_) emit->emitIns_R_L(INS_adr, EA_PTRSIZE, genPendingCallLabel, targetReg); -#endif break; case GT_STORE_OBJ: diff --git a/src/coreclr/src/jit/codegenlegacy.cpp b/src/coreclr/src/jit/codegenlegacy.cpp index 05a162d..1c24b9c 100644 --- a/src/coreclr/src/jit/codegenlegacy.cpp +++ b/src/coreclr/src/jit/codegenlegacy.cpp @@ -13063,22 +13063,12 @@ void CodeGen::genCodeForBBlist() bbFinallyRet = block->bbNext->bbJumpDest; bbFinallyRet->bbFlags |= BBF_JMP_TARGET; -#if 0 - // We don't know the address of finally funclet yet. But adr requires the offset - // to finally funclet from current IP is within 4095 bytes. So this code is disabled - // for now. - getEmitter()->emitIns_J_R (INS_adr, - EA_4BYTE, - bbFinallyRet, - REG_LR); -#else // 0 // Load the address where the finally funclet should return into LR. // The funclet prolog/epilog will do "push {lr}" / "pop {pc}" to do // the return. getEmitter()->emitIns_R_L(INS_movw, EA_4BYTE_DSP_RELOC, bbFinallyRet, REG_LR); getEmitter()->emitIns_R_L(INS_movt, EA_4BYTE_DSP_RELOC, bbFinallyRet, REG_LR); regTracker.rsTrackRegTrash(REG_LR); -#endif // 0 // Jump to the finally BB inst_JMP(EJ_jmp, block->bbJumpDest); @@ -21364,7 +21354,7 @@ regNumber CodeGen::genPInvokeCallProlog(LclVarDsc* frameListRoot, #if CPU_LOAD_STORE_ARCH regNumber tmpReg = regSet.rsGrabReg(RBM_ALLINT & ~genRegMask(tcbReg)); - getEmitter()->emitIns_J_R(INS_adr, EA_PTRSIZE, returnLabel, tmpReg); + getEmitter()->emitIns_R_L(INS_adr, EA_PTRSIZE, returnLabel, tmpReg); regTracker.rsTrackRegTrash(tmpReg); getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, tmpReg, compiler->lvaInlinedPInvokeFrameVar, pInfo->inlinedCallFrameInfo.offsetOfReturnAddress); diff --git a/src/coreclr/src/jit/emitarm.cpp b/src/coreclr/src/jit/emitarm.cpp index 2b8eb25..b738c33 100644 --- a/src/coreclr/src/jit/emitarm.cpp +++ b/src/coreclr/src/jit/emitarm.cpp @@ -4241,24 +4241,29 @@ void emitter::emitIns_J(instruction ins, BasicBlock* dst, int instrCount /* = 0 void emitter::emitIns_R_L(instruction ins, emitAttr attr, BasicBlock* dst, regNumber reg) { - insFormat fmt = IF_NONE; - assert(dst->bbFlags & BBF_JMP_TARGET); + insFormat fmt = IF_NONE; + instrDescJmp* id; + /* Figure out the encoding format of the instruction */ switch (ins) { + case INS_adr: + id = emitNewInstrLbl(); + fmt = IF_T2_M1; + break; case INS_movt: case INS_movw: + id = emitNewInstrJmp(); fmt = IF_T2_N1; break; default: unreached(); } - assert(fmt == IF_T2_N1); + assert((fmt == IF_T2_M1) || (fmt == IF_T2_N1)); - instrDescJmp* id = emitNewInstrJmp(); - insSize isz = emitInsSize(fmt); + insSize isz = emitInsSize(fmt); id->idIns(ins); id->idReg1(reg); @@ -4275,7 +4280,16 @@ void emitter::emitIns_R_L(instruction ins, emitAttr attr, BasicBlock* dst, regNu id->idAddr()->iiaBBlabel = dst; id->idjShort = false; - id->idjKeepLong = true; + + if (ins == INS_adr) + { + id->idReg2(REG_PC); + id->idjKeepLong = emitComp->fgInDifferentRegions(emitComp->compCurBB, dst); + } + else + { + id->idjKeepLong = true; + } /* Record the jump's IG and offset within it */ @@ -4332,39 +4346,30 @@ void emitter::emitIns_J_R(instruction ins, emitAttr attr, BasicBlock* dst, regNu { assert(dst->bbFlags & BBF_JMP_TARGET); - instrDescJmp* id; - if (ins == INS_adr) + insFormat fmt = IF_NONE; + switch (ins) { - id = emitNewInstrLbl(); - - id->idIns(INS_adr); - id->idInsFmt(IF_T2_M1); - id->idInsSize(emitInsSize(IF_T2_M1)); - id->idAddr()->iiaBBlabel = dst; - id->idReg1(reg); - id->idReg2(REG_PC); - - /* Assume the label reference will be long */ - - id->idjShort = 0; - id->idjKeepLong = emitComp->fgInDifferentRegions(emitComp->compCurBB, dst); + case INS_cbz: + case INS_cbnz: + fmt = IF_T1_I; + break; + default: + unreached(); } - else - { - assert(ins == INS_cbz || INS_cbnz); - assert(isLowRegister(reg)); - id = emitNewInstrJmp(); + assert(fmt == IF_T1_I); - id->idIns(ins); - id->idInsFmt(IF_T1_I); - id->idInsSize(emitInsSize(IF_T1_I)); - id->idReg1(reg); + assert(isLowRegister(reg)); - /* This jump better be short or-else! */ - id->idjShort = true; - id->idAddr()->iiaBBlabel = dst; - id->idjKeepLong = false; - } + instrDescJmp* id = emitNewInstrJmp(); + id->idIns(ins); + id->idInsFmt(IF_T1_I); + id->idInsSize(emitInsSize(IF_T1_I)); + id->idReg1(reg); + + /* This jump better be short or-else! */ + id->idjShort = true; + id->idAddr()->iiaBBlabel = dst; + id->idjKeepLong = false; /* Record the jump's IG and offset within it */ -- 2.7.4