bool CodeGeneratorX86Shared::visitOutOfLineUndoALUOperation(OutOfLineUndoALUOperation *ool) { LInstruction *ins = ool->ins(); Register reg = ToRegister(ins->getDef(0)); mozilla::DebugOnly<LAllocation *> lhs = ins->getOperand(0); LAllocation *rhs = ins->getOperand(1); JS_ASSERT(reg == ToRegister(lhs)); JS_ASSERT_IF(rhs->isGeneralReg(), reg != ToRegister(rhs)); // Undo the effect of the ALU operation, which was performed on the output // register and overflowed. Writing to the output register clobbered an // input reg, and the original value of the input needs to be recovered // to satisfy the constraint imposed by any RECOVERED_INPUT operands to // the bailout snapshot. if (rhs->isConstant()) { Imm32 constant(ToInt32(rhs)); if (ins->isAddI()) masm.subl(constant, reg); else masm.addl(constant, reg); } else { if (ins->isAddI()) masm.subl(ToOperand(rhs), reg); else masm.addl(ToOperand(rhs), reg); } return bailout(ool->ins()->snapshot()); }
bool GreedyAllocator::prescanUses(LInstruction *ins) { for (size_t i = 0; i < ins->numOperands(); i++) { LAllocation *a = ins->getOperand(i); if (!a->isUse()) { JS_ASSERT(a->isConstant()); continue; } LUse *use = a->toUse(); VirtualRegister *vr = getVirtualRegister(use); if (use->policy() == LUse::FIXED) { // A def or temp may use the same register, so we have to use the // unchecked version. disallowed.addUnchecked(GetFixedRegister(vr->def, use)); } else if (vr->hasRegister()) { discouraged.addUnchecked(vr->reg()); } } return true; }