void GCInfo::gcMarkRegPtrVal(GenTreePtr tree) { if (varTypeIsGC(tree->TypeGet())) { if (tree->gtOper == GT_LCL_VAR) compiler->codeGen->genMarkLclVar(tree); if (tree->InReg()) { gcMarkRegSetNpt(genRegMask(tree->gtRegNum)); } } }
regNumber CodeGen::genAssignArithFloat(genTreeOps oper, GenTreePtr dst, regNumber dstreg, GenTreePtr src, regNumber srcreg) { regNumber result; // dst should be a regvar or memory if (dst->IsRegVar()) { regNumber reg = dst->gtRegNum; if (src->IsRegVar()) { inst_RV_RV(ins_MathOp(oper, dst->gtType), reg, src->gtRegNum, dst->gtType); } else { inst_RV_TT(ins_MathOp(oper, dst->gtType), reg, src, 0, EmitSize(dst)); } result = reg; } else // dst in memory { // since this is an asgop the ACTUAL destination is memory // but it is also one of the sources and SSE ops do not allow mem dests // so we have loaded it into a reg, and that is what dstreg represents assert(dstreg != REG_NA); if ( (src->InReg())) { inst_RV_RV(ins_MathOp(oper, dst->gtType), dstreg, src->gtRegNum, dst->gtType); } else { //mem mem operation inst_RV_TT(ins_MathOp(oper, dst->gtType), dstreg, src, 0, EmitSize(dst)); } dst->gtFlags &= ~GTF_REG_VAL; // ??? inst_TT_RV(ins_FloatStore(dst->gtType), dst, dstreg, 0, EmitSize(dst)); result = REG_NA; } return result; }
void CodeGen::genComputeAddressableFloat(GenTreePtr tree, regMaskTP addrRegInt, regMaskTP addrRegFlt, RegSet::KeepReg keptReg, regMaskTP needReg, RegSet::KeepReg keepReg, bool freeOnly /* = false */) { noway_assert(genStillAddressable(tree)); noway_assert(varTypeIsFloating(tree->TypeGet())); genDoneAddressableFloat(tree, addrRegInt, addrRegFlt, keptReg); regNumber reg; if (tree->InReg()) { reg = tree->gtRegNum; if (freeOnly && !(genRegMaskFloat(reg, tree->TypeGet()) & regSet.RegFreeFloat())) { goto LOAD_REG; } } else { LOAD_REG: RegSet::RegisterPreference pref(needReg, RBM_NONE); reg = regSet.PickRegFloat(tree->TypeGet(), &pref); genLoadFloat(tree, reg); } genMarkTreeInReg(tree, reg); if (keepReg == RegSet::KEEP_REG) { regSet.SetUsedRegFloat(tree, true); } }