Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4436,8 +4436,8 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree)
if (targetReg == REG_NA)
{
// stack store
emit->emitInsMov(ins_Store(targetType, compiler->isSIMDTypeLocalAligned(lclNum)), emitTypeSize(targetType),
tree);
emit->emitInsStoreLcl(ins_Store(targetType, compiler->isSIMDTypeLocalAligned(lclNum)),
emitTypeSize(targetType), tree);
varDsc->lvRegNum = REG_STK;
}
else
Expand Down Expand Up @@ -4512,7 +4512,7 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree)
else
{
genConsumeAddress(addr);
emit->emitInsMov(ins_Load(targetType), emitTypeSize(tree), tree);
emit->emitInsLoadInd(ins_Load(targetType), emitTypeSize(tree), tree->gtRegNum, tree);
}

genProduceReg(tree);
Expand Down Expand Up @@ -4774,7 +4774,7 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
}
else
{
getEmitter()->emitInsMov(ins_Store(data->TypeGet()), emitTypeSize(tree), tree);
getEmitter()->emitInsStoreInd(ins_Store(data->TypeGet()), emitTypeSize(tree), tree);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -1718,7 +1718,9 @@ class emitter
CORINFO_FIELD_HANDLE emitFltOrDblConst(GenTreeDblCon* tree, emitAttr attr = EA_UNKNOWN);
regNumber emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src);
regNumber emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src1, GenTree* src2);
void emitInsMov(instruction ins, emitAttr attr, GenTree* node);
void emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, GenTreeIndir* mem);
void emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* mem);
void emitInsStoreLcl(instruction ins, emitAttr attr, GenTreeLclVarCommon* varNode);
insFormat emitMapFmtForIns(insFormat fmt, instruction ins);
insFormat emitMapFmtAtoM(insFormat fmt);
void emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, instruction ins);
Expand Down
237 changes: 128 additions & 109 deletions src/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2639,132 +2639,151 @@ void emitter::spillIntArgRegsToShadowSlots()
}
}

// this is very similar to emitInsBinary and probably could be folded in to same
// except the requirements on the incoming parameter are different,
// ex: the memory op in storeind case must NOT be contained
void emitter::emitInsMov(instruction ins, emitAttr attr, GenTree* node)
//------------------------------------------------------------------------
// emitInsLoadInd: Emits a "mov reg, [mem]" (or a variant such as "movzx" or "movss")
// instruction for a GT_IND node.
//
// Arguments:
// ins - the instruction to emit
// attr - the instruction operand size
// dstReg - the destination register
// mem - the GT_IND node
//
void emitter::emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, GenTreeIndir* mem)
{
UNATIVE_OFFSET sz;
instrDesc* id;
assert(mem->OperIs(GT_IND));

GenTree* addr = mem->Addr();

switch (node->OperGet())
if (addr->OperGet() == GT_CLS_VAR_ADDR)
{
case GT_IND:
{
GenTreeIndir* mem = node->AsIndir();
GenTreePtr addr = mem->Addr();
emitIns_R_C(ins, attr, dstReg, addr->gtClsVar.gtClsVarHnd, 0);
return;
}

if (addr->OperGet() == GT_CLS_VAR_ADDR)
{
emitIns_R_C(ins, attr, mem->gtRegNum, addr->gtClsVar.gtClsVarHnd, 0);
return;
}
else if (addr->OperGet() == GT_LCL_VAR_ADDR)
{
GenTreeLclVarCommon* varNode = addr->AsLclVarCommon();
emitIns_R_S(ins, attr, mem->gtRegNum, varNode->GetLclNum(), 0);
codeGen->genUpdateLife(varNode);
return;
}
else
{
assert(addr->OperIsAddrMode() || (addr->IsCnsIntOrI() && addr->isContained()) || !addr->isContained());
size_t offset = mem->Offset();
id = emitNewInstrAmd(attr, offset);
id->idIns(ins);
id->idReg1(mem->gtRegNum);
emitHandleMemOp(mem, id, IF_RWR_ARD, ins);
sz = emitInsSizeAM(id, insCodeRM(ins));
id->idCodeSize(sz);
}
}
break;
if (addr->OperGet() == GT_LCL_VAR_ADDR)
{
GenTreeLclVarCommon* varNode = addr->AsLclVarCommon();
emitIns_R_S(ins, attr, dstReg, varNode->GetLclNum(), 0);
codeGen->genUpdateLife(varNode);
return;
}

case GT_STOREIND:
{
GenTreeStoreInd* mem = node->AsStoreInd();
GenTreePtr addr = mem->Addr();
size_t offset = mem->Offset();
GenTree* data = mem->Data();
assert(addr->OperIsAddrMode() || (addr->IsCnsIntOrI() && addr->isContained()) || !addr->isContained());
size_t offset = mem->Offset();
instrDesc* id = emitNewInstrAmd(attr, offset);
id->idIns(ins);
id->idReg1(dstReg);
emitHandleMemOp(mem, id, IF_RWR_ARD, ins);
UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins));
id->idCodeSize(sz);
dispIns(id);
emitCurIGsize += sz;
}

