Skip to content

Commit 5ec1fcd

Browse files
committed
Add basic support for GT_CLS_VAR_ADDR to the ARM64 JIT
1 parent 07a08aa commit 5ec1fcd

File tree

3 files changed

+45
-17
lines changed

3 files changed

+45
-17
lines changed

src/coreclr/src/jit/emitarm64.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12718,7 +12718,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
1271812718

1271912719
if (addr->isContained())
1272012720
{
12721-
assert(addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_LEA);
12721+
assert(addr->OperGet() == GT_CLS_VAR_ADDR || addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_LEA);
1272212722

1272312723
int offset = 0;
1272412724
DWORD lsl = 0;
@@ -12795,7 +12795,13 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
1279512795
}
1279612796
else // no Index register
1279712797
{
12798-
if (emitIns_valid_imm_for_ldst_offset(offset, emitTypeSize(indir->TypeGet())))
12798+
if (addr->OperGet() == GT_CLS_VAR_ADDR)
12799+
{
12800+
// Get a temp integer register to compute long address.
12801+
regNumber addrReg = indir->GetSingleTempReg();
12802+
emitIns_R_C(ins, attr, dataReg, addrReg, addr->AsClsVar()->gtClsVarHnd, 0);
12803+
}
12804+
else if (emitIns_valid_imm_for_ldst_offset(offset, emitTypeSize(indir->TypeGet())))
1279912805
{
1280012806
// Then load/store dataReg from/to [memBase + offset]
1280112807
emitIns_R_R_I(ins, attr, dataReg, memBase->GetRegNum(), offset);

src/coreclr/src/jit/lowerarmarch.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,10 +857,12 @@ void Lowering::ContainCheckIndir(GenTreeIndir* indirNode)
857857
}
858858
#endif // FEATURE_SIMD
859859

860-
GenTree* addr = indirNode->Addr();
861-
bool makeContained = true;
860+
GenTree* addr = indirNode->Addr();
861+
862862
if ((addr->OperGet() == GT_LEA) && IsSafeToContainMem(indirNode, addr))
863863
{
864+
bool makeContained = true;
865+
864866
#ifdef TARGET_ARM
865867
// ARM floating-point load/store doesn't support a form similar to integer
866868
// ldr Rdst, [Rbase + Roffset] with offset in a register. The only supported
@@ -884,12 +886,23 @@ void Lowering::ContainCheckIndir(GenTreeIndir* indirNode)
884886
}
885887
}
886888
}
887-
#endif
889+
#endif // TARGET_ARM
890+
888891
if (makeContained)
889892
{
890893
MakeSrcContained(indirNode, addr);
891894
}
892895
}
896+
#ifdef TARGET_ARM64
897+
else if (addr->OperGet() == GT_CLS_VAR_ADDR)
898+
{
899+
// These nodes go into an addr mode:
900+
// - GT_CLS_VAR_ADDR turns into a constant.
901+
902+
// make this contained, it turns into a constant that goes into an addr mode
903+
MakeSrcContained(indirNode, addr);
904+
}
905+
#endif // TARGET_ARM64
893906
}
894907

895908
//------------------------------------------------------------------------

src/coreclr/src/jit/lsraarmarch.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,23 +74,32 @@ int LinearScan::BuildIndir(GenTreeIndir* indirTree)
7474

7575
if (addr->isContained())
7676
{
77-
assert(addr->OperGet() == GT_LEA);
78-
GenTreeAddrMode* lea = addr->AsAddrMode();
79-
index = lea->Index();
80-
cns = lea->Offset();
81-
82-
// On ARM we may need a single internal register
83-
// (when both conditions are true then we still only need a single internal register)
84-
if ((index != nullptr) && (cns != 0))
77+
if (addr->OperGet() == GT_LEA)
8578
{
86-
// ARM does not support both Index and offset so we need an internal register
87-
buildInternalIntRegisterDefForNode(indirTree);
79+
GenTreeAddrMode* lea = addr->AsAddrMode();
80+
index = lea->Index();
81+
cns = lea->Offset();
82+
83+
// On ARM we may need a single internal register
84+
// (when both conditions are true then we still only need a single internal register)
85+
if ((index != nullptr) && (cns != 0))
86+
{
87+
// ARM does not support both Index and offset so we need an internal register
88+
buildInternalIntRegisterDefForNode(indirTree);
89+
}
90+
else if (!emitter::emitIns_valid_imm_for_ldst_offset(cns, emitTypeSize(indirTree)))
91+
{
92+
// This offset can't be contained in the ldr/str instruction, so we need an internal register
93+
buildInternalIntRegisterDefForNode(indirTree);
94+
}
8895
}
89-
else if (!emitter::emitIns_valid_imm_for_ldst_offset(cns, emitTypeSize(indirTree)))
96+
#ifdef TARGET_ARM64
97+
else if (addr->OperGet() == GT_CLS_VAR_ADDR)
9098
{
91-
// This offset can't be contained in the ldr/str instruction, so we need an internal register
99+
// Reserve int to load constant from memory (IF_LARGELDC)
92100
buildInternalIntRegisterDefForNode(indirTree);
93101
}
102+
#endif // TARGET_ARM64
94103
}
95104

96105
#ifdef FEATURE_SIMD

0 commit comments

Comments
 (0)