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
112 changes: 0 additions & 112 deletions src/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3365,118 +3365,6 @@ CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for also removing this here


// Generate code for division (or mod) by power of two
// or negative powers of two. (meaning -1 * a power of two, not 2^(-1))
// Op2 must be a contained integer constant.
void
CodeGen::genCodeForPow2Div(GenTreeOp* tree)
{
#if 0
GenTree *dividend = tree->gtOp.gtOp1;
GenTree *divisor = tree->gtOp.gtOp2;
genTreeOps oper = tree->OperGet();
emitAttr size = emitTypeSize(tree);
emitter *emit = getEmitter();
regNumber targetReg = tree->gtRegNum;
var_types targetType = tree->TypeGet();

bool isSigned = oper == GT_MOD || oper == GT_DIV;

// precondition: extended dividend is in RDX:RAX
// which means it is either all zeros or all ones

noway_assert(divisor->isContained());
GenTreeIntConCommon* divImm = divisor->AsIntConCommon();
int64_t imm = divImm->IconValue();
ssize_t abs_imm = abs(imm);
noway_assert(isPow2(abs_imm));


if (isSigned)
{
if (imm == 1)
{
if (targetReg != REG_RAX)
inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);

return;
}

if (abs_imm == 2)
{
if (oper == GT_MOD)
{
emit->emitIns_R_I(INS_and, size, REG_RAX, 1); // result is 0 or 1
// xor with rdx will flip all bits if negative
emit->emitIns_R_R(INS_xor, size, REG_RAX, REG_RDX); // 111.11110 or 0
}
else
{
assert(oper == GT_DIV);
// add 1 if it's negative
emit->emitIns_R_R(INS_sub, size, REG_RAX, REG_RDX);
}
}
else
{
// add imm-1 if negative
emit->emitIns_R_I(INS_and, size, REG_RDX, abs_imm - 1);
emit->emitIns_R_R(INS_add, size, REG_RAX, REG_RDX);
}

if (oper == GT_DIV)
{
unsigned shiftAmount = genLog2(unsigned(abs_imm));
inst_RV_SH(INS_sar, size, REG_RAX, shiftAmount);

if (imm < 0)
{
emit->emitIns_R(INS_neg, size, REG_RAX);
}
}
else
{
assert(oper == GT_MOD);
if (abs_imm > 2)
{
emit->emitIns_R_I(INS_and, size, REG_RAX, abs_imm - 1);
}
// RDX contains 'imm-1' if negative
emit->emitIns_R_R(INS_sub, size, REG_RAX, REG_RDX);
}

if (targetReg != REG_RAX)
{
inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
}
}
else
{
assert (imm > 0);

if (targetReg != dividend->gtRegNum)
{
inst_RV_RV(INS_mov, targetReg, dividend->gtRegNum, targetType);
}

if (oper == GT_UDIV)
{
inst_RV_SH(INS_shr, size, targetReg, genLog2(unsigned(imm)));
}
else
{
assert(oper == GT_UMOD);

emit->emitIns_R_I(INS_and, size, targetReg, imm -1);
}
}
#else // !0
NYI("genCodeForPow2Div");
#endif // !0
}


/***********************************************************************************************
* Generate code for localloc
*/
Expand Down
2 changes: 0 additions & 2 deletions src/jit/codegenlinear.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

void genCodeForMulHi(GenTreeOp* treeNode);

void genCodeForPow2Div(GenTreeOp* treeNode);

void genLeaInstruction(GenTreeAddrMode *lea);

void genSetRegToCond(regNumber dstReg, GenTreePtr tree);
Expand Down
162 changes: 18 additions & 144 deletions src/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1280,42 +1280,30 @@ void CodeGen::genCodeForDivMod(GenTreeOp* treeNode)
gcInfo.gcMarkRegSetNpt(RBM_RDX);
}

if (divisor->isContainedIntOrIImmed())
{
GenTreeIntConCommon* divImm = divisor->AsIntConCommon();
assert(divImm->IsIntCnsFitsInI32());
ssize_t imm = divImm->IconValue();
assert(isPow2(abs(imm)));
genCodeForPow2Div(treeNode->AsOp());
}
// Perform the 'targetType' (64-bit or 32-bit) divide instruction
instruction ins;
if (oper == GT_UMOD || oper == GT_UDIV)
ins = INS_div;
Copy link
Copy Markdown

@briansull briansull Jun 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs braces (i.e.) and I would also add a comment says that INS_div is an unsigned divide (as I always found this mnemonic to be confusing on x86)
{
ins = INS_div; // unsigned divide
}
else
{
ins = INS_idiv; // signed divide
}

