Skip to content

Commit

Permalink
Clean two 'instr_XYZ' methods up
Browse files Browse the repository at this point in the history
  • Loading branch information
SingleAccretion committed Feb 14, 2022
1 parent 798d5e1 commit 644c055
Showing 1 changed file with 54 additions and 224 deletions.
278 changes: 54 additions & 224 deletions src/coreclr/jit/instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1136,118 +1136,34 @@ void CodeGen::inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenT
emitter* emit = GetEmitter();
noway_assert(emit->emitVerifyEncodable(ins, EA_SIZE(attr), reg1));

if (rmOp->isContained() || rmOp->isUsedFromSpillTemp())
{
TempDsc* tmpDsc = nullptr;
unsigned varNum = BAD_VAR_NUM;
unsigned offset = (unsigned)-1;

if (rmOp->isUsedFromSpillTemp())
{
assert(rmOp->IsRegOptional());

tmpDsc = getSpillTempDsc(rmOp);
varNum = tmpDsc->tdTempNum();
offset = 0;
OperandDesc rmOpDesc = genOperandDesc(rmOp);

regSet.tmpRlsTemp(tmpDsc);
}
else if (rmOp->isIndir() || rmOp->OperIsHWIntrinsic())
{
GenTree* addr;
GenTreeIndir* memIndir = nullptr;

if (rmOp->isIndir())
{
memIndir = rmOp->AsIndir();
addr = memIndir->Addr();
}
else
{
#if defined(FEATURE_HW_INTRINSICS)
assert(rmOp->AsHWIntrinsic()->OperIsMemoryLoad());
assert(rmOp->AsHWIntrinsic()->GetOperandCount() == 1);
addr = rmOp->AsHWIntrinsic()->Op(1);
#else
unreached();
#endif // FEATURE_HW_INTRINSICS
}

switch (addr->OperGet())
{
case GT_LCL_VAR_ADDR:
case GT_LCL_FLD_ADDR:
{
assert(addr->isContained());
varNum = addr->AsLclVarCommon()->GetLclNum();
offset = addr->AsLclVarCommon()->GetLclOffs();
break;
}
switch (rmOpDesc.GetKind())
{
case OperandKind::ClsVar:
emit->emitIns_R_C_I(ins, attr, reg1, rmOpDesc.GetFieldHnd(), 0, ival);
break;

case GT_CLS_VAR_ADDR:
{
emit->emitIns_R_C_I(ins, attr, reg1, addr->AsClsVar()->gtClsVarHnd, 0, ival);
return;
}
case OperandKind::Local:
emit->emitIns_R_S_I(ins, attr, reg1, rmOpDesc.GetVarNum(), rmOpDesc.GetLclOffset(), ival);
break;

default:
{
GenTreeIndir load = indirForm(rmOp->TypeGet(), addr);

if (memIndir == nullptr)
{
// This is the HW intrinsic load case.
// Until we improve the handling of addressing modes in the emitter, we'll create a
// temporary GT_IND to generate code with.
memIndir = &load;
}
emit->emitIns_R_A_I(ins, attr, reg1, memIndir, ival);
return;
}
}
}
else
case OperandKind::Indir:
{
switch (rmOp->OperGet())
{
case GT_LCL_FLD:
varNum = rmOp->AsLclFld()->GetLclNum();
offset = rmOp->AsLclFld()->GetLclOffs();
break;

case GT_LCL_VAR:
{
assert(rmOp->IsRegOptional() || !compiler->lvaGetDesc(rmOp->AsLclVar())->lvIsRegCandidate());
varNum = rmOp->AsLclVar()->GetLclNum();
offset = 0;
break;
}

case GT_CNS_DBL:
{
GenTreeDblCon* cns = rmOp->AsDblCon();
CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(cns->gtDconVal, emitTypeSize(cns));
emit->emitIns_R_C_I(ins, attr, reg1, hnd, 0, ival);
return;
}

default:
unreached();
}
// Until we improve the handling of addressing modes in the emitter, we'll create a
// temporary GT_IND to generate code with.
GenTreeIndir indirForm;
GenTreeIndir* indir = rmOpDesc.GetIndirForm(&indirForm);
emit->emitIns_R_A_I(ins, attr, reg1, indir, ival);
}
break;

// Ensure we got a good varNum and offset.
// We also need to check for `tmpDsc != nullptr` since spill temp numbers
// are negative and start with -1, which also happens to be BAD_VAR_NUM.
assert((varNum != BAD_VAR_NUM) || (tmpDsc != nullptr));
assert(offset != (unsigned)-1);
case OperandKind::Reg:
emit->emitIns_SIMD_R_R_I(ins, attr, reg1, rmOp->GetRegNum(), ival);
break;

emit->emitIns_R_S_I(ins, attr, reg1, varNum, offset, ival);
}
else
{
regNumber rmOpReg = rmOp->GetRegNum();
emit->emitIns_SIMD_R_R_I(ins, attr, reg1, rmOpReg, ival);
default:
unreached();
}
}

