diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp index 57a9adcc3f42..a0931db8d3a7 100644 --- a/src/jit/codegenxarch.cpp +++ b/src/jit/codegenxarch.cpp @@ -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 @@ -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); @@ -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); } } } diff --git a/src/jit/emit.h b/src/jit/emit.h index cfad5c60d713..a9dc076958ff 100644 --- a/src/jit/emit.h +++ b/src/jit/emit.h @@ -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); diff --git a/src/jit/emitxarch.cpp b/src/jit/emitxarch.cpp index fe20e9e297bb..2463e42ed1fb 100644 --- a/src/jit/emitxarch.cpp +++ b/src/jit/emitxarch.cpp @@ -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");