else
{
// Perform the 'targetType' (64-bit or 32-bit) divide instruction
instruction ins;
if (oper == GT_UMOD || oper == GT_UDIV)
ins = INS_div;
else
ins = INS_idiv;
ins = INS_idiv;

emit->emitInsBinary(ins, size, treeNode, divisor);
emit->emitInsBinary(ins, size, treeNode, divisor);

// Signed divide RDX:RAX by r/m64, with result
// stored in RAX := Quotient, RDX := Remainder.
// Move the result to the desired register, if necessary
if (oper == GT_DIV || oper == GT_UDIV)
// DIV/IDIV instructions always store the quotient in RAX and the remainder in RDX.
// Move the result to the desired register, if necessary
if (oper == GT_DIV || oper == GT_UDIV)
{
if (targetReg != REG_RAX)
{
if (targetReg != REG_RAX)
{
inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
}
inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
}
else
}
else
{
assert((oper == GT_MOD) || (oper == GT_UMOD));
if (targetReg != REG_RDX)
{
assert((oper == GT_MOD) || (oper == GT_UMOD));
if (targetReg != REG_RDX)
{
inst_RV_RV(INS_mov, targetReg, REG_RDX, targetType);
}
inst_RV_RV(INS_mov, targetReg, REG_RDX, targetType);
}
}
}
Expand Down Expand Up @@ -2888,120 +2876,6 @@ CodeGen::genMultiRegCallStoreToLocal(GenTreePtr treeNode)
#endif // !FEATURE_UNIX_AMD64_STRUCT_PASSING
}

// Generate code for division (or mod) by power of two
// or negative powers of two. (meaning -1 * a power of two, not 2^(-1))
// Op2 must be a contained integer constant.
void
CodeGen::genCodeForPow2Div(GenTreeOp* tree)
{
GenTree *dividend = tree->gtOp.gtOp1;
GenTree *divisor = tree->gtOp.gtOp2;
genTreeOps oper = tree->OperGet();
emitAttr size = emitTypeSize(tree);
emitter *emit = getEmitter();
regNumber targetReg = tree->gtRegNum;
var_types targetType = tree->TypeGet();

bool isSigned = oper == GT_MOD || oper == GT_DIV;

// precondition: extended dividend is in RDX:RAX
// which means it is either all zeros or all ones

noway_assert(divisor->isContained());
GenTreeIntConCommon* divImm = divisor->AsIntConCommon();
ssize_t imm = divImm->IconValue();
ssize_t abs_imm = abs(imm);
noway_assert(isPow2(abs_imm));


if (isSigned)
{
if (imm == 1)
{
if (oper == GT_DIV)
{
if (targetReg != REG_RAX)
inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
}
else
{
assert(oper == GT_MOD);
instGen_Set_Reg_To_Zero(size, targetReg);
}

return;
}

if (abs_imm == 2)
{
if (oper == GT_MOD)
{
emit->emitIns_R_I(INS_and, size, REG_RAX, 1); // result is 0 or 1
// xor with rdx will flip all bits if negative
emit->emitIns_R_R(INS_xor, size, REG_RAX, REG_RDX); // 111.11110 or 0
}
else
{
assert(oper == GT_DIV);
// add 1 if it's negative
emit->emitIns_R_R(INS_sub, size, REG_RAX, REG_RDX);
}
}
else
{
// add imm-1 if negative
emit->emitIns_R_I(INS_and, size, REG_RDX, abs_imm - 1);
emit->emitIns_R_R(INS_add, size, REG_RAX, REG_RDX);
}

if (oper == GT_DIV)
{
unsigned shiftAmount = genLog2(unsigned(abs_imm));
inst_RV_SH(INS_sar, size, REG_RAX, shiftAmount);

if (imm < 0)
{
emit->emitIns_R(INS_neg, size, REG_RAX);
}
}
else
{
assert(oper == GT_MOD);
if (abs_imm > 2)
{
emit->emitIns_R_I(INS_and, size, REG_RAX, abs_imm - 1);
}
// RDX contains 'imm-1' if negative
emit->emitIns_R_R(INS_sub, size, REG_RAX, REG_RDX);
}

if (targetReg != REG_RAX)
{
inst_RV_RV(INS_mov, targetReg, REG_RAX, targetType);
}
}
else
{
assert (imm > 0);

if (targetReg != dividend->gtRegNum)
{
inst_RV_RV(INS_mov, targetReg, dividend->gtRegNum, targetType);
}

if (oper == GT_UDIV)
{
inst_RV_SH(INS_shr, size, targetReg, genLog2(unsigned(imm)));
}
else
{
assert(oper == GT_UMOD);

emit->emitIns_R_I(INS_and, size, targetReg, imm -1);
}
}
}


/***********************************************************************************************
* Generate code for localloc
Expand Down
Loading