//------------------------------------------------------------------------ // LowerRotate: Lower GT_ROL and GT_ROR nodes. // // Arguments: // tree - the node to lower // // Return Value: // None. // void Lowering::LowerRotate(GenTree* tree) { if (tree->OperGet() == GT_ROL) { // There is no ROL instruction on ARM. Convert ROL into ROR. GenTree* rotatedValue = tree->gtOp.gtOp1; unsigned rotatedValueBitSize = genTypeSize(rotatedValue->gtType) * 8; GenTree* rotateLeftIndexNode = tree->gtOp.gtOp2; if (rotateLeftIndexNode->IsCnsIntOrI()) { ssize_t rotateLeftIndex = rotateLeftIndexNode->gtIntCon.gtIconVal; ssize_t rotateRightIndex = rotatedValueBitSize - rotateLeftIndex; rotateLeftIndexNode->gtIntCon.gtIconVal = rotateRightIndex; } else { GenTree* tmp = comp->gtNewOperNode(GT_NEG, genActualType(rotateLeftIndexNode->gtType), rotateLeftIndexNode); BlockRange().InsertAfter(rotateLeftIndexNode, tmp); tree->gtOp.gtOp2 = tmp; } tree->ChangeOper(GT_ROR); } ContainCheckShiftRotate(tree->AsOp()); }
//------------------------------------------------------------------------ // TreeNodeInfoInitShiftRotate: Set the NodeInfo for a shift or rotate. // // Arguments: // tree - The node of interest // // Return Value: // None. // void Lowering::TreeNodeInfoInitShiftRotate(GenTree* tree) { ContainCheckShiftRotate(tree->AsOp()); TreeNodeInfo* info = &(tree->gtLsraInfo); LinearScan* l = m_lsra; GenTreePtr shiftBy = tree->gtOp.gtOp2; info->srcCount = shiftBy->isContained() ? 1 : 2; info->dstCount = 1; #ifdef _TARGET_ARM_ // The first operand of a GT_LSH_HI and GT_RSH_LO oper is a GT_LONG so that // we can have a three operand form. Increment the srcCount. GenTreePtr source = tree->gtOp.gtOp1; if (tree->OperGet() == GT_LSH_HI || tree->OperGet() == GT_RSH_LO) { assert((source->OperGet() == GT_LONG) && source->isContained()); info->srcCount++; if (tree->OperGet() == GT_LSH_HI) { GenTreePtr sourceLo = source->gtOp.gtOp1; sourceLo->gtLsraInfo.isDelayFree = true; } else { GenTreePtr sourceHi = source->gtOp.gtOp2; sourceHi->gtLsraInfo.isDelayFree = true; } source->gtLsraInfo.hasDelayFreeSrc = true; info->hasDelayFreeSrc = true; } #endif // _TARGET_ARM_ }