//-------------------------------------------------------------------------------------------------- // ToGenTree - Convert a "condition" into a gentree node. // // Arguments: // comp Compiler instance to allocate trees // // Return Values: // Returns the gen tree representation for the conditional operator on lhs and rhs trees // GenTreePtr LC_Condition::ToGenTree(Compiler* comp) { GenTree* op1Tree = op1.ToGenTree(comp); GenTree* op2Tree = op2.ToGenTree(comp); assert(genTypeSize(genActualType(op1Tree->TypeGet())) == genTypeSize(genActualType(op2Tree->TypeGet()))); return comp->gtNewOperNode(oper, TYP_INT, op1Tree, op2Tree); }
//------------------------------------------------------------------------ // 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()); }
//------------------------------------------------------------------------ // LowerCast: Lower GT_CAST(srcType, DstType) nodes. // // Arguments: // tree - GT_CAST node to be lowered // // Return Value: // None. // // Notes: // Casts from float/double to a smaller int type are transformed as follows: // GT_CAST(float/double, byte) = GT_CAST(GT_CAST(float/double, int32), byte) // GT_CAST(float/double, sbyte) = GT_CAST(GT_CAST(float/double, int32), sbyte) // GT_CAST(float/double, int16) = GT_CAST(GT_CAST(double/double, int32), int16) // GT_CAST(float/double, uint16) = GT_CAST(GT_CAST(double/double, int32), uint16) // // Note that for the overflow conversions we still depend on helper calls and // don't expect to see them here. // i) GT_CAST(float/double, int type with overflow detection) // void Lowering::LowerCast(GenTree* tree) { assert(tree->OperGet() == GT_CAST); JITDUMP("LowerCast for: "); DISPNODE(tree); JITDUMP("\n"); GenTree* op1 = tree->gtOp.gtOp1; var_types dstType = tree->CastToType(); var_types srcType = genActualType(op1->TypeGet()); var_types tmpType = TYP_UNDEF; if (varTypeIsFloating(srcType)) { noway_assert(!tree->gtOverflow()); assert(!varTypeIsSmall(dstType)); // fgMorphCast creates intermediate casts when converting from float to small // int. } assert(!varTypeIsSmall(srcType)); if (tmpType != TYP_UNDEF) { GenTree* tmp = comp->gtNewCastNode(tmpType, op1, tree->IsUnsigned(), tmpType); tmp->gtFlags |= (tree->gtFlags & (GTF_OVERFLOW | GTF_EXCEPT)); tree->gtFlags &= ~GTF_UNSIGNED; tree->gtOp.gtOp1 = tmp; BlockRange().InsertAfter(op1, tmp); } // Now determine if we have operands that should be contained. ContainCheckCast(tree->AsCast()); }
//------------------------------------------------------------------------ // LowerCast: Lower GT_CAST(srcType, DstType) nodes. // // Arguments: // tree - GT_CAST node to be lowered // // Return Value: // None. // // Notes: // Casts from float/double to a smaller int type are transformed as follows: // GT_CAST(float/double, byte) = GT_CAST(GT_CAST(float/double, int32), byte) // GT_CAST(float/double, sbyte) = GT_CAST(GT_CAST(float/double, int32), sbyte) // GT_CAST(float/double, int16) = GT_CAST(GT_CAST(double/double, int32), int16) // GT_CAST(float/double, uint16) = GT_CAST(GT_CAST(double/double, int32), uint16) // // Note that for the overflow conversions we still depend on helper calls and // don't expect to see them here. // i) GT_CAST(float/double, int type with overflow detection) // void Lowering::LowerCast(GenTree* tree) { assert(tree->OperGet() == GT_CAST); JITDUMP("LowerCast for: "); DISPNODE(tree); JITDUMP("\n"); GenTreePtr op1 = tree->gtOp.gtOp1; var_types dstType = tree->CastToType(); var_types srcType = genActualType(op1->TypeGet()); var_types tmpType = TYP_UNDEF; if (varTypeIsFloating(srcType)) { noway_assert(!tree->gtOverflow()); } assert(!varTypeIsSmall(srcType)); // case of src is a floating point type and dst is a small type. if (varTypeIsFloating(srcType) && varTypeIsSmall(dstType)) { NYI_ARM("Lowering for cast from float to small type"); // Not tested yet. tmpType = TYP_INT; } if (tmpType != TYP_UNDEF) { GenTreePtr tmp = comp->gtNewCastNode(tmpType, op1, tmpType); tmp->gtFlags |= (tree->gtFlags & (GTF_UNSIGNED | GTF_OVERFLOW | GTF_EXCEPT)); tree->gtFlags &= ~GTF_UNSIGNED; tree->gtOp.gtOp1 = tmp; BlockRange().InsertAfter(op1, tmp); } // Now determine if we have operands that should be contained. ContainCheckCast(tree->AsCast()); }