Expand All @@ -1273,136 +1189,50 @@ void CodeGen::inst_RV_RV_TT(
// TODO-XArch-CQ: Commutative operations can have op1 be contained
// TODO-XArch-CQ: Non-VEX encoded instructions can have both ops contained

if (op2->isContained() || op2->isUsedFromSpillTemp())
OperandDesc op2Desc = genOperandDesc(op2);
switch (op2Desc.GetKind())
{
TempDsc* tmpDsc = nullptr;
unsigned varNum = BAD_VAR_NUM;
unsigned offset = (unsigned)-1;

if (op2->isUsedFromSpillTemp())
{
assert(op2->IsRegOptional());
case OperandKind::ClsVar:
emit->emitIns_SIMD_R_R_C(ins, size, targetReg, op1Reg, op2Desc.GetFieldHnd(), 0);
break;

tmpDsc = getSpillTempDsc(op2);
varNum = tmpDsc->tdTempNum();
offset = 0;
case OperandKind::Local:
emit->emitIns_SIMD_R_R_S(ins, size, targetReg, op1Reg, op2Desc.GetVarNum(), op2Desc.GetLclOffset());
break;

regSet.tmpRlsTemp(tmpDsc);
}
else if (op2->isIndir() || op2->OperIsHWIntrinsic())
case OperandKind::Indir:
{
GenTree* addr;
GenTreeIndir* memIndir = nullptr;

if (op2->isIndir())
{
memIndir = op2->AsIndir();
addr = memIndir->Addr();
}
else
{
#if defined(FEATURE_HW_INTRINSICS)
assert(op2->AsHWIntrinsic()->OperIsMemoryLoad());
assert(op2->AsHWIntrinsic()->GetOperandCount() == 1);
addr = op2->AsHWIntrinsic()->Op(1);
#else
unreached();
#endif // FEATURE_HW_INTRINSICS
}

switch (addr->OperGet())
{
case GT_LCL_VAR_ADDR:
case GT_LCL_FLD_ADDR:
{
assert(addr->isContained());
varNum = addr->AsLclVarCommon()->GetLclNum();
offset = addr->AsLclVarCommon()->GetLclOffs();
break;
}

case GT_CLS_VAR_ADDR:
{
emit->emitIns_SIMD_R_R_C(ins, size, targetReg, op1Reg, addr->AsClsVar()->gtClsVarHnd, 0);
return;
}

default:
{
GenTreeIndir load = indirForm(op2->TypeGet(), addr);

if (memIndir == nullptr)
{
// This is the HW intrinsic load case.
// Until we improve the handling of addressing modes in the emitter, we'll create a
// temporary GT_IND to generate code with.
memIndir = &load;
}
emit->emitIns_SIMD_R_R_A(ins, size, targetReg, op1Reg, memIndir);
return;
}
}
// Until we improve the handling of addressing modes in the emitter, we'll create a
// temporary GT_IND to generate code with.
GenTreeIndir indirForm;
GenTreeIndir* indir = op2Desc.GetIndirForm(&indirForm);
emit->emitIns_SIMD_R_R_A(ins, size, targetReg, op1Reg, indir);
}
else
{
switch (op2->OperGet())
{
case GT_LCL_FLD:
{
varNum = op2->AsLclFld()->GetLclNum();
offset = op2->AsLclFld()->GetLclOffs();
break;
}

case GT_LCL_VAR:
{
assert(op2->IsRegOptional() || !compiler->lvaGetDesc(op2->AsLclVar())->lvIsRegCandidate());
varNum = op2->AsLclVar()->GetLclNum();
offset = 0;
break;
}
break;

case GT_CNS_DBL:
{
GenTreeDblCon* cns = op2->AsDblCon();
CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(cns->gtDconVal, emitTypeSize(cns));
emit->emitIns_SIMD_R_R_C(ins, size, targetReg, op1Reg, hnd, 0);
return;
}
case OperandKind::Reg:
{
regNumber op2Reg = op2->GetRegNum();

default:
{
unreached();
}
if ((op1Reg != targetReg) && (op2Reg == targetReg) && isRMW)
{
// We have "reg2 = reg1 op reg2" where "reg1 != reg2" on a RMW instruction.
//
// For non-commutative instructions, we should have ensured that op2 was marked
// delay free in order to prevent it from getting assigned the same register
// as target. However, for commutative instructions, we can just swap the operands
// in order to have "reg2 = reg2 op reg1" which will end up producing the right code.

op2Reg = op1Reg;
op1Reg = targetReg;
}
}

// Ensure we got a good varNum and offset.
// We also need to check for `tmpDsc != nullptr` since spill temp numbers
// are negative and start with -1, which also happens to be BAD_VAR_NUM.
assert((varNum != BAD_VAR_NUM) || (tmpDsc != nullptr));
assert(offset != (unsigned)-1);

emit->emitIns_SIMD_R_R_S(ins, size, targetReg, op1Reg, varNum, offset);
}
else
{
regNumber op2Reg = op2->GetRegNum();

if ((op1Reg != targetReg) && (op2Reg == targetReg) && isRMW)
{
// We have "reg2 = reg1 op reg2" where "reg1 != reg2" on a RMW instruction.
//
// For non-commutative instructions, we should have ensured that op2 was marked
// delay free in order to prevent it from getting assigned the same register
// as target. However, for commutative instructions, we can just swap the operands
// in order to have "reg2 = reg2 op reg1" which will end up producing the right code.

op2Reg = op1Reg;
op1Reg = targetReg;
emit->emitIns_SIMD_R_R_R(ins, size, targetReg, op1Reg, op2Reg);
}
break;

emit->emitIns_SIMD_R_R_R(ins, size, targetReg, op1Reg, op2Reg);
default:
unreached();
}
}
#endif // TARGET_XARCH
Expand Down

0 comments on commit 644c055

Please sign in to comment.