if (addr->OperGet() == GT_CLS_VAR_ADDR)
{
if (data->isContainedIntOrIImmed())
{
emitIns_C_I(ins, attr, addr->gtClsVar.gtClsVarHnd, 0, (int)data->AsIntConCommon()->IconValue());
}
else
{
assert(!data->isContained());
emitIns_C_R(ins, attr, addr->gtClsVar.gtClsVarHnd, data->gtRegNum, 0);
}
return;
}
else if (addr->OperGet() == GT_LCL_VAR_ADDR)
{
GenTreeLclVarCommon* varNode = addr->AsLclVarCommon();
if (data->isContainedIntOrIImmed())
{
emitIns_S_I(ins, attr, varNode->GetLclNum(), 0, (int)data->AsIntConCommon()->IconValue());
}
else
{
assert(!data->isContained());
emitIns_S_R(ins, attr, data->gtRegNum, varNode->GetLclNum(), 0);
}
codeGen->genUpdateLife(varNode);
return;
}
else if (data->isContainedIntOrIImmed())
{
int icon = (int)data->AsIntConCommon()->IconValue();
id = emitNewInstrAmdCns(attr, offset, icon);
id->idIns(ins);
emitHandleMemOp(mem, id, IF_AWR_CNS, ins);
sz = emitInsSizeAM(id, insCodeMI(ins), icon);
id->idCodeSize(sz);
}
else
{
assert(!data->isContained());
id = emitNewInstrAmd(attr, offset);
id->idIns(ins);
emitHandleMemOp(mem, id, IF_AWR_RRD, ins);
id->idReg1(data->gtRegNum);
sz = emitInsSizeAM(id, insCodeMR(ins));
id->idCodeSize(sz);
}
}
break;
//------------------------------------------------------------------------
// emitInsStoreInd: Emits a "mov [mem], reg/imm" (or a variant such as "movss")
// instruction for a GT_STOREIND node.
//
// Arguments:
// ins - the instruction to emit
// attr - the instruction operand size
// mem - the GT_STOREIND node
//
void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* mem)
{
assert(mem->OperIs(GT_STOREIND));

GenTree* addr = mem->Addr();
GenTree* data = mem->Data();

case GT_STORE_LCL_VAR:
if (addr->OperGet() == GT_CLS_VAR_ADDR)
{
if (data->isContainedIntOrIImmed())
{
emitIns_C_I(ins, attr, addr->gtClsVar.gtClsVarHnd, 0, (int)data->AsIntConCommon()->IconValue());
}
else
{
GenTreeLclVarCommon* varNode = node->AsLclVarCommon();
GenTree* data = varNode->gtOp.gtOp1;
codeGen->inst_set_SV_var(varNode);
assert(varNode->gtRegNum == REG_NA); // stack store
assert(!data->isContained());
emitIns_C_R(ins, attr, addr->gtClsVar.gtClsVarHnd, data->gtRegNum, 0);
}
return;
}

if (data->isContainedIntOrIImmed())
{
emitIns_S_I(ins, attr, varNode->GetLclNum(), 0, (int)data->AsIntConCommon()->IconValue());
}
else
{
assert(!data->isContained());
emitIns_S_R(ins, attr, data->gtRegNum, varNode->GetLclNum(), 0);
}
codeGen->genUpdateLife(varNode);
if (addr->OperGet() == GT_LCL_VAR_ADDR)
{
GenTreeLclVarCommon* varNode = addr->AsLclVarCommon();
if (data->isContainedIntOrIImmed())
{
emitIns_S_I(ins, attr, varNode->GetLclNum(), 0, (int)data->AsIntConCommon()->IconValue());
}
return;
else
{
assert(!data->isContained());
emitIns_S_R(ins, attr, data->gtRegNum, varNode->GetLclNum(), 0);
}
codeGen->genUpdateLife(varNode);
return;
}

default:
unreached();
size_t offset = mem->Offset();
UNATIVE_OFFSET sz;
instrDesc* id;

if (data->isContainedIntOrIImmed())
{
int icon = (int)data->AsIntConCommon()->IconValue();
id = emitNewInstrAmdCns(attr, offset, icon);
id->idIns(ins);
emitHandleMemOp(mem, id, IF_AWR_CNS, ins);
sz = emitInsSizeAM(id, insCodeMI(ins), icon);
id->idCodeSize(sz);
}
else
{
assert(!data->isContained());
id = emitNewInstrAmd(attr, offset);
id->idIns(ins);
emitHandleMemOp(mem, id, IF_AWR_RRD, ins);
id->idReg1(data->gtRegNum);
sz = emitInsSizeAM(id, insCodeMR(ins));
id->idCodeSize(sz);
}

dispIns(id);
emitCurIGsize += sz;
}

//------------------------------------------------------------------------
// emitInsStoreLcl: Emits a "mov [mem], reg/imm" (or a variant such as "movss")
// instruction for a GT_STORE_LCL_VAR node.
//
// Arguments:
// ins - the instruction to emit
// attr - the instruction operand size
// varNode - the GT_STORE_LCL_VAR node
//
void emitter::emitInsStoreLcl(instruction ins, emitAttr attr, GenTreeLclVarCommon* varNode)
{
assert(varNode->OperIs(GT_STORE_LCL_VAR));
assert(varNode->gtRegNum == REG_NA); // stack store

GenTree* data = varNode->gtGetOp1();
codeGen->inst_set_SV_var(varNode);

if (data->isContainedIntOrIImmed())
{
emitIns_S_I(ins, attr, varNode->GetLclNum(), 0, (int)data->AsIntConCommon()->IconValue());
}
else
{
assert(!data->isContained());
emitIns_S_R(ins, attr, data->gtRegNum, varNode->GetLclNum(), 0);
}
codeGen->genUpdateLife(varNode);
}

CORINFO_FIELD_HANDLE emitter::emitLiteralConst(ssize_t cnsValIn, emitAttr attr /*= EA_8BYTE*/)
{
NYI("emitLiteralConst");
Expand Down