Skip to content

Commit fde7630

Browse files
Add support to use an indirected address for JMP instructions to ARM64 (dotnet#19281)
* Add support to use an indirected address for JMP instructions to ARM64 - Merge logic between ARM and ARM64
1 parent b37c6d8 commit fde7630

File tree

4 files changed

+24
-40
lines changed

4 files changed

+24
-40
lines changed

src/jit/codegencommon.cpp

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8730,14 +8730,14 @@ void CodeGen::genFnEpilog(BasicBlock* block)
87308730
assert(methHnd != nullptr);
87318731
assert(addrInfo.addr != nullptr);
87328732

8733-
#ifdef _TARGET_ARM_
8733+
#ifdef _TARGET_ARMARCH_
87348734
emitter::EmitCallType callType;
87358735
void* addr;
87368736
regNumber indCallReg;
87378737
switch (addrInfo.accessType)
87388738
{
87398739
case IAT_VALUE:
8740-
if (arm_Valid_Imm_For_BL((ssize_t)addrInfo.addr))
8740+
if (validImmForBL((ssize_t)addrInfo.addr))
87418741
{
87428742
// Simple direct call
87438743
callType = emitter::EC_FUNC_TOKEN;
@@ -8754,7 +8754,7 @@ void CodeGen::genFnEpilog(BasicBlock* block)
87548754
// Load the address into a register, load indirect and call through a register
87558755
// We have to use R12 since we assume the argument registers are in use
87568756
callType = emitter::EC_INDIR_R;
8757-
indCallReg = REG_R12;
8757+
indCallReg = REG_INDIRECT_CALL_TARGET_REG;
87588758
addr = NULL;
87598759
instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, indCallReg, (ssize_t)addrInfo.addr);
87608760
if (addrInfo.accessType == IAT_PVALUE)
@@ -8794,6 +8794,9 @@ void CodeGen::genFnEpilog(BasicBlock* block)
87948794
addr,
87958795
0, // argSize
87968796
EA_UNKNOWN, // retSize
8797+
#if defined(_TARGET_ARM64_)
8798+
EA_UNKNOWN, // secondRetSize
8799+
#endif
87978800
gcInfo.gcVarPtrSetCur,
87988801
gcInfo.gcRegGCrefSetCur,
87998802
gcInfo.gcRegByrefSetCur,
@@ -8805,35 +8808,7 @@ void CodeGen::genFnEpilog(BasicBlock* block)
88058808
true); // isJump
88068809
// clang-format on
88078810
CLANG_FORMAT_COMMENT_ANCHOR;
8808-
8809-
#else // _TARGET_ARM64_
8810-
if (addrInfo.accessType != IAT_VALUE)
8811-
{
8812-
NYI_ARM64("Unsupported JMP indirection");
8813-
}
8814-
8815-
emitter::EmitCallType callType = emitter::EC_FUNC_TOKEN;
8816-
8817-
// Simply emit a jump to the methodHnd. This is similar to a call so we can use
8818-
// the same descriptor with some minor adjustments.
8819-
8820-
// clang-format off
8821-
getEmitter()->emitIns_Call(callType,
8822-
methHnd,
8823-
INDEBUG_LDISASM_COMMA(nullptr)
8824-
addrInfo.addr,
8825-
0, // argSize
8826-
EA_UNKNOWN, // retSize
8827-
EA_UNKNOWN, // secondRetSize
8828-
gcInfo.gcVarPtrSetCur,
8829-
gcInfo.gcRegGCrefSetCur,
8830-
gcInfo.gcRegByrefSetCur,
8831-
BAD_IL_OFFSET, REG_NA, REG_NA, 0, 0, /* iloffset, ireg, xreg, xmul, disp */
8832-
true); /* isJump */
8833-
// clang-format on
8834-
CLANG_FORMAT_COMMENT_ANCHOR;
8835-
8836-
#endif // _TARGET_ARM64_
8811+
#endif //_TARGET_ARMARCH_
88378812
}
88388813
#if FEATURE_FASTTAILCALL
88398814
else

src/jit/instr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,17 @@ bool CodeGen::ins_Writes_Dest(instruction ins)
13331333
}
13341334
#endif // _TARGET_ARM_
13351335

1336+
#if defined(_TARGET_ARM64_)
1337+
bool CodeGenInterface::validImmForBL(ssize_t addr)
1338+
{
1339+
// On arm64, we always assume a call target is in range and generate a 28-bit relative
1340+
// 'bl' instruction. If this isn't sufficient range, the VM will generate a jump stub when
1341+
// we call recordRelocation(). See the IMAGE_REL_ARM64_BRANCH26 case in jitinterface.cpp
1342+
// (for JIT) or zapinfo.cpp (for NGEN). If we cannot allocate a jump stub, it is fatal.
1343+
return true;
1344+
}
1345+
#endif // _TARGET_ARM64_
1346+
13361347
/*****************************************************************************
13371348
*
13381349
* Get the machine dependent instruction for performing sign/zero extension.

src/jit/lowerarmarch.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3939
//
4040
bool Lowering::IsCallTargetInRange(void* addr)
4141
{
42-
#ifdef _TARGET_ARM64_
43-
// On arm64, we always assume a call target is in range and generate a 28-bit relative
44-
// 'bl' instruction. If this isn't sufficient range, the VM will generate a jump stub when
45-
// we call recordRelocation(). See the IMAGE_REL_ARM64_BRANCH26 case in jitinterface.cpp
46-
// (for JIT) or zapinfo.cpp (for NGEN). If we cannot allocate a jump stub, it is fatal.
47-
return true;
48-
#elif defined(_TARGET_ARM_)
4942
return comp->codeGen->validImmForBL((ssize_t)addr);
50-
#endif
5143
}
5244

5345
//------------------------------------------------------------------------

src/jit/target.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,9 @@ typedef unsigned char regNumberSmall;
10891089
#define REG_R2R_INDIRECT_PARAM REG_R4
10901090
#define RBM_R2R_INDIRECT_PARAM RBM_R4
10911091

1092+
// JMP Indirect call register
1093+
#define REG_INDIRECT_CALL_TARGET_REG REG_R12
1094+
10921095
// Registers used by PInvoke frame setup
10931096
#define REG_PINVOKE_FRAME REG_R4
10941097
#define RBM_PINVOKE_FRAME RBM_R4
@@ -1402,6 +1405,9 @@ typedef unsigned char regNumberSmall;
14021405
#define REG_R2R_INDIRECT_PARAM REG_R11
14031406
#define RBM_R2R_INDIRECT_PARAM RBM_R11
14041407

1408+
// JMP Indirect call register
1409+
#define REG_INDIRECT_CALL_TARGET_REG REG_IP0
1410+
14051411
// Registers used by PInvoke frame setup
14061412
#define REG_PINVOKE_FRAME REG_R9
14071413
#define RBM_PINVOKE_FRAME RBM_R9

0 commit comments

Comments
 (0)