Skip to content

Commit af3df85

Browse files
committed
Make emitInsStore/LoadInd more usable
Currently they only work with indir nodes. There's no reason to have such a limitation.
1 parent 77535a6 commit af3df85

File tree

5 files changed

+104
-75
lines changed

5 files changed

+104
-75
lines changed

src/jit/codegenxarch.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4639,7 +4639,7 @@ void CodeGen::genCodeForIndexAddr(GenTreeIndexAddr* node)
46394639
tmpReg = node->GetSingleTempReg();
46404640
arrLen.gtRegNum = tmpReg;
46414641
arrLen.ClearContained();
4642-
getEmitter()->emitInsLoadInd(ins_Load(TYP_INT), EA_4BYTE, arrLen.gtRegNum, &arrLen);
4642+
getEmitter()->emitInsLoad(ins_Load(TYP_INT), EA_4BYTE, arrLen.gtRegNum, arrLen.Addr());
46434643
}
46444644
else
46454645
#endif
@@ -4717,7 +4717,7 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree)
47174717
else
47184718
{
47194719
genConsumeAddress(addr);
4720-
emit->emitInsLoadInd(ins_Load(targetType), emitTypeSize(tree), tree->gtRegNum, tree);
4720+
emit->emitInsLoad(ins_Load(targetType), emitTypeSize(tree), tree->gtRegNum, tree->Addr());
47214721
}
47224722

47234723
genProduceReg(tree);
@@ -4991,7 +4991,7 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
49914991
}
49924992
else
49934993
{
4994-
getEmitter()->emitInsStoreInd(ins_Store(data->TypeGet()), emitTypeSize(tree), tree);
4994+
getEmitter()->emitInsStore(ins_Store(data->TypeGet()), emitTypeSize(tree), tree->Addr(), tree->Data());
49954995
}
49964996
}
49974997
}

src/jit/emit.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,12 +1593,12 @@ class emitter
15931593
CORINFO_FIELD_HANDLE emitFltOrDblConst(double constValue, emitAttr attr);
15941594
regNumber emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src);
15951595
regNumber emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src1, GenTree* src2);
1596-
void emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, GenTreeIndir* mem);
1597-
void emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* mem);
1596+
void emitInsLoad(instruction ins, emitAttr attr, regNumber dstReg, GenTree* addr);
1597+
void emitInsStore(instruction ins, emitAttr attr, GenTree* addr, GenTree* data);
15981598
void emitInsStoreLcl(instruction ins, emitAttr attr, GenTreeLclVarCommon* varNode);
15991599
insFormat emitMapFmtForIns(insFormat fmt, instruction ins);
16001600
insFormat emitMapFmtAtoM(insFormat fmt);
1601-
void emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, instruction ins);
1601+
void emitSetAddrMode(instrDesc* id, instruction ins, insFormat fmt, GenTree* addr);
16021602
void spillIntArgRegsToShadowSlots();
16031603

16041604
/************************************************************************/

src/jit/emitxarch.cpp

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2622,14 +2622,14 @@ emitter::insFormat emitter::emitMapFmtAtoM(insFormat fmt)
26222622
}
26232623

