From: mikedn Date: Tue, 1 Aug 2017 20:38:12 +0000 (+0300) Subject: Refactor emitter::emitInsMov (#12905) X-Git-Tag: accepted/tizen/base/20180629.140029~1083^2~14 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a18ab64e5ac3933a0fa441c42c8401193cb5047a;p=platform%2Fupstream%2Fcoreclr.git Refactor emitter::emitInsMov (#12905) * Split emitter::emitInsMov into separate functions None of this function's callers need it to figure out what kind of "mov" to emit, the callers already know what they need and they should call the appropiate function. Copy & paste code, no actual changes. * Pass the destination register to emitInsLoadInd This way it can be used for contained indirs where the destination register is set on the parent node. * Cleanup emitInsLoadInd/emitInsStoreInd/emitInsStoreLcl --- diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp index baef1cb..6f2df2a 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 cfad5c6..a9dc076 100644 --- a/src/jit/emit.h +++ b/src/jit/emit.h @@ -1718,7 +1718,9 @@ private: 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 fe20e9e..2463e42 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");