未验证 提交 320f4736 编写于 作者: E Egor Bogatov 提交者: GitHub

Better approach (#66902)

上级 c5d40c9e
......@@ -10120,7 +10120,7 @@ void CodeGen::genCodeForBfiz(GenTreeOp* tree)
//
void CodeGen::genCodeForAddEx(GenTreeOp* tree)
{
assert(tree->OperIs(GT_ADDEX) && !(tree->gtFlags & GTF_SET_FLAGS));
assert(tree->OperIs(GT_ADDEX));
genConsumeOperands(tree);
GenTree* op;
......@@ -10146,13 +10146,15 @@ void CodeGen::genCodeForAddEx(GenTreeOp* tree)
GenTreeCast* cast = containedOp->AsCast();
assert(varTypeIsLong(cast->CastToType()));
insOpts opts = cast->IsUnsigned() ? INS_OPTS_UXTW : INS_OPTS_SXTW;
GetEmitter()->emitIns_R_R_R(INS_add, emitActualTypeSize(tree), dstReg, op1Reg, op2Reg, opts);
GetEmitter()->emitIns_R_R_R(tree->gtSetFlags() ? INS_adds : INS_add, emitActualTypeSize(tree), dstReg, op1Reg,
op2Reg, opts);
}
else
{
assert(containedOp->OperIs(GT_LSH));
ssize_t cns = containedOp->gtGetOp2()->AsIntCon()->IconValue();
GetEmitter()->emitIns_R_R_R_I(INS_add, emitActualTypeSize(tree), dstReg, op1Reg, op2Reg, cns, INS_OPTS_LSL);
GetEmitter()->emitIns_R_R_R_I(tree->gtSetFlags() ? INS_adds : INS_add, emitActualTypeSize(tree), dstReg, op1Reg,
op2Reg, cns, INS_OPTS_LSL);
}
genProduceReg(tree);
}
......
......@@ -1062,17 +1062,16 @@ bool CodeGen::genCreateAddrMode(
/* All indirect address modes require the address to be an addition */
if (addr->gtOper != GT_ADD)
{
return false;
}
// Can't use indirect addressing mode as we need to check for overflow.
// Also, can't use 'lea' as it doesn't set the flags.
if (addr->gtOverflow())
if (!addr->OperIs(GT_ADD))
{
#if TARGET_ARM64
if (!addr->OperIs(GT_ADDEX))
{
return false;
}
#else
return false;
#endif
}
GenTree* rv1 = nullptr;
......@@ -1099,6 +1098,31 @@ bool CodeGen::genCreateAddrMode(
op2 = addr->AsOp()->gtOp2;
}
#if TARGET_ARM64
if (addr->OperIs(GT_ADDEX))
{
if (op2->isContained() && op2->OperIs(GT_CAST))
{
*rv1Ptr = op1;
*rv2Ptr = op2;
*mulPtr = 1;
*cnsPtr = 0;
*revPtr = false; // op2 is never a gc type
assert(!varTypeIsGC(op2));
return true;
}
return false;
}
#endif
// Can't use indirect addressing mode as we need to check for overflow.
// Also, can't use 'lea' as it doesn't set the flags.
if (addr->gtOverflow())
{
return false;
}
bool rev = false; // Is op2 first in the evaluation order?
/*
......
......@@ -1600,6 +1600,13 @@ void CodeGen::genConsumeRegs(GenTree* tree)
assert(cast->isContained());
genConsumeAddress(cast->CastOp());
}
else if (tree->OperIs(GT_CAST))
{
// Can be contained as part of LEA on ARM64
GenTreeCast* cast = tree->AsCast();
assert(cast->isContained());
genConsumeAddress(cast->CastOp());
}
#endif
else if (tree->OperIsLocalRead())
{
......
......@@ -13548,17 +13548,28 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
}
else // no scale
{
if (index->OperIs(GT_BFIZ) && index->isContained())
if (index->OperIs(GT_BFIZ, GT_CAST) && index->isContained())
{
// Then load/store dataReg from/to [memBase + index*scale with sign/zero extension]
GenTreeCast* cast = index->gtGetOp1()->AsCast();
GenTreeCast* cast;
int cns;
if (index->OperIs(GT_BFIZ))
{
cast = index->gtGetOp1()->AsCast();
cns = (int)index->gtGetOp2()->AsIntCon()->IconValue();
}
else
{
cast = index->AsCast();
cns = 0;
}
// For now, this code only supports extensions from i32/u32
assert(cast->isContained() && varTypeIsInt(cast->CastFromType()));
assert(cast->isContained());
emitIns_R_R_R_Ext(ins, attr, dataReg, memBase->GetRegNum(), cast->CastOp()->GetRegNum(),
cast->IsUnsigned() ? INS_OPTS_UXTW : INS_OPTS_SXTW,
(int)index->gtGetOp2()->AsIntCon()->IconValue());
cast->IsUnsigned() ? INS_OPTS_UXTW : INS_OPTS_SXTW, cns);
}
else
{
......
......@@ -5257,7 +5257,14 @@ bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* par
{
if (!addr->OperIs(GT_ADD) || addr->gtOverflow())
{
#ifdef TARGET_ARM64
if (!addr->OperIs(GT_ADDEX))
{
return false;
}
#else
return false;
#endif
}
#ifdef TARGET_ARM64
......@@ -5397,6 +5404,11 @@ bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* par
}
#ifdef TARGET_ARM64
if ((index != nullptr) && index->OperIs(GT_CAST) && (scale == 1) && (offset == 0) && varTypeIsByte(targetType))
{
MakeSrcContained(addrMode, index);
}
// Check if we can "contain" LEA(BFIZ) in order to extend 32bit index to 64bit as part of load/store.
if ((index != nullptr) && index->OperIs(GT_BFIZ) && index->gtGetOp1()->OperIs(GT_CAST) &&
index->gtGetOp2()->IsCnsIntOrI() && (varTypeIsIntegral(targetType) || varTypeIsFloating(targetType)))
......
......@@ -701,6 +701,12 @@ int LinearScan::BuildNode(GenTree* tree)
assert(cast->isContained() && (cns == 0));
BuildUse(cast->CastOp());
}
else if (index->OperIs(GT_CAST) && index->isContained())
{
GenTreeCast* cast = index->AsCast();
assert(cast->isContained() && (cns == 0));
BuildUse(cast->CastOp());
}
else
{
BuildUse(index);
......
......@@ -3076,6 +3076,13 @@ int LinearScan::BuildAddrUses(GenTree* addr, regMaskTP candidates)
BuildUse(cast->CastOp(), candidates);
srcCount++;
}
else if (addrMode->Index()->OperIs(GT_CAST))
{
GenTreeCast* cast = addrMode->Index()->AsCast();
assert(cast->isContained());
BuildUse(cast->CastOp(), candidates);
srcCount++;
}
#endif
}
return srcCount;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册