26242624
//------------------------------------------------------------------------
2625-
// emitHandleMemOp: For a memory operand, fill in the relevant fields of the instrDesc.
2625+
// emitSetAddrMode: For a memory operand, fill in the relevant fields of the instrDesc.
26262626
//
26272627
// Arguments:
2628-
// indir - the memory operand.
26292628
// id - the instrDesc to fill in.
2629+
// ins - the instruction we are generating. This might affect the instruction format we choose.
26302630
// fmt - the instruction format to use. This must be one of the ARD, AWR, or ARW formats. If necessary (such as for
26312631
// GT_CLS_VAR_ADDR), this function will map it to the correct format.
2632-
// ins - the instruction we are generating. This might affect the instruction format we choose.
2632+
// addr - the address operand of the indir
26332633
//
26342634
// Assumptions:
26352635
// The correctly sized instrDesc must already be created, e.g., via emitNewInstrAmd() or emitNewInstrAmdCns();
@@ -2647,11 +2647,12 @@ emitter::insFormat emitter::emitMapFmtAtoM(insFormat fmt)
26472647
//
26482648
// idSetIsDspReloc() is called if necessary.
26492649
//
2650-
void emitter::emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, instruction ins)
2650+
void emitter::emitSetAddrMode(instrDesc* id, instruction ins, insFormat fmt, GenTree* addr)
26512651
{
26522652
assert(fmt != IF_NONE);
26532653

2654-
GenTree* memBase = indir->Base();
2654+
AddressModeInfo amInfo(addr);
2655+
GenTree* memBase = amInfo.Base();
26552656

26562657
if ((memBase != nullptr) && memBase->isContained() && (memBase->OperGet() == GT_CLS_VAR_ADDR))
26572658
{
@@ -2708,20 +2709,20 @@ void emitter::emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt,
27082709
id->idAddr()->iiaAddrMode.amBaseReg = REG_NA;
27092710
}
27102711

2711-
if (indir->HasIndex())
2712+
if (amInfo.HasIndex())
27122713
{
2713-
id->idAddr()->iiaAddrMode.amIndxReg = indir->Index()->gtRegNum;
2714+
id->idAddr()->iiaAddrMode.amIndxReg = amInfo.Index()->gtRegNum;
27142715
}
27152716
else
27162717
{
27172718
id->idAddr()->iiaAddrMode.amIndxReg = REG_NA;
27182719
}
2719-
id->idAddr()->iiaAddrMode.amScale = emitEncodeScale(indir->Scale());
2720+
id->idAddr()->iiaAddrMode.amScale = emitEncodeScale(amInfo.Scale());
27202721

27212722
id->idInsFmt(emitMapFmtForIns(fmt, ins));
27222723

27232724
// disp must have already been set in the instrDesc constructor.
2724-
assert(emitGetInsAmdAny(id) == indir->Offset()); // make sure "disp" is stored properly
2725+
assert(emitGetInsAmdAny(id) == amInfo.Offset()); // make sure "disp" is stored properly
27252726
}
27262727
}
27272728

@@ -2762,21 +2763,16 @@ void emitter::spillIntArgRegsToShadowSlots()
27622763
}
27632764

27642765
//------------------------------------------------------------------------
2765-
// emitInsLoadInd: Emits a "mov reg, [mem]" (or a variant such as "movzx" or "movss")
2766-
// instruction for a GT_IND node.
2766+
// emitInsLoad: Emits a "mov reg, [mem]" (or a variant such as "movzx" or "movss").
27672767
//
27682768
// Arguments:
27692769
// ins - the instruction to emit
27702770
// attr - the instruction operand size
27712771
// dstReg - the destination register
2772-
// mem - the GT_IND node
2772+
// addr - the address node
27732773
//
2774-
void emitter::emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, GenTreeIndir* mem)
2774+
void emitter::emitInsLoad(instruction ins, emitAttr attr, regNumber dstReg, GenTree* addr)
27752775
{
2776-
assert(mem->OperIs(GT_IND));
2777-
2778-
GenTree* addr = mem->Addr();
2779-
27802776
if (addr->OperGet() == GT_CLS_VAR_ADDR)
27812777
{
27822778
emitIns_R_C(ins, attr, dstReg, addr->gtClsVar.gtClsVarHnd, 0);
@@ -2792,33 +2788,28 @@ void emitter::emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, G
27922788
}
27932789

27942790
assert(addr->OperIsAddrMode() || (addr->IsCnsIntOrI() && addr->isContained()) || !addr->isContained());
2795-
ssize_t offset = mem->Offset();
2791+
ssize_t offset = AddressModeInfo(addr).Offset();
27962792
instrDesc* id = emitNewInstrAmd(attr, offset);
27972793
id->idIns(ins);
27982794
id->idReg1(dstReg);
2799-
emitHandleMemOp(mem, id, IF_RWR_ARD, ins);
2795+
emitSetAddrMode(id, ins, IF_RWR_ARD, addr);
28002796
UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins));
28012797
id->idCodeSize(sz);
28022798
dispIns(id);
28032799
emitCurIGsize += sz;
28042800
}
28052801

28062802
//------------------------------------------------------------------------
2807-
// emitInsStoreInd: Emits a "mov [mem], reg/imm" (or a variant such as "movss")
2808-
// instruction for a GT_STOREIND node.
2803+
// emitInsStore: Emits a "mov [mem], reg/imm" (or a variant such as "movss").
28092804
//
28102805
// Arguments:
28112806
// ins - the instruction to emit
28122807
// attr - the instruction operand size
2813-
// mem - the GT_STOREIND node
2808+
// addr - the address node
2809+
// data - the data node
28142810
//
2815-
void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* mem)
2811+
void emitter::emitInsStore(instruction ins, emitAttr attr, GenTree* addr, GenTree* data)
28162812
{
2817-
assert(mem->OperIs(GT_STOREIND));
2818-
2819-
GenTree* addr = mem->Addr();
2820-
GenTree* data = mem->Data();
2821-
28222813
if (addr->OperGet() == GT_CLS_VAR_ADDR)
28232814
{
28242815
if (data->isContainedIntOrIImmed())
@@ -2849,7 +2840,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m
28492840
return;
28502841
}
28512842

2852-
ssize_t offset = mem->Offset();
2843+
ssize_t offset = AddressModeInfo(addr).Offset();
28532844
UNATIVE_OFFSET sz;
28542845
instrDesc* id;
28552846

@@ -2858,7 +2849,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m
28582849
int icon = (int)data->AsIntConCommon()->IconValue();
28592850
id = emitNewInstrAmdCns(attr, offset, icon);
28602851
id->idIns(ins);
2861-
emitHandleMemOp(mem, id, IF_AWR_CNS, ins);
2852+
emitSetAddrMode(id, ins, IF_AWR_CNS, addr);
28622853
sz = emitInsSizeAM(id, insCodeMI(ins), icon);
28632854
id->idCodeSize(sz);
28642855
}
@@ -2867,7 +2858,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m
28672858
assert(!data->isContained());
28682859
id = emitNewInstrAmd(attr, offset);
28692860
id->idIns(ins);
2870-
emitHandleMemOp(mem, id, IF_AWR_RRD, ins);
2861+
emitSetAddrMode(id, ins, IF_AWR_RRD, addr);
28712862
id->idReg1(data->gtRegNum);
28722863
sz = emitInsSizeAM(id, insCodeMR(ins));
28732864
id->idCodeSize(sz);
@@ -3144,7 +3135,7 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G
31443135
}
31453136
}
31463137
assert(fmt != IF_NONE);
3147-
emitHandleMemOp(memIndir, id, fmt, ins);
3138+
emitSetAddrMode(id, ins, fmt, memIndir->Addr());
31483139

31493140
// Determine the instruction size
31503141
UNATIVE_OFFSET sz = 0;
@@ -3366,7 +3357,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI
33663357
}
33673358

33683359
id = emitNewInstrAmdCns(attr, offset, iconVal);
3369-
emitHandleMemOp(storeInd, id, IF_ARW_CNS, ins);
3360+
emitSetAddrMode(id, ins, IF_ARW_CNS, storeInd->Addr());
33703361
id->idIns(ins);
33713362
sz = emitInsSizeAM(id, insCodeMI(ins), iconVal);
33723363
}
@@ -3376,7 +3367,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI
33763367

33773368
// ind, reg
33783369
id = emitNewInstrAmd(attr, offset);
3379-
emitHandleMemOp(storeInd, id, IF_ARW_RRD, ins);
3370+
emitSetAddrMode(id, ins, IF_ARW_RRD, storeInd->Addr());
33803371
id->idReg1(src->gtRegNum);
33813372
id->idIns(ins);
33823373
sz = emitInsSizeAM(id, insCodeMR(ins));
@@ -3424,7 +3415,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI
34243415
}
34253416

34263417
instrDesc* id = emitNewInstrAmd(attr, offset);
3427-
emitHandleMemOp(storeInd, id, IF_ARW, ins);
3418+
emitSetAddrMode(id, ins, IF_ARW, storeInd->Addr());
34283419
id->idIns(ins);
34293420
UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeMR(ins));
34303421
id->idCodeSize(sz);
@@ -3983,7 +3974,7 @@ void emitter::emitIns_R_A(instruction ins, emitAttr attr, regNumber reg1, GenTre
39833974
id->idIns(ins);
39843975
id->idReg1(reg1);
39853976

3986-
emitHandleMemOp(indir, id, IF_RRW_ARD, ins);
3977+
emitSetAddrMode(id, ins, IF_RRW_ARD, indir->Addr());
39873978

39883979
UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins));
39893980
id->idCodeSize(sz);
@@ -4003,7 +3994,7 @@ void emitter::emitIns_R_A_I(instruction ins, emitAttr attr, regNumber reg1, GenT
40033994
id->idIns(ins);
40043995
id->idReg1(reg1);
40053996

4006-
emitHandleMemOp(indir, id, IF_RRW_ARD_CNS, ins);
3997+
emitSetAddrMode(id, ins, IF_RRW_ARD_CNS, indir->Addr());
40073998

40083999
UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival);
40094000

@@ -4122,7 +4113,7 @@ void emitter::emitIns_R_R_A(instruction ins, emitAttr attr, regNumber reg1, regN
41224113
id->idReg1(reg1);
41234114
id->idReg2(reg2);
41244115

4125-
emitHandleMemOp(indir, id, IF_RWR_RRD_ARD, ins);
4116+
emitSetAddrMode(id, ins, IF_RWR_RRD_ARD, indir->Addr());
41264117

41274118
UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins));
41284119
id->idCodeSize(sz);
@@ -4311,7 +4302,7 @@ void emitter::emitIns_R_R_A_I(
43114302
id->idReg1(reg1);
43124303
id->idReg2(reg2);
43134304

4314-
emitHandleMemOp(indir, id, fmt, ins);
4305+
emitSetAddrMode(id, ins, fmt, indir->Addr());
43154306

43164307
UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival);
43174308
id->idCodeSize(sz);
@@ -4477,7 +4468,7 @@ void emitter::emitIns_R_R_A_R(
44774468
id->idReg1(targetReg);
44784469
id->idReg2(op1Reg);
44794470

4480-
emitHandleMemOp(indir, id, IF_RWR_RRD_ARD_RRD, ins);
4471+
emitSetAddrMode(id, ins, IF_RWR_RRD_ARD_RRD, indir->Addr());
44814472

44824473
UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival);
44834474
id->idCodeSize(sz);

src/jit/gentree.cpp

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15812,54 +15812,46 @@ bool GenTree::isContainedIndir() const
1581215812
return isIndir() && isContained();
1581315813
}
1581415814

15815-
bool GenTree::isIndirAddrMode()
15815+
bool AddressModeInfo::IsContainedAddressMode() const
1581615816
{
15817-
return isIndir() && AsIndir()->Addr()->OperIsAddrMode() && AsIndir()->Addr()->isContained();
15817+
return Addr()->OperIsAddrMode() && Addr()->isContained();
1581815818
}
1581915819

1582015820
bool GenTree::isIndir() const
1582115821
{
1582215822
return OperGet() == GT_IND || OperGet() == GT_STOREIND;
1582315823
}
1582415824

15825-
bool GenTreeIndir::HasBase()
15825+
bool AddressModeInfo::HasBase() const
1582615826
{
1582715827
return Base() != nullptr;
1582815828
}
1582915829

15830-
bool GenTreeIndir::HasIndex()
15830+
bool AddressModeInfo::HasIndex() const
1583115831
{
1583215832
return Index() != nullptr;
1583315833
}
1583415834

15835-
GenTree* GenTreeIndir::Base()
15835+
GenTree* AddressModeInfo::Base() const
1583615836
{
15837-
GenTree* addr = Addr();
15838-
15839-
if (isIndirAddrMode())
15837+
if (IsContainedAddressMode())
1584015838
{
15841-
GenTree* result = addr->AsAddrMode()->Base();
15842-
if (result != nullptr)
15843-
{
15844-
result = result->gtEffectiveVal();
15845-
}
15839+
GenTree* result = Addr()->AsAddrMode()->Base();
15840+
assert((result == nullptr) || (result->gtEffectiveVal() == result));
1584615841
return result;
1584715842
}
1584815843
else
1584915844
{
15850-
return addr; // TODO: why do we return 'addr' here, but we return 'nullptr' in the equivalent Index() case?
15845+
return m_addr; // TODO: why do we return 'addr' here, but we return 'nullptr' in the equivalent Index() case?
1585115846
}
1585215847
}
1585315848

15854-
GenTree* GenTreeIndir::Index()
15849+
GenTree* AddressModeInfo::Index() const
1585515850
{
15856-
if (isIndirAddrMode())
15851+
if (IsContainedAddressMode())
1585715852
{
1585815853
GenTree* result = Addr()->AsAddrMode()->Index();
15859-
if (result != nullptr)
15860-
{
15861-
result = result->gtEffectiveVal();
15862-
}
15854+
assert((result == nullptr) || (result->gtEffectiveVal() == result));
1586315855
return result;
1586415856
}
1586515857
else
@@ -15868,7 +15860,7 @@ GenTree* GenTreeIndir::Index()
1586815860
}
1586915861
}
1587015862

15871-
unsigned GenTreeIndir::Scale()
15863+
unsigned AddressModeInfo::Scale() const
1587215864
{
1587315865
if (HasIndex())
1587415866
{
@@ -15880,9 +15872,9 @@ unsigned GenTreeIndir::Scale()
1588015872
}
1588115873
}
1588215874

15883-
ssize_t GenTreeIndir::Offset()
15875+
ssize_t AddressModeInfo::Offset() const
1588415876
{
15885-
if (isIndirAddrMode())
15877+
if (IsContainedAddressMode())
1588615878
{
1588715879
return Addr()->AsAddrMode()->Offset();
1588815880
}

0 commit comments

Comments
